1 1.1 christos /* 2 1.1 christos * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos * 4 1.1 christos * Licensed under the Apache License 2.0 (the "License"). You may not use 5 1.1 christos * this file except in compliance with the License. You can obtain a copy 6 1.1 christos * in the file LICENSE in the source distribution or at 7 1.1 christos * https://www.openssl.org/source/license.html 8 1.1 christos */ 9 1.1 christos 10 1.1 christos /* 11 1.1 christos * CMAC low level APIs are deprecated for public use, but still ok for internal 12 1.1 christos * use. 13 1.1 christos */ 14 1.1 christos #include "internal/deprecated.h" 15 1.1 christos 16 1.1 christos #include <stdio.h> 17 1.1 christos #include <string.h> 18 1.1 christos #include <stdlib.h> 19 1.1 christos 20 1.1 christos #include "internal/nelem.h" 21 1.1 christos 22 1.1 christos #include <openssl/cmac.h> 23 1.1 christos #include <openssl/aes.h> 24 1.1 christos #include <openssl/evp.h> 25 1.1 christos 26 1.1 christos #include "testutil.h" 27 1.1 christos 28 1.1 christos static const char xtskey[32] = { 29 1.1 christos 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 30 1.1 christos 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 31 1.1 christos 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f 32 1.1 christos }; 33 1.1 christos 34 1.1 christos static struct test_st { 35 1.1 christos const char key[32]; 36 1.1 christos int key_len; 37 1.1 christos unsigned char data[4096]; 38 1.1 christos int data_len; 39 1.1 christos const char *mac; 40 1.1 christos } test[] = { 41 1.1.1.2 christos { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 42 1.1.1.2 christos 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, 43 1.1 christos 16, 44 1.1 christos "My test data", 45 1.1 christos 12, 46 1.1.1.2 christos "29cec977c48f63c200bd5c4a6881b224" }, 47 1.1.1.2 christos { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 48 1.1.1.2 christos 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 49 1.1.1.2 christos 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, 50 1.1 christos 32, 51 1.1 christos "My test data", 52 1.1 christos 12, 53 1.1.1.2 christos "db6493aa04e4761f473b2b453c031c9a" }, 54 1.1.1.2 christos { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 55 1.1.1.2 christos 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 56 1.1.1.2 christos 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, 57 1.1 christos 32, 58 1.1 christos "My test data again", 59 1.1 christos 18, 60 1.1.1.2 christos "65c11c75ecf590badd0a5e56cbb8af60" }, 61 1.1 christos /* for aes-128-cbc */ 62 1.1 christos { 63 1.1.1.2 christos { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 64 1.1.1.2 christos 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, 65 1.1 christos 16, 66 1.1 christos /* repeat the string below until filling 3072 bytes */ 67 1.1 christos "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#", 68 1.1 christos 3072, 69 1.1.1.2 christos "35da8a02a7afce90e5b711308cee2dee" }, 70 1.1 christos /* for aes-192-cbc */ 71 1.1 christos { 72 1.1.1.2 christos { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 73 1.1 christos 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 74 1.1.1.2 christos 0x16, 0x17 }, 75 1.1 christos 24, 76 1.1 christos /* repeat the string below until filling 4095 bytes */ 77 1.1 christos "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#", 78 1.1 christos 4095, 79 1.1.1.2 christos "59053f4e81f3593610f987adb547c5b2" }, 80 1.1 christos /* for aes-256-cbc */ 81 1.1 christos { 82 1.1.1.2 christos { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 83 1.1 christos 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 84 1.1.1.2 christos 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, 85 1.1 christos 32, 86 1.1 christos /* repeat the string below until filling 2560 bytes */ 87 1.1 christos "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#", 88 1.1 christos 2560, 89 1.1.1.2 christos "9c6cf85f7f4baca99725764a0df973a9" }, 90 1.1 christos /* for des-ede3-cbc */ 91 1.1 christos { 92 1.1.1.2 christos { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 93 1.1 christos 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 94 1.1.1.2 christos 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, 95 1.1 christos 24, 96 1.1 christos /* repeat the string below until filling 2048 bytes */ 97 1.1 christos "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#", 98 1.1 christos 2048, 99 1.1.1.2 christos "2c2fccc7fcc5d98a" }, 100 1.1 christos /* for sm4-cbc */ 101 1.1 christos { 102 1.1.1.2 christos { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 103 1.1.1.2 christos 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, 104 1.1 christos 16, 105 1.1 christos /* repeat the string below until filling 2049 bytes */ 106 1.1 christos "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#", 107 1.1 christos 2049, 108 1.1.1.2 christos "c9a9cbc82a3b2d96074e386fce1216f2" }, 109 1.1 christos }; 110 1.1 christos 111 1.1 christos static char *pt(unsigned char *md, unsigned int len); 112 1.1 christos 113 1.1 christos static int test_cmac_bad(void) 114 1.1 christos { 115 1.1 christos CMAC_CTX *ctx = NULL; 116 1.1 christos int ret = 0; 117 1.1 christos 118 1.1 christos ctx = CMAC_CTX_new(); 119 1.1 christos if (!TEST_ptr(ctx) 120 1.1 christos || !TEST_false(CMAC_Init(ctx, NULL, 0, NULL, NULL)) 121 1.1 christos || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len)) 122 1.1.1.2 christos /* Should be able to pass cipher first, and then key */ 123 1.1 christos || !TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_128_cbc(), NULL)) 124 1.1.1.2 christos /* Must have a key */ 125 1.1 christos || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len)) 126 1.1.1.2 christos /* Now supply the key */ 127 1.1 christos || !TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, NULL, NULL)) 128 1.1.1.2 christos /* Update should now work */ 129 1.1 christos || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len)) 130 1.1.1.2 christos /* XTS is not a suitable cipher to use */ 131 1.1 christos || !TEST_false(CMAC_Init(ctx, xtskey, sizeof(xtskey), EVP_aes_128_xts(), 132 1.1.1.2 christos NULL)) 133 1.1 christos || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len))) 134 1.1 christos goto err; 135 1.1 christos 136 1.1 christos ret = 1; 137 1.1 christos err: 138 1.1 christos CMAC_CTX_free(ctx); 139 1.1 christos return ret; 140 1.1 christos } 141 1.1 christos 142 1.1 christos static int test_cmac_run(void) 143 1.1 christos { 144 1.1 christos char *p; 145 1.1 christos CMAC_CTX *ctx = NULL; 146 1.1 christos unsigned char buf[AES_BLOCK_SIZE]; 147 1.1 christos size_t len; 148 1.1 christos int ret = 0; 149 1.1 christos size_t case_idx = 0; 150 1.1 christos 151 1.1 christos ctx = CMAC_CTX_new(); 152 1.1 christos 153 1.1 christos /* Construct input data, fill repeatedly until reaching data length */ 154 1.1 christos for (case_idx = 0; case_idx < OSSL_NELEM(test); case_idx++) { 155 1.1 christos size_t str_len = strlen((char *)test[case_idx].data); 156 1.1 christos size_t fill_len = test[case_idx].data_len - str_len; 157 1.1 christos size_t fill_idx = str_len; 158 1.1 christos while (fill_len > 0) { 159 1.1 christos if (fill_len > str_len) { 160 1.1 christos memcpy(&test[case_idx].data[fill_idx], test[case_idx].data, str_len); 161 1.1 christos fill_len -= str_len; 162 1.1 christos fill_idx += str_len; 163 1.1 christos } else { 164 1.1 christos memcpy(&test[case_idx].data[fill_idx], test[case_idx].data, fill_len); 165 1.1 christos fill_len = 0; 166 1.1 christos } 167 1.1 christos } 168 1.1 christos } 169 1.1 christos 170 1.1 christos if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, 171 1.1.1.2 christos EVP_aes_128_cbc(), NULL)) 172 1.1 christos || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len)) 173 1.1 christos || !TEST_true(CMAC_Final(ctx, buf, &len))) 174 1.1 christos goto err; 175 1.1 christos 176 1.1 christos p = pt(buf, len); 177 1.1 christos if (!TEST_str_eq(p, test[0].mac)) 178 1.1 christos goto err; 179 1.1 christos 180 1.1 christos if (!TEST_true(CMAC_Init(ctx, test[1].key, test[1].key_len, 181 1.1.1.2 christos EVP_aes_256_cbc(), NULL)) 182 1.1 christos || !TEST_true(CMAC_Update(ctx, test[1].data, test[1].data_len)) 183 1.1 christos || !TEST_true(CMAC_Final(ctx, buf, &len))) 184 1.1 christos goto err; 185 1.1 christos 186 1.1 christos p = pt(buf, len); 187 1.1 christos if (!TEST_str_eq(p, test[1].mac)) 188 1.1 christos goto err; 189 1.1 christos 190 1.1 christos if (!TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL)) 191 1.1 christos || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len)) 192 1.1 christos || !TEST_true(CMAC_Final(ctx, buf, &len))) 193 1.1 christos goto err; 194 1.1 christos p = pt(buf, len); 195 1.1 christos if (!TEST_str_eq(p, test[2].mac)) 196 1.1 christos goto err; 197 1.1 christos /* Test reusing a key */ 198 1.1 christos if (!TEST_true(CMAC_Init(ctx, NULL, 0, NULL, NULL)) 199 1.1 christos || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len)) 200 1.1 christos || !TEST_true(CMAC_Final(ctx, buf, &len))) 201 1.1 christos goto err; 202 1.1 christos p = pt(buf, len); 203 1.1 christos if (!TEST_str_eq(p, test[2].mac)) 204 1.1 christos goto err; 205 1.1 christos 206 1.1 christos /* Test setting the cipher and key separately */ 207 1.1 christos if (!TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_256_cbc(), NULL)) 208 1.1 christos || !TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL)) 209 1.1 christos || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len)) 210 1.1 christos || !TEST_true(CMAC_Final(ctx, buf, &len))) 211 1.1 christos goto err; 212 1.1 christos p = pt(buf, len); 213 1.1 christos if (!TEST_str_eq(p, test[2].mac)) 214 1.1 christos goto err; 215 1.1 christos 216 1.1 christos /* Test data length is greater than 1 block length */ 217 1.1 christos if (!TEST_true(CMAC_Init(ctx, test[3].key, test[3].key_len, 218 1.1.1.2 christos EVP_aes_128_cbc(), NULL)) 219 1.1 christos || !TEST_true(CMAC_Update(ctx, test[3].data, test[3].data_len)) 220 1.1 christos || !TEST_true(CMAC_Final(ctx, buf, &len))) 221 1.1 christos goto err; 222 1.1 christos p = pt(buf, len); 223 1.1 christos if (!TEST_str_eq(p, test[3].mac)) 224 1.1 christos goto err; 225 1.1 christos 226 1.1 christos if (!TEST_true(CMAC_Init(ctx, test[4].key, test[4].key_len, 227 1.1.1.2 christos EVP_aes_192_cbc(), NULL)) 228 1.1 christos || !TEST_true(CMAC_Update(ctx, test[4].data, test[4].data_len)) 229 1.1 christos || !TEST_true(CMAC_Final(ctx, buf, &len))) 230 1.1 christos goto err; 231 1.1 christos p = pt(buf, len); 232 1.1 christos if (!TEST_str_eq(p, test[4].mac)) 233 1.1 christos goto err; 234 1.1 christos 235 1.1 christos if (!TEST_true(CMAC_Init(ctx, test[5].key, test[5].key_len, 236 1.1.1.2 christos EVP_aes_256_cbc(), NULL)) 237 1.1 christos || !TEST_true(CMAC_Update(ctx, test[5].data, test[5].data_len)) 238 1.1 christos || !TEST_true(CMAC_Final(ctx, buf, &len))) 239 1.1 christos goto err; 240 1.1 christos p = pt(buf, len); 241 1.1 christos if (!TEST_str_eq(p, test[5].mac)) 242 1.1 christos goto err; 243 1.1 christos 244 1.1 christos #ifndef OPENSSL_NO_DES 245 1.1 christos if (!TEST_true(CMAC_Init(ctx, test[6].key, test[6].key_len, 246 1.1.1.2 christos EVP_des_ede3_cbc(), NULL)) 247 1.1 christos || !TEST_true(CMAC_Update(ctx, test[6].data, test[6].data_len)) 248 1.1 christos || !TEST_true(CMAC_Final(ctx, buf, &len))) 249 1.1 christos goto err; 250 1.1 christos p = pt(buf, len); 251 1.1 christos if (!TEST_str_eq(p, test[6].mac)) 252 1.1 christos goto err; 253 1.1 christos #endif 254 1.1 christos 255 1.1 christos #ifndef OPENSSL_NO_SM4 256 1.1 christos if (!TEST_true(CMAC_Init(ctx, test[7].key, test[7].key_len, 257 1.1.1.2 christos EVP_sm4_cbc(), NULL)) 258 1.1 christos || !TEST_true(CMAC_Update(ctx, test[7].data, test[7].data_len)) 259 1.1 christos || !TEST_true(CMAC_Final(ctx, buf, &len))) 260 1.1 christos goto err; 261 1.1 christos p = pt(buf, len); 262 1.1 christos if (!TEST_str_eq(p, test[7].mac)) 263 1.1 christos goto err; 264 1.1 christos #endif 265 1.1 christos 266 1.1 christos ret = 1; 267 1.1 christos err: 268 1.1 christos CMAC_CTX_free(ctx); 269 1.1 christos return ret; 270 1.1 christos } 271 1.1 christos 272 1.1 christos static int test_cmac_copy(void) 273 1.1 christos { 274 1.1 christos char *p; 275 1.1 christos CMAC_CTX *ctx = NULL, *ctx2 = NULL; 276 1.1 christos unsigned char buf[AES_BLOCK_SIZE]; 277 1.1 christos size_t len; 278 1.1 christos int ret = 0; 279 1.1 christos 280 1.1 christos ctx = CMAC_CTX_new(); 281 1.1 christos ctx2 = CMAC_CTX_new(); 282 1.1 christos if (!TEST_ptr(ctx) || !TEST_ptr(ctx2)) 283 1.1 christos goto err; 284 1.1 christos 285 1.1 christos if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, 286 1.1.1.2 christos EVP_aes_128_cbc(), NULL)) 287 1.1 christos || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len)) 288 1.1 christos || !TEST_true(CMAC_CTX_copy(ctx2, ctx)) 289 1.1 christos || !TEST_true(CMAC_Final(ctx2, buf, &len))) 290 1.1 christos goto err; 291 1.1 christos 292 1.1 christos p = pt(buf, len); 293 1.1 christos if (!TEST_str_eq(p, test[0].mac)) 294 1.1 christos goto err; 295 1.1 christos 296 1.1 christos ret = 1; 297 1.1 christos err: 298 1.1 christos CMAC_CTX_free(ctx2); 299 1.1 christos CMAC_CTX_free(ctx); 300 1.1 christos return ret; 301 1.1 christos } 302 1.1 christos 303 1.1 christos #define OSSL_HEX_CHARS_PER_BYTE 2 304 1.1 christos static char *pt(unsigned char *md, unsigned int len) 305 1.1 christos { 306 1.1 christos unsigned int i; 307 1.1 christos static char buf[81]; 308 1.1 christos 309 1.1 christos for (i = 0; i < len && (i + 1) * OSSL_HEX_CHARS_PER_BYTE < sizeof(buf); i++) 310 1.1 christos BIO_snprintf(buf + i * OSSL_HEX_CHARS_PER_BYTE, 311 1.1.1.2 christos OSSL_HEX_CHARS_PER_BYTE + 1, "%02x", md[i]); 312 1.1 christos return buf; 313 1.1 christos } 314 1.1 christos 315 1.1 christos int setup_tests(void) 316 1.1 christos { 317 1.1 christos ADD_TEST(test_cmac_bad); 318 1.1 christos ADD_TEST(test_cmac_run); 319 1.1 christos ADD_TEST(test_cmac_copy); 320 1.1 christos return 1; 321 1.1 christos } 322