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