1 /* 2 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 /* 11 * CMAC low level APIs are deprecated for public use, but still ok for internal 12 * use. 13 */ 14 #include "internal/deprecated.h" 15 16 #include <stdio.h> 17 #include <string.h> 18 #include <stdlib.h> 19 20 #include "internal/nelem.h" 21 22 #include <openssl/cmac.h> 23 #include <openssl/aes.h> 24 #include <openssl/evp.h> 25 26 #include "testutil.h" 27 28 static const char xtskey[32] = { 29 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 30 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 31 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f 32 }; 33 34 static struct test_st { 35 const char key[32]; 36 int key_len; 37 const unsigned char data[64]; 38 int data_len; 39 const char *mac; 40 } test[3] = { 41 { 42 { 43 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 44 0x0b, 0x0c, 0x0d, 0x0e, 0x0f 45 }, 46 16, 47 "My test data", 48 12, 49 "29cec977c48f63c200bd5c4a6881b224" 50 }, 51 { 52 { 53 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 54 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 55 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f 56 }, 57 32, 58 "My test data", 59 12, 60 "db6493aa04e4761f473b2b453c031c9a" 61 }, 62 { 63 { 64 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 65 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 66 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f 67 }, 68 32, 69 "My test data again", 70 18, 71 "65c11c75ecf590badd0a5e56cbb8af60" 72 }, 73 }; 74 75 static char *pt(unsigned char *md, unsigned int len); 76 77 static int test_cmac_bad(void) 78 { 79 CMAC_CTX *ctx = NULL; 80 int ret = 0; 81 82 ctx = CMAC_CTX_new(); 83 if (!TEST_ptr(ctx) 84 || !TEST_false(CMAC_Init(ctx, NULL, 0, NULL, NULL)) 85 || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len)) 86 /* Should be able to pass cipher first, and then key */ 87 || !TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_128_cbc(), NULL)) 88 /* Must have a key */ 89 || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len)) 90 /* Now supply the key */ 91 || !TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, NULL, NULL)) 92 /* Update should now work */ 93 || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len)) 94 /* XTS is not a suitable cipher to use */ 95 || !TEST_false(CMAC_Init(ctx, xtskey, sizeof(xtskey), EVP_aes_128_xts(), 96 NULL)) 97 || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len))) 98 goto err; 99 100 ret = 1; 101 err: 102 CMAC_CTX_free(ctx); 103 return ret; 104 } 105 106 static int test_cmac_run(void) 107 { 108 char *p; 109 CMAC_CTX *ctx = NULL; 110 unsigned char buf[AES_BLOCK_SIZE]; 111 size_t len; 112 int ret = 0; 113 114 ctx = CMAC_CTX_new(); 115 116 if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, 117 EVP_aes_128_cbc(), NULL)) 118 || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len)) 119 || !TEST_true(CMAC_Final(ctx, buf, &len))) 120 goto err; 121 122 p = pt(buf, len); 123 if (!TEST_str_eq(p, test[0].mac)) 124 goto err; 125 126 if (!TEST_true(CMAC_Init(ctx, test[1].key, test[1].key_len, 127 EVP_aes_256_cbc(), NULL)) 128 || !TEST_true(CMAC_Update(ctx, test[1].data, test[1].data_len)) 129 || !TEST_true(CMAC_Final(ctx, buf, &len))) 130 goto err; 131 132 p = pt(buf, len); 133 if (!TEST_str_eq(p, test[1].mac)) 134 goto err; 135 136 if (!TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL)) 137 || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len)) 138 || !TEST_true(CMAC_Final(ctx, buf, &len))) 139 goto err; 140 p = pt(buf, len); 141 if (!TEST_str_eq(p, test[2].mac)) 142 goto err; 143 /* Test reusing a key */ 144 if (!TEST_true(CMAC_Init(ctx, NULL, 0, NULL, NULL)) 145 || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len)) 146 || !TEST_true(CMAC_Final(ctx, buf, &len))) 147 goto err; 148 p = pt(buf, len); 149 if (!TEST_str_eq(p, test[2].mac)) 150 goto err; 151 152 /* Test setting the cipher and key separately */ 153 if (!TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_256_cbc(), NULL)) 154 || !TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL)) 155 || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len)) 156 || !TEST_true(CMAC_Final(ctx, buf, &len))) 157 goto err; 158 p = pt(buf, len); 159 if (!TEST_str_eq(p, test[2].mac)) 160 goto err; 161 162 ret = 1; 163 err: 164 CMAC_CTX_free(ctx); 165 return ret; 166 } 167 168 static int test_cmac_copy(void) 169 { 170 char *p; 171 CMAC_CTX *ctx = NULL, *ctx2 = NULL; 172 unsigned char buf[AES_BLOCK_SIZE]; 173 size_t len; 174 int ret = 0; 175 176 ctx = CMAC_CTX_new(); 177 ctx2 = CMAC_CTX_new(); 178 if (!TEST_ptr(ctx) || !TEST_ptr(ctx2)) 179 goto err; 180 181 if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, 182 EVP_aes_128_cbc(), NULL)) 183 || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len)) 184 || !TEST_true(CMAC_CTX_copy(ctx2, ctx)) 185 || !TEST_true(CMAC_Final(ctx2, buf, &len))) 186 goto err; 187 188 p = pt(buf, len); 189 if (!TEST_str_eq(p, test[0].mac)) 190 goto err; 191 192 ret = 1; 193 err: 194 CMAC_CTX_free(ctx2); 195 CMAC_CTX_free(ctx); 196 return ret; 197 } 198 199 static char *pt(unsigned char *md, unsigned int len) 200 { 201 unsigned int i; 202 static char buf[80]; 203 204 for (i = 0; i < len; i++) 205 sprintf(&(buf[i * 2]), "%02x", md[i]); 206 return buf; 207 } 208 209 int setup_tests(void) 210 { 211 ADD_TEST(test_cmac_bad); 212 ADD_TEST(test_cmac_run); 213 ADD_TEST(test_cmac_copy); 214 return 1; 215 } 216 217