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/crypto/cmac.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 /*      $OpenBSD: cmac.c,v 1.3 2017/05/02 17:07:06 mikeb Exp $  */
    2 
    3 /*-
    4  * Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 
   19 /*
   20  * This code implements the CMAC (Cipher-based Message Authentication)
   21  * algorithm described in FIPS SP800-38B using the AES-128 cipher.
   22  */
   23 
   24 #include <sys/param.h>
   25 #include <sys/systm.h>
   26 
   27 #include <crypto/aes.h>
   28 #include <crypto/cmac.h>
   29 
   30 #define LSHIFT(v, r) do {                                       \
   31         int i;                                                  \
   32         for (i = 0; i < 15; i++)                                \
   33                 (r)[i] = (v)[i] << 1 | (v)[i + 1] >> 7;         \
   34         (r)[15] = (v)[15] << 1;                                 \
   35 } while (0)
   36 
   37 #define XOR(v, r) do {                                          \
   38         int i;                                                  \
   39         for (i = 0; i < 16; i++)                                \
   40                 (r)[i] ^= (v)[i];                               \
   41 } while (0)
   42 
   43 void
   44 AES_CMAC_Init(AES_CMAC_CTX *ctx)
   45 {
   46         memset(ctx->X, 0, sizeof ctx->X);
   47         ctx->M_n = 0;
   48 }
   49 
   50 void
   51 AES_CMAC_SetKey(AES_CMAC_CTX *ctx, const u_int8_t key[AES_CMAC_KEY_LENGTH])
   52 {
   53         AES_Setkey(&ctx->aesctx, key, 16);
   54 }
   55 
   56 void
   57 AES_CMAC_Update(AES_CMAC_CTX *ctx, const u_int8_t *data, u_int len)
   58 {
   59         u_int mlen;
   60 
   61         if (ctx->M_n > 0) {
   62                 mlen = MIN(16 - ctx->M_n, len);
   63                 memcpy(ctx->M_last + ctx->M_n, data, mlen);
   64                 ctx->M_n += mlen;
   65                 if (ctx->M_n < 16 || len == mlen)
   66                         return;
   67                 XOR(ctx->M_last, ctx->X);
   68                 AES_Encrypt(&ctx->aesctx, ctx->X, ctx->X);
   69                 data += mlen;
   70                 len -= mlen;
   71         }
   72         while (len > 16) {      /* not last block */
   73                 XOR(data, ctx->X);
   74                 AES_Encrypt(&ctx->aesctx, ctx->X, ctx->X);
   75                 data += 16;
   76                 len -= 16;
   77         }
   78         /* potential last block, save it */
   79         memcpy(ctx->M_last, data, len);
   80         ctx->M_n = len;
   81 }
   82 
   83 void
   84 AES_CMAC_Final(u_int8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX *ctx)
   85 {
   86         u_int8_t K[16];
   87 
   88         /* generate subkey K1 */
   89         memset(K, 0, sizeof K);
   90         AES_Encrypt(&ctx->aesctx, K, K);
   91 
   92         if (K[0] & 0x80) {
   93                 LSHIFT(K, K);
   94                 K[15] ^= 0x87;
   95         } else
   96                 LSHIFT(K, K);
   97 
   98         if (ctx->M_n == 16) {
   99                 /* last block was a complete block */
  100                 XOR(K, ctx->M_last);
  101         } else {
  102                 /* generate subkey K2 */
  103                 if (K[0] & 0x80) {
  104                         LSHIFT(K, K);
  105                         K[15] ^= 0x87;
  106                 } else
  107                         LSHIFT(K, K);
  108 
  109                 /* padding(M_last) */
  110                 ctx->M_last[ctx->M_n] = 0x80;
  111                 while (++ctx->M_n < 16)
  112                         ctx->M_last[ctx->M_n] = 0;
  113 
  114                 XOR(K, ctx->M_last);
  115         }
  116         XOR(ctx->M_last, ctx->X);
  117         AES_Encrypt(&ctx->aesctx, ctx->X, digest);
  118 
  119         explicit_bzero(K, sizeof K);
  120 }

Cache object: a702da82763f6209b997b246d5783d9e


[ 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.