1 /* $OpenBSD: cmac.c,v 1.24 2024/05/20 14:53:37 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_local.h" 61 62 /* 63 * This implementation follows https://doi.org/10.6028/NIST.SP.800-38B 64 */ 65 66 /* 67 * CMAC context. k1 and k2 are the secret subkeys, computed as in section 6.1. 68 * The temporary block tbl is a scratch buffer that holds intermediate secrets. 69 */ 70 struct CMAC_CTX_st { 71 EVP_CIPHER_CTX *cipher_ctx; 72 unsigned char k1[EVP_MAX_BLOCK_LENGTH]; 73 unsigned char k2[EVP_MAX_BLOCK_LENGTH]; 74 unsigned char tbl[EVP_MAX_BLOCK_LENGTH]; 75 unsigned char last_block[EVP_MAX_BLOCK_LENGTH]; 76 /* Bytes in last block. -1 means not initialized. */ 77 int nlast_block; 78 }; 79 80 /* 81 * SP 800-38B, section 6.1, steps 2 and 3: given the input key l, calculate 82 * the subkeys k1 and k2: shift l one bit to the left. If the most significant 83 * bit of l was 1, additionally xor the result with Rb to get kn. 84 * 85 * Step 2: calculate k1 with l being the intermediate block CIPH_K(0), 86 * Step 3: calculate k2 from l == k1. 87 * 88 * Per 5.3, Rb is the lexically first irreducible polynomial of degree b with 89 * the minimum number of non-zero terms. This gives R128 = (1 << 128) | 0x87 90 * and R64 = (1 << 64) | 0x1b for the only supported block sizes 128 and 64. 91 */ 92 static void 93 make_kn(unsigned char *kn, const unsigned char *l, int block_size) 94 { 95 unsigned char mask, Rb; 96 int i; 97 98 /* Choose Rb according to the block size in bytes. */ 99 Rb = block_size == 16 ? 0x87 : 0x1b; 100 101 /* Compute l << 1 up to last byte. */ 102 for (i = 0; i < block_size - 1; i++) 103 kn[i] = (l[i] << 1) | (l[i + 1] >> 7); 104 105 /* Only xor with Rb if the MSB is one. */ 106 mask = 0 - (l[0] >> 7); 107 kn[block_size - 1] = (l[block_size - 1] << 1) ^ (Rb & mask); 108 } 109 110 CMAC_CTX * 111 CMAC_CTX_new(void) 112 { 113 CMAC_CTX *ctx; 114 115 if ((ctx = calloc(1, sizeof(CMAC_CTX))) == NULL) 116 goto err; 117 if ((ctx->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) 118 goto err; 119 120 ctx->nlast_block = -1; 121 122 return ctx; 123 124 err: 125 CMAC_CTX_free(ctx); 126 127 return NULL; 128 } 129 LCRYPTO_ALIAS(CMAC_CTX_new); 130 131 void 132 CMAC_CTX_cleanup(CMAC_CTX *ctx) 133 { 134 (void)EVP_CIPHER_CTX_reset(ctx->cipher_ctx); 135 explicit_bzero(ctx->tbl, EVP_MAX_BLOCK_LENGTH); 136 explicit_bzero(ctx->k1, EVP_MAX_BLOCK_LENGTH); 137 explicit_bzero(ctx->k2, EVP_MAX_BLOCK_LENGTH); 138 explicit_bzero(ctx->last_block, EVP_MAX_BLOCK_LENGTH); 139 ctx->nlast_block = -1; 140 } 141 LCRYPTO_ALIAS(CMAC_CTX_cleanup); 142 143 EVP_CIPHER_CTX * 144 CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx) 145 { 146 return ctx->cipher_ctx; 147 } 148 LCRYPTO_ALIAS(CMAC_CTX_get0_cipher_ctx); 149 150 void 151 CMAC_CTX_free(CMAC_CTX *ctx) 152 { 153 if (ctx == NULL) 154 return; 155 156 CMAC_CTX_cleanup(ctx); 157 EVP_CIPHER_CTX_free(ctx->cipher_ctx); 158 freezero(ctx, sizeof(CMAC_CTX)); 159 } 160 LCRYPTO_ALIAS(CMAC_CTX_free); 161 162 int 163 CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in) 164 { 165 int block_size; 166 167 if (in->nlast_block == -1) 168 return 0; 169 if (!EVP_CIPHER_CTX_copy(out->cipher_ctx, in->cipher_ctx)) 170 return 0; 171 block_size = EVP_CIPHER_CTX_block_size(in->cipher_ctx); 172 memcpy(out->k1, in->k1, block_size); 173 memcpy(out->k2, in->k2, block_size); 174 memcpy(out->tbl, in->tbl, block_size); 175 memcpy(out->last_block, in->last_block, block_size); 176 out->nlast_block = in->nlast_block; 177 return 1; 178 } 179 LCRYPTO_ALIAS(CMAC_CTX_copy); 180 181 int 182 CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, 183 const EVP_CIPHER *cipher, ENGINE *impl) 184 { 185 static const unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH]; 186 int block_size; 187 188 /* All zeros means restart */ 189 if (key == NULL && cipher == NULL && keylen == 0) { 190 /* Not initialised */ 191 if (ctx->nlast_block == -1) 192 return 0; 193 if (!EVP_EncryptInit_ex(ctx->cipher_ctx, NULL, NULL, NULL, zero_iv)) 194 return 0; 195 explicit_bzero(ctx->tbl, sizeof(ctx->tbl)); 196 ctx->nlast_block = 0; 197 return 1; 198 } 199 200 /* Initialise context. */ 201 if (cipher != NULL) { 202 /* 203 * Disallow ciphers for which EVP_Cipher() behaves differently. 204 * These are AEAD ciphers (or AES keywrap) for which the CMAC 205 * construction makes little sense. 206 */ 207 if ((cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0) 208 return 0; 209 if (!EVP_EncryptInit_ex(ctx->cipher_ctx, cipher, NULL, NULL, NULL)) 210 return 0; 211 } 212 213 /* Non-NULL key means initialisation is complete. */ 214 if (key != NULL) { 215 if (EVP_CIPHER_CTX_cipher(ctx->cipher_ctx) == NULL) 216 return 0; 217 218 /* make_kn() only supports block sizes of 8 and 16 bytes. */ 219 block_size = EVP_CIPHER_CTX_block_size(ctx->cipher_ctx); 220 if (block_size != 8 && block_size != 16) 221 return 0; 222 223 /* 224 * Section 6.1, step 1: store the intermediate secret CIPH_K(0) 225 * in ctx->tbl. 226 */ 227 if (!EVP_CIPHER_CTX_set_key_length(ctx->cipher_ctx, keylen)) 228 return 0; 229 if (!EVP_EncryptInit_ex(ctx->cipher_ctx, NULL, NULL, key, zero_iv)) 230 return 0; 231 if (!EVP_Cipher(ctx->cipher_ctx, ctx->tbl, zero_iv, block_size)) 232 return 0; 233 234 /* Section 6.1, step 2: compute k1 from intermediate secret. */ 235 make_kn(ctx->k1, ctx->tbl, block_size); 236 /* Section 6.1, step 3: compute k2 from k1. */ 237 make_kn(ctx->k2, ctx->k1, block_size); 238 239 /* Destroy intermediate secret and reset last block count. */ 240 explicit_bzero(ctx->tbl, sizeof(ctx->tbl)); 241 ctx->nlast_block = 0; 242 243 /* Reset context again to get ready for the first data block. */ 244 if (!EVP_EncryptInit_ex(ctx->cipher_ctx, NULL, NULL, NULL, zero_iv)) 245 return 0; 246 } 247 248 return 1; 249 } 250 LCRYPTO_ALIAS(CMAC_Init); 251 252 int 253 CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) 254 { 255 const unsigned char *data = in; 256 size_t block_size; 257 258 if (ctx->nlast_block == -1) 259 return 0; 260 if (dlen == 0) 261 return 1; 262 block_size = EVP_CIPHER_CTX_block_size(ctx->cipher_ctx); 263 /* Copy into partial block if we need to */ 264 if (ctx->nlast_block > 0) { 265 size_t nleft; 266 267 nleft = block_size - ctx->nlast_block; 268 if (dlen < nleft) 269 nleft = dlen; 270 memcpy(ctx->last_block + ctx->nlast_block, data, nleft); 271 dlen -= nleft; 272 ctx->nlast_block += nleft; 273 /* If no more to process return */ 274 if (dlen == 0) 275 return 1; 276 data += nleft; 277 /* Else not final block so encrypt it */ 278 if (!EVP_Cipher(ctx->cipher_ctx, ctx->tbl, ctx->last_block, 279 block_size)) 280 return 0; 281 } 282 /* Encrypt all but one of the complete blocks left */ 283 while (dlen > block_size) { 284 if (!EVP_Cipher(ctx->cipher_ctx, ctx->tbl, data, block_size)) 285 return 0; 286 dlen -= block_size; 287 data += block_size; 288 } 289 /* Copy any data left to last block buffer */ 290 memcpy(ctx->last_block, data, dlen); 291 ctx->nlast_block = dlen; 292 return 1; 293 } 294 LCRYPTO_ALIAS(CMAC_Update); 295 296 int 297 CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen) 298 { 299 int i, block_size, lb; 300 301 if (ctx->nlast_block == -1) 302 return 0; 303 block_size = EVP_CIPHER_CTX_block_size(ctx->cipher_ctx); 304 *poutlen = (size_t)block_size; 305 if (!out) 306 return 1; 307 lb = ctx->nlast_block; 308 /* Is last block complete? */ 309 if (lb == block_size) { 310 for (i = 0; i < block_size; i++) 311 out[i] = ctx->last_block[i] ^ ctx->k1[i]; 312 } else { 313 ctx->last_block[lb] = 0x80; 314 if (block_size - lb > 1) 315 memset(ctx->last_block + lb + 1, 0, block_size - lb - 1); 316 for (i = 0; i < block_size; i++) 317 out[i] = ctx->last_block[i] ^ ctx->k2[i]; 318 } 319 if (!EVP_Cipher(ctx->cipher_ctx, out, out, block_size)) { 320 explicit_bzero(out, block_size); 321 return 0; 322 } 323 return 1; 324 } 325 LCRYPTO_ALIAS(CMAC_Final); 326