1 /*
2 * Copyright (c) 2022 Rockchip Electronics Co. Ltd.
3 */
4
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <string.h>
8 #include <error.h>
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <pthread.h>
12 #include <sys/ioctl.h>
13
14 #include "cryptodev.h"
15 #include "rk_cryptodev.h"
16 #include "rkcrypto_mem.h"
17 #include "rkcrypto_core.h"
18 #include "rkcrypto_core_int.h"
19 #include "rkcrypto_trace.h"
20 #include "rkcrypto_rsa_helper.h"
21 #include "rk_list.h"
22
23 #ifndef ARRAY_SIZE
24 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
25 #endif
26
27 #ifndef container_of
28 #define container_of(ptr, type, member) ({ \
29 const typeof(((type *) 0)->member) *__mptr = (ptr); \
30 (type *) ((char *) __mptr - offsetof(type, member));})
31 #endif
32
33 #define rkop_to_cop(rkop) \
34 ((rkop == RK_OP_CIPHER_ENC) ? COP_ENCRYPT : COP_DECRYPT)
35
36 enum RK_CRYPTO_CONFIG_TYPE {
37 RK_CONFIG_TYPE_CIPHER = 0,
38 RK_CONFIG_TYPE_AE,
39 RK_CONFIG_TYPE_HASH,
40 };
41
42 struct algo_map_info {
43 uint32_t algo;
44 uint32_t mode;
45 uint32_t crypto_id;
46 };
47
48 struct hash_result {
49 uint8_t hash[AALG_MAX_RESULT_LEN];
50 uint32_t len;
51 };
52
53 struct sess_id_node {
54 uint32_t sess_id;
55 uint32_t config_type;
56 void *priv;
57
58 union {
59 rk_cipher_config cipher;
60 rk_ae_config ae;
61 rk_hash_config hash;
62 } config;
63
64 struct list_head list;
65 };
66
67 struct ae_node_priv {
68 void *iv;
69 uint8_t *aad_virt;
70 int aad_fd;
71 };
72
73 static int cryptodev_fd = -1;
74 static int cryptodev_refcnt;
75
76 static struct list_head sess_id_list;
77 pthread_mutex_t sess_mutex = PTHREAD_MUTEX_INITIALIZER;
78
79 #define CHECK_CRYPTO_INITED() do {\
80 if (cryptodev_fd < 0) {\
81 E_TRACE("RK_CRYPTO is uninitialized\n");\
82 return RK_CRYPTO_ERR_UNINITED;\
83 }\
84 } while (0)
85
86 static const struct {
87 const uint32_t kernel_code;
88 const uint32_t rk_crypto_code;
89 } kernel_crypto_code[] = {
90 {0, RK_CRYPTO_SUCCESS},
91 {-EINVAL, RK_CRYPTO_ERR_PARAMETER},
92 {-ENOENT, RK_CRYPTO_ERR_NOT_SUPPORTED},
93 {-ENOMEM, RK_CRYPTO_ERR_OUT_OF_MEMORY},
94 {-EACCES, RK_CRYPTO_ERR_ACCESS_DENIED},
95 {-EBUSY, RK_CRYPTO_ERR_BUSY},
96 {-ETIMEDOUT, RK_CRYPTO_ERR_TIMEOUT},
97 {-ENOKEY, RK_CRYPTO_ERR_KEY},
98 {-EBADMSG, RK_CRYPTO_ERR_MAC_INVALID},
99 };
100
kernel_to_crypto_code(uint32_t tee_code)101 static RK_RES kernel_to_crypto_code(uint32_t tee_code)
102 {
103 uint32_t i;
104
105 for (i = 0; i < ARRAY_SIZE(kernel_crypto_code); i++) {
106 if (tee_code == kernel_crypto_code[i].kernel_code)
107 return kernel_crypto_code[i].rk_crypto_code;
108 }
109
110 /* Others convert to RK_CRYPTO_ERR_GENERIC. */
111 return RK_CRYPTO_ERR_GENERIC;
112 }
113
114 const struct algo_map_info algo_map_tbl[] = {
115 {RK_ALGO_DES, RK_CIPHER_MODE_ECB, CRYPTO_RK_DES_ECB},
116 {RK_ALGO_DES, RK_CIPHER_MODE_CBC, CRYPTO_RK_DES_CBC},
117 {RK_ALGO_DES, RK_CIPHER_MODE_CFB, CRYPTO_RK_DES_CFB},
118 {RK_ALGO_DES, RK_CIPHER_MODE_OFB, CRYPTO_RK_DES_OFB},
119
120 {RK_ALGO_TDES, RK_CIPHER_MODE_ECB, CRYPTO_RK_3DES_ECB},
121 {RK_ALGO_TDES, RK_CIPHER_MODE_CBC, CRYPTO_RK_3DES_CBC},
122 {RK_ALGO_TDES, RK_CIPHER_MODE_CFB, CRYPTO_RK_3DES_CFB},
123 {RK_ALGO_TDES, RK_CIPHER_MODE_OFB, CRYPTO_RK_3DES_OFB},
124
125 {RK_ALGO_SM4, RK_CIPHER_MODE_ECB, CRYPTO_RK_SM4_ECB},
126 {RK_ALGO_SM4, RK_CIPHER_MODE_CBC, CRYPTO_RK_SM4_CBC},
127 {RK_ALGO_SM4, RK_CIPHER_MODE_CFB, CRYPTO_RK_SM4_CFB},
128 {RK_ALGO_SM4, RK_CIPHER_MODE_OFB, CRYPTO_RK_SM4_OFB},
129 {RK_ALGO_SM4, RK_CIPHER_MODE_CTS, CRYPTO_RK_SM4_CTS},
130 {RK_ALGO_SM4, RK_CIPHER_MODE_CTR, CRYPTO_RK_SM4_CTR},
131 {RK_ALGO_SM4, RK_CIPHER_MODE_XTS, CRYPTO_RK_SM4_XTS},
132 {RK_ALGO_SM4, RK_CIPHER_MODE_CCM, CRYPTO_RK_SM4_CCM},
133 {RK_ALGO_SM4, RK_CIPHER_MODE_GCM, CRYPTO_RK_SM4_GCM},
134
135 {RK_ALGO_AES, RK_CIPHER_MODE_ECB, CRYPTO_RK_AES_ECB},
136 {RK_ALGO_AES, RK_CIPHER_MODE_CBC, CRYPTO_RK_AES_CBC},
137 {RK_ALGO_AES, RK_CIPHER_MODE_CFB, CRYPTO_RK_AES_CFB},
138 {RK_ALGO_AES, RK_CIPHER_MODE_OFB, CRYPTO_RK_AES_OFB},
139 {RK_ALGO_AES, RK_CIPHER_MODE_CTS, CRYPTO_RK_AES_CTS},
140 {RK_ALGO_AES, RK_CIPHER_MODE_CTR, CRYPTO_RK_AES_CTR},
141 {RK_ALGO_AES, RK_CIPHER_MODE_XTS, CRYPTO_RK_AES_XTS},
142 {RK_ALGO_AES, RK_CIPHER_MODE_CCM, CRYPTO_RK_AES_CCM},
143 {RK_ALGO_AES, RK_CIPHER_MODE_GCM, CRYPTO_RK_AES_GCM},
144
145 {RK_ALGO_MD5, 0, CRYPTO_RK_MD5},
146 {RK_ALGO_SHA1, 0, CRYPTO_RK_SHA1},
147 {RK_ALGO_SHA224, 0, CRYPTO_RK_SHA224},
148 {RK_ALGO_SHA256, 0, CRYPTO_RK_SHA256},
149 {RK_ALGO_SHA384, 0, CRYPTO_RK_SHA384},
150 {RK_ALGO_SHA512, 0, CRYPTO_RK_SHA512},
151 {RK_ALGO_SHA512_224, 0, CRYPTO_RK_SHA512_224},
152 {RK_ALGO_SHA512_256, 0, CRYPTO_RK_SHA512_256},
153 {RK_ALGO_SM3, 0, CRYPTO_RK_SM3},
154
155 {RK_ALGO_HMAC_MD5, 0, CRYPTO_RK_MD5_HMAC},
156 {RK_ALGO_HMAC_SHA1, 0, CRYPTO_RK_SHA1_HMAC},
157 {RK_ALGO_HMAC_SHA256, 0, CRYPTO_RK_SHA256_HMAC},
158 {RK_ALGO_HMAC_SHA512, 0, CRYPTO_RK_SHA512_HMAC},
159 {RK_ALGO_HMAC_SM3, 0, CRYPTO_RK_SM3_HMAC},
160 {RK_ALGO_CMAC_SM4, 0, CRYPTO_RK_SM4_CMAC},
161 {RK_ALGO_CBCMAC_SM4, 0, CRYPTO_RK_SM4_CBC_MAC},
162 {RK_ALGO_CMAC_AES, 0, CRYPTO_RK_AES_CMAC},
163 {RK_ALGO_CBCMAC_AES, 0, CRYPTO_RK_AES_CBC_MAC},
164 };
165
rk_get_hash_len(uint32_t algo)166 static uint32_t rk_get_hash_len(uint32_t algo)
167 {
168 switch (algo) {
169 case RK_ALGO_MD5:
170 case RK_ALGO_HMAC_MD5:
171 return MD5_HASH_SIZE;
172 case RK_ALGO_SHA1:
173 case RK_ALGO_HMAC_SHA1:
174 return SHA1_HASH_SIZE;
175 case RK_ALGO_SHA224:
176 case RK_ALGO_SHA512_224:
177 return SHA224_HASH_SIZE;
178 case RK_ALGO_SHA256:
179 case RK_ALGO_SHA512_256:
180 case RK_ALGO_HMAC_SHA256:
181 return SHA256_HASH_SIZE;
182 case RK_ALGO_SHA384:
183 return SHA384_HASH_SIZE;
184 case RK_ALGO_SHA512:
185 case RK_ALGO_HMAC_SHA512:
186 return SHA512_HASH_SIZE;
187 case RK_ALGO_SM3:
188 case RK_ALGO_HMAC_SM3:
189 return SM3_HASH_SIZE;
190 default:
191 return 0;
192 }
193 }
194
xioctl(int fd,unsigned long int request,void * arg)195 static RK_RES xioctl(int fd, unsigned long int request, void *arg)
196 {
197 return ioctl(fd, request, arg) ? kernel_to_crypto_code(-errno) : RK_CRYPTO_SUCCESS;
198 }
199
rk_get_crypto_id(uint32_t algo,uint32_t mode,uint32_t * crypto_id)200 static RK_RES rk_get_crypto_id(uint32_t algo, uint32_t mode, uint32_t *crypto_id)
201 {
202 uint32_t i;
203
204 for (i = 0; i < ARRAY_SIZE(algo_map_tbl); i++) {
205 if (algo == algo_map_tbl[i].algo && mode == algo_map_tbl[i].mode) {
206 *crypto_id = algo_map_tbl[i].crypto_id;
207 return RK_CRYPTO_SUCCESS;
208 }
209 }
210
211 return RK_CRYPTO_ERR_GENERIC;
212 }
213
rk_add_sess_node(uint32_t sess_id,uint32_t config_type,const void * config,void * priv)214 static RK_RES rk_add_sess_node(uint32_t sess_id, uint32_t config_type, const void *config, void *priv)
215 {
216 struct sess_id_node *node;
217
218 node = malloc(sizeof(*node));
219 if (!node) {
220 E_TRACE("malloc node error!\n");
221 return RK_CRYPTO_ERR_OUT_OF_MEMORY;
222 }
223
224 switch (config_type) {
225 case RK_CONFIG_TYPE_CIPHER:
226 memcpy(&node->config.cipher, config, sizeof(node->config.cipher));
227 break;
228 case RK_CONFIG_TYPE_AE:
229 memcpy(&node->config.ae, config, sizeof(node->config.ae));
230 break;
231 case RK_CONFIG_TYPE_HASH:
232 memcpy(&node->config.hash, config, sizeof(node->config.hash));
233 break;
234 default:
235 free(node);
236 return RK_CRYPTO_ERR_PARAMETER;
237 }
238
239 node->sess_id = sess_id;
240 node->priv = priv;
241 node->config_type = config_type;
242
243 pthread_mutex_lock(&sess_mutex);
244
245 list_add_tail(&node->list, &sess_id_list);
246
247 pthread_mutex_unlock(&sess_mutex);
248
249 return RK_CRYPTO_SUCCESS;
250 }
251
rk_get_sess_node(uint32_t sess_id)252 static struct sess_id_node *rk_get_sess_node(uint32_t sess_id)
253 {
254 struct list_head *pos = NULL;
255 struct sess_id_node *node = NULL;
256
257 pthread_mutex_lock(&sess_mutex);
258
259 list_for_each(pos, &sess_id_list) {
260 node = list_entry(pos, struct sess_id_node, list);
261
262 if (node->sess_id == sess_id) {
263 goto exit;
264 }
265 }
266
267 exit:
268 pthread_mutex_unlock(&sess_mutex);
269 return node;
270 }
271
rk_get_sess_config(uint32_t sess_id)272 static void *rk_get_sess_config(uint32_t sess_id)
273 {
274 struct sess_id_node *node;
275
276 node = rk_get_sess_node(sess_id);
277
278 return node ? &node->config : NULL;
279 }
280
rk_del_sess_node(uint32_t sess_id)281 static RK_RES rk_del_sess_node(uint32_t sess_id)
282 {
283 struct list_head *pos = NULL, *n = NULL;
284 RK_RES res = RK_CRYPTO_ERR_GENERIC;
285
286 pthread_mutex_lock(&sess_mutex);
287
288 list_for_each_safe(pos, n, &sess_id_list) {
289 struct sess_id_node *node;
290
291 node = list_entry(pos, struct sess_id_node, list);
292
293 if (node->sess_id == sess_id) {
294 list_del(pos);
295 free(node);
296 res = RK_CRYPTO_SUCCESS;
297 goto exit;
298 }
299 }
300
301 exit:
302 pthread_mutex_unlock(&sess_mutex);
303 return res;
304 }
305
rk_create_session(struct session_op * sess,uint32_t config_type,const void * config,void * priv,rk_handle * handle)306 static RK_RES rk_create_session(struct session_op *sess, uint32_t config_type,
307 const void *config, void *priv, rk_handle *handle)
308 {
309 RK_RES res;
310
311 res = xioctl(cryptodev_fd, CIOCGSESSION, sess);
312 if (res) {
313 if (res != RK_CRYPTO_ERR_NOT_SUPPORTED)
314 E_TRACE("CIOCGSESSION error %d!\n", errno);
315
316 goto exit;
317 }
318
319 res = rk_add_sess_node(sess->ses, config_type, config, priv);
320 if (res) {
321 E_TRACE("rk_add_sess_node error[%x]!\n", res);
322 xioctl(cryptodev_fd, CIOCFSESSION, &sess->ses);
323 } else {
324 *handle = sess->ses;
325 }
326 exit:
327 return res;
328 }
329
rk_destroy_session(rk_handle handle)330 static RK_RES rk_destroy_session(rk_handle handle)
331 {
332 RK_RES res;
333
334 res = xioctl(cryptodev_fd, CIOCFSESSION, &handle);
335 if (res) {
336 E_TRACE("CIOCFSESSION error!");
337 return res;
338 }
339
340 return rk_del_sess_node(handle);
341 }
342
rk_update_user_iv(const void * cfg)343 static RK_RES rk_update_user_iv(const void *cfg)
344 {
345 struct sess_id_node *node;
346 struct ae_node_priv *ae_priv = NULL;
347
348 node = container_of(cfg, struct sess_id_node, config.cipher);
349 if (!node)
350 return RK_CRYPTO_ERR_STATE;
351
352 if (node->priv) {
353 V_TRACE("update user iv.");
354
355 switch (node->config_type) {
356 case RK_CONFIG_TYPE_CIPHER:
357 memcpy(node->priv, node->config.cipher.iv, sizeof(node->config.cipher.iv));
358 break;
359 case RK_CONFIG_TYPE_AE:
360 ae_priv = node->priv;
361 memcpy(ae_priv->iv, node->config.ae.iv, node->config.ae.iv_len);
362 break;
363 default:
364 break;
365 }
366 }
367
368 return RK_CRYPTO_SUCCESS;
369 }
370
rk_mpi_bitlen(const uint8_t * data,uint32_t data_len)371 static size_t rk_mpi_bitlen(const uint8_t *data, uint32_t data_len)
372 {
373 uint32_t i;
374
375 while (data_len--) {
376 if (*data) {
377 uint8_t tmp = *data;
378
379 for (i = 0; i < 8; i++) {
380 if (!tmp)
381 break;
382
383 tmp = tmp >> 1;
384 }
385
386 return data_len * 8 + i;
387 }
388
389 data++;
390 }
391
392 return 0;
393 }
394
rk_crypto_init(void)395 RK_RES rk_crypto_init(void)
396 {
397 I_TRACE("%s\n", RK_CRYPTO_API_FULL_VERSION);
398
399 if (cryptodev_fd < 0) {
400 rk_crypto_mem_init();
401
402 INIT_LIST_HEAD(&sess_id_list);
403
404 /* Open the crypto device */
405 cryptodev_fd = open("/dev/crypto", O_RDWR, 0);
406 if (cryptodev_fd < 0) {
407 E_TRACE("open cryptodev error!\n");
408 return kernel_to_crypto_code(-errno);
409 }
410
411 /* Set close-on-exec (not really neede here) */
412 if (fcntl(cryptodev_fd, F_SETFD, 1) == -1) {
413 E_TRACE("cryptodev F_SETFD error!\n");
414 goto error;
415 }
416 }
417
418 cryptodev_refcnt++;
419
420 return RK_CRYPTO_SUCCESS;
421 error:
422 if (cryptodev_fd >= 0)
423 close(cryptodev_fd);
424
425 return RK_CRYPTO_ERR_GENERIC;
426 }
427
rk_crypto_deinit(void)428 void rk_crypto_deinit(void)
429 {
430 if (--cryptodev_refcnt == 0 && cryptodev_fd >= 0) {
431 /* free sess_id list */
432 struct list_head *pos = NULL, *n = NULL;
433
434 pthread_mutex_lock(&sess_mutex);
435
436 list_for_each_safe(pos, n, &sess_id_list) {
437 struct sess_id_node *node;
438
439 node = list_entry(pos, struct sess_id_node, list);
440 list_del(pos);
441 free(node);
442 }
443
444 pthread_mutex_unlock(&sess_mutex);
445
446 close(cryptodev_fd);
447 cryptodev_fd = -1;
448 rk_crypto_mem_deinit();
449
450 }
451
452 if (cryptodev_refcnt < 0)
453 cryptodev_refcnt = 0;
454 }
455
rk_cipher_init(const rk_cipher_config * config,rk_handle * handle)456 RK_RES rk_cipher_init(const rk_cipher_config *config, rk_handle *handle)
457 {
458 RK_RES res;
459 struct session_op sess;
460 uint32_t crypto_id = 0;
461
462 CHECK_CRYPTO_INITED();
463
464 RK_CRYPTO_CHECK_PARAM(!config || !handle);
465
466 memset(&sess, 0, sizeof(sess));
467
468 res = rk_get_crypto_id(config->algo, config->mode, &crypto_id);
469 if (res) {
470 E_TRACE("rk_get_crypto_id error!\n");
471 return res;
472 }
473
474 sess.cipher = crypto_id;
475 sess.key = (__u8 *)config->key;
476 sess.keylen = config->key_len;
477
478 return rk_create_session(&sess, RK_CONFIG_TYPE_CIPHER,
479 config, (void *)config->iv, handle);
480 }
481
rk_cipher_crypt(rk_handle handle,int in_fd,int out_fd,uint32_t len)482 RK_RES rk_cipher_crypt(rk_handle handle, int in_fd, int out_fd, uint32_t len)
483 {
484 struct crypt_fd_op cryp;
485 rk_cipher_config *cipher_cfg;
486 RK_RES res = RK_CRYPTO_ERR_GENERIC;
487
488 CHECK_CRYPTO_INITED();
489
490 RK_CRYPTO_CHECK_PARAM(len == 0);
491
492 cipher_cfg = rk_get_sess_config(handle);
493 if (!cipher_cfg) {
494 E_TRACE("rk_get_sess_config error!\n");
495 return RK_CRYPTO_ERR_STATE;
496 }
497
498 memset(&cryp, 0, sizeof(cryp));
499
500 /* Encrypt data.in to data.encrypted */
501 cryp.ses = handle;
502 cryp.len = len;
503 cryp.src_fd = in_fd;
504 cryp.dst_fd = out_fd;
505 cryp.iv = (void *)cipher_cfg->iv;
506 cryp.op = rkop_to_cop(cipher_cfg->operation);
507 cryp.flags = COP_FLAG_WRITE_IV;
508
509 res = xioctl(cryptodev_fd, RIOCCRYPT_FD, &cryp);
510 if (res) {
511 E_TRACE("RIOCCRYPT_FD error!\n");
512 goto exit;
513 }
514
515 res = rk_update_user_iv(cipher_cfg);
516 if (res) {
517 E_TRACE("rk_update_user_iv error!\n");
518 goto exit;
519 }
520
521 exit:
522 return res;
523 }
524
rk_cipher_crypt_virt(rk_handle handle,const uint8_t * in,uint8_t * out,uint32_t len)525 RK_RES rk_cipher_crypt_virt(rk_handle handle, const uint8_t *in, uint8_t *out, uint32_t len)
526 {
527 struct crypt_op cryp;
528 rk_cipher_config *cipher_cfg;
529 RK_RES res = RK_CRYPTO_ERR_GENERIC;
530
531 CHECK_CRYPTO_INITED();
532
533 RK_CRYPTO_CHECK_PARAM(!in || !out || len == 0);
534
535 cipher_cfg = rk_get_sess_config(handle);
536 if (!cipher_cfg) {
537 E_TRACE("rk_get_sess_config error!\n");
538 return RK_CRYPTO_ERR_STATE;
539 }
540
541 memset(&cryp, 0, sizeof(cryp));
542
543 /* Encrypt data.in to data.encrypted */
544 cryp.ses = handle;
545 cryp.len = len;
546 cryp.src = (void *)in;
547 cryp.dst = out;
548 cryp.iv = (void *)cipher_cfg->iv;
549 cryp.op = rkop_to_cop(cipher_cfg->operation);
550 cryp.flags = COP_FLAG_WRITE_IV;
551
552 res = xioctl(cryptodev_fd, CIOCCRYPT, &cryp);
553 if (res) {
554 E_TRACE("CIOCCRYPT error!\n");
555 goto exit;
556 }
557
558 res = rk_update_user_iv(cipher_cfg);
559 if (res) {
560 E_TRACE("rk_update_user_iv error!\n");
561 goto exit;
562 }
563
564 exit:
565 return res;
566 }
567
rk_cipher_final(rk_handle handle)568 RK_RES rk_cipher_final(rk_handle handle)
569 {
570 CHECK_CRYPTO_INITED();
571
572 return rk_destroy_session(handle);
573 }
574
rk_ae_init(const rk_ae_config * config,rk_handle * handle)575 RK_RES rk_ae_init(const rk_ae_config *config, rk_handle *handle)
576 {
577 RK_RES res;
578 struct session_op sess;
579 uint32_t crypto_id = 0;
580 struct ae_node_priv *ae_priv = NULL;
581
582 CHECK_CRYPTO_INITED();
583
584 RK_CRYPTO_CHECK_PARAM(!config || !handle);
585
586 memset(&sess, 0, sizeof(sess));
587
588 res = rk_get_crypto_id(config->algo, config->mode, &crypto_id);
589 if (res) {
590 E_TRACE("rk_get_crypto_id error!\n");
591 return res;
592 }
593
594 sess.cipher = crypto_id;
595 sess.key = (__u8 *)config->key;
596 sess.keylen = config->key_len;
597
598 ae_priv = calloc(1, sizeof(*ae_priv));
599 if (!ae_priv) {
600 E_TRACE("malloc ae_priv error!\n");
601 return RK_CRYPTO_ERR_OUT_OF_MEMORY;
602 }
603
604 ae_priv->iv = (void *)config->iv;
605
606 return rk_create_session(&sess, RK_CONFIG_TYPE_AE,
607 config, (void *)ae_priv, handle);
608 }
609
ae_set_aad(rk_handle handle,int aad_fd,uint8_t * aad_virt)610 static RK_RES ae_set_aad(rk_handle handle, int aad_fd, uint8_t *aad_virt)
611 {
612 struct sess_id_node *node = NULL;
613 struct ae_node_priv *ae_priv = NULL;
614
615 node = rk_get_sess_node(handle);
616 if (!node) {
617 E_TRACE("rk_get_sess_node error!\n");
618 return RK_CRYPTO_ERR_STATE;
619 }
620
621 ae_priv = node->priv;
622
623 if (aad_fd)
624 ae_priv->aad_fd = aad_fd;
625 if (aad_virt)
626 ae_priv->aad_virt = aad_virt;
627
628 return RK_CRYPTO_SUCCESS;
629 }
630
rk_ae_set_aad(rk_handle handle,int aad_fd)631 RK_RES rk_ae_set_aad(rk_handle handle, int aad_fd)
632 {
633 return ae_set_aad(handle, aad_fd, NULL);
634 }
635
rk_ae_set_aad_virt(rk_handle handle,uint8_t * aad_virt)636 RK_RES rk_ae_set_aad_virt(rk_handle handle, uint8_t *aad_virt)
637 {
638 return ae_set_aad(handle, 0, aad_virt);
639 }
640
rk_ae_crypt(rk_handle handle,int in_fd,int out_fd,uint32_t len,uint8_t * tag)641 RK_RES rk_ae_crypt(rk_handle handle, int in_fd, int out_fd, uint32_t len, uint8_t *tag)
642 {
643 struct crypt_auth_fd_op op;
644 rk_ae_config *ae_cfg = NULL;
645 struct sess_id_node *node = NULL;
646 struct ae_node_priv *ae_priv = NULL;
647 RK_RES res = RK_CRYPTO_ERR_GENERIC;
648
649 CHECK_CRYPTO_INITED();
650
651 RK_CRYPTO_CHECK_PARAM(len == 0);
652
653 node = rk_get_sess_node(handle);
654 if (!node) {
655 E_TRACE("rk_get_sess_node error!\n");
656 return RK_CRYPTO_ERR_STATE;
657 }
658
659 ae_priv = node->priv;
660
661 /* make sure rk_ae_set_aad has been called */
662 RK_CRYPTO_CHECK_PARAM(ae_priv->aad_fd == 0);
663
664 ae_cfg = rk_get_sess_config(handle);
665 if (!ae_cfg) {
666 E_TRACE("rk_get_sess_config error!\n");
667 return RK_CRYPTO_ERR_STATE;
668 }
669
670 if (ae_cfg->tag_len)
671 RK_CRYPTO_CHECK_PARAM(!tag);
672
673 memset(&op, 0, sizeof(op));
674
675 /* Encrypt data.in to data.encrypted */
676 op.ses = handle;
677 op.op = rkop_to_cop(ae_cfg->operation);
678 op.flags = COP_FLAG_WRITE_IV | COP_FLAG_AEAD_RK_TYPE;
679 op.len = len;
680 op.src_fd = in_fd;
681 op.dst_fd = out_fd;
682 op.iv = (unsigned long)ae_cfg->iv | (__u64)0;
683 op.iv_len = ae_cfg->iv_len;
684 op.auth_fd = ae_priv->aad_fd;
685 op.auth_len = ae_cfg->aad_len;
686 op.tag_len = ae_cfg->tag_len;
687 op.tag = (unsigned long)tag | (__u64)0;
688
689 V_TRACE("in and out are %s address.", (in_fd == out_fd) ? "the same" : "different");
690 V_TRACE("cipher data len = %d, aad_len = %d, tag_len = %d",
691 len, ae_cfg->aad_len, ae_cfg->tag_len);
692
693 res = xioctl(cryptodev_fd, RIOCAUTHCRYPT_FD, &op);
694 if (res) {
695 E_TRACE("RIOCCRYPT_FD error!\n");
696 goto exit;
697 }
698
699 res = rk_update_user_iv(ae_cfg);
700 if (res) {
701 E_TRACE("rk_update_user_iv error[0x%x]!\n", res);
702 goto exit;
703 }
704
705 exit:
706 return res;
707 }
708
rk_ae_crypt_virt(rk_handle handle,const uint8_t * in,uint8_t * out,uint32_t len,uint8_t * tag)709 RK_RES rk_ae_crypt_virt(rk_handle handle, const uint8_t *in, uint8_t *out, uint32_t len,
710 uint8_t *tag)
711 {
712 struct crypt_auth_op op;
713 rk_ae_config *ae_cfg = NULL;
714 struct sess_id_node *node = NULL;
715 struct ae_node_priv *ae_priv = NULL;
716 RK_RES res = RK_CRYPTO_ERR_GENERIC;
717
718 CHECK_CRYPTO_INITED();
719
720 RK_CRYPTO_CHECK_PARAM(!in || !out || len == 0);
721
722 node = rk_get_sess_node(handle);
723 if (!node) {
724 E_TRACE("rk_get_sess_node error!\n");
725 return RK_CRYPTO_ERR_STATE;
726 }
727
728 ae_priv = node->priv;
729
730 /* make sure rk_ae_set_aad_virt has been called */
731 RK_CRYPTO_CHECK_PARAM(ae_priv->aad_virt == 0);
732
733 ae_cfg = rk_get_sess_config(handle);
734 if (!ae_cfg) {
735 E_TRACE("rk_get_sess_config error!\n");
736 return RK_CRYPTO_ERR_STATE;
737 }
738
739 memset(&op, 0, sizeof(op));
740
741 /* Encrypt data.in to data.encrypted */
742 op.ses = handle;
743 op.op = rkop_to_cop(ae_cfg->operation);
744 op.flags = COP_FLAG_WRITE_IV | COP_FLAG_AEAD_RK_TYPE;
745 op.len = len;
746 op.src = (void *)in;
747 op.dst = out;
748 op.iv = (void *)ae_cfg->iv;
749 op.iv_len = ae_cfg->iv_len;
750 op.auth_src = ae_priv->aad_virt;
751 op.auth_len = ae_cfg->aad_len;
752 op.tag_len = ae_cfg->tag_len;
753 op.tag = tag;
754
755 V_TRACE("in and out are %s address.", (in == out) ? "the same" : "different");
756 V_TRACE("cipher data len = %d, aad_len = %d, tag_len = %d",
757 len, ae_cfg->aad_len, ae_cfg->tag_len);
758
759 res = xioctl(cryptodev_fd, CIOCAUTHCRYPT, &op);
760 if (res) {
761 E_TRACE("CIOCAUTHCRYPT error!\n");
762 goto exit;
763 }
764
765 res = rk_update_user_iv(ae_cfg);
766 if (res) {
767 E_TRACE("rk_update_user_iv error[0x%x]!\n", res);
768 goto exit;
769 }
770
771 exit:
772 return res;
773 }
774
rk_ae_final(rk_handle handle)775 RK_RES rk_ae_final(rk_handle handle)
776 {
777 struct sess_id_node *node = NULL;
778
779 CHECK_CRYPTO_INITED();
780
781 node = rk_get_sess_node(handle);
782 if (!node) {
783 E_TRACE("rk_get_sess_node error!\n");
784 return RK_CRYPTO_ERR_STATE;
785 }
786
787 free(node->priv);
788
789 return rk_destroy_session(handle);
790 }
791
rk_hash_init(const rk_hash_config * config,rk_handle * handle)792 RK_RES rk_hash_init(const rk_hash_config *config, rk_handle *handle)
793 {
794 RK_RES res;
795 struct session_op sess;
796 uint32_t crypto_id = 0;
797
798 CHECK_CRYPTO_INITED();
799
800 RK_CRYPTO_CHECK_PARAM(!config || !handle);
801
802 memset(&sess, 0, sizeof(sess));
803
804 res = rk_get_crypto_id(config->algo, 0, &crypto_id);
805 if (res) {
806 E_TRACE("rk_get_crypto_id error!\n");
807 return res;
808 }
809
810 sess.mac = crypto_id;
811 if (config->key && config->key_len) {
812 sess.mackey = config->key;
813 sess.mackeylen = config->key_len;
814 }
815
816 return rk_create_session(&sess, RK_CONFIG_TYPE_HASH, config, NULL, handle);
817 }
818
rk_hash_update(rk_handle handle,int data_fd,uint32_t data_len)819 RK_RES rk_hash_update(rk_handle handle, int data_fd, uint32_t data_len)
820 {
821 struct crypt_fd_op cryp;
822 RK_RES res;
823
824 CHECK_CRYPTO_INITED();
825
826 RK_CRYPTO_CHECK_PARAM(data_len == 0);
827
828 memset(&cryp, 0, sizeof(cryp));
829
830 cryp.ses = handle;
831 cryp.len = data_len;
832 cryp.src_fd = data_fd;
833 cryp.mac = NULL;
834 cryp.flags = COP_FLAG_UPDATE;
835
836 res = xioctl(cryptodev_fd, RIOCCRYPT_FD, &cryp);
837 if (res) {
838 E_TRACE("RIOCCRYPT_FD error!\n");
839 return res;
840 }
841
842 return RK_CRYPTO_SUCCESS;
843 }
844
rk_hash_update_virt(rk_handle handle,const uint8_t * data,uint32_t data_len)845 RK_RES rk_hash_update_virt(rk_handle handle, const uint8_t *data, uint32_t data_len)
846 {
847 struct crypt_op cryp;
848 RK_RES res;
849
850 CHECK_CRYPTO_INITED();
851
852 RK_CRYPTO_CHECK_PARAM(!data || data_len == 0);
853
854 memset(&cryp, 0, sizeof(cryp));
855
856 cryp.ses = handle;
857 cryp.len = data_len;
858 cryp.src = (void *)data;
859 cryp.mac = NULL;
860 cryp.flags = COP_FLAG_UPDATE;
861
862 res = xioctl(cryptodev_fd, CIOCCRYPT, &cryp);
863 if (res) {
864 E_TRACE("CIOCCRYPT error!\n");
865 return res;
866 }
867
868 return RK_CRYPTO_SUCCESS;
869 }
870
rk_hash_final(rk_handle handle,uint8_t * hash)871 RK_RES rk_hash_final(rk_handle handle, uint8_t *hash)
872 {
873 RK_RES res = RK_CRYPTO_SUCCESS;
874 struct crypt_op cryp;
875 rk_hash_config *hash_cfg;
876 uint8_t hash_tmp[SHA512_HASH_SIZE];
877 uint32_t hash_tmp_len;
878
879 CHECK_CRYPTO_INITED();
880
881 hash_cfg = rk_get_sess_config(handle);
882 if (!hash_cfg) {
883 E_TRACE("handle[%u] rk_get_sess_config error!\n", handle);
884 goto exit;
885 }
886
887 hash_tmp_len = rk_get_hash_len(hash_cfg->algo);
888
889 /* final update 0 Byte */
890 memset(&cryp, 0, sizeof(cryp));
891
892 cryp.ses = handle;
893 cryp.mac = hash_tmp;
894 cryp.flags = COP_FLAG_FINAL;
895
896 res = xioctl(cryptodev_fd, CIOCCRYPT, &cryp);
897 if (res) {
898 E_TRACE("CIOCCRYPT error!\n");
899 goto exit;
900 }
901
902 if (hash)
903 memcpy(hash, hash_tmp, hash_tmp_len);
904
905 exit:
906 return rk_destroy_session(handle);
907 }
908
rk_crypto_fd_ioctl(uint32_t request,struct crypt_fd_map_op * mop)909 RK_RES rk_crypto_fd_ioctl(uint32_t request, struct crypt_fd_map_op *mop)
910 {
911 RK_RES res;
912
913 CHECK_CRYPTO_INITED();
914
915 RK_CRYPTO_CHECK_PARAM(request != RIOCCRYPT_FD_MAP &&
916 request != RIOCCRYPT_FD_UNMAP);
917 RK_CRYPTO_CHECK_PARAM(!mop);
918
919 res = xioctl(cryptodev_fd, request, mop);
920 if (res) {
921 E_TRACE("ioctl cryptodev_fd failed!");
922 return res;
923 }
924
925 return RK_CRYPTO_SUCCESS;
926 }
927
rk_rsa_crypt_common(void * key,uint16_t flag,uint16_t op,const uint8_t * in,uint32_t in_len,uint8_t * out,uint32_t * out_len)928 static RK_RES rk_rsa_crypt_common(void *key, uint16_t flag, uint16_t op,
929 const uint8_t *in, uint32_t in_len,
930 uint8_t *out, uint32_t *out_len)
931 {
932 RK_RES res = RK_CRYPTO_ERR_GENERIC;
933 uint8_t *asn1_key = NULL;
934 uint16_t asn1_key_len = RK_RSA_BER_KEY_MAX, key_bits;
935 struct crypt_rsa_op rop;
936
937 CHECK_CRYPTO_INITED();
938
939 RK_CRYPTO_CHECK_PARAM(!key);
940
941 asn1_key = malloc(asn1_key_len);
942 if (!asn1_key) {
943 E_TRACE("ioctl cryptodev_fd failed!");
944 return RK_CRYPTO_ERR_OUT_OF_MEMORY;
945 }
946
947 memset(asn1_key, 0x00, asn1_key_len);
948
949 /* Encode the key in ASN1 format */
950 if ((flag & COP_FLAG_RSA_PRIV) == COP_FLAG_RSA_PRIV)
951 res = rk_rsa_privkey_encode((rk_rsa_priv_key_pack *)key,
952 asn1_key, &asn1_key_len, &key_bits);
953 else
954 res = rk_rsa_pubkey_encode((rk_rsa_pub_key_pack *)key,
955 asn1_key, &asn1_key_len, &key_bits);
956
957 if (res) {
958 E_TRACE("asn1 encode failed %x!", res);
959 res = RK_CRYPTO_ERR_KEY;
960 goto exit;
961 }
962
963 if (key_bits / 8 != in_len) {
964 E_TRACE("RIOCCRYPT_RSA_CRYPT length not match!");
965 res = RK_CRYPTO_ERR_PARAMETER;
966 goto exit;
967 }
968
969 memset(&rop, 0x00, sizeof(rop));
970
971 rop.op = op;
972 rop.flags = flag;
973 rop.key = (unsigned long)asn1_key | (__u64)0;
974 rop.key_len = asn1_key_len;
975 rop.in = (unsigned long)in | (__u64)0;
976 rop.in_len = in_len;
977 rop.out = (unsigned long)out | (__u64)0;
978
979 res = xioctl(cryptodev_fd, RIOCCRYPT_RSA_CRYPT, &rop);
980 if (res) {
981 E_TRACE("ioctl cryptodev_fd failed! [%d]", -errno);
982 goto exit;
983 }
984
985 *out_len = rop.out_len;
986 res = RK_CRYPTO_SUCCESS;
987 exit:
988 memset(asn1_key, 0x00, asn1_key_len);
989
990 free(asn1_key);
991
992 return res;
993 }
994
rk_rsa_pub_encrypt(const rk_rsa_pub_key_pack * pub,enum RK_RSA_CRYPT_PADDING padding,const uint8_t * in,uint32_t in_len,uint8_t * out,uint32_t * out_len)995 RK_RES rk_rsa_pub_encrypt(const rk_rsa_pub_key_pack *pub, enum RK_RSA_CRYPT_PADDING padding,
996 const uint8_t *in, uint32_t in_len, uint8_t *out, uint32_t *out_len)
997 {
998 RK_RES res;
999 uint8_t data_pad[MAX_RSA_KEY_BITS / 8];
1000 uint32_t data_pad_len = sizeof(data_pad);
1001
1002 RK_CRYPTO_CHECK_PARAM(!pub || !in || !out || !out_len);
1003 RK_CRYPTO_CHECK_PARAM(in_len == 0);
1004
1005 /* deal with padding */
1006 res = rk_rsa_crypt_do_padding(padding, pub->key.n_len, false,
1007 in, in_len, data_pad, &data_pad_len);
1008 if (res) {
1009 D_TRACE("rsa padding %d error!", padding);
1010 return res;
1011 }
1012
1013 return rk_rsa_crypt_common((void *)pub, COP_FLAG_RSA_PUB, AOP_ENCRYPT,
1014 data_pad, data_pad_len, out, out_len);
1015 }
1016
rk_rsa_priv_decrypt(const rk_rsa_priv_key_pack * priv,enum RK_RSA_CRYPT_PADDING padding,const uint8_t * in,uint32_t in_len,uint8_t * out,uint32_t * out_len)1017 RK_RES rk_rsa_priv_decrypt(const rk_rsa_priv_key_pack *priv, enum RK_RSA_CRYPT_PADDING padding,
1018 const uint8_t *in, uint32_t in_len, uint8_t *out, uint32_t *out_len)
1019 {
1020 RK_RES res;
1021 uint8_t data_pad[MAX_RSA_KEY_BITS / 8];
1022 uint32_t data_pad_len = sizeof(data_pad);
1023
1024 RK_CRYPTO_CHECK_PARAM(!priv || !in || !out || !out_len);
1025 RK_CRYPTO_CHECK_PARAM(priv->key.n_len != in_len);
1026
1027 res = rk_rsa_crypt_common((void *)priv, COP_FLAG_RSA_PRIV, AOP_DECRYPT,
1028 in, in_len, data_pad, &data_pad_len);
1029 if (res) {
1030 D_TRACE("rk_rsa_crypt_common error! %x", res);
1031 return res;
1032 }
1033
1034 return rk_rsa_crypt_undo_padding(padding, priv->key.n_len, true,
1035 data_pad, data_pad_len, out, out_len);
1036 }
1037
rk_rsa_priv_encrypt(const rk_rsa_priv_key_pack * priv,enum RK_RSA_CRYPT_PADDING padding,const uint8_t * in,uint32_t in_len,uint8_t * out,uint32_t * out_len)1038 RK_RES rk_rsa_priv_encrypt(const rk_rsa_priv_key_pack *priv, enum RK_RSA_CRYPT_PADDING padding,
1039 const uint8_t *in, uint32_t in_len, uint8_t *out, uint32_t *out_len)
1040 {
1041 RK_RES res;
1042 uint8_t data_pad[MAX_RSA_KEY_BITS / 8];
1043 uint32_t data_pad_len = sizeof(data_pad);
1044
1045 RK_CRYPTO_CHECK_PARAM(!priv || !in || !out || !out_len);
1046 RK_CRYPTO_CHECK_PARAM(in_len == 0);
1047
1048 /* deal with padding */
1049 res = rk_rsa_crypt_do_padding(padding, priv->key.n_len, true,
1050 in, in_len, data_pad, &data_pad_len);
1051 if (res) {
1052 D_TRACE("rsa padding %d error!", padding);
1053 return res;
1054 }
1055
1056 return rk_rsa_crypt_common((void *)priv, COP_FLAG_RSA_PRIV, AOP_DECRYPT,
1057 data_pad, data_pad_len, out, out_len);
1058 }
1059
rk_rsa_pub_decrypt(const rk_rsa_pub_key_pack * pub,enum RK_RSA_CRYPT_PADDING padding,const uint8_t * in,uint32_t in_len,uint8_t * out,uint32_t * out_len)1060 RK_RES rk_rsa_pub_decrypt(const rk_rsa_pub_key_pack *pub, enum RK_RSA_CRYPT_PADDING padding,
1061 const uint8_t *in, uint32_t in_len, uint8_t *out, uint32_t *out_len)
1062 {
1063 RK_RES res;
1064 uint8_t data_pad[MAX_RSA_KEY_BITS / 8];
1065 uint32_t data_pad_len = sizeof(data_pad);
1066
1067 RK_CRYPTO_CHECK_PARAM(!pub || !in || !out || !out_len);
1068 RK_CRYPTO_CHECK_PARAM(pub->key.n_len != in_len);
1069
1070 res = rk_rsa_crypt_common((void *)pub, COP_FLAG_RSA_PUB, AOP_ENCRYPT,
1071 in, in_len, data_pad, &data_pad_len);
1072 if (res) {
1073 D_TRACE("rk_rsa_crypt_common error! %x", res);
1074 return res;
1075 }
1076
1077 return rk_rsa_crypt_undo_padding(padding, pub->key.n_len, false,
1078 data_pad, data_pad_len, out, out_len);
1079 }
1080
rk_rsa_sign(const rk_rsa_priv_key_pack * priv,enum RK_RSA_SIGN_PADDING padding,const uint8_t * in,uint32_t in_len,const uint8_t * hash,uint8_t * out,uint32_t * out_len)1081 RK_RES rk_rsa_sign(const rk_rsa_priv_key_pack *priv, enum RK_RSA_SIGN_PADDING padding,
1082 const uint8_t *in, uint32_t in_len, const uint8_t *hash,
1083 uint8_t *out, uint32_t *out_len)
1084 {
1085 RK_RES res;
1086 uint8_t data_pad[MAX_RSA_KEY_BITS / 8];
1087 uint32_t data_pad_len = sizeof(data_pad);
1088
1089 RK_CRYPTO_CHECK_PARAM(!in && !hash);
1090 RK_CRYPTO_CHECK_PARAM(in && in_len == 0);
1091 RK_CRYPTO_CHECK_PARAM(!priv || !out || !out_len);
1092
1093 /* deal with padding */
1094 res = rk_rsa_sign_do_padding(padding, priv->key.n_len,
1095 rk_mpi_bitlen(priv->key.n, priv->key.n_len),
1096 in, in_len, hash, data_pad, &data_pad_len);
1097 if (res) {
1098 D_TRACE("rsa padding %d error!", padding);
1099 return res;
1100 }
1101
1102 return rk_rsa_crypt_common((void *)priv, COP_FLAG_RSA_PRIV, AOP_DECRYPT,
1103 data_pad, data_pad_len, out, out_len);
1104 }
1105
rk_rsa_verify(const rk_rsa_pub_key_pack * pub,enum RK_RSA_SIGN_PADDING padding,const uint8_t * in,uint32_t in_len,const uint8_t * hash,uint8_t * sign,uint32_t sign_len)1106 RK_RES rk_rsa_verify(const rk_rsa_pub_key_pack *pub, enum RK_RSA_SIGN_PADDING padding,
1107 const uint8_t *in, uint32_t in_len, const uint8_t *hash,
1108 uint8_t *sign, uint32_t sign_len)
1109 {
1110 RK_RES res;
1111 uint8_t dec_pad[MAX_RSA_KEY_BITS / 8];
1112 uint32_t dec_pad_len = sizeof(dec_pad);
1113
1114 RK_CRYPTO_CHECK_PARAM(!in && !hash);
1115 RK_CRYPTO_CHECK_PARAM(in && in_len == 0);
1116 RK_CRYPTO_CHECK_PARAM(!pub || !sign);
1117 RK_CRYPTO_CHECK_PARAM(pub->key.n_len != sign_len);
1118
1119 res = rk_rsa_crypt_common((void *)pub, COP_FLAG_RSA_PUB, AOP_ENCRYPT,
1120 sign, sign_len, dec_pad, &dec_pad_len);
1121 if (res) {
1122 D_TRACE("rsa rk_rsa_crypt_common error[%x]!", res);
1123 goto exit;
1124 }
1125
1126 /* deal with padding */
1127 res = rk_rsa_sign_undo_padding(padding, pub->key.n_len,
1128 rk_mpi_bitlen(pub->key.n, pub->key.n_len),
1129 in, in_len, hash, dec_pad);
1130 if (res) {
1131 D_TRACE("rsa padding %d error!", padding);
1132 goto exit;
1133 }
1134
1135 exit:
1136 return res ? RK_CRYPTO_ERR_VERIFY : RK_CRYPTO_SUCCESS;
1137 }
1138