The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/opencrypto/cbc_mac.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2018-2019 iXsystems Inc.  All rights reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   23  */
   24 
   25 #include <sys/cdefs.h>
   26 __FBSDID("$FreeBSD$");
   27 
   28 #include <sys/types.h>
   29 #include <sys/systm.h>
   30 #include <sys/param.h>
   31 #include <sys/endian.h>
   32 #include <opencrypto/cbc_mac.h>
   33 #include <opencrypto/xform_auth.h>
   34 
   35 /*
   36  * Given two CCM_CBC_BLOCK_LEN blocks, xor
   37  * them into dst, and then encrypt dst.
   38  */
   39 static void
   40 xor_and_encrypt(struct aes_cbc_mac_ctx *ctx,
   41                 const uint8_t *src, uint8_t *dst)
   42 {
   43         const uint64_t *b1;
   44         uint64_t *b2;
   45         uint64_t temp_block[CCM_CBC_BLOCK_LEN/sizeof(uint64_t)];
   46 
   47         b1 = (const uint64_t*)src;
   48         b2 = (uint64_t*)dst;
   49 
   50         for (size_t count = 0;
   51              count < CCM_CBC_BLOCK_LEN/sizeof(uint64_t);
   52              count++) {
   53                 temp_block[count] = b1[count] ^ b2[count];
   54         }
   55         rijndaelEncrypt(ctx->keysched, ctx->rounds, (void*)temp_block, dst);
   56 }
   57 
   58 void
   59 AES_CBC_MAC_Init(void *vctx)
   60 {
   61         struct aes_cbc_mac_ctx *ctx;
   62 
   63         ctx = vctx;
   64         bzero(ctx, sizeof(*ctx));
   65 }
   66 
   67 void
   68 AES_CBC_MAC_Setkey(void *vctx, const uint8_t *key, u_int klen)
   69 {
   70         struct aes_cbc_mac_ctx *ctx;
   71 
   72         ctx = vctx;
   73         ctx->rounds = rijndaelKeySetupEnc(ctx->keysched, key, klen * 8);
   74 }
   75 
   76 /*
   77  * This is called to set the nonce, aka IV.
   78  *
   79  * Note that the caller is responsible for constructing b0 as well
   80  * as the length and padding around the AAD and passing that data
   81  * to _Update.
   82  */
   83 void
   84 AES_CBC_MAC_Reinit(void *vctx, const uint8_t *nonce, u_int nonceLen)
   85 {
   86         struct aes_cbc_mac_ctx *ctx = vctx;
   87 
   88         ctx->nonce = nonce;
   89         ctx->nonceLength = nonceLen;
   90 
   91         ctx->blockIndex = 0;
   92 
   93         /* XOR b0 with all 0's on first call to _Update. */
   94         memset(ctx->block, 0, CCM_CBC_BLOCK_LEN);
   95 }
   96 
   97 int
   98 AES_CBC_MAC_Update(void *vctx, const void *vdata, u_int length)
   99 {
  100         struct aes_cbc_mac_ctx *ctx;
  101         const uint8_t *data;
  102         size_t copy_amt;
  103         
  104         ctx = vctx;
  105         data = vdata;
  106 
  107         /*
  108          * _Update can be called with non-aligned update lengths.  Use
  109          * the staging block when necessary.
  110          */
  111         while (length != 0) {
  112                 uint8_t *ptr;
  113 
  114                 /*
  115                  * If there is no partial block and the length is at
  116                  * least a full block, encrypt the full block without
  117                  * copying to the staging block.
  118                  */
  119                 if (ctx->blockIndex == 0 && length >= CCM_CBC_BLOCK_LEN) {
  120                         xor_and_encrypt(ctx, data, ctx->block);
  121                         length -= CCM_CBC_BLOCK_LEN;
  122                         data += CCM_CBC_BLOCK_LEN;
  123                         continue;
  124                 }
  125 
  126                 copy_amt = MIN(sizeof(ctx->staging_block) - ctx->blockIndex,
  127                     length);
  128                 ptr = ctx->staging_block + ctx->blockIndex;
  129                 bcopy(data, ptr, copy_amt);
  130                 data += copy_amt;
  131                 ctx->blockIndex += copy_amt;
  132                 length -= copy_amt;
  133                 if (ctx->blockIndex == sizeof(ctx->staging_block)) {
  134                         /* We've got a full block */
  135                         xor_and_encrypt(ctx, ctx->staging_block, ctx->block);
  136                         ctx->blockIndex = 0;
  137                 }
  138         }
  139         return (0);
  140 }
  141 
  142 void
  143 AES_CBC_MAC_Final(uint8_t *buf, void *vctx)
  144 {
  145         struct aes_cbc_mac_ctx *ctx;
  146         uint8_t s0[CCM_CBC_BLOCK_LEN];
  147 
  148         ctx = vctx;
  149 
  150         /*
  151          * We first need to check to see if we've got any data
  152          * left over to encrypt.
  153          */
  154         if (ctx->blockIndex != 0) {
  155                 memset(ctx->staging_block + ctx->blockIndex, 0,
  156                     CCM_CBC_BLOCK_LEN - ctx->blockIndex);
  157                 xor_and_encrypt(ctx, ctx->staging_block, ctx->block);
  158         }
  159         explicit_bzero(ctx->staging_block, sizeof(ctx->staging_block));
  160 
  161         bzero(s0, sizeof(s0));
  162         s0[0] = (15 - ctx->nonceLength) - 1;
  163         bcopy(ctx->nonce, s0 + 1, ctx->nonceLength);
  164         rijndaelEncrypt(ctx->keysched, ctx->rounds, s0, s0);
  165         for (size_t indx = 0; indx < AES_CBC_MAC_HASH_LEN; indx++)
  166                 buf[indx] = ctx->block[indx] ^ s0[indx];
  167         explicit_bzero(s0, sizeof(s0));
  168 }

Cache object: a0a374a0137fa46c1e50401f3942a673


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.