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