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