1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/init.h>
8 #include <zephyr/kernel.h>
9 #include <string.h>
10 #include <zephyr/device.h>
11 #include <zephyr/drivers/i2c.h>
12 #include <zephyr/sys/__assert.h>
13 #include <zephyr/crypto/crypto.h>
14
15 #define DT_DRV_COMPAT atmel_ataes132a
16
17 #include "crypto_ataes132a_priv.h"
18
19 #define D10D24S 11
20 #define MAX_RETRIES 3
21 #define ATAES132A_AES_KEY_SIZE 16
22
23 /* ATAES132A can store up to 16 different crypto keys */
24 #define CRYPTO_MAX_SESSION 16
25
26 #define LOG_LEVEL CONFIG_CRYPTO_LOG_LEVEL
27 #include <zephyr/logging/log.h>
28 LOG_MODULE_REGISTER(ataes132a);
29
30 static struct ataes132a_driver_state ataes132a_state[CRYPTO_MAX_SESSION];
31
ataes132a_init_states(void)32 static void ataes132a_init_states(void)
33 {
34 int i;
35
36 for (i = 0; i < ATAES132A_AES_KEY_SIZE; i++) {
37 ataes132a_state[i].in_use = false;
38 ataes132a_state[i].key_id = i;
39 }
40 }
41
ataes132a_send_command(const struct device * dev,uint8_t opcode,uint8_t mode,uint8_t * params,uint8_t nparams,uint8_t * response,uint8_t * nresponse)42 static int ataes132a_send_command(const struct device *dev, uint8_t opcode,
43 uint8_t mode, uint8_t *params,
44 uint8_t nparams, uint8_t *response,
45 uint8_t *nresponse)
46 {
47 int retry_count = 0;
48 struct ataes132a_device_data *data = dev->data;
49 const struct ataes132a_device_config *cfg = dev->config;
50 uint8_t count;
51 uint8_t status;
52 uint8_t crc[2];
53 int i, i2c_return;
54
55 count = nparams + 5;
56 if (count > 64) {
57 LOG_ERR("command too large for command buffer");
58 return -EDOM;
59 }
60
61 /* If there is a command in progress, idle wait until it is available.
62 * If there is concurrency protection around the driver, this should
63 * never happen.
64 */
65 read_reg_i2c(&cfg->i2c, ATAES_STATUS_REG, &status);
66
67 while (status & ATAES_STATUS_WIP) {
68 k_busy_wait(D10D24S);
69 read_reg_i2c(&cfg->i2c, ATAES_STATUS_REG, &status);
70 }
71
72 data->command_buffer[0] = count;
73 data->command_buffer[1] = opcode;
74 data->command_buffer[2] = mode;
75 for (i = 0; i < nparams; i++) {
76 data->command_buffer[i + 3] = params[i];
77 }
78
79 /*Calculate command CRC*/
80 ataes132a_atmel_crc(data->command_buffer, nparams + 3, crc);
81 data->command_buffer[nparams + 3] = crc[0];
82 data->command_buffer[nparams + 4] = crc[1];
83
84 /*Reset i/O address start before sending a command*/
85 write_reg_i2c(&cfg->i2c, ATAES_COMMAND_ADDRR_RESET, 0x0);
86
87 /*Send a command through the command buffer*/
88 i2c_return = burst_write_i2c(&cfg->i2c, ATAES_COMMAND_MEM_ADDR,
89 data->command_buffer, count);
90
91 LOG_DBG("BURST WRITE RETURN: %d", i2c_return);
92
93 /* Idle-waiting for the command completion*/
94 do {
95 k_busy_wait(D10D24S);
96 read_reg_i2c(&cfg->i2c, ATAES_STATUS_REG, &status);
97 } while (status & ATAES_STATUS_WIP);
98
99 if (status & ATAES_STATUS_CRC) {
100 LOG_ERR("incorrect CRC command");
101 return -EINVAL;
102 }
103
104 if (!(status & ATAES_STATUS_RDY)) {
105 LOG_ERR("expected response is not in place");
106 return -EINVAL;
107 }
108
109 /* Read the response */
110 burst_read_i2c(&cfg->i2c, ATAES_COMMAND_MEM_ADDR, data->command_buffer, 64);
111
112 count = data->command_buffer[0];
113
114 /* Calculate and validate response CRC */
115 ataes132a_atmel_crc(data->command_buffer, count - 2, crc);
116
117 LOG_DBG("COMMAND CRC %x%x", data->command_buffer[count - 2],
118 data->command_buffer[count - 1]);
119 LOG_DBG("CALCULATED CRC %x%x", crc[0], crc[1]);
120
121 /* If CRC fails retry reading MAX RETRIES times */
122 while (crc[0] != data->command_buffer[count - 2] ||
123 crc[1] != data->command_buffer[count - 1]) {
124 if (retry_count > MAX_RETRIES - 1) {
125 LOG_ERR("response crc validation rebase"
126 " max retries");
127 return -EINVAL;
128 }
129
130 burst_read_i2c(&cfg->i2c, ATAES_COMMAND_MEM_ADDR, data->command_buffer, 64);
131
132 count = data->command_buffer[0];
133
134 ataes132a_atmel_crc(data->command_buffer, count - 2, crc);
135 retry_count++;
136
137 LOG_DBG("COMMAND RETRY %d", retry_count);
138 LOG_DBG("COMMAND CRC %x%x",
139 data->command_buffer[count - 2],
140 data->command_buffer[count - 1]);
141 LOG_DBG("CALCULATED CRC %x%x", crc[0], crc[1]);
142 }
143
144 if ((status & ATAES_STATUS_ERR) || data->command_buffer[1] != 0x00) {
145 LOG_ERR("command execution error %x",
146 data->command_buffer[1]);
147 return -EIO;
148 }
149
150 LOG_DBG("Read the response count: %d", count);
151
152 for (i = 0; i < count - 3; i++) {
153 response[i] = data->command_buffer[i + 1];
154 }
155
156 *nresponse = count - 3;
157
158 return 0;
159 }
160
ataes132a_init(const struct device * dev)161 int ataes132a_init(const struct device *dev)
162 {
163 struct ataes132a_device_data *ataes132a = dev->data;
164 const struct ataes132a_device_config *cfg = dev->config;
165 uint32_t i2c_cfg;
166
167 LOG_DBG("ATAES132A INIT");
168
169 if (!device_is_ready(cfg->i2c.bus)) {
170 LOG_ERR("Bus device is not ready");
171 return -ENODEV;
172 }
173
174 i2c_cfg = I2C_MODE_CONTROLLER | I2C_SPEED_SET(ATAES132A_BUS_SPEED);
175
176 i2c_configure(cfg->i2c.bus, i2c_cfg);
177
178 k_sem_init(&ataes132a->device_sem, 1, K_SEM_MAX_LIMIT);
179
180 ataes132a_init_states();
181
182 return 0;
183 }
184
ataes132a_aes_ccm_decrypt(const struct device * dev,uint8_t key_id,struct ataes132a_mac_mode * mac_mode,struct ataes132a_mac_packet * mac_packet,struct cipher_aead_pkt * aead_op,uint8_t * nonce_buf)185 int ataes132a_aes_ccm_decrypt(const struct device *dev,
186 uint8_t key_id,
187 struct ataes132a_mac_mode *mac_mode,
188 struct ataes132a_mac_packet *mac_packet,
189 struct cipher_aead_pkt *aead_op,
190 uint8_t *nonce_buf)
191 {
192 uint8_t command_mode = 0x0;
193 struct ataes132a_device_data *data = dev->data;
194 uint8_t out_len;
195 uint8_t in_buf_len;
196 uint8_t return_code;
197 uint8_t expected_out_len;
198 uint8_t param_buffer[52];
199
200 if (!aead_op) {
201 LOG_ERR("Parameter cannot be null");
202 return -EINVAL;
203 }
204
205 if (!aead_op->pkt) {
206 LOG_ERR("Parameter cannot be null");
207 return -EINVAL;
208 }
209
210 in_buf_len = aead_op->pkt->in_len;
211 expected_out_len = aead_op->pkt->out_len;
212
213 /*The KeyConfig[EKeyID].ExternalCrypto bit must be 1b.*/
214 if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_EXTERNAL)) {
215 LOG_ERR("key %x external mode disabled", key_id);
216 return -EINVAL;
217 }
218
219 if (in_buf_len != 16U && in_buf_len != 32U) {
220 LOG_ERR("ccm mode only accepts input blocks of 16"
221 " and 32 bytes");
222 return -EINVAL;
223 }
224
225 if (expected_out_len > 32) {
226 LOG_ERR("ccm mode cannot generate more than"
227 " 32 output bytes");
228 return -EINVAL;
229 }
230
231 /* If KeyConfig[key_id].AuthKey is set, then prior authentication
232 * is required
233 */
234 if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_AUTHKEY)) {
235 LOG_DBG("keep in mind key %x will require"
236 " previous authentication", key_id);
237 }
238
239 if (!aead_op->pkt->in_buf || !aead_op->pkt->out_buf) {
240 return 0;
241 }
242
243 /* If the KeyConfig[EKeyID].RandomNonce bit is set
244 * the current nonce register content will be used.
245 * If there is an invalid random nonce or if there
246 * is no nonce synchronization between device
247 * the decrypt operation will fail accordingly.
248 */
249 if (ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_RAND_NONCE) {
250 LOG_DBG("key %x requires random nonce,"
251 " nonce_buf will be ignored", key_id);
252
253 LOG_DBG("current nonce register will be used");
254
255 }
256
257 k_sem_take(&data->device_sem, K_FOREVER);
258
259 /* If the KeyConfig[EKeyID].RandomNonce bit is not set
260 * then the nonce send as parameter will be loaded into
261 * the nonce register.
262 */
263 if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_RAND_NONCE)
264 && nonce_buf) {
265 param_buffer[0] = 0x0;
266 param_buffer[1] = 0x0;
267 param_buffer[2] = 0x0;
268 param_buffer[3] = 0x0;
269 memcpy(param_buffer + 4, nonce_buf, 12);
270
271 return_code = ataes132a_send_command(dev, ATAES_NONCE_OP,
272 0x0, param_buffer, 16,
273 param_buffer, &out_len);
274
275 if (return_code != 0U) {
276 LOG_ERR("nonce command ended with code %d",
277 return_code);
278 k_sem_give(&data->device_sem);
279 return -EINVAL;
280 }
281
282 if (param_buffer[0] != 0U) {
283 LOG_ERR("nonce command failed with error"
284 " code %d", param_buffer[0]);
285 k_sem_give(&data->device_sem);
286 return -EIO;
287 }
288 }
289
290 /* If the KeyConfig[EKeyID].RandomNonce bit is not set
291 * and the nonce send as parameter is a null value,
292 * the command will use the current nonce register value.
293 */
294 if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_RAND_NONCE)
295 && !nonce_buf) {
296 LOG_DBG("current nonce register will be used");
297 }
298
299 /* Client decryption mode requires a MAC packet to specify the
300 * encryption key id and the MAC count of the encryption device
301 * to synchronize MAC generation
302 */
303 if (mac_packet) {
304 param_buffer[0] = mac_packet->encryption_key_id;
305 param_buffer[2] = mac_packet->encryption_mac_count;
306 } else {
307 param_buffer[0] = 0x0;
308 param_buffer[2] = 0x0;
309 LOG_DBG("normal decryption mode"
310 " ignores mac_packet parameter");
311 }
312
313 /* Client decryption mode requires a MAC packet to specify
314 * if MAC counter, serial number and small zone number are
315 * included in MAC generation.
316 */
317 if (mac_mode) {
318 if (mac_mode->include_counter) {
319 LOG_DBG("including usage counter in the MAC: "
320 "decrypt and encrypt dev must be the same");
321 command_mode = command_mode | ATAES_MAC_MODE_COUNTER;
322 }
323
324 if (mac_mode->include_serial) {
325 LOG_DBG("including serial number in the MAC: "
326 "decrypt and encrypt dev must be the same");
327 command_mode = command_mode | ATAES_MAC_MODE_SERIAL;
328 }
329
330 if (mac_mode->include_smallzone) {
331 LOG_DBG("including small zone in the MAC: "
332 "decrypt and encrypt dev share the "
333 "first four bytes of their small zone");
334 command_mode = command_mode | ATAES_MAC_MODE_SMALLZONE;
335 }
336 }
337
338 param_buffer[1] = key_id;
339 param_buffer[3] = expected_out_len;
340 if (aead_op->tag) {
341 memcpy(param_buffer + 4, aead_op->tag, 16);
342 }
343 memcpy(param_buffer + 20, aead_op->pkt->in_buf, in_buf_len);
344
345 return_code = ataes132a_send_command(dev, ATAES_DECRYPT_OP,
346 command_mode, param_buffer,
347 in_buf_len + 4, param_buffer,
348 &out_len);
349
350 if (return_code != 0U) {
351 LOG_ERR("decrypt command ended with code %d", return_code);
352 k_sem_give(&data->device_sem);
353 return -EINVAL;
354 }
355
356 if (!IN_RANGE(out_len, 2, 33)) {
357 LOG_ERR("decrypt command response has invalid"
358 " size %d", out_len);
359 k_sem_give(&data->device_sem);
360 return -EINVAL;
361 }
362
363 if (param_buffer[0] != 0U) {
364 LOG_ERR("legacy command failed with error"
365 " code %d", param_buffer[0]);
366 k_sem_give(&data->device_sem);
367 return -param_buffer[0];
368 }
369
370 if (expected_out_len != out_len - 1) {
371 LOG_ERR("decrypted output data size %d and expected data"
372 " size %d are different", out_len - 1,
373 expected_out_len);
374 k_sem_give(&data->device_sem);
375 return -EINVAL;
376 }
377
378 memcpy(aead_op->pkt->out_buf, param_buffer + 1, out_len - 1);
379
380 k_sem_give(&data->device_sem);
381
382 return 0;
383 }
384
ataes132a_aes_ccm_encrypt(const struct device * dev,uint8_t key_id,struct ataes132a_mac_mode * mac_mode,struct cipher_aead_pkt * aead_op,uint8_t * nonce_buf,uint8_t * mac_count)385 int ataes132a_aes_ccm_encrypt(const struct device *dev,
386 uint8_t key_id,
387 struct ataes132a_mac_mode *mac_mode,
388 struct cipher_aead_pkt *aead_op,
389 uint8_t *nonce_buf,
390 uint8_t *mac_count)
391 {
392 uint8_t command_mode = 0x0;
393 struct ataes132a_device_data *data = dev->data;
394 uint8_t buf_len;
395 uint8_t out_len;
396 uint8_t return_code;
397
398 const uint8_t key_id_len = 1;
399 const uint8_t buf_len_len = 1;
400 const uint8_t max_input_len = 32;
401 const uint8_t nonce_len = 12;
402 const uint8_t tag_len = 16;
403
404 uint8_t param_buffer[key_id_len + buf_len_len + max_input_len + nonce_len + tag_len];
405
406 if (!aead_op) {
407 LOG_ERR("Parameter cannot be null");
408 return -EINVAL;
409 }
410
411 if (!aead_op->pkt) {
412 LOG_ERR("Parameter cannot be null");
413 return -EINVAL;
414 }
415
416 buf_len = aead_op->pkt->in_len;
417
418 /*The KeyConfig[EKeyID].ExternalCrypto bit must be 1b.*/
419 if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_EXTERNAL)) {
420 LOG_ERR("key %x external mode disabled", key_id);
421 return -EINVAL;
422 }
423
424 if (buf_len > 32) {
425 LOG_ERR("only up to 32 bytes accepted for ccm mode");
426 return -EINVAL;
427 }
428
429 /* If KeyConfig[key_id].AuthKey is set, then prior authentication
430 * is required
431 */
432 if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_AUTHKEY)) {
433 LOG_DBG("keep in mind key %x will require"
434 " previous authentication", key_id);
435 }
436
437 if (!aead_op->pkt->in_buf || !aead_op->pkt->out_buf) {
438 return 0;
439 }
440
441 /* If the KeyConfig[EKeyID].RandomNonce bit is set
442 * the current nonce register content will be used.
443 * If there is an invalid random nonce or if there
444 * is no nonce synchronization between device
445 * the decrypt operation will fail accordingly.
446 */
447 if (ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_RAND_NONCE) {
448 LOG_DBG("key %x requires random nonce,"
449 " nonce_buf will be ignored", key_id);
450
451 LOG_DBG("current nonce register will be used");
452
453 }
454
455 k_sem_take(&data->device_sem, K_FOREVER);
456
457 /* If the KeyConfig[EKeyID].RandomNonce bit is not set
458 * then the nonce send as parameter will be loaded into
459 * the nonce register.
460 */
461 if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_RAND_NONCE)
462 && nonce_buf) {
463 param_buffer[0] = 0x0;
464 param_buffer[1] = 0x0;
465 param_buffer[2] = 0x0;
466 param_buffer[3] = 0x0;
467 memcpy(param_buffer + 4, nonce_buf, 12);
468
469 return_code = ataes132a_send_command(dev, ATAES_NONCE_OP,
470 0x0, param_buffer, 16,
471 param_buffer, &out_len);
472
473 if (return_code != 0U) {
474 LOG_ERR("nonce command ended with code %d",
475 return_code);
476 k_sem_give(&data->device_sem);
477 return -EINVAL;
478 }
479
480 if (param_buffer[0] != 0U) {
481 LOG_ERR("nonce command failed with error"
482 " code %d", param_buffer[0]);
483 k_sem_give(&data->device_sem);
484 return -EIO;
485 }
486 }
487 /* If the KeyConfig[EKeyID].RandomNonce bit is not set
488 * and the nonce send as parameter is a null value,
489 * the command will use the current nonce register value.
490 */
491 if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_RAND_NONCE)
492 && !nonce_buf) {
493 LOG_DBG("current nonce register will be used");
494 }
495
496 /* MAC packet to specify if MAC counter, serial number and small zone
497 * number are included in MAC generation.
498 */
499 if (mac_mode) {
500 if (mac_mode->include_counter) {
501 LOG_DBG("including usage counter in the MAC: "
502 "decrypt and encrypt dev must be the same");
503 command_mode = command_mode | ATAES_MAC_MODE_COUNTER;
504 }
505
506 if (mac_mode->include_serial) {
507 LOG_DBG("including serial number in the MAC: "
508 "decrypt and encrypt dev must be the same");
509 command_mode = command_mode | ATAES_MAC_MODE_SERIAL;
510 }
511
512 if (mac_mode->include_smallzone) {
513 LOG_DBG("including small zone in the MAC: "
514 "decrypt and encrypt dev share the "
515 "first four bytes of their small zone");
516 command_mode = command_mode | ATAES_MAC_MODE_SMALLZONE;
517 }
518 }
519
520 param_buffer[0] = key_id;
521 param_buffer[1] = buf_len;
522 memcpy(param_buffer + 2, aead_op->pkt->in_buf, buf_len);
523
524 return_code = ataes132a_send_command(dev, ATAES_ENCRYPT_OP,
525 command_mode, param_buffer,
526 buf_len + 2, param_buffer,
527 &out_len);
528
529 if (return_code != 0U) {
530 LOG_ERR("encrypt command ended with code %d", return_code);
531 k_sem_give(&data->device_sem);
532 return -EINVAL;
533 }
534
535 if (!IN_RANGE(out_len, 33, 49)) {
536 LOG_ERR("encrypt command response has invalid"
537 " size %d", out_len);
538 k_sem_give(&data->device_sem);
539 return -EINVAL;
540 }
541
542 if (param_buffer[0] != 0U) {
543 LOG_ERR("encrypt command failed with error"
544 " code %d", param_buffer[0]);
545 k_sem_give(&data->device_sem);
546 return -EIO;
547 }
548
549 if (aead_op->tag) {
550 memcpy(aead_op->tag, param_buffer + 1, 16);
551 }
552
553 memcpy(aead_op->pkt->out_buf, param_buffer + 17, out_len - 17U);
554
555 if (mac_mode) {
556 if (mac_mode->include_counter) {
557 param_buffer[0] = 0x0;
558 param_buffer[1] = 0x0;
559 param_buffer[2] = 0x0;
560 param_buffer[3] = 0x0;
561 ataes132a_send_command(dev, ATAES_INFO_OP, 0x0,
562 param_buffer, 4,
563 param_buffer, &out_len);
564 if (param_buffer[0] != 0U) {
565 LOG_ERR("info command failed with error"
566 " code %d", param_buffer[0]);
567 k_sem_give(&data->device_sem);
568 return -EIO;
569 }
570 if (mac_count) {
571 *mac_count = param_buffer[2];
572 }
573 }
574 }
575
576 k_sem_give(&data->device_sem);
577
578 return 0;
579 }
580
ataes132a_aes_ecb_block(const struct device * dev,uint8_t key_id,struct cipher_pkt * pkt)581 int ataes132a_aes_ecb_block(const struct device *dev,
582 uint8_t key_id,
583 struct cipher_pkt *pkt)
584 {
585 struct ataes132a_device_data *data = dev->data;
586 uint8_t buf_len;
587 uint8_t out_len;
588 uint8_t return_code;
589 uint8_t param_buffer[19];
590
591 if (!pkt) {
592 LOG_ERR("Parameter cannot be null");
593 return -EINVAL;
594 }
595
596 buf_len = pkt->in_len;
597 if (buf_len > 16) {
598 LOG_ERR("input block cannot be above 16 bytes");
599 return -EINVAL;
600 }
601
602 /* AES ECB can only be executed if the ChipConfig.LegacyE configuration
603 * is set to 1 and if KeyConfig[key_id].LegacyOK is set to 1.
604 */
605 if (!(ataes132a_state[key_id].chip_config & ATAES_CHIPCONFIG_LEGACYE)) {
606 LOG_ERR("legacy mode disabled");
607 return -EINVAL;
608 }
609
610 if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_LEGACYOK)) {
611 LOG_ERR("key %x legacy mode disabled", key_id);
612 return -EINVAL;
613 }
614
615 LOG_DBG("Chip config: %x", ataes132a_state[key_id].chip_config);
616 LOG_DBG("Key ID: %d", key_id);
617 LOG_DBG("Key config: %x", ataes132a_state[key_id].key_config);
618
619 /* If KeyConfig[key_id].AuthKey is set, then prior authentication
620 * is required
621 */
622 if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_AUTHKEY)) {
623 LOG_DBG("keep in mind key %x will require"
624 " previous authentication", key_id);
625 }
626
627 if (!pkt->in_buf || !pkt->out_buf) {
628 return 0;
629 }
630
631 k_sem_take(&data->device_sem, K_FOREVER);
632
633 param_buffer[0] = 0x0;
634 param_buffer[1] = key_id;
635 param_buffer[2] = 0x0;
636 memcpy(param_buffer + 3, pkt->in_buf, buf_len);
637 (void)memset(param_buffer + 3 + buf_len, 0x0, 16 - buf_len);
638
639 return_code = ataes132a_send_command(dev, ATAES_LEGACY_OP, 0x00,
640 param_buffer, buf_len + 3,
641 param_buffer, &out_len);
642
643 if (return_code != 0U) {
644 LOG_ERR("legacy command ended with code %d", return_code);
645 k_sem_give(&data->device_sem);
646 return -EINVAL;
647 }
648
649 if (out_len != 17U) {
650 LOG_ERR("legacy command response has invalid"
651 " size %d", out_len);
652 k_sem_give(&data->device_sem);
653 return -EINVAL;
654 }
655 if (param_buffer[0] != 0U) {
656 LOG_ERR("legacy command failed with error"
657 " code %d", param_buffer[0]);
658 k_sem_give(&data->device_sem);
659 return -EIO;
660 }
661
662 memcpy(pkt->out_buf, param_buffer + 1, 16);
663
664 k_sem_give(&data->device_sem);
665
666 return 0;
667 }
668
do_ccm_encrypt_mac(struct cipher_ctx * ctx,struct cipher_aead_pkt * aead_op,uint8_t * nonce)669 static int do_ccm_encrypt_mac(struct cipher_ctx *ctx,
670 struct cipher_aead_pkt *aead_op, uint8_t *nonce)
671 {
672 const struct device *dev = ctx->device;
673 struct ataes132a_driver_state *state = ctx->drv_sessn_state;
674 struct ataes132a_mac_mode mac_mode;
675 uint8_t key_id;
676
677 key_id = state->key_id;
678
679 __ASSERT_NO_MSG(*(uint8_t *)ctx->key.handle == key_id);
680
681 /* Removing all this salt from the MAC reduces the protection
682 * but allows any other crypto implementations to authorize
683 * the message.
684 */
685 mac_mode.include_counter = false;
686 mac_mode.include_serial = false;
687 mac_mode.include_smallzone = false;
688
689 if (aead_op->pkt->in_len <= 16 &&
690 aead_op->pkt->out_buf_max < 16) {
691 LOG_ERR("Not enough space available in out buffer.");
692 return -EINVAL;
693 }
694
695 if (aead_op->pkt->in_len > 16 &&
696 aead_op->pkt->out_buf_max < 32) {
697 LOG_ERR("Not enough space available in out buffer.");
698 return -EINVAL;
699 }
700
701 if (aead_op->pkt->in_len <= 16) {
702 aead_op->pkt->out_len = 16;
703 } else if (aead_op->pkt->in_len > 16) {
704 aead_op->pkt->out_len = 32;
705 }
706
707 if (aead_op->ad != NULL || aead_op->ad_len != 0U) {
708 LOG_ERR("Associated data is not supported.");
709 return -EINVAL;
710 }
711
712 ataes132a_aes_ccm_encrypt(dev, key_id, &mac_mode,
713 aead_op, nonce, NULL);
714
715 return 0;
716 }
717
do_ccm_decrypt_auth(struct cipher_ctx * ctx,struct cipher_aead_pkt * aead_op,uint8_t * nonce)718 static int do_ccm_decrypt_auth(struct cipher_ctx *ctx,
719 struct cipher_aead_pkt *aead_op, uint8_t *nonce)
720 {
721 const struct device *dev = ctx->device;
722 struct ataes132a_driver_state *state = ctx->drv_sessn_state;
723 struct ataes132a_mac_mode mac_mode;
724 uint8_t key_id;
725
726 key_id = state->key_id;
727
728 __ASSERT_NO_MSG(*(uint8_t *)ctx->key.handle == key_id);
729
730 /* Removing all this salt from the MAC reduces the protection
731 * but allows any other crypto implementations to authorize
732 * the message.
733 */
734 mac_mode.include_counter = false;
735 mac_mode.include_serial = false;
736 mac_mode.include_smallzone = false;
737
738 if (aead_op->pkt->in_len <= 16 &&
739 aead_op->pkt->out_buf_max < 16) {
740 LOG_ERR("Not enough space available in out buffer.");
741 return -EINVAL;
742 }
743
744 if (aead_op->pkt->in_len > 16 &&
745 aead_op->pkt->out_buf_max < 32) {
746 LOG_ERR("Not enough space available in out buffer.");
747 return -EINVAL;
748 }
749
750 aead_op->pkt->ctx = ctx;
751
752 if (aead_op->ad != NULL || aead_op->ad_len != 0U) {
753 LOG_ERR("Associated data is not supported.");
754 return -EINVAL;
755 }
756
757 /* Normal Decryption Mode will only decrypt host generated packets */
758 ataes132a_aes_ccm_decrypt(dev, key_id, &mac_mode,
759 NULL, aead_op, nonce);
760
761 return 0;
762 }
763
do_block(struct cipher_ctx * ctx,struct cipher_pkt * pkt)764 static int do_block(struct cipher_ctx *ctx, struct cipher_pkt *pkt)
765 {
766 const struct device *dev = ctx->device;
767 struct ataes132a_driver_state *state = ctx->drv_sessn_state;
768 uint8_t key_id;
769
770 key_id = state->key_id;
771
772 __ASSERT_NO_MSG(*(uint8_t *)ctx->key.handle == key_id);
773
774 if (pkt->out_buf_max < 16) {
775 LOG_ERR("Not enough space available in out buffer.");
776 return -EINVAL;
777 }
778
779 pkt->out_len = 16;
780
781 return ataes132a_aes_ecb_block(dev, key_id, pkt);
782 }
783
ataes132a_session_free(const struct device * dev,struct cipher_ctx * session)784 static int ataes132a_session_free(const struct device *dev,
785 struct cipher_ctx *session)
786 {
787 struct ataes132a_driver_state *state = session->drv_sessn_state;
788
789 ARG_UNUSED(dev);
790
791 state->in_use = false;
792
793 return 0;
794 }
795
ataes132a_session_setup(const struct device * dev,struct cipher_ctx * ctx,enum cipher_algo algo,enum cipher_mode mode,enum cipher_op op_type)796 static int ataes132a_session_setup(const struct device *dev,
797 struct cipher_ctx *ctx,
798 enum cipher_algo algo, enum cipher_mode mode,
799 enum cipher_op op_type)
800 {
801 uint8_t key_id = *((uint8_t *)ctx->key.handle);
802 const struct ataes132a_device_config *cfg = dev->config;
803 uint8_t config;
804
805 if (ataes132a_state[key_id].in_use) {
806 LOG_ERR("Session in progress");
807 return -EINVAL;
808 }
809 if (mode == CRYPTO_CIPHER_MODE_CCM &&
810 ctx->mode_params.ccm_info.tag_len != 16U) {
811 LOG_ERR("ATAES132A support 16 byte tag only.");
812 return -EINVAL;
813 }
814 if (mode == CRYPTO_CIPHER_MODE_CCM &&
815 ctx->mode_params.ccm_info.nonce_len != 12U) {
816 LOG_ERR("ATAES132A support 12 byte nonce only.");
817 return -EINVAL;
818 }
819
820 ataes132a_state[key_id].in_use = true;
821 read_reg_i2c(&cfg->i2c, ATAES_KEYCFG_REG(key_id), &config);
822 ataes132a_state[key_id].key_config = config;
823 read_reg_i2c(&cfg->i2c, ATAES_CHIPCONFIG_REG, &config);
824 ataes132a_state[key_id].chip_config = config;
825
826 ctx->drv_sessn_state = &ataes132a_state[key_id];
827 ctx->device = dev;
828
829 if (algo != CRYPTO_CIPHER_ALGO_AES) {
830 LOG_ERR("ATAES132A unsupported algorithm");
831 return -EINVAL;
832 }
833
834 /*ATAES132A support I2C polling only*/
835 if (!(ctx->flags & CAP_SYNC_OPS)) {
836 LOG_ERR("Async not supported by this driver");
837 return -EINVAL;
838 }
839
840 if (ctx->keylen != ATAES132A_AES_KEY_SIZE) {
841 LOG_ERR("ATAES132A unsupported key size");
842 return -EINVAL;
843 }
844
845 if (op_type == CRYPTO_CIPHER_OP_ENCRYPT) {
846 switch (mode) {
847 case CRYPTO_CIPHER_MODE_ECB:
848 ctx->ops.block_crypt_hndlr = do_block;
849 break;
850 case CRYPTO_CIPHER_MODE_CCM:
851 ctx->ops.ccm_crypt_hndlr = do_ccm_encrypt_mac;
852 break;
853 default:
854 LOG_ERR("ATAES132A unsupported mode");
855 return -EINVAL;
856 }
857 } else {
858 switch (mode) {
859 case CRYPTO_CIPHER_MODE_ECB:
860 ctx->ops.block_crypt_hndlr = do_block;
861 break;
862 case CRYPTO_CIPHER_MODE_CCM:
863 ctx->ops.ccm_crypt_hndlr = do_ccm_decrypt_auth;
864 break;
865 default:
866 LOG_ERR("ATAES132A unsupported mode");
867 return -EINVAL;
868 }
869 }
870
871 ctx->ops.cipher_mode = mode;
872
873 return 0;
874 }
875
ataes132a_query_caps(const struct device * dev)876 static int ataes132a_query_caps(const struct device *dev)
877 {
878 return (CAP_OPAQUE_KEY_HNDL | CAP_SEPARATE_IO_BUFS |
879 CAP_SYNC_OPS | CAP_AUTONONCE);
880 }
881
882 static const struct ataes132a_device_config ataes132a_config = {
883 .i2c = I2C_DT_SPEC_INST_GET(0),
884 };
885
886 static DEVICE_API(crypto, crypto_enc_funcs) = {
887 .cipher_begin_session = ataes132a_session_setup,
888 .cipher_free_session = ataes132a_session_free,
889 .cipher_async_callback_set = NULL,
890 .query_hw_caps = ataes132a_query_caps,
891 };
892
893 struct ataes132a_device_data ataes132a_data;
894
895 DEVICE_DT_INST_DEFINE(0, ataes132a_init,
896 NULL, &ataes132a_data, &ataes132a_config,
897 POST_KERNEL, CONFIG_CRYPTO_INIT_PRIORITY,
898 (void *)&crypto_enc_funcs);
899