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