LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/cmac - cmac.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 98 0.0 %
Date: 2015-10-10 Functions: 0 10 0.0 %

          Line data    Source code
       1             : /* crypto/cmac/cmac.c */
       2             : /*
       3             :  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
       4             :  * project.
       5             :  */
       6             : /* ====================================================================
       7             :  * Copyright (c) 2010 The OpenSSL Project.  All rights reserved.
       8             :  *
       9             :  * Redistribution and use in source and binary forms, with or without
      10             :  * modification, are permitted provided that the following conditions
      11             :  * are met:
      12             :  *
      13             :  * 1. Redistributions of source code must retain the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer.
      15             :  *
      16             :  * 2. Redistributions in binary form must reproduce the above copyright
      17             :  *    notice, this list of conditions and the following disclaimer in
      18             :  *    the documentation and/or other materials provided with the
      19             :  *    distribution.
      20             :  *
      21             :  * 3. All advertising materials mentioning features or use of this
      22             :  *    software must display the following acknowledgment:
      23             :  *    "This product includes software developed by the OpenSSL Project
      24             :  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
      25             :  *
      26             :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      27             :  *    endorse or promote products derived from this software without
      28             :  *    prior written permission. For written permission, please contact
      29             :  *    licensing@OpenSSL.org.
      30             :  *
      31             :  * 5. Products derived from this software may not be called "OpenSSL"
      32             :  *    nor may "OpenSSL" appear in their names without prior written
      33             :  *    permission of the OpenSSL Project.
      34             :  *
      35             :  * 6. Redistributions of any form whatsoever must retain the following
      36             :  *    acknowledgment:
      37             :  *    "This product includes software developed by the OpenSSL Project
      38             :  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
      39             :  *
      40             :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      41             :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      42             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      43             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      44             :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      45             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      46             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      47             :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      49             :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      50             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      51             :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      52             :  * ====================================================================
      53             :  */
      54             : 
      55             : #include <stdio.h>
      56             : #include <stdlib.h>
      57             : #include <string.h>
      58             : #include "cryptlib.h"
      59             : #include <openssl/cmac.h>
      60             : 
      61             : #ifdef OPENSSL_FIPS
      62             : # include <openssl/fips.h>
      63             : #endif
      64             : 
      65             : struct CMAC_CTX_st {
      66             :     /* Cipher context to use */
      67             :     EVP_CIPHER_CTX cctx;
      68             :     /* Keys k1 and k2 */
      69             :     unsigned char k1[EVP_MAX_BLOCK_LENGTH];
      70             :     unsigned char k2[EVP_MAX_BLOCK_LENGTH];
      71             :     /* Temporary block */
      72             :     unsigned char tbl[EVP_MAX_BLOCK_LENGTH];
      73             :     /* Last (possibly partial) block */
      74             :     unsigned char last_block[EVP_MAX_BLOCK_LENGTH];
      75             :     /* Number of bytes in last block: -1 means context not initialised */
      76             :     int nlast_block;
      77             : };
      78             : 
      79             : /* Make temporary keys K1 and K2 */
      80             : 
      81           0 : static void make_kn(unsigned char *k1, unsigned char *l, int bl)
      82             : {
      83             :     int i;
      84             :     /* Shift block to left, including carry */
      85           0 :     for (i = 0; i < bl; i++) {
      86           0 :         k1[i] = l[i] << 1;
      87           0 :         if (i < bl - 1 && l[i + 1] & 0x80)
      88           0 :             k1[i] |= 1;
      89             :     }
      90             :     /* If MSB set fixup with R */
      91           0 :     if (l[0] & 0x80)
      92           0 :         k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b;
      93           0 : }
      94             : 
      95           0 : CMAC_CTX *CMAC_CTX_new(void)
      96             : {
      97             :     CMAC_CTX *ctx;
      98           0 :     ctx = OPENSSL_malloc(sizeof(CMAC_CTX));
      99           0 :     if (!ctx)
     100             :         return NULL;
     101           0 :     EVP_CIPHER_CTX_init(&ctx->cctx);
     102           0 :     ctx->nlast_block = -1;
     103           0 :     return ctx;
     104             : }
     105             : 
     106           0 : void CMAC_CTX_cleanup(CMAC_CTX *ctx)
     107             : {
     108             : #ifdef OPENSSL_FIPS
     109             :     if (FIPS_mode() && !ctx->cctx.engine) {
     110             :         FIPS_cmac_ctx_cleanup(ctx);
     111             :         return;
     112             :     }
     113             : #endif
     114           0 :     EVP_CIPHER_CTX_cleanup(&ctx->cctx);
     115           0 :     OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH);
     116           0 :     OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH);
     117           0 :     OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH);
     118           0 :     OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH);
     119           0 :     ctx->nlast_block = -1;
     120           0 : }
     121             : 
     122           0 : EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx)
     123             : {
     124           0 :     return &ctx->cctx;
     125             : }
     126             : 
     127           0 : void CMAC_CTX_free(CMAC_CTX *ctx)
     128             : {
     129           0 :     if (!ctx)
     130           0 :         return;
     131           0 :     CMAC_CTX_cleanup(ctx);
     132           0 :     OPENSSL_free(ctx);
     133             : }
     134             : 
     135           0 : int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
     136             : {
     137             :     int bl;
     138           0 :     if (in->nlast_block == -1)
     139             :         return 0;
     140           0 :     if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx))
     141             :         return 0;
     142           0 :     bl = EVP_CIPHER_CTX_block_size(&in->cctx);
     143           0 :     memcpy(out->k1, in->k1, bl);
     144           0 :     memcpy(out->k2, in->k2, bl);
     145           0 :     memcpy(out->tbl, in->tbl, bl);
     146           0 :     memcpy(out->last_block, in->last_block, bl);
     147           0 :     out->nlast_block = in->nlast_block;
     148           0 :     return 1;
     149             : }
     150             : 
     151           0 : int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
     152             :               const EVP_CIPHER *cipher, ENGINE *impl)
     153             : {
     154             :     static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH];
     155             : #ifdef OPENSSL_FIPS
     156             :     if (FIPS_mode()) {
     157             :         /* If we have an ENGINE need to allow non FIPS */
     158             :         if ((impl || ctx->cctx.engine)
     159             :             && !(ctx->cctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) {
     160             :             EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS);
     161             :             return 0;
     162             :         }
     163             :         /*
     164             :          * Other algorithm blocking will be done in FIPS_cmac_init, via
     165             :          * FIPS_cipherinit().
     166             :          */
     167             :         if (!impl && !ctx->cctx.engine)
     168             :             return FIPS_cmac_init(ctx, key, keylen, cipher, NULL);
     169             :     }
     170             : #endif
     171             :     /* All zeros means restart */
     172           0 :     if (!key && !cipher && !impl && keylen == 0) {
     173             :         /* Not initialised */
     174           0 :         if (ctx->nlast_block == -1)
     175             :             return 0;
     176           0 :         if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
     177             :             return 0;
     178           0 :         memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx));
     179           0 :         ctx->nlast_block = 0;
     180           0 :         return 1;
     181             :     }
     182             :     /* Initialiase context */
     183           0 :     if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL))
     184             :         return 0;
     185             :     /* Non-NULL key means initialisation complete */
     186           0 :     if (key) {
     187             :         int bl;
     188           0 :         if (!EVP_CIPHER_CTX_cipher(&ctx->cctx))
     189             :             return 0;
     190           0 :         if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen))
     191             :             return 0;
     192           0 :         if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv))
     193             :             return 0;
     194           0 :         bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
     195           0 :         if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl))
     196             :             return 0;
     197           0 :         make_kn(ctx->k1, ctx->tbl, bl);
     198           0 :         make_kn(ctx->k2, ctx->k1, bl);
     199           0 :         OPENSSL_cleanse(ctx->tbl, bl);
     200             :         /* Reset context again ready for first data block */
     201           0 :         if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
     202             :             return 0;
     203             :         /* Zero tbl so resume works */
     204             :         memset(ctx->tbl, 0, bl);
     205           0 :         ctx->nlast_block = 0;
     206             :     }
     207             :     return 1;
     208             : }
     209             : 
     210           0 : int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
     211             : {
     212             :     const unsigned char *data = in;
     213             :     size_t bl;
     214             : #ifdef OPENSSL_FIPS
     215             :     if (FIPS_mode() && !ctx->cctx.engine)
     216             :         return FIPS_cmac_update(ctx, in, dlen);
     217             : #endif
     218           0 :     if (ctx->nlast_block == -1)
     219             :         return 0;
     220           0 :     if (dlen == 0)
     221             :         return 1;
     222           0 :     bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
     223             :     /* Copy into partial block if we need to */
     224           0 :     if (ctx->nlast_block > 0) {
     225             :         size_t nleft;
     226           0 :         nleft = bl - ctx->nlast_block;
     227           0 :         if (dlen < nleft)
     228             :             nleft = dlen;
     229           0 :         memcpy(ctx->last_block + ctx->nlast_block, data, nleft);
     230           0 :         dlen -= nleft;
     231           0 :         ctx->nlast_block += nleft;
     232             :         /* If no more to process return */
     233           0 :         if (dlen == 0)
     234             :             return 1;
     235           0 :         data += nleft;
     236             :         /* Else not final block so encrypt it */
     237           0 :         if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block, bl))
     238             :             return 0;
     239             :     }
     240             :     /* Encrypt all but one of the complete blocks left */
     241           0 :     while (dlen > bl) {
     242           0 :         if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl))
     243             :             return 0;
     244           0 :         dlen -= bl;
     245           0 :         data += bl;
     246             :     }
     247             :     /* Copy any data left to last block buffer */
     248           0 :     memcpy(ctx->last_block, data, dlen);
     249           0 :     ctx->nlast_block = dlen;
     250           0 :     return 1;
     251             : 
     252             : }
     253             : 
     254           0 : int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
     255             : {
     256             :     int i, bl, lb;
     257             : #ifdef OPENSSL_FIPS
     258             :     if (FIPS_mode() && !ctx->cctx.engine)
     259             :         return FIPS_cmac_final(ctx, out, poutlen);
     260             : #endif
     261           0 :     if (ctx->nlast_block == -1)
     262             :         return 0;
     263           0 :     bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
     264           0 :     *poutlen = (size_t)bl;
     265           0 :     if (!out)
     266             :         return 1;
     267           0 :     lb = ctx->nlast_block;
     268             :     /* Is last block complete? */
     269           0 :     if (lb == bl) {
     270           0 :         for (i = 0; i < bl; i++)
     271           0 :             out[i] = ctx->last_block[i] ^ ctx->k1[i];
     272             :     } else {
     273           0 :         ctx->last_block[lb] = 0x80;
     274           0 :         if (bl - lb > 1)
     275           0 :             memset(ctx->last_block + lb + 1, 0, bl - lb - 1);
     276           0 :         for (i = 0; i < bl; i++)
     277           0 :             out[i] = ctx->last_block[i] ^ ctx->k2[i];
     278             :     }
     279           0 :     if (!EVP_Cipher(&ctx->cctx, out, out, bl)) {
     280           0 :         OPENSSL_cleanse(out, bl);
     281           0 :         return 0;
     282             :     }
     283             :     return 1;
     284             : }
     285             : 
     286           0 : int CMAC_resume(CMAC_CTX *ctx)
     287             : {
     288           0 :     if (ctx->nlast_block == -1)
     289             :         return 0;
     290             :     /*
     291             :      * The buffer "tbl" containes the last fully encrypted block which is the
     292             :      * last IV (or all zeroes if no last encrypted block). The last block has
     293             :      * not been modified since CMAC_final(). So reinitliasing using the last
     294             :      * decrypted block will allow CMAC to continue after calling
     295             :      * CMAC_Final().
     296             :      */
     297           0 :     return EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, ctx->tbl);
     298             : }

Generated by: LCOV version 1.10