1 /* test_cmac_mode.c - TinyCrypt AES-CMAC tests (including SP 800-38B tests) */
2
3 /*
4 * Copyright (C) 2015 by Intel Corporation, All Rights Reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * - Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * - Neither the name of Intel Corporation nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32 /*
33 * DESCRIPTION
34 * This module tests the following AES-CMAC test (including SP 800-38B):
35 *
36 * Scenarios tested include:
37 * - CMAC test #1 (GF(2^128) double))
38 * - CMAC test #2 null msg (SP 800-38B test vector #1)
39 * - CMAC test #3 1 block msg (SP 800-38B test vector #2)
40 * - CMAC test #4 320 bit msg (SP 800-38B test vector #3)
41 * - CMAC test #5 512 bit msg(SP 800-38B test vector #4)
42 */
43
44 #include <tinycrypt/cmac_mode.h>
45 #include <tinycrypt/constants.h>
46 #include <tinycrypt/aes.h>
47 #include <zephyr/test_utils.h>
48
49 #include <stdio.h>
50 #include <string.h>
51 #include <zephyr/ztest.h>
52
53 #define BUF_LEN 16
54
show(const char * label,const uint8_t * s,size_t slen)55 static void show(const char *label, const uint8_t *s, size_t slen)
56 {
57 uint32_t i;
58
59 TC_PRINT("%s\t", label);
60 for (i = 0U; i < slen; ++i) {
61 TC_PRINT("%02x", s[i]);
62 }
63 TC_PRINT("\n");
64 }
65
66 extern void gf_double(uint8_t *out, uint8_t *in);
67
verify_gf_2_128_double(uint8_t * K1,uint8_t * K2,struct tc_cmac_struct s)68 static uint32_t verify_gf_2_128_double(uint8_t *K1, uint8_t *K2, struct tc_cmac_struct s)
69 {
70 uint32_t result = TC_PASS;
71
72 TC_PRINT("Performing CMAC test #1 (GF(2^128) double):\n");
73
74 uint8_t zero[BUF_LEN];
75 uint8_t L[BUF_LEN];
76 const uint8_t l[BUF_LEN] = {
77 0x7d, 0xf7, 0x6b, 0x0c, 0x1a, 0xb8, 0x99, 0xb3,
78 0x3e, 0x42, 0xf0, 0x47, 0xb9, 0x1b, 0x54, 0x6f
79 };
80 const uint8_t k1[BUF_LEN] = {
81 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
82 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
83 };
84 const uint8_t k2[BUF_LEN] = {
85 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
86 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
87 };
88
89 (void) memset(zero, '\0', sizeof(zero));
90 tc_aes_encrypt(L, zero, s.sched);
91 if (memcmp(L, l, BUF_LEN) != 0) {
92 TC_ERROR("%s: AES encryption failed\n", __func__);
93 show("expected L =", l, sizeof(l));
94 show("computed L =", L, sizeof(L));
95 return TC_FAIL;
96 }
97
98 gf_double(K1, L);
99 if (memcmp(K1, k1, BUF_LEN) != 0) {
100 TC_ERROR("%s: gf_2_128_double failed when msb = 0\n", __func__);
101 show("expected K1 =", k1, sizeof(k1));
102 show("computed K1 =", K1, sizeof(k1));
103 return TC_FAIL;
104 }
105
106 gf_double(K2, K1);
107 if (memcmp(K2, k2, BUF_LEN) != 0) {
108 TC_ERROR("%s: gf_2_128_double failed when msb = 1\n", __func__);
109 show("expected K2 =", k2, sizeof(k2));
110 show("computed K2 =", K2, sizeof(k2));
111 return TC_FAIL;
112 }
113
114 return result;
115 }
116
verify_cmac_null_msg(TCCmacState_t s)117 static uint32_t verify_cmac_null_msg(TCCmacState_t s)
118 {
119 uint32_t result = TC_PASS;
120
121 TC_PRINT("Performing CMAC test #2 (SP 800-38B test vector #1):\n");
122
123 const uint8_t tag[BUF_LEN] = {
124 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
125 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
126 };
127 uint8_t Tag[BUF_LEN];
128
129 (void) tc_cmac_init(s);
130 (void) tc_cmac_update(s, (const uint8_t *) 0, 0);
131 (void) tc_cmac_final(Tag, s);
132
133 if (memcmp(Tag, tag, BUF_LEN) != 0) {
134 TC_ERROR("%s: aes_cmac failed with null msg = 1\n", __func__);
135 show("expected Tag =", tag, sizeof(tag));
136 show("computed Tag =", Tag, sizeof(Tag));
137 return TC_FAIL;
138 }
139
140 return result;
141 }
142
verify_cmac_1_block_msg(TCCmacState_t s)143 static uint32_t verify_cmac_1_block_msg(TCCmacState_t s)
144 {
145 uint32_t result = TC_PASS;
146
147 TC_PRINT("Performing CMAC test #3 (SP 800-38B test vector #2):\n");
148
149 const uint8_t msg[BUF_LEN] = {
150 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
151 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a
152 };
153 const uint8_t tag[BUF_LEN] = {
154 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
155 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
156 };
157 uint8_t Tag[BUF_LEN];
158
159 (void) tc_cmac_init(s);
160 (void) tc_cmac_update(s, msg, sizeof(msg));
161 (void) tc_cmac_final(Tag, s);
162
163 if (memcmp(Tag, tag, BUF_LEN) != 0) {
164 TC_ERROR("%s: aes_cmac failed with 1 block msg\n", __func__);
165 show("aes_cmac failed with 1 block msg =", msg, sizeof(msg));
166 show("expected Tag =", tag, sizeof(tag));
167 show("computed Tag =", Tag, sizeof(Tag));
168 return TC_FAIL;
169 }
170
171 return result;
172 }
173
verify_cmac_320_bit_msg(TCCmacState_t s)174 static uint32_t verify_cmac_320_bit_msg(TCCmacState_t s)
175 {
176 uint32_t result = TC_PASS;
177
178 TC_PRINT("Performing CMAC test #4 (SP 800-38B test vector #3):\n");
179
180 const uint8_t msg[40] = {
181 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
182 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
183 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
184 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
185 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11
186 };
187 const uint8_t tag[BUF_LEN] = {
188 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
189 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
190 };
191 uint8_t Tag[BUF_LEN];
192
193 (void) tc_cmac_init(s);
194 (void) tc_cmac_update(s, msg, sizeof(msg));
195 (void) tc_cmac_final(Tag, s);
196
197 if (memcmp(Tag, tag, BUF_LEN) != 0) {
198 TC_ERROR("%s: aes_cmac failed with 320 bit msg\n", __func__);
199 show("aes_cmac failed with 320 bit msg =", msg, sizeof(msg));
200 show("expected Tag =", tag, sizeof(tag));
201 show("computed Tag =", Tag, sizeof(Tag));
202 return TC_FAIL;
203 }
204
205 return result;
206 }
207
verify_cmac_512_bit_msg(TCCmacState_t s)208 static uint32_t verify_cmac_512_bit_msg(TCCmacState_t s)
209 {
210 uint32_t result = TC_PASS;
211
212 TC_PRINT("Performing CMAC test #5 (SP 800-38B test vector #4)\n");
213
214 const uint8_t msg[64] = {
215 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
216 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
217 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
218 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
219 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
220 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
221 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
222 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
223 };
224 const uint8_t tag[BUF_LEN] = {
225 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
226 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
227 };
228 uint8_t Tag[BUF_LEN];
229
230 (void)tc_cmac_init(s);
231 (void)tc_cmac_update(s, msg, sizeof(msg));
232 (void)tc_cmac_final(Tag, s);
233
234 if (memcmp(Tag, tag, BUF_LEN) != 0) {
235 TC_ERROR("%s: aes_cmac failed with 512 bit msg\n", __func__);
236 show("aes_cmac failed with 512 bit msg =", msg, sizeof(msg));
237 show("expected Tag =", tag, sizeof(tag));
238 show("computed Tag =", Tag, sizeof(Tag));
239 return TC_FAIL;
240 }
241
242 return result;
243 }
244
245 /*
246 * Main task to test CMAC
247 */
248
ZTEST(tinycrypt,test_cmac_mode)249 ZTEST(tinycrypt, test_cmac_mode)
250 {
251
252 uint32_t result = TC_PASS;
253
254 struct tc_cmac_struct state;
255 struct tc_aes_key_sched_struct sched;
256
257 const uint8_t key[BUF_LEN] = {
258 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
259 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
260 };
261 uint8_t K1[BUF_LEN], K2[BUF_LEN];
262
263
264 (void) tc_cmac_setup(&state, key, &sched);
265 result = verify_gf_2_128_double(K1, K2, state);
266
267 /**TESTPOINT: Check result - test 1*/
268 zassert_false(result, "CMAC test #1 (128 double) failed");
269
270 (void) tc_cmac_setup(&state, key, &sched);
271 result = verify_cmac_null_msg(&state);
272
273 /**TESTPOINT: Check result - test 2*/
274 zassert_false(result, "CMAC test #2 (null msg) failed");
275
276 (void) tc_cmac_setup(&state, key, &sched);
277 result = verify_cmac_1_block_msg(&state);
278
279 /**TESTPOINT: Check result - test 3*/
280 zassert_false(result, "CMAC test #1 (1 block msg) failed");
281
282 (void) tc_cmac_setup(&state, key, &sched);
283 result = verify_cmac_320_bit_msg(&state);
284
285 /**TESTPOINT: Check result - test 4*/
286 zassert_false(result, "CMAC test #1 (320 bit msg) failed");
287
288 (void) tc_cmac_setup(&state, key, &sched);
289 result = verify_cmac_512_bit_msg(&state);
290
291 /**TESTPOINT: Check result - test 5*/
292 zassert_false(result, "CMAC test #1 (512 bit msg) failed");
293
294 TC_PRINT("All CMAC tests succeeded!\n");
295 }
296