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