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