1392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* crypto/cmac/cmac.c */ 2392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * project. 4392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */ 5392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* ==================================================================== 6392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * Copyright (c) 2010 The OpenSSL Project. All rights reserved. 7392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 8392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * Redistribution and use in source and binary forms, with or without 9392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * modification, are permitted provided that the following conditions 10392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * are met: 11392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 12392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 1. Redistributions of source code must retain the above copyright 13392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * notice, this list of conditions and the following disclaimer. 14392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 15392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 2. Redistributions in binary form must reproduce the above copyright 16392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * notice, this list of conditions and the following disclaimer in 17392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * the documentation and/or other materials provided with the 18392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * distribution. 19392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 20392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 3. All advertising materials mentioning features or use of this 21392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * software must display the following acknowledgment: 22392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * "This product includes software developed by the OpenSSL Project 23392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 25392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * endorse or promote products derived from this software without 27392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * prior written permission. For written permission, please contact 28392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * licensing@OpenSSL.org. 29392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 30392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 5. Products derived from this software may not be called "OpenSSL" 31392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * nor may "OpenSSL" appear in their names without prior written 32392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * permission of the OpenSSL Project. 33392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 34392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 6. Redistributions of any form whatsoever must retain the following 35392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * acknowledgment: 36392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * "This product includes software developed by the OpenSSL Project 37392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 39392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * OF THE POSSIBILITY OF SUCH DAMAGE. 51392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * ==================================================================== 52392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */ 53392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 54392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <stdio.h> 55392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <stdlib.h> 56392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <string.h> 57392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include "cryptlib.h" 58392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/cmac.h> 59392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 60392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS 61392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/fips.h> 62392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 63392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 64392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstruct CMAC_CTX_st 65392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 66392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Cipher context to use */ 67392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom EVP_CIPHER_CTX cctx; 68392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Keys k1 and k2 */ 69392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned char k1[EVP_MAX_BLOCK_LENGTH]; 70392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned char k2[EVP_MAX_BLOCK_LENGTH]; 71392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Temporary block */ 72392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned char tbl[EVP_MAX_BLOCK_LENGTH]; 73392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Last (possibly partial) block */ 74392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned char last_block[EVP_MAX_BLOCK_LENGTH]; 75392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Number of bytes in last block: -1 means context not initialised */ 76392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom int nlast_block; 77392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom }; 78392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 79392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 80392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* Make temporary keys K1 and K2 */ 81392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 82392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic void make_kn(unsigned char *k1, unsigned char *l, int bl) 83392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 84392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom int i; 85392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Shift block to left, including carry */ 86392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i = 0; i < bl; i++) 87392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 88392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom k1[i] = l[i] << 1; 89392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (i < bl - 1 && l[i + 1] & 0x80) 90392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom k1[i] |= 1; 91392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 92392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* If MSB set fixup with R */ 93392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (l[0] & 0x80) 94392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b; 95392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 96392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 97392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromCMAC_CTX *CMAC_CTX_new(void) 98392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 99392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom CMAC_CTX *ctx; 100392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx = OPENSSL_malloc(sizeof(CMAC_CTX)); 101392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!ctx) 102392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return NULL; 103392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom EVP_CIPHER_CTX_init(&ctx->cctx); 104392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nlast_block = -1; 105392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return ctx; 106392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 107392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 108392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid CMAC_CTX_cleanup(CMAC_CTX *ctx) 109392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 110392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS 111392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (FIPS_mode() && !ctx->cctx.engine) 112392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 113392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom FIPS_cmac_ctx_cleanup(ctx); 114392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return; 115392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 116392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 117392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom EVP_CIPHER_CTX_cleanup(&ctx->cctx); 118392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH); 119392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH); 120392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH); 121392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH); 122392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nlast_block = -1; 123392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 124392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 125392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromEVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx) 126392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 127392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return &ctx->cctx; 128392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 129392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 130392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid CMAC_CTX_free(CMAC_CTX *ctx) 131392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 132392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom CMAC_CTX_cleanup(ctx); 133392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom OPENSSL_free(ctx); 134392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 135392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 136392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in) 137392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 138392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom int bl; 139392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (in->nlast_block == -1) 140392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 141392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx)) 142392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 143392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom bl = EVP_CIPHER_CTX_block_size(&in->cctx); 144392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memcpy(out->k1, in->k1, bl); 145392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memcpy(out->k2, in->k2, bl); 146392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memcpy(out->tbl, in->tbl, bl); 147392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memcpy(out->last_block, in->last_block, bl); 148392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom out->nlast_block = in->nlast_block; 149392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 1; 150392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 151392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 152392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, 153392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom const EVP_CIPHER *cipher, ENGINE *impl) 154392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 155392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH]; 156392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS 157392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (FIPS_mode()) 158392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 159392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* If we have an ENGINE need to allow non FIPS */ 160392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if ((impl || ctx->cctx.engine) 161392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom && !(ctx->cctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) 162392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 163392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 164392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS); 165392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 166392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 167392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Other algorithm blocking will be done in FIPS_cmac_init, 168392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * via FIPS_cipherinit(). 169392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */ 170392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!impl && !ctx->cctx.engine) 171392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return FIPS_cmac_init(ctx, key, keylen, cipher, NULL); 172392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 173392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 174392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* All zeros means restart */ 175392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!key && !cipher && !impl && keylen == 0) 176392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 177392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Not initialised */ 178392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (ctx->nlast_block == -1) 179392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 180392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) 181392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 182a1a5710c055e139ea00e785f9eb55b3af3e4dab1Brian Carlstrom memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx)); 183a1a5710c055e139ea00e785f9eb55b3af3e4dab1Brian Carlstrom ctx->nlast_block = 0; 184392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 1; 185392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 186392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Initialiase context */ 187392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL)) 188392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 189392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Non-NULL key means initialisation complete */ 190392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (key) 191392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 192392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom int bl; 193392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EVP_CIPHER_CTX_cipher(&ctx->cctx)) 194392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 195392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen)) 196392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 197392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv)) 198392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 199392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); 200392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl)) 201392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 202392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom make_kn(ctx->k1, ctx->tbl, bl); 203392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom make_kn(ctx->k2, ctx->k1, bl); 204392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom OPENSSL_cleanse(ctx->tbl, bl); 205392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Reset context again ready for first data block */ 206392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) 207392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 208392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Zero tbl so resume works */ 209392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memset(ctx->tbl, 0, bl); 210392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nlast_block = 0; 211392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 212392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 1; 213392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 214392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 215392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) 216392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 217392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom const unsigned char *data = in; 218392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t bl; 219392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS 220392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (FIPS_mode() && !ctx->cctx.engine) 221392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return FIPS_cmac_update(ctx, in, dlen); 222392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 223392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (ctx->nlast_block == -1) 224392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 225392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (dlen == 0) 226392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 1; 227392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); 228392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Copy into partial block if we need to */ 229392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (ctx->nlast_block > 0) 230392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 231392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t nleft; 232392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom nleft = bl - ctx->nlast_block; 233392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (dlen < nleft) 234392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom nleft = dlen; 235392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memcpy(ctx->last_block + ctx->nlast_block, data, nleft); 236392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom dlen -= nleft; 237392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nlast_block += nleft; 238392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* If no more to process return */ 239392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (dlen == 0) 240392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 1; 241392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom data += nleft; 242392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Else not final block so encrypt it */ 243392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block,bl)) 244392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 245392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 246392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Encrypt all but one of the complete blocks left */ 247392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom while(dlen > bl) 248392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 249392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl)) 250392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 251392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom dlen -= bl; 252392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom data += bl; 253392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 254392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Copy any data left to last block buffer */ 255392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memcpy(ctx->last_block, data, dlen); 256392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nlast_block = dlen; 257392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 1; 258392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 259392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 260392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 261392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen) 262392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 263392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom int i, bl, lb; 264392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS 265392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (FIPS_mode() && !ctx->cctx.engine) 266392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return FIPS_cmac_final(ctx, out, poutlen); 267392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 268392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (ctx->nlast_block == -1) 269392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 270392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); 271392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom *poutlen = (size_t)bl; 272392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!out) 273392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 1; 274392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom lb = ctx->nlast_block; 275392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Is last block complete? */ 276392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (lb == bl) 277392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 278392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i = 0; i < bl; i++) 279392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom out[i] = ctx->last_block[i] ^ ctx->k1[i]; 280392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 281392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom else 282392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 283392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->last_block[lb] = 0x80; 284392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (bl - lb > 1) 285392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memset(ctx->last_block + lb + 1, 0, bl - lb - 1); 286392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i = 0; i < bl; i++) 287392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom out[i] = ctx->last_block[i] ^ ctx->k2[i]; 288392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 289392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EVP_Cipher(&ctx->cctx, out, out, bl)) 290392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 291392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom OPENSSL_cleanse(out, bl); 292392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 293392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 294392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 1; 295392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 296392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 297392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint CMAC_resume(CMAC_CTX *ctx) 298392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 299392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (ctx->nlast_block == -1) 300392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 301392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* The buffer "tbl" containes the last fully encrypted block 302392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * which is the last IV (or all zeroes if no last encrypted block). 303392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * The last block has not been modified since CMAC_final(). 304392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * So reinitliasing using the last decrypted block will allow 305392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * CMAC to continue after calling CMAC_Final(). 306392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */ 307392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, ctx->tbl); 308392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 309