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