1 /*
2  * Copyright (c) 2016 Intel Corporation.
3  * Copyright 2025 NXP
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /* Sample to illustrate the usage of crypto APIs.
9  */
10 
11 #include <zephyr/device.h>
12 #include <zephyr/kernel.h>
13 #include <string.h>
14 #include <zephyr/crypto/crypto.h>
15 
16 #define LOG_LEVEL CONFIG_CRYPTO_LOG_LEVEL
17 #include <zephyr/logging/log.h>
18 LOG_MODULE_REGISTER(main);
19 
20 #ifdef CONFIG_CRYPTO_MBEDTLS_SHIM
21 #define CRYPTO_DRV_NAME CONFIG_CRYPTO_MBEDTLS_SHIM_DRV_NAME
22 #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_cryp)
23 #define CRYPTO_DEV_COMPAT st_stm32_cryp
24 #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_aes)
25 #define CRYPTO_DEV_COMPAT st_stm32_aes
26 #elif DT_HAS_COMPAT_STATUS_OKAY(nxp_mcux_dcp)
27 #define CRYPTO_DEV_COMPAT nxp_mcux_dcp
28 #elif DT_HAS_COMPAT_STATUS_OKAY(nxp_s32_crypto_hse_mu)
29 #define CRYPTO_DEV_COMPAT nxp_s32_crypto_hse_mu
30 #elif CONFIG_CRYPTO_NRF_ECB
31 #define CRYPTO_DEV_COMPAT nordic_nrf_ecb
32 #elif DT_HAS_COMPAT_STATUS_OKAY(renesas_smartbond_crypto)
33 #define CRYPTO_DEV_COMPAT renesas_smartbond_crypto
34 #elif DT_HAS_COMPAT_STATUS_OKAY(ti_cc23x0_aes)
35 #define CRYPTO_DEV_COMPAT ti_cc23x0_aes
36 #elif CONFIG_CRYPTO_SI32
37 #define CRYPTO_DEV_COMPAT silabs_si32_aes
38 #elif CONFIG_CRYPTO_ESP32_AES
39 #define CRYPTO_DEV_COMPAT espressif_esp32_aes
40 #else
41 #error "You need to enable one crypto device"
42 #endif
43 
44 /* Some crypto drivers require IO buffers to be aligned, i.e. due to underlying DMA requirements. */
45 #define IO_ALIGNMENT_BYTES 4
46 
47 const static uint8_t key[16]
48 	__aligned(IO_ALIGNMENT_BYTES) = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
49 					 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
50 
51 static uint8_t plaintext[64] __aligned(IO_ALIGNMENT_BYTES) = {
52 	0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73,
53 	0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7,
54 	0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4,
55 	0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45,
56 	0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10};
57 
58 uint32_t cap_flags;
59 
print_buffer_comparison(const uint8_t * wanted_result,uint8_t * result,size_t length)60 static void print_buffer_comparison(const uint8_t *wanted_result,
61 				    uint8_t *result, size_t length)
62 {
63 	int i, j;
64 
65 	printk("Was waiting for: \n");
66 
67 	for (i = 0, j = 1; i < length; i++, j++) {
68 		printk("0x%02x ", wanted_result[i]);
69 
70 		if (j == 10) {
71 			printk("\n");
72 			j = 0;
73 		}
74 	}
75 
76 	printk("\nBut got:\n");
77 
78 	for (i = 0, j = 1; i < length; i++, j++) {
79 		printk("0x%02x ", result[i]);
80 
81 		if (j == 10) {
82 			printk("\n");
83 			j = 0;
84 		}
85 	}
86 
87 	printk("\n");
88 }
89 
validate_hw_compatibility(const struct device * dev)90 int validate_hw_compatibility(const struct device *dev)
91 {
92 	uint32_t flags = 0U;
93 
94 	flags = crypto_query_hwcaps(dev);
95 	if ((flags & CAP_RAW_KEY) == 0U) {
96 		LOG_INF("Please provision the key separately "
97 			"as the module doesnt support a raw key");
98 		return -1;
99 	}
100 
101 	if ((flags & CAP_SYNC_OPS) == 0U) {
102 		LOG_ERR("The app assumes sync semantics. "
103 		  "Please rewrite the app accordingly before proceeding");
104 		return -1;
105 	}
106 
107 	if ((flags & CAP_SEPARATE_IO_BUFS) == 0U) {
108 		LOG_ERR("The app assumes distinct IO buffers. "
109 		"Please rewrite the app accordingly before proceeding");
110 		return -1;
111 	}
112 
113 	cap_flags = CAP_RAW_KEY | CAP_SYNC_OPS | CAP_SEPARATE_IO_BUFS;
114 
115 	return 0;
116 
117 }
118 
ecb_mode(const struct device * dev)119 void ecb_mode(const struct device *dev)
120 {
121 	/* from FIPS-197 test vectors */
122 	const uint8_t ecb_key[16] = {
123 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
124 		0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
125 	};
126 	uint8_t ecb_plaintext[16]
127 		__aligned(IO_ALIGNMENT_BYTES) = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
128 						 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
129 	uint8_t ecb_ciphertext[16]
130 		__aligned(IO_ALIGNMENT_BYTES) = {0x69, 0xC4, 0xE0, 0xD8, 0x6A, 0x7B, 0x04, 0x30,
131 						 0xD8, 0xCD, 0xB7, 0x80, 0x70, 0xB4, 0xC5, 0x5A};
132 
133 	uint8_t encrypted[16] __aligned(IO_ALIGNMENT_BYTES) = {0};
134 	uint8_t decrypted[16] __aligned(IO_ALIGNMENT_BYTES) = {0};
135 	struct cipher_ctx ini = {
136 		.keylen = sizeof(ecb_key),
137 		.key.bit_stream = ecb_key,
138 		.flags = cap_flags,
139 	};
140 	struct cipher_pkt encrypt = {
141 		.in_buf = ecb_plaintext,
142 		.in_len = sizeof(ecb_plaintext),
143 		.out_buf_max = sizeof(encrypted),
144 		.out_buf = encrypted,
145 	};
146 	struct cipher_pkt decrypt = {
147 		.in_buf = encrypt.out_buf,
148 		.in_len = sizeof(encrypted),
149 		.out_buf = decrypted,
150 		.out_buf_max = sizeof(decrypted),
151 	};
152 
153 	if (cipher_begin_session(dev, &ini, CRYPTO_CIPHER_ALGO_AES,
154 				 CRYPTO_CIPHER_MODE_ECB,
155 				 CRYPTO_CIPHER_OP_ENCRYPT)) {
156 		return;
157 	}
158 
159 	if (cipher_block_op(&ini, &encrypt)) {
160 		LOG_ERR("ECB mode ENCRYPT - Failed");
161 		goto out;
162 	}
163 
164 	LOG_INF("Output length (encryption): %d", encrypt.out_len);
165 
166 	if (memcmp(encrypt.out_buf, ecb_ciphertext, sizeof(ecb_ciphertext))) {
167 		LOG_ERR("ECB mode ENCRYPT - Mismatch between expected and "
168 			    "returned cipher text");
169 		print_buffer_comparison(ecb_ciphertext, encrypt.out_buf,
170 					sizeof(ecb_ciphertext));
171 		goto out;
172 	}
173 
174 	LOG_INF("ECB mode ENCRYPT - Match");
175 	cipher_free_session(dev, &ini);
176 
177 	if (cipher_begin_session(dev, &ini, CRYPTO_CIPHER_ALGO_AES,
178 				 CRYPTO_CIPHER_MODE_ECB,
179 				 CRYPTO_CIPHER_OP_DECRYPT)) {
180 		return;
181 	}
182 
183 	if (cipher_block_op(&ini, &decrypt)) {
184 		LOG_ERR("ECB mode DECRYPT - Failed");
185 		goto out;
186 	}
187 
188 	LOG_INF("Output length (decryption): %d", decrypt.out_len);
189 
190 	if (memcmp(decrypt.out_buf, ecb_plaintext, sizeof(ecb_plaintext))) {
191 		LOG_ERR("ECB mode DECRYPT - Mismatch between plaintext and "
192 			    "decrypted cipher text");
193 		print_buffer_comparison(ecb_plaintext, decrypt.out_buf,
194 					sizeof(ecb_plaintext));
195 		goto out;
196 	}
197 
198 	LOG_INF("ECB mode DECRYPT - Match");
199 out:
200 	cipher_free_session(dev, &ini);
201 }
202 
203 static const uint8_t cbc_ciphertext[80] = {
204 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
205 	0x0c, 0x0d, 0x0e, 0x0f, 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
206 	0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, 0x50, 0x86, 0xcb, 0x9b,
207 	0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
208 	0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e,
209 	0x22, 0x22, 0x95, 0x16, 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09,
210 	0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7
211 };
212 
cbc_mode(const struct device * dev)213 void cbc_mode(const struct device *dev)
214 {
215 	uint8_t encrypted[80] __aligned(IO_ALIGNMENT_BYTES) = {0};
216 	uint8_t decrypted[64] __aligned(IO_ALIGNMENT_BYTES) = {0};
217 	struct cipher_ctx ini = {
218 		.keylen = sizeof(key),
219 		.key.bit_stream = key,
220 		.flags = cap_flags,
221 	};
222 	struct cipher_pkt encrypt = {
223 		.in_buf = plaintext,
224 		.in_len = sizeof(plaintext),
225 		.out_buf_max = sizeof(encrypted),
226 		.out_buf = encrypted,
227 	};
228 	struct cipher_pkt decrypt = {
229 		.in_buf = encrypt.out_buf,
230 		.in_len = sizeof(encrypted),
231 		.out_buf = decrypted,
232 		.out_buf_max = sizeof(decrypted),
233 	};
234 
235 	static uint8_t iv[16] = {
236 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
237 		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
238 	};
239 
240 	if (cipher_begin_session(dev, &ini, CRYPTO_CIPHER_ALGO_AES,
241 				 CRYPTO_CIPHER_MODE_CBC,
242 				 CRYPTO_CIPHER_OP_ENCRYPT)) {
243 		return;
244 	}
245 
246 	if (cipher_cbc_op(&ini, &encrypt, iv)) {
247 		LOG_ERR("CBC mode ENCRYPT - Failed");
248 		goto out;
249 	}
250 
251 	LOG_INF("Output length (encryption): %d", encrypt.out_len);
252 
253 	if (memcmp(encrypt.out_buf, cbc_ciphertext, sizeof(cbc_ciphertext))) {
254 		LOG_ERR("CBC mode ENCRYPT - Mismatch between expected and "
255 			    "returned cipher text");
256 		print_buffer_comparison(cbc_ciphertext, encrypt.out_buf,
257 					sizeof(cbc_ciphertext));
258 		goto out;
259 	}
260 
261 	LOG_INF("CBC mode ENCRYPT - Match");
262 	cipher_free_session(dev, &ini);
263 
264 	if (cipher_begin_session(dev, &ini, CRYPTO_CIPHER_ALGO_AES,
265 				 CRYPTO_CIPHER_MODE_CBC,
266 				 CRYPTO_CIPHER_OP_DECRYPT)) {
267 		return;
268 	}
269 
270 	if (cipher_cbc_op(&ini, &decrypt, encrypted)) {
271 		LOG_ERR("CBC mode DECRYPT - Failed");
272 		goto out;
273 	}
274 
275 	LOG_INF("Output length (decryption): %d", decrypt.out_len);
276 
277 	if (memcmp(decrypt.out_buf, plaintext, sizeof(plaintext))) {
278 		LOG_ERR("CBC mode DECRYPT - Mismatch between plaintext and "
279 			    "decrypted cipher text");
280 		print_buffer_comparison(plaintext, decrypt.out_buf,
281 					sizeof(plaintext));
282 		goto out;
283 	}
284 
285 	LOG_INF("CBC mode DECRYPT - Match");
286 out:
287 	cipher_free_session(dev, &ini);
288 }
289 
290 static const uint8_t ctr_ciphertext[64] = {
291 	0x22, 0xe5, 0x2f, 0xb1, 0x77, 0xd8, 0x65, 0xb2,
292 	0xf7, 0xc6, 0xb5, 0x12, 0x69, 0x2d, 0x11, 0x4d,
293 	0xed, 0x6c, 0x1c, 0x72, 0x25, 0xda, 0xf6, 0xa2,
294 	0xaa, 0xd9, 0xd3, 0xda, 0x2d, 0xba, 0x21, 0x68,
295 	0x35, 0xc0, 0xaf, 0x6b, 0x6f, 0x40, 0xc3, 0xc6,
296 	0xef, 0xc5, 0x85, 0xd0, 0x90, 0x2c, 0xc2, 0x63,
297 	0x12, 0x2b, 0xc5, 0x8e, 0x72, 0xde, 0x5c, 0xa2,
298 	0xa3, 0x5c, 0x85, 0x3a, 0xb9, 0x2c, 0x6, 0xbb
299 };
300 
ctr_mode(const struct device * dev)301 void ctr_mode(const struct device *dev)
302 {
303 	uint8_t encrypted[64] __aligned(IO_ALIGNMENT_BYTES) = {0};
304 	uint8_t decrypted[64] __aligned(IO_ALIGNMENT_BYTES) = {0};
305 	struct cipher_ctx ini = {
306 		.keylen = sizeof(key),
307 		.key.bit_stream = key,
308 		.flags = cap_flags,
309 		/*  ivlen + ctrlen = keylen , so ctrlen is 128 - 96 = 32 bits */
310 		.mode_params.ctr_info.ctr_len = 32,
311 	};
312 	struct cipher_pkt encrypt = {
313 		.in_buf = plaintext,
314 		.in_len = sizeof(plaintext),
315 		.out_buf_max = sizeof(encrypted),
316 		.out_buf = encrypted,
317 	};
318 	struct cipher_pkt decrypt = {
319 		.in_buf = encrypted,
320 		.in_len = sizeof(encrypted),
321 		.out_buf = decrypted,
322 		.out_buf_max = sizeof(decrypted),
323 	};
324 	uint8_t iv[12] = {
325 		0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
326 		0xf8, 0xf9, 0xfa, 0xfb
327 	};
328 
329 	if (cipher_begin_session(dev, &ini, CRYPTO_CIPHER_ALGO_AES,
330 				 CRYPTO_CIPHER_MODE_CTR,
331 				 CRYPTO_CIPHER_OP_ENCRYPT)) {
332 		return;
333 	}
334 
335 	if (cipher_ctr_op(&ini, &encrypt, iv)) {
336 		LOG_ERR("CTR mode ENCRYPT - Failed");
337 		goto out;
338 	}
339 
340 	LOG_INF("Output length (encryption): %d", encrypt.out_len);
341 
342 	if (memcmp(encrypt.out_buf, ctr_ciphertext, sizeof(ctr_ciphertext))) {
343 		LOG_ERR("CTR mode ENCRYPT - Mismatch between expected "
344 			    "and returned cipher text");
345 		print_buffer_comparison(ctr_ciphertext, encrypt.out_buf,
346 					sizeof(ctr_ciphertext));
347 		goto out;
348 	}
349 
350 	LOG_INF("CTR mode ENCRYPT - Match");
351 	cipher_free_session(dev, &ini);
352 
353 	if (cipher_begin_session(dev, &ini, CRYPTO_CIPHER_ALGO_AES,
354 				 CRYPTO_CIPHER_MODE_CTR,
355 				 CRYPTO_CIPHER_OP_DECRYPT)) {
356 		return;
357 	}
358 
359 	if (cipher_ctr_op(&ini, &decrypt, iv)) {
360 		LOG_ERR("CTR mode DECRYPT - Failed");
361 		goto out;
362 	}
363 
364 	LOG_INF("Output length (decryption): %d", decrypt.out_len);
365 
366 	if (memcmp(decrypt.out_buf, plaintext, sizeof(plaintext))) {
367 		LOG_ERR("CTR mode DECRYPT - Mismatch between plaintext "
368 			    "and decrypted cipher text");
369 		print_buffer_comparison(plaintext,
370 					decrypt.out_buf, sizeof(plaintext));
371 		goto out;
372 	}
373 
374 	LOG_INF("CTR mode DECRYPT - Match");
375 out:
376 	cipher_free_session(dev, &ini);
377 }
378 
379 /* RFC 3610 test vector #1 */
380 const static uint8_t ccm_key[16] = {
381 	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
382 	0xcc, 0xcd, 0xce, 0xcf
383 };
384 static uint8_t ccm_nonce[13] = {
385 	0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4,
386 	0xa5
387 };
388 static uint8_t ccm_hdr[8] = {
389 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
390 };
391 static uint8_t ccm_data[23] __aligned(IO_ALIGNMENT_BYTES) = {
392 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
393 	0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e};
394 static const uint8_t ccm_expected[31] = {0x58, 0x8c, 0x97, 0x9a, 0x61, 0xc6, 0x63, 0xd2,
395 					 0xf0, 0x66, 0xd0, 0xc2, 0xc0, 0xf9, 0x89, 0x80,
396 					 0x6d, 0x5f, 0x6b, 0x61, 0xda, 0xc3, 0x84, 0x17,
397 					 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0};
398 
ccm_mode(const struct device * dev)399 void ccm_mode(const struct device *dev)
400 {
401 	uint8_t encrypted[50] __aligned(IO_ALIGNMENT_BYTES);
402 	uint8_t decrypted[32] __aligned(IO_ALIGNMENT_BYTES);
403 	struct cipher_ctx ini = {
404 		.keylen = sizeof(ccm_key),
405 		.key.bit_stream = ccm_key,
406 		.mode_params.ccm_info = {
407 			.nonce_len = sizeof(ccm_nonce),
408 			.tag_len = 8,
409 		},
410 		.flags = cap_flags,
411 	};
412 	struct cipher_pkt encrypt = {
413 		.in_buf = ccm_data,
414 		.in_len = sizeof(ccm_data),
415 		.out_buf_max = sizeof(encrypted),
416 		.out_buf = encrypted,
417 	};
418 	struct cipher_aead_pkt ccm_op = {
419 		.ad = ccm_hdr,
420 		.ad_len = sizeof(ccm_hdr),
421 		.pkt = &encrypt,
422 		.tag = encrypted + sizeof(ccm_data),
423 	};
424 	struct cipher_pkt decrypt = {
425 		.in_buf = encrypted,
426 		.in_len = sizeof(ccm_data),
427 		.out_buf = decrypted,
428 		.out_buf_max = sizeof(decrypted),
429 	};
430 
431 	if (cipher_begin_session(dev, &ini, CRYPTO_CIPHER_ALGO_AES,
432 				 CRYPTO_CIPHER_MODE_CCM,
433 				 CRYPTO_CIPHER_OP_ENCRYPT)) {
434 		return;
435 	}
436 
437 	ccm_op.pkt = &encrypt;
438 	if (cipher_ccm_op(&ini, &ccm_op, ccm_nonce)) {
439 		LOG_ERR("CCM mode ENCRYPT - Failed");
440 		goto out;
441 	}
442 
443 	LOG_INF("Output length (encryption): %d", encrypt.out_len);
444 
445 	if (memcmp(encrypt.out_buf, ccm_expected, sizeof(ccm_expected))) {
446 		LOG_ERR("CCM mode ENCRYPT - Mismatch between expected "
447 			    "and returned cipher text");
448 		print_buffer_comparison(ccm_expected,
449 					encrypt.out_buf, sizeof(ccm_expected));
450 		goto out;
451 	}
452 
453 	LOG_INF("CCM mode ENCRYPT - Match");
454 	cipher_free_session(dev, &ini);
455 
456 	if (cipher_begin_session(dev, &ini, CRYPTO_CIPHER_ALGO_AES,
457 				 CRYPTO_CIPHER_MODE_CCM,
458 				 CRYPTO_CIPHER_OP_DECRYPT)) {
459 		return;
460 	}
461 
462 	ccm_op.pkt = &decrypt;
463 	if (cipher_ccm_op(&ini, &ccm_op, ccm_nonce)) {
464 		LOG_ERR("CCM mode DECRYPT - Failed");
465 		goto out;
466 	}
467 
468 	LOG_INF("Output length (decryption): %d", decrypt.out_len);
469 
470 	if (memcmp(decrypt.out_buf, ccm_data, sizeof(ccm_data))) {
471 		LOG_ERR("CCM mode DECRYPT - Mismatch between plaintext "
472 			"and decrypted cipher text");
473 		print_buffer_comparison(ccm_data,
474 					decrypt.out_buf, sizeof(ccm_data));
475 		goto out;
476 	}
477 
478 	LOG_INF("CCM mode DECRYPT - Match");
479 out:
480 	cipher_free_session(dev, &ini);
481 }
482 
483 /*  MACsec GCM-AES test vector 2.4.1 */
484 const static uint8_t gcm_key[16] = {
485 	0x07, 0x1b, 0x11, 0x3b, 0x0c, 0xa7, 0x43, 0xfe, 0xcc, 0xcf, 0x3d, 0x05,
486 	0x1f, 0x73, 0x73, 0x82
487 };
488 static uint8_t gcm_nonce[12] = {
489 	0xf0, 0x76, 0x1e, 0x8d, 0xcd, 0x3d, 0x00, 0x01, 0x76, 0xd4, 0x57, 0xed
490 };
491 static uint8_t gcm_hdr[20] = {
492 	0xe2, 0x01, 0x06, 0xd7, 0xcd, 0x0d, 0xf0, 0x76, 0x1e, 0x8d, 0xcd, 0x3d,
493 	0x88, 0xe5, 0x4c, 0x2a, 0x76, 0xd4, 0x57, 0xed
494 };
495 static uint8_t gcm_data[42] __aligned(IO_ALIGNMENT_BYTES) = {
496 	0x08, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
497 	0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
498 	0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x00, 0x04};
499 static const uint8_t gcm_expected[58] = {
500 	0x13, 0xb4, 0xc7, 0x2b, 0x38, 0x9d, 0xc5, 0x01, 0x8e, 0x72, 0xa1, 0x71, 0xdd, 0x85, 0xa5,
501 	0xd3, 0x75, 0x22, 0x74, 0xd3, 0xa0, 0x19, 0xfb, 0xca, 0xed, 0x09, 0xa4, 0x25, 0xcd, 0x9b,
502 	0x2e, 0x1c, 0x9b, 0x72, 0xee, 0xe7, 0xc9, 0xde, 0x7d, 0x52, 0xb3, 0xf3, 0xd6, 0xa5, 0x28,
503 	0x4f, 0x4a, 0x6d, 0x3f, 0xe2, 0x2a, 0x5d, 0x6c, 0x2b, 0x96, 0x04, 0x94, 0xc3};
504 
gcm_mode(const struct device * dev)505 void gcm_mode(const struct device *dev)
506 {
507 	uint8_t encrypted[60] __aligned(IO_ALIGNMENT_BYTES) = {0};
508 	uint8_t decrypted[44] __aligned(IO_ALIGNMENT_BYTES) = {0};
509 	struct cipher_ctx ini = {
510 		.keylen = sizeof(gcm_key),
511 		.key.bit_stream = gcm_key,
512 		.mode_params.gcm_info = {
513 			.nonce_len = sizeof(gcm_nonce),
514 			.tag_len = 16,
515 		},
516 		.flags = cap_flags,
517 	};
518 	struct cipher_pkt encrypt = {
519 		.in_buf = gcm_data,
520 		.in_len = sizeof(gcm_data),
521 		.out_buf_max = sizeof(encrypted),
522 		.out_buf = encrypted,
523 	};
524 	struct cipher_aead_pkt gcm_op = {
525 		.ad = gcm_hdr,
526 		.ad_len = sizeof(gcm_hdr),
527 		.pkt = &encrypt,
528 		.tag = encrypted + sizeof(gcm_data),
529 	};
530 	struct cipher_pkt decrypt = {
531 		.in_buf = encrypted,
532 		.in_len = sizeof(gcm_data),
533 		.out_buf = decrypted,
534 		.out_buf_max = sizeof(decrypted),
535 	};
536 
537 	if (cipher_begin_session(dev, &ini, CRYPTO_CIPHER_ALGO_AES,
538 				 CRYPTO_CIPHER_MODE_GCM,
539 				 CRYPTO_CIPHER_OP_ENCRYPT)) {
540 		return;
541 	}
542 
543 	gcm_op.pkt = &encrypt;
544 	if (cipher_gcm_op(&ini, &gcm_op, gcm_nonce)) {
545 		LOG_ERR("GCM mode ENCRYPT - Failed");
546 		goto out;
547 	}
548 
549 	LOG_INF("Output length (encryption): %d", encrypt.out_len);
550 
551 	if (memcmp(encrypt.out_buf, gcm_expected, sizeof(gcm_expected))) {
552 		LOG_ERR("GCM mode ENCRYPT - Mismatch between expected "
553 			    "and returned cipher text");
554 		print_buffer_comparison(gcm_expected,
555 					encrypt.out_buf, sizeof(gcm_expected));
556 		goto out;
557 	}
558 
559 	LOG_INF("GCM mode ENCRYPT - Match");
560 	cipher_free_session(dev, &ini);
561 
562 	if (cipher_begin_session(dev, &ini, CRYPTO_CIPHER_ALGO_AES,
563 				 CRYPTO_CIPHER_MODE_GCM,
564 				 CRYPTO_CIPHER_OP_DECRYPT)) {
565 		return;
566 	}
567 
568 	gcm_op.pkt = &decrypt;
569 	if (cipher_gcm_op(&ini, &gcm_op, gcm_nonce)) {
570 		LOG_ERR("GCM mode DECRYPT - Failed");
571 		goto out;
572 	}
573 
574 	LOG_INF("Output length (decryption): %d", decrypt.out_len);
575 
576 	if (memcmp(decrypt.out_buf, gcm_data, sizeof(gcm_data))) {
577 		LOG_ERR("GCM mode DECRYPT - Mismatch between plaintext "
578 			"and decrypted cipher text");
579 		print_buffer_comparison(gcm_data,
580 					decrypt.out_buf, sizeof(gcm_data));
581 		goto out;
582 	}
583 
584 	LOG_INF("GCM mode DECRYPT - Match");
585 out:
586 	cipher_free_session(dev, &ini);
587 }
588 
589 struct mode_test {
590 	const char *mode;
591 	void (*mode_func)(const struct device *dev);
592 };
593 
main(void)594 int main(void)
595 {
596 #ifdef CRYPTO_DRV_NAME
597 	const struct device *dev = device_get_binding(CRYPTO_DRV_NAME);
598 
599 	if (!dev) {
600 		LOG_ERR("%s pseudo device not found", CRYPTO_DRV_NAME);
601 		return 0;
602 	}
603 #else
604 	const struct device *const dev = DEVICE_DT_GET_ONE(CRYPTO_DEV_COMPAT);
605 
606 	if (!device_is_ready(dev)) {
607 		LOG_ERR("Crypto device is not ready\n");
608 		return 0;
609 	}
610 #endif
611 	const struct mode_test modes[] = {
612 		{ .mode = "ECB Mode", .mode_func = ecb_mode },
613 		{ .mode = "CBC Mode", .mode_func = cbc_mode },
614 		{ .mode = "CTR Mode", .mode_func = ctr_mode },
615 		{ .mode = "CCM Mode", .mode_func = ccm_mode },
616 		{ .mode = "GCM Mode", .mode_func = gcm_mode },
617 		{ },
618 	};
619 	int i;
620 
621 	if (validate_hw_compatibility(dev)) {
622 		LOG_ERR("Incompatible h/w");
623 		return 0;
624 	}
625 
626 	LOG_INF("Cipher Sample");
627 
628 	for (i = 0; modes[i].mode; i++) {
629 		LOG_INF("%s", modes[i].mode);
630 		modes[i].mode_func(dev);
631 	}
632 	return 0;
633 }
634