1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2021 Rockchip Electronics Co. Ltd.
4 */
5
6 #include <tee_internal_api.h>
7 #include <tee_internal_api_extensions.h>
8 #include <tee_api_defines.h>
9 #include <tee_api_defines_extensions.h>
10 #include <utee_defines.h>
11 #include <util.h>
12 #include "rk_crypto_api.h"
13
14 #define CRYPTO_DEBUG 0
15
16
long2byte(uint64_t value,uint8_t ch[8])17 static uint32_t long2byte(uint64_t value, uint8_t ch[8])
18 {
19 int i;
20 uint32_t len = 0;
21
22 for (i = 7; i >= 0; i--) {
23 ch[i] = (value & 0xff00000000000000) >> 56;
24 value = value << 8;
25 if (ch[i] != 0 && len == 0)
26 len = i + 1;
27 }
28
29 return len;
30 }
31
rk_gen_rsa_key(rsa_key_t * rsa_key,uint32_t key_len,uint64_t public_exponent)32 TEE_Result rk_gen_rsa_key(rsa_key_t *rsa_key, uint32_t key_len,
33 uint64_t public_exponent)
34 {
35 TEE_Result res;
36 TEE_ObjectHandle obj;
37 TEE_Attribute attr;
38 uint8_t e[8] = {0};
39 uint32_t e_len = 0;
40 uint32_t out_len = 0;
41
42 if (rsa_key == NULL)
43 return TEE_ERROR_BAD_PARAMETERS;
44
45 if (key_len != 32 && key_len != 64 && key_len != 96 &&
46 key_len != 128 && key_len != 192 && key_len != 256 &&
47 key_len != 384 && key_len != 512)
48 return TEE_ERROR_BAD_PARAMETERS;
49
50 /* support 3 and 65537 for now */
51 if (public_exponent != 3 && public_exponent != 65537)
52 return TEE_ERROR_BAD_PARAMETERS;
53
54 e_len = long2byte(public_exponent, e);
55
56 TEE_InitRefAttribute(&attr, TEE_ATTR_RSA_PUBLIC_EXPONENT, e, e_len);
57
58 res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, key_len * 8, &obj);
59 if (res != TEE_SUCCESS) {
60 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
61 return res;
62 }
63
64 res = TEE_GenerateKey(obj, key_len * 8, &attr, 1);
65 if (res != TEE_SUCCESS) {
66 EMSG("TEE_GenerateKey failed with code 0x%x", res);
67 goto exit;
68 }
69
70 out_len = sizeof(rsa_key->n);
71 res = TEE_GetObjectBufferAttribute(obj, TEE_ATTR_RSA_MODULUS, rsa_key->n,
72 &out_len);
73 if (res != TEE_SUCCESS) {
74 EMSG("TEE_GetObjectBufferAttribute for RSA_n failed with code 0x%x", res);
75 goto exit;
76 }
77 rsa_key->key_len = out_len;
78
79 res = TEE_GetObjectBufferAttribute(obj, TEE_ATTR_RSA_PUBLIC_EXPONENT,
80 rsa_key->e, &e_len);
81 if (res != TEE_SUCCESS) {
82 EMSG("TEE_GetObjectBufferAttribute for RSA_e failed with code 0x%x", res);
83 goto exit;
84 }
85 rsa_key->e_len = e_len;
86
87 out_len = sizeof(rsa_key->d);
88 res = TEE_GetObjectBufferAttribute(obj, TEE_ATTR_RSA_PRIVATE_EXPONENT,
89 rsa_key->d, &out_len);
90 if (res != TEE_SUCCESS) {
91 EMSG("TEE_GetObjectBufferAttribute for RSA_d failed with code 0x%x", res);
92 goto exit;
93 }
94 rsa_key->d_len = out_len;
95
96 out_len = sizeof(rsa_key->p);
97 res = TEE_GetObjectBufferAttribute(obj, TEE_ATTR_RSA_PRIME1, rsa_key->p,
98 &out_len);
99 if (res != TEE_SUCCESS) {
100 EMSG("TEE_GetObjectBufferAttribute for RSA_p failed with code 0x%x", res);
101 goto exit;
102 }
103 rsa_key->p_len = out_len;
104
105 out_len = sizeof(rsa_key->q);
106 res = TEE_GetObjectBufferAttribute(obj, TEE_ATTR_RSA_PRIME2, rsa_key->q,
107 &out_len);
108 if (res != TEE_SUCCESS) {
109 EMSG("TEE_GetObjectBufferAttribute for RSA_q failed with code 0x%x", res);
110 goto exit;
111 }
112 rsa_key->q_len = out_len;
113
114 out_len = sizeof(rsa_key->dp);
115 res = TEE_GetObjectBufferAttribute(obj, TEE_ATTR_RSA_EXPONENT1, rsa_key->dp,
116 &out_len);
117 if (res != TEE_SUCCESS) {
118 EMSG("TEE_GetObjectBufferAttribute for RSA_dp failed with code 0x%x", res);
119 goto exit;
120 }
121 rsa_key->dp_len = out_len;
122
123 out_len = sizeof(rsa_key->dq);
124 res = TEE_GetObjectBufferAttribute(obj, TEE_ATTR_RSA_EXPONENT2, rsa_key->dq,
125 &out_len);
126 if (res != TEE_SUCCESS) {
127 EMSG("TEE_GetObjectBufferAttribute for RSA_dq failed with code 0x%x", res);
128 goto exit;
129 }
130 rsa_key->dq_len = out_len;
131
132 out_len = sizeof(rsa_key->iq);
133 res = TEE_GetObjectBufferAttribute(obj, TEE_ATTR_RSA_COEFFICIENT, rsa_key->iq,
134 &out_len);
135 if (res != TEE_SUCCESS) {
136 EMSG("TEE_GetObjectBufferAttribute for RSA_iq failed with code 0x%x", res);
137 goto exit;
138 }
139 rsa_key->iq_len = out_len;
140
141 exit:
142 TEE_FreeTransientObject(obj);
143
144 return res;
145 }
146
rk_gen_ec_key(ec_key_t * ec_key,uint32_t key_len,uint32_t curve)147 TEE_Result rk_gen_ec_key(ec_key_t *ec_key, uint32_t key_len /* bit */,
148 uint32_t curve)
149 {
150 TEE_Result res;
151 TEE_ObjectHandle obj;
152 TEE_Attribute attr;
153 uint32_t out_len = 0;
154 uint32_t padding_len = 0;
155 uint32_t key_size_bytes = 0;
156 uint8_t tmp_buf[66] = {0};
157
158 #if CRYPTO_DEBUG
159 IMSG("key_len = %d; curve = %d", key_len, curve);
160 #endif
161
162 if (ec_key == NULL)
163 return TEE_ERROR_BAD_PARAMETERS;
164
165 if (key_len != 192 && key_len != 224 && key_len != 256 &&
166 key_len != 384 && key_len != 521)
167 return TEE_ERROR_BAD_PARAMETERS;
168
169 if (curve != TEE_ECC_CURVE_NIST_P192 &&
170 curve != TEE_ECC_CURVE_NIST_P224 &&
171 curve != TEE_ECC_CURVE_NIST_P256 &&
172 curve != TEE_ECC_CURVE_NIST_P384 &&
173 curve != TEE_ECC_CURVE_NIST_P521)
174 return TEE_ERROR_BAD_PARAMETERS;
175
176 ec_key->curve = curve;
177 ec_key->key_len = key_len;
178
179 key_size_bytes = (key_len + 7) / 8;
180
181 TEE_InitValueAttribute(&attr, TEE_ATTR_ECC_CURVE, curve, 0);
182
183 res = TEE_AllocateTransientObject(TEE_TYPE_ECDSA_KEYPAIR, key_len, &obj);
184 if (res != TEE_SUCCESS) {
185 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
186 return res;
187 }
188
189 res = TEE_GenerateKey(obj, key_len, &attr, 1);
190 if (res != TEE_SUCCESS) {
191 EMSG("TEE_GenerateKey failed with code 0x%x", res);
192 goto exit;
193 }
194
195 out_len = sizeof(tmp_buf);
196 res = TEE_GetObjectBufferAttribute(obj, TEE_ATTR_ECC_PRIVATE_VALUE, tmp_buf,
197 &out_len);
198 if (res != TEE_SUCCESS) {
199 EMSG("TEE_GetObjectBufferAttribute for ECC_d failed with code 0x%x", res);
200 goto exit;
201 }
202
203 padding_len = key_size_bytes - out_len;
204 TEE_MemFill(ec_key->d, 0, padding_len);
205 TEE_MemMove(ec_key->d + padding_len, tmp_buf, out_len);
206 ec_key->d_len = key_size_bytes;
207
208 out_len = sizeof(tmp_buf);
209 res = TEE_GetObjectBufferAttribute(obj, TEE_ATTR_ECC_PUBLIC_VALUE_X, tmp_buf,
210 &out_len);
211 if (res != TEE_SUCCESS) {
212 EMSG("TEE_GetObjectBufferAttribute for ECC_x failed with code 0x%x", res);
213 goto exit;
214 }
215
216 padding_len = key_size_bytes - out_len;
217 TEE_MemFill(ec_key->x, 0, padding_len);
218 TEE_MemMove(ec_key->x + padding_len, tmp_buf, out_len);
219 ec_key->x_len = key_size_bytes;
220
221 out_len = sizeof(tmp_buf);
222 res = TEE_GetObjectBufferAttribute(obj, TEE_ATTR_ECC_PUBLIC_VALUE_Y, tmp_buf,
223 &out_len);
224 if (res != TEE_SUCCESS) {
225 EMSG("TEE_GetObjectBufferAttribute for ECC_y failed with code 0x%x", res);
226 goto exit;
227 }
228
229 padding_len = key_size_bytes - out_len;
230 TEE_MemFill(ec_key->y, 0, padding_len);
231 TEE_MemMove(ec_key->y + padding_len, tmp_buf, out_len);
232 ec_key->y_len = key_size_bytes;
233
234 exit:
235 TEE_FreeTransientObject(obj);
236
237 return res;
238 }
239
rk_cipher_crypto(uint8_t * in,uint8_t * out,uint32_t len,uint8_t * key,uint32_t key_len,uint8_t * iv,uint32_t algo,TEE_OperationMode mode)240 TEE_Result rk_cipher_crypto(uint8_t *in, uint8_t *out, uint32_t len,
241 uint8_t *key, uint32_t key_len, uint8_t *iv,
242 uint32_t algo, TEE_OperationMode mode)
243 {
244 TEE_Result res = 0;
245 TEE_OperationHandle crypto_op = NULL;
246 TEE_ObjectHandle obj = NULL;
247 TEE_ObjectHandle obj_2 = NULL;
248 TEE_Attribute attr;
249 uint32_t obj_type;
250 uint32_t iv_len = 0;
251 uint32_t out_size = 0;
252 uint32_t obj_key_size = 0;
253 uint32_t op_key_size = 0;
254
255 if (in == NULL || out == NULL || key == NULL)
256 return TEE_ERROR_BAD_PARAMETERS;
257
258 if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT)
259 return TEE_ERROR_BAD_PARAMETERS;
260
261 #if CRYPTO_DEBUG
262 IMSG("in is 0x%x; out is 0x%x; key is 0x%x; ", *in, *out, *key);
263 IMSG("in_len is %d; key_len is %d; algo is %08x", len, key_len, algo);
264 if (iv)
265 IMSG("iv is 0x%x", *iv);
266 #endif
267 out_size = len;
268
269 switch (algo) {
270 case TEE_ALG_AES_ECB_NOPAD:
271 case TEE_ALG_AES_CBC_NOPAD:
272 case TEE_ALG_AES_CTR:
273 case TEE_ALG_AES_CTS:
274 if (key_len != 16 && key_len != 24 && key_len != 32)
275 return TEE_ERROR_BAD_PARAMETERS;
276 /* CTS is only for data which is not multiple of AES_BLOCK_SIZE
277 * Others except CTR, are only for data which is multiple of AES_BLOCK_SIZE */
278 if (((algo == TEE_ALG_AES_CTS) && (len % AES_BLOCK_SIZE == 0)) ||
279 ((algo != TEE_ALG_AES_CTS) &&
280 (algo != TEE_ALG_AES_CTR) && (len % AES_BLOCK_SIZE != 0)))
281 return TEE_ERROR_BAD_PARAMETERS;
282 obj_type = TEE_TYPE_AES;
283 iv_len = AES_BLOCK_SIZE;
284 obj_key_size = key_len * 8;
285 op_key_size = obj_key_size;
286 break;
287 case TEE_ALG_AES_XTS:
288 if (key_len != 32 && key_len != 64)
289 return TEE_ERROR_BAD_PARAMETERS;
290 obj_type = TEE_TYPE_AES;
291 iv_len = AES_BLOCK_SIZE;
292 key_len = key_len / 2; //Divide the key into two XTS keys.
293 obj_key_size = key_len * 8;
294 op_key_size = obj_key_size * 2; //Should specifies both two keys.
295 break;
296 case TEE_ALG_SM4_ECB_NOPAD:
297 case TEE_ALG_SM4_CBC_NOPAD:
298 case TEE_ALG_SM4_CTR:
299 if (key_len != 16)
300 return TEE_ERROR_BAD_PARAMETERS;
301 /* CTS is only for data which is not multiple of AES_BLOCK_SIZE
302 * Others is only for data which is multiple of AES_BLOCK_SIZE */
303 if (len % SM4_BLOCK_SIZE != 0)
304 return TEE_ERROR_BAD_PARAMETERS;
305 obj_type = TEE_TYPE_SM4;
306 iv_len = SM4_BLOCK_SIZE;
307 obj_key_size = key_len * 8;
308 op_key_size = obj_key_size;
309 break;
310 case TEE_ALG_DES_ECB_NOPAD:
311 case TEE_ALG_DES_CBC_NOPAD:
312 if ((key_len != 8) || (len % DES_BLOCK_SIZE != 0))
313 return TEE_ERROR_BAD_PARAMETERS;
314 obj_type = TEE_TYPE_DES;
315 iv_len = DES_BLOCK_SIZE;
316 obj_key_size = key_len * 7;
317 op_key_size = obj_key_size;
318 break;
319 case TEE_ALG_DES3_ECB_NOPAD:
320 case TEE_ALG_DES3_CBC_NOPAD:
321 if ((key_len != 16 && key_len != 24) || (len % DES_BLOCK_SIZE != 0))
322 return TEE_ERROR_BAD_PARAMETERS;
323 obj_type = TEE_TYPE_DES3;
324 iv_len = DES_BLOCK_SIZE;
325 obj_key_size = key_len * 7;
326 op_key_size = obj_key_size;
327 break;
328 default:
329 return TEE_ERROR_BAD_PARAMETERS;
330 }
331
332 if (!iv)
333 iv_len = 0;
334
335 res = TEE_AllocateOperation(&crypto_op, algo, mode, op_key_size);
336 if (res != TEE_SUCCESS) {
337 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
338 goto exit;
339 }
340
341 /* Set object of key 1 */
342 TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key, key_len);
343 res = TEE_AllocateTransientObject(obj_type, obj_key_size, &obj);
344 if (res != TEE_SUCCESS) {
345 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
346 goto exit;
347 }
348 res = TEE_PopulateTransientObject(obj, &attr, 1);
349 if (res != TEE_SUCCESS) {
350 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
351 goto exit;
352 }
353
354 if (algo == TEE_ALG_AES_XTS) {
355 /* Set object of key 2 */
356 TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key + key_len,
357 key_len);
358 res = TEE_AllocateTransientObject(obj_type, obj_key_size, &obj_2);
359 if (res != TEE_SUCCESS) {
360 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
361 goto exit;
362 }
363 res = TEE_PopulateTransientObject(obj_2, &attr, 1);
364 if (res != TEE_SUCCESS) {
365 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
366 goto exit;
367 }
368
369 /* Set operation of two keys */
370 res = TEE_SetOperationKey2(crypto_op, obj, obj_2);
371 if (res != TEE_SUCCESS) {
372 EMSG("TEE_SetOperationKey2 failed with code 0x%x", res);
373 goto exit;
374 }
375 } else {
376 /* Set operation of one key */
377 res = TEE_SetOperationKey(crypto_op, obj);
378 if (res != TEE_SUCCESS) {
379 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
380 goto exit;
381 }
382 }
383
384 TEE_CipherInit(crypto_op, iv, iv_len);
385 res = TEE_CipherDoFinal(crypto_op, in, len, out, &out_size);
386
387 if (res != TEE_SUCCESS) {
388 EMSG("TEE_CipherDoFinal failed with code 0x%x", res);
389 goto exit;
390 }
391
392 exit:
393 if (obj)
394 TEE_FreeTransientObject(obj);
395 if (obj_2)
396 TEE_FreeTransientObject(obj_2);
397 if (crypto_op)
398 TEE_FreeOperation(crypto_op);
399 return res;
400 }
401
rk_set_padding(crypto_ctx_t * ctx,int padding)402 TEE_Result rk_set_padding(crypto_ctx_t *ctx, int padding)
403 {
404 if (!ctx)
405 return TEE_ERROR_BAD_PARAMETERS;
406 if (padding)
407 ctx->padding = PKCS7_PADDING;
408 else
409 ctx->padding = NO_PADDING;
410
411 return TEE_SUCCESS;
412 }
413
rk_set_sign_mode(crypto_ctx_t * ctx,unsigned int mode)414 TEE_Result rk_set_sign_mode(crypto_ctx_t *ctx, unsigned int mode)
415 {
416 if (ctx == NULL)
417 return TEE_ERROR_BAD_PARAMETERS;
418
419 if (mode != SIGN_DIGEST && mode != SIGN_DATA)
420 return TEE_ERROR_BAD_PARAMETERS;
421
422 ctx->sign_mode = mode;
423
424 return TEE_SUCCESS;
425 }
426
rk_aes_padding_pkcs7(uint8_t * in,uint8_t * out,uint32_t len)427 static TEE_Result rk_aes_padding_pkcs7(uint8_t *in, uint8_t *out, uint32_t len)
428 {
429 int pad_len;
430
431 if ((!in) || (!out))
432 return TEE_ERROR_BAD_PARAMETERS;
433
434 pad_len = AES_BLOCK_SIZE - len % AES_BLOCK_SIZE;
435
436 TEE_MemMove(out, in, len);
437 TEE_MemFill(&out[len], pad_len, pad_len);
438
439 return TEE_SUCCESS;
440 }
441
rk_cut_pkcs7_padding(uint8_t * out,uint32_t * out_len)442 static int rk_cut_pkcs7_padding(uint8_t *out, uint32_t *out_len)
443 {
444 int i, n;
445 int len = 0;
446
447 if (out == NULL || out_len == NULL)
448 return TEE_ERROR_BAD_PARAMETERS;
449 if (*out_len == 0)
450 return TEE_ERROR_BAD_PARAMETERS;
451
452 len = *out_len;
453
454 n = out[len - 1];
455
456 for (i = 0; i < n; i ++) {
457 if (out[len - 1 - i] != n) {
458 return TEE_ERROR_BAD_FORMAT;
459 }
460 }
461
462 *out_len -= n;
463
464 return TEE_SUCCESS;
465 }
466
rk_crypto_malloc_ctx(void)467 crypto_ctx_t *rk_crypto_malloc_ctx(void)
468 {
469 return TEE_Malloc(sizeof(crypto_ctx_t), TEE_MALLOC_FILL_ZERO);
470 }
471
rk_crypto_free_ctx(crypto_ctx_t ** ctx)472 void rk_crypto_free_ctx(crypto_ctx_t **ctx)
473 {
474 if (!*ctx)
475 return;
476
477 if ((*ctx)->obj)
478 TEE_FreeTransientObject((*ctx)->obj);
479 if ((*ctx)->obj_2)
480 TEE_FreeTransientObject((*ctx)->obj_2);
481 if ((*ctx)->op)
482 TEE_FreeOperation((*ctx)->op);
483
484 TEE_MemFill(*ctx, 0, sizeof(crypto_ctx_t));
485 TEE_Free(*ctx);
486 *ctx = NULL;
487 }
488
rk_cipher_begin(crypto_ctx_t * ctx,uint8_t * key,uint32_t key_len,uint8_t * iv,uint32_t algo,TEE_OperationMode mode)489 TEE_Result rk_cipher_begin(crypto_ctx_t *ctx, uint8_t *key, uint32_t key_len,
490 uint8_t *iv, uint32_t algo, TEE_OperationMode mode)
491 {
492 TEE_Result res = 0;
493 TEE_OperationHandle crypto_op = NULL;
494 TEE_ObjectHandle obj = NULL;
495 TEE_ObjectHandle obj_2 = NULL;
496 TEE_Attribute attr;
497 uint32_t obj_type;
498 uint32_t iv_len = 0;
499 uint32_t obj_key_size = 0;
500 uint32_t op_key_size = 0;
501
502 if (ctx == NULL || key == NULL)
503 return TEE_ERROR_BAD_PARAMETERS;
504
505 if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT)
506 return TEE_ERROR_BAD_PARAMETERS;
507
508 if (TEE_ALG_GET_CLASS(algo) != TEE_OPERATION_CIPHER)
509 return TEE_ERROR_BAD_PARAMETERS;
510
511 #if CRYPTO_DEBUG
512 IMSG("key is 0x%x; key_len is %d; algo is %08x", *key, key_len, algo);
513 if (iv)
514 IMSG("iv is 0x%x", *iv);
515 #endif
516
517 switch (algo) {
518 case TEE_ALG_AES_ECB_NOPAD:
519 case TEE_ALG_AES_CBC_NOPAD:
520 case TEE_ALG_AES_CTR:
521 case TEE_ALG_AES_CTS:
522 if (key_len != 16 && key_len != 24 && key_len != 32)
523 return TEE_ERROR_BAD_PARAMETERS;
524 obj_type = TEE_TYPE_AES;
525 iv_len = AES_BLOCK_SIZE;
526 obj_key_size = key_len * 8;
527 op_key_size = obj_key_size;
528 break;
529 case TEE_ALG_AES_XTS:
530 if (key_len != 32 && key_len != 64)
531 return TEE_ERROR_BAD_PARAMETERS;
532 obj_type = TEE_TYPE_AES;
533 iv_len = AES_BLOCK_SIZE;
534 key_len = key_len / 2; //Divide the key into two XTS keys.
535 obj_key_size = key_len * 8;
536 op_key_size = obj_key_size * 2; //Should specifies both two keys.
537 break;
538 case TEE_ALG_SM4_ECB_NOPAD:
539 case TEE_ALG_SM4_CBC_NOPAD:
540 case TEE_ALG_SM4_CTR:
541 if (key_len != 16)
542 return TEE_ERROR_BAD_PARAMETERS;
543 obj_type = TEE_TYPE_SM4;
544 iv_len = SM4_BLOCK_SIZE;
545 obj_key_size = key_len * 8;
546 op_key_size = obj_key_size;
547 break;
548 case TEE_ALG_DES_ECB_NOPAD:
549 case TEE_ALG_DES_CBC_NOPAD:
550 if (key_len != 8)
551 return TEE_ERROR_BAD_PARAMETERS;
552 obj_type = TEE_TYPE_DES;
553 iv_len = DES_BLOCK_SIZE;
554 obj_key_size = key_len * 7;
555 op_key_size = obj_key_size;
556 break;
557 case TEE_ALG_DES3_ECB_NOPAD:
558 case TEE_ALG_DES3_CBC_NOPAD:
559 if (key_len != 16 && key_len != 24)
560 return TEE_ERROR_BAD_PARAMETERS;
561 obj_type = TEE_TYPE_DES3;
562 iv_len = DES_BLOCK_SIZE;
563 obj_key_size = key_len * 7;
564 op_key_size = obj_key_size;
565 break;
566 default:
567 return TEE_ERROR_BAD_PARAMETERS;
568 }
569
570 if (!iv)
571 iv_len = 0;
572
573 res = TEE_AllocateOperation(&crypto_op, algo, mode, op_key_size);
574 if (res != TEE_SUCCESS) {
575 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
576 goto exit;
577 }
578
579 /* Set object of key 1 */
580 TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key, key_len);
581 res = TEE_AllocateTransientObject(obj_type, obj_key_size, &obj);
582 if (res != TEE_SUCCESS) {
583 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
584 goto exit;
585 }
586 res = TEE_PopulateTransientObject(obj, &attr, 1);
587 if (res != TEE_SUCCESS) {
588 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
589 goto exit;
590 }
591
592 if (algo == TEE_ALG_AES_XTS) {
593 /* Set object of key 2 */
594 TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key + key_len,
595 key_len);
596 res = TEE_AllocateTransientObject(obj_type, obj_key_size, &obj_2);
597 if (res != TEE_SUCCESS) {
598 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
599 goto exit;
600 }
601 res = TEE_PopulateTransientObject(obj_2, &attr, 1);
602 if (res != TEE_SUCCESS) {
603 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
604 goto exit;
605 }
606
607 /* Set operation of two keys */
608 res = TEE_SetOperationKey2(crypto_op, obj, obj_2);
609 if (res != TEE_SUCCESS) {
610 EMSG("TEE_SetOperationKey2 failed with code 0x%x", res);
611 goto exit;
612 }
613 } else {
614 /* Set operation of one key */
615 res = TEE_SetOperationKey(crypto_op, obj);
616 if (res != TEE_SUCCESS) {
617 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
618 goto exit;
619 }
620 }
621
622 TEE_CipherInit(crypto_op, iv, iv_len);
623
624 ctx->obj = obj;
625 ctx->obj_2 = obj_2;
626 ctx->op = crypto_op;
627 ctx->algo = algo;
628 ctx->mode = mode;
629 ctx->buffer_offs = 0;
630
631 return TEE_SUCCESS;
632
633 exit:
634 if (obj)
635 TEE_FreeTransientObject(obj);
636 if (obj_2)
637 TEE_FreeTransientObject(obj_2);
638 if (crypto_op)
639 TEE_FreeOperation(crypto_op);
640
641 return res;
642 }
643
rk_cipher_buffer_update(crypto_ctx_t * ctx,uint8_t * in,uint8_t * out,uint32_t in_len,uint32_t * out_len)644 static TEE_Result rk_cipher_buffer_update(crypto_ctx_t *ctx, uint8_t *in,
645 uint8_t *out,
646 uint32_t in_len, uint32_t *out_len)
647 {
648 TEE_Result res = 0;
649 uint32_t real_in_len = 0;
650 uint32_t tmp_out_len = 0;
651 uint32_t out_size = 0;
652 uint32_t buf_offs = 0;
653
654 #if CRYPTO_DEBUG
655 IMSG("ctx->buffer_offs: %d; ctx->algo: 0x%x",
656 ctx->buffer_offs, ctx->algo);
657 if (in && out && out_len)
658 IMSG("in is 0x%x; out is 0x%x; in_len is %d; out_len is %d",
659 *in, *out, in_len, *out_len);
660 #endif
661
662 buf_offs = ctx->buffer_offs;
663
664 if ((ctx->buffer_offs + in_len) <= AES_BLOCK_SIZE) {
665 TEE_MemMove(ctx->buffer + ctx->buffer_offs, in, in_len);
666 ctx->buffer_offs += in_len;
667 out_size = 0;
668 if ((ctx->buffer_offs == AES_BLOCK_SIZE) &&
669 ((ctx->padding == NO_PADDING) ||
670 ((ctx->padding == PKCS7_PADDING) && ctx->mode == TEE_MODE_ENCRYPT))) {
671 tmp_out_len = AES_BLOCK_SIZE;
672 if (*out_len < tmp_out_len)
673 return TEE_ERROR_SHORT_BUFFER;
674 res = TEE_CipherUpdate(ctx->op, ctx->buffer, ctx->buffer_offs, out,
675 &tmp_out_len);
676 if (res != TEE_SUCCESS) {
677 EMSG("TEE_CipherUpdate failed with code 0x%x\n", res);
678 return res;
679 }
680 ctx->buffer_offs = 0;
681 out_size += tmp_out_len;
682 }
683 } else {
684 if (ctx->padding == NO_PADDING) {
685 real_in_len = ((ctx->buffer_offs + in_len) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
686 } else if (ctx->padding == PKCS7_PADDING) {
687 if (ctx->mode == TEE_MODE_DECRYPT)
688 real_in_len = ROUNDUP(ctx->buffer_offs + in_len,
689 AES_BLOCK_SIZE) - AES_BLOCK_SIZE;
690 else
691 real_in_len = ROUNDDOWN(ctx->buffer_offs + in_len, AES_BLOCK_SIZE);
692 }
693
694 if (*out_len < real_in_len)
695 return TEE_ERROR_SHORT_BUFFER;
696
697 /* update one block size data */
698 TEE_MemMove(ctx->buffer + ctx->buffer_offs, in,
699 AES_BLOCK_SIZE - ctx->buffer_offs);
700 tmp_out_len = AES_BLOCK_SIZE;
701 res = TEE_CipherUpdate(ctx->op, ctx->buffer, AES_BLOCK_SIZE, out, &tmp_out_len);
702 if (res != TEE_SUCCESS) {
703 EMSG("TEE_CipherUpdate failed with code 0x%x\n", res);
704 return res;
705 }
706 out_size += tmp_out_len;
707
708 tmp_out_len = real_in_len - AES_BLOCK_SIZE;
709 res = TEE_CipherUpdate(ctx->op, in + AES_BLOCK_SIZE - ctx->buffer_offs,
710 tmp_out_len, out + AES_BLOCK_SIZE, &tmp_out_len);
711 if (res != TEE_SUCCESS) {
712 EMSG("TEE_CipherUpdate failed with code 0x%x\n", res);
713 return res;
714 }
715 out_size += tmp_out_len;
716
717 tmp_out_len = (ctx->buffer_offs + in_len) % AES_BLOCK_SIZE;
718 if (ctx->padding == NO_PADDING) {
719 ctx->buffer_offs = tmp_out_len;
720 } else if (ctx->padding == PKCS7_PADDING) {
721 if (ctx->mode == TEE_MODE_DECRYPT)
722 ctx->buffer_offs = tmp_out_len == 0 ? 16 : tmp_out_len;
723 else
724 ctx->buffer_offs = tmp_out_len;
725 }
726
727 TEE_MemMove(ctx->buffer, in + real_in_len - buf_offs, ctx->buffer_offs);
728 }
729
730 *out_len = out_size;
731
732 #if CRYPTO_DEBUG
733 IMSG("out[0] is 0x%x; out_size is %d", *out, out_size);
734 #endif
735
736 return TEE_SUCCESS;
737 }
738
rk_cipher_update(crypto_ctx_t * ctx,uint8_t * in,uint8_t * out,uint32_t in_len,uint32_t * out_len)739 TEE_Result rk_cipher_update(crypto_ctx_t *ctx, uint8_t *in, uint8_t *out,
740 uint32_t in_len, uint32_t *out_len)
741 {
742 TEE_Result res = 0;
743
744 if (ctx == NULL ||
745 (in == NULL && in_len != 0) ||
746 out_len == NULL ||
747 (out == NULL && *out_len != 0))
748 return TEE_ERROR_BAD_PARAMETERS;
749
750 if (ctx->obj == NULL || ctx->op == NULL)
751 return TEE_ERROR_BAD_PARAMETERS;
752
753 #if CRYPTO_DEBUG
754 IMSG("ctx->obj: 0x%x;ctx->op: 0x%x;ctx->algo: 0x%x",
755 (uint32_t)ctx->obj, (uint32_t)ctx->op, ctx->algo);
756 IMSG("in is 0x%x; out is 0x%x; in_len is %d; out_len is %d",
757 *in, *out, in_len, *out_len);
758 #endif
759
760 if (ctx->algo == TEE_ALG_AES_ECB_NOPAD ||
761 ctx->algo == TEE_ALG_AES_CBC_NOPAD ||
762 ctx->algo == TEE_ALG_SM4_ECB_NOPAD ||
763 ctx->algo == TEE_ALG_SM4_CBC_NOPAD) {
764 res = rk_cipher_buffer_update(ctx, in, out, in_len, out_len);
765 if (res != TEE_SUCCESS) {
766 EMSG("rk_cipher_buffer_update failed with code 0x%x\n", res);
767 return res;
768 }
769 } else {
770 res = TEE_CipherUpdate(ctx->op, in, in_len, out, out_len);
771 if (res != TEE_SUCCESS) {
772 EMSG("TEE_CipherUpdate failed with code 0x%x\n", res);
773 return res;
774 }
775 }
776
777 return TEE_SUCCESS;
778 }
779
rk_cipher_finish(crypto_ctx_t * ctx,uint8_t * out,uint32_t * out_len)780 TEE_Result rk_cipher_finish(crypto_ctx_t *ctx, uint8_t *out, uint32_t *out_len)
781 {
782 TEE_Result res = 0;
783 uint8_t feed_in[32];
784 int fd_len = 0;
785
786 if (ctx == NULL ||
787 out_len == NULL ||
788 (out == NULL && *out_len != 0))
789 return TEE_ERROR_BAD_PARAMETERS;
790
791 if (ctx->obj == NULL || ctx->op == NULL)
792 return TEE_ERROR_BAD_PARAMETERS;
793
794 #if CRYPTO_DEBUG
795 IMSG("ctx->obj: 0x%x;ctx->op: 0x%x;ctx->algo: 0x%x; ctx->padding: %d",
796 (uint32_t)ctx->obj, (uint32_t)ctx->op, ctx->algo, ctx->padding);
797 #endif
798
799 if ((ctx->algo == TEE_ALG_AES_ECB_NOPAD) ||
800 (ctx->algo == TEE_ALG_AES_CBC_NOPAD) ||
801 (ctx->algo == TEE_ALG_SM4_ECB_NOPAD) ||
802 (ctx->algo == TEE_ALG_SM4_CBC_NOPAD)) {
803 if (ctx->padding == NO_PADDING) {
804 if (ctx->buffer_offs % AES_BLOCK_SIZE) {
805 EMSG("The length of all data is NOT multiple of block size");
806 return TEE_ERROR_BAD_PARAMETERS;
807 }
808 res = TEE_CipherDoFinal(ctx->op, NULL, 0, out, out_len);
809 if (res != TEE_SUCCESS) {
810 EMSG("TEE_CipherDoFinal failed with code 0x%x", res);
811 return res;
812 }
813 } else if (ctx->padding == PKCS7_PADDING) {
814 if (ctx->mode == TEE_MODE_ENCRYPT) {
815 res = rk_aes_padding_pkcs7(ctx->buffer, feed_in, ctx->buffer_offs);
816 if (res != TEE_SUCCESS) {
817 EMSG("rk_aes_padding_pkcs7 failed with 0x%x", res);
818 return res;
819 }
820
821 fd_len = (ctx->buffer_offs / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE;
822
823 if ((int)*out_len < fd_len)
824 return TEE_ERROR_SHORT_BUFFER;
825
826 res = TEE_CipherDoFinal(ctx->op, feed_in, fd_len, out, out_len);
827 if (res != TEE_SUCCESS) {
828 EMSG("TEE_CipherDoFinal failed with code 0x%x", res);
829 return res;
830 }
831 } else {
832 if (*out_len < ctx->buffer_offs) {
833 return TEE_ERROR_SHORT_BUFFER;
834 }
835 if (ctx->buffer_offs % AES_BLOCK_SIZE) {
836 EMSG("The length of all data is NOT multiple of block size");
837 return TEE_ERROR_BAD_PARAMETERS;
838 }
839 res = TEE_CipherDoFinal(ctx->op, ctx->buffer, ctx->buffer_offs, out, out_len);
840 if (res != TEE_SUCCESS) {
841 EMSG("TEE_CipherDoFinal failed with code 0x%x", res);
842 return res;
843 }
844
845 res = rk_cut_pkcs7_padding(out, out_len);
846 if (res != TEE_SUCCESS) {
847 EMSG("rk_cut_pkcs7_padding failed with code 0x%x", res);
848 return res;
849 }
850
851 }
852 }
853 } else {
854 res = TEE_CipherDoFinal(ctx->op, NULL, 0, out, out_len);
855 if (res != TEE_SUCCESS) {
856 EMSG("TEE_CipherDoFinal failed with code 0x%x", res);
857 return res;
858 }
859 }
860
861 return TEE_SUCCESS;
862 }
863
rk_ae_begin(crypto_ctx_t * ctx,uint8_t * key,uint32_t key_len,uint8_t * iv,uint32_t iv_len,uint32_t aad_len,uint32_t tag_len,uint32_t payload_len,uint32_t algo,TEE_OperationMode mode)864 TEE_Result rk_ae_begin(crypto_ctx_t *ctx, uint8_t *key, uint32_t key_len,
865 uint8_t *iv, uint32_t iv_len, uint32_t aad_len, uint32_t tag_len,
866 uint32_t payload_len, uint32_t algo, TEE_OperationMode mode)
867 {
868 TEE_Result res = 0;
869 TEE_OperationHandle crypto_op = NULL;
870 TEE_ObjectHandle obj = NULL;
871 TEE_Attribute attr;
872 uint32_t obj_type;
873 uint32_t max_key_size = 0;
874 uint32_t tag_bit_len = tag_len * 8;
875
876 if (ctx == NULL || key == NULL)
877 return TEE_ERROR_BAD_PARAMETERS;
878
879 if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT)
880 return TEE_ERROR_BAD_PARAMETERS;
881
882 #if CRYPTO_DEBUG
883 IMSG("key is 0x%x; key_len is %d; algo is %08x",
884 *key, key_len, algo);
885 IMSG("aad_len is %d; tag_len is %d; payload_len is %d",
886 aad_len, tag_len, payload_len);
887 if (iv)
888 IMSG("iv is 0x%x", *iv);
889 IMSG("iv_len is %d", iv_len);
890 #endif
891
892 if (key_len != 16 && key_len != 24 && key_len != 32)
893 return TEE_ERROR_BAD_PARAMETERS;
894 obj_type = TEE_TYPE_AES;
895 max_key_size = key_len * 8;
896
897 if (algo == TEE_ALG_AES_GCM) {
898 if (iv_len > AES_BLOCK_SIZE)
899 return TEE_ERROR_BAD_PARAMETERS;
900 if (tag_bit_len != 128 && tag_bit_len != 120 && tag_bit_len != 112 &&
901 tag_bit_len != 104 && tag_bit_len != 96)
902 return TEE_ERROR_BAD_PARAMETERS;
903 } else if (algo == TEE_ALG_AES_CCM) {
904 if (iv_len > 15 || iv_len < 7 || iv == NULL)
905 return TEE_ERROR_BAD_PARAMETERS;
906 if (tag_bit_len != 128 && tag_bit_len != 112 && tag_bit_len != 96 &&
907 tag_bit_len != 80 && tag_bit_len != 64 && tag_bit_len != 48 &&
908 tag_bit_len != 32)
909 return TEE_ERROR_BAD_PARAMETERS;
910 } else {
911 return TEE_ERROR_BAD_PARAMETERS;
912 }
913
914 TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key, key_len);
915
916 res = TEE_AllocateTransientObject(obj_type, max_key_size, &obj);
917 if (res != TEE_SUCCESS) {
918 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
919 goto exit;
920 }
921
922 res = TEE_PopulateTransientObject(obj, &attr, 1);
923 if (res != TEE_SUCCESS) {
924 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
925 goto exit;
926 }
927
928 res = TEE_AllocateOperation(&crypto_op, algo, mode, max_key_size);
929 if (res != TEE_SUCCESS) {
930 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
931 goto exit;
932 }
933
934 res = TEE_SetOperationKey(crypto_op, obj);
935 if (res != TEE_SUCCESS) {
936 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
937 goto exit;
938 }
939
940 res = TEE_AEInit(crypto_op, iv, iv_len, tag_bit_len, aad_len, payload_len);
941 if (res != TEE_SUCCESS) {
942 EMSG("TEE_AEInit failed with code 0x%x", res);
943 goto exit;
944 }
945
946 ctx->obj = obj;
947 ctx->op = crypto_op;
948 ctx->algo = algo;
949 ctx->mode = mode;
950
951 return TEE_SUCCESS;
952
953 exit:
954 if (obj)
955 TEE_FreeTransientObject(obj);
956 if (crypto_op)
957 TEE_FreeOperation(crypto_op);
958
959 return res;
960 }
961
962
rk_ae_update(crypto_ctx_t * ctx,uint8_t * in,uint8_t * out,uint32_t in_len,uint32_t * out_len,rk_ae_update_type_t is_aad)963 TEE_Result rk_ae_update(crypto_ctx_t *ctx, uint8_t *in, uint8_t *out,
964 uint32_t in_len, uint32_t *out_len, rk_ae_update_type_t is_aad)
965 {
966 TEE_Result res = 0;
967
968 if (ctx == NULL || (in == NULL && in_len != 0))
969 return TEE_ERROR_BAD_PARAMETERS;
970
971 if (!is_aad && (out_len == NULL || (out == NULL && *out_len != 0)))
972 return TEE_ERROR_BAD_PARAMETERS;
973
974 if (ctx->obj == NULL || ctx->op == NULL)
975 return TEE_ERROR_BAD_PARAMETERS;
976
977 if (is_aad) {
978 TEE_AEUpdateAAD(ctx->op, in, in_len);
979 } else {
980 res = TEE_AEUpdate(ctx->op, in, in_len, out, out_len);
981 if (res != TEE_SUCCESS) {
982 EMSG("TEE_AEUpdate failed with code 0x%x", res);
983 return res;
984 }
985 }
986
987 return TEE_SUCCESS;
988 }
989
rk_ae_finish(crypto_ctx_t * ctx,uint8_t * in,uint8_t * out,uint8_t * tag,uint32_t in_len,uint32_t * out_len,uint32_t * tag_len)990 TEE_Result rk_ae_finish(crypto_ctx_t *ctx, uint8_t *in, uint8_t *out,
991 uint8_t *tag,
992 uint32_t in_len, uint32_t *out_len, uint32_t *tag_len)
993 {
994 TEE_Result res = 0;
995 uint32_t tmp_out_len;
996 uint32_t tmp_tag_len;
997
998 if (ctx == NULL ||
999 (in == NULL && in_len != 0) ||
1000 out_len == NULL ||
1001 (out == NULL && *out_len != 0) ||
1002 tag == NULL || tag_len == NULL)
1003 return TEE_ERROR_BAD_PARAMETERS;
1004
1005 if (ctx->obj == NULL || ctx->op == NULL)
1006 return TEE_ERROR_BAD_PARAMETERS;
1007
1008 tmp_tag_len = *tag_len;
1009 tmp_out_len = *out_len;
1010
1011 #if CRYPTO_DEBUG
1012 IMSG("ctx->obj: 0x%x;ctx->op: 0x%x;ctx->algo: 0x%x;ctx->mode: 0x%x",
1013 (uint32_t)ctx->obj, (uint32_t)ctx->op, ctx->algo, ctx->mode);
1014 IMSG("in_len = %d, out_len = %d, tag_len = %d",
1015 in_len, tmp_out_len, tmp_tag_len);
1016 #endif
1017
1018 if (ctx->mode == TEE_MODE_ENCRYPT) {
1019 res = TEE_AEEncryptFinal(ctx->op, in, in_len, out, &tmp_out_len,
1020 tag, &tmp_tag_len);
1021 } else {
1022 uint8_t tmp_tag[16];
1023
1024 if (tmp_tag_len > sizeof(tmp_tag))
1025 return TEE_ERROR_BAD_PARAMETERS;
1026
1027 TEE_MemMove(tmp_tag, tag, tmp_tag_len);
1028 res = TEE_AEDecryptFinal(ctx->op, in, in_len, out, &tmp_out_len,
1029 tmp_tag, tmp_tag_len);
1030 }
1031
1032 *tag_len = tmp_tag_len;
1033 *out_len = tmp_out_len;
1034
1035 if (res != TEE_SUCCESS) {
1036 EMSG("TEE_AEFinal failed with code 0x%x", res);
1037 return res;
1038 }
1039
1040 return TEE_SUCCESS;
1041 }
1042
rk_hash_begin(crypto_ctx_t * ctx,uint32_t algo)1043 TEE_Result rk_hash_begin(crypto_ctx_t *ctx, uint32_t algo)
1044 {
1045 TEE_Result res = 0;
1046 TEE_OperationHandle hash_op = NULL;
1047
1048 if (!ctx)
1049 return TEE_ERROR_BAD_PARAMETERS;
1050
1051 if (TEE_ALG_GET_CLASS(algo) != TEE_OPERATION_DIGEST)
1052 return TEE_ERROR_BAD_PARAMETERS;
1053
1054 res = TEE_AllocateOperation(&hash_op, algo, TEE_MODE_DIGEST, 0);
1055 if (res != TEE_SUCCESS) {
1056 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
1057 return res;
1058 }
1059
1060 ctx->op = hash_op;
1061
1062 return TEE_SUCCESS;
1063 }
1064
rk_hash_update(crypto_ctx_t * ctx,uint8_t * in,uint32_t in_len)1065 TEE_Result rk_hash_update(crypto_ctx_t *ctx, uint8_t *in, uint32_t in_len)
1066 {
1067 if (ctx == NULL || (in == NULL && in_len != 0)) {
1068 return TEE_ERROR_BAD_PARAMETERS;
1069 }
1070
1071 if (ctx->op == NULL) {
1072 return TEE_ERROR_BAD_PARAMETERS;
1073 }
1074
1075 TEE_DigestUpdate(ctx->op, in, in_len);
1076
1077 return TEE_SUCCESS;
1078 }
1079
rk_hash_finish(crypto_ctx_t * ctx,uint8_t * in,uint8_t * out,uint32_t in_len,uint32_t * out_len)1080 TEE_Result rk_hash_finish(crypto_ctx_t *ctx, uint8_t *in, uint8_t *out,
1081 uint32_t in_len, uint32_t *out_len)
1082 {
1083 TEE_Result res = 0;
1084
1085 if (ctx == NULL ||
1086 (in == NULL && in_len != 0) ||
1087 out_len == NULL ||
1088 (out == NULL && *out_len != 0)) {
1089 return TEE_ERROR_BAD_PARAMETERS;
1090 }
1091
1092 if (ctx->op == NULL) {
1093 return TEE_ERROR_BAD_PARAMETERS;
1094 }
1095
1096 res = TEE_DigestDoFinal(ctx->op, in, in_len, out, out_len);
1097 if (res != TEE_SUCCESS) {
1098 EMSG("TEE_DigestDoFinal failed with code 0x%x", res);
1099 return res;
1100 }
1101
1102 return TEE_SUCCESS;
1103 }
1104
rk_hash_crypto(uint8_t * in,uint8_t * out,uint32_t in_len,uint32_t out_len,uint32_t algo)1105 TEE_Result rk_hash_crypto(uint8_t *in, uint8_t *out, uint32_t in_len,
1106 uint32_t out_len, uint32_t algo)
1107 {
1108 TEE_Result res = TEE_SUCCESS;
1109 crypto_ctx_t *ctx = NULL;
1110 uint32_t out_size = out_len;
1111
1112 ctx = rk_crypto_malloc_ctx();
1113 if (!ctx) {
1114 EMSG("Malloc context memory FAILED!");
1115 return TEE_ERROR_OUT_OF_MEMORY;
1116 }
1117
1118 res = rk_hash_begin(ctx, algo);
1119 if (res) {
1120 EMSG("---rk_hash_begin---FAILED! return value: 0x%x", res);
1121 goto exit;
1122 }
1123
1124 res = rk_hash_update(ctx, in, in_len);
1125 if (res) {
1126 EMSG("---rk_hash_update---FAILED! return value: 0x%x", res);
1127 goto exit;
1128 }
1129
1130 res = rk_hash_finish(ctx, NULL, out, 0, &out_size);
1131 if (res) {
1132 EMSG("---rk_hash_finish---FAILED! return value: 0x%x", res);
1133 goto exit;
1134 }
1135
1136 if (out_size != out_len) {
1137 EMSG("out_size:%d != out_len:%d", out_size, out_len);
1138 res = TEE_ERROR_GENERIC;
1139 goto exit;
1140 }
1141
1142 exit:
1143 if (ctx)
1144 rk_crypto_free_ctx(&ctx);
1145
1146 return res;
1147 }
1148
rk_mac_crypto(uint8_t * in,uint8_t * out,uint32_t in_len,uint32_t * out_len,uint8_t * key,uint32_t key_len,uint8_t * iv,uint32_t algo)1149 TEE_Result rk_mac_crypto(uint8_t *in, uint8_t *out, uint32_t in_len,
1150 uint32_t *out_len, uint8_t *key, uint32_t key_len,
1151 uint8_t *iv, uint32_t algo)
1152 {
1153 TEE_OperationHandle mac_op;
1154 TEE_ObjectHandle obj;
1155 TEE_Attribute attr;
1156 TEE_Result res = 0;
1157 uint32_t obj_type = 0;
1158 uint32_t iv_len = 0;
1159 uint32_t out_size = 0;
1160 uint32_t max_key_size = 0;
1161
1162 if (!in || !out || !key || !in_len || !key_len)
1163 return TEE_ERROR_BAD_PARAMETERS;
1164
1165 /* AES_CMAC is only for data which is larger than AES_BLOCK_SIZE */
1166 if (algo == TEE_ALG_AES_CMAC && in_len < AES_BLOCK_SIZE)
1167 return TEE_ERROR_BAD_PARAMETERS;
1168
1169 #if CRYPTO_DEBUG
1170 IMSG("in is 0x%x; out is 0x%x; key is 0x%x", *in, *out, *key);
1171 IMSG("in_len is %d; out_len is %d; key_len is %d; iv_len is %d; algo is %08x",
1172 in_len, *out_len, key_len, iv_len, algo);
1173 if (iv)
1174 IMSG("iv is 0x%x", *iv);
1175 #endif
1176
1177 switch (algo) {
1178 case TEE_ALG_AES_CMAC:
1179 obj_type = TEE_TYPE_AES;
1180 iv_len = AES_BLOCK_SIZE;
1181 max_key_size = key_len * 8;
1182 out_size = AES_BLOCK_SIZE;
1183 break;
1184 case TEE_ALG_HMAC_SHA256:
1185 obj_type = TEE_TYPE_HMAC_SHA256;
1186 iv_len = AES_BLOCK_SIZE;
1187 max_key_size = key_len * 8;
1188 out_size = SHA256_HASH_SIZE;
1189 break;
1190 case TEE_ALG_HMAC_SHA1:
1191 obj_type = TEE_TYPE_HMAC_SHA1;
1192 iv_len = AES_BLOCK_SIZE;
1193 max_key_size = key_len * 8;
1194 out_size = SHA1_HASH_SIZE;
1195 break;
1196 case TEE_ALG_HMAC_MD5:
1197 obj_type = TEE_TYPE_HMAC_MD5;
1198 iv_len = AES_BLOCK_SIZE;
1199 max_key_size = key_len * 8;
1200 out_size = MD5_HASH_SIZE;
1201 break;
1202 case TEE_ALG_HMAC_SM3:
1203 obj_type = TEE_TYPE_HMAC_SM3;
1204 iv_len = AES_BLOCK_SIZE;
1205 max_key_size = key_len * 8;
1206 out_size = SM3_HASH_SIZE;
1207 break;
1208 default:
1209 return TEE_ERROR_BAD_PARAMETERS;
1210 }
1211
1212 if (!iv)
1213 iv_len = 0;
1214
1215 TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key, key_len);
1216
1217 res = TEE_AllocateTransientObject(obj_type, max_key_size, &obj);
1218 if (res != TEE_SUCCESS) {
1219 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
1220 goto exit;
1221 }
1222
1223 res = TEE_PopulateTransientObject(obj, &attr, 1);
1224 if (res != TEE_SUCCESS) {
1225 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
1226 goto exit;
1227 }
1228
1229 res = TEE_AllocateOperation(&mac_op, algo, TEE_MODE_MAC, max_key_size);
1230 if (res != TEE_SUCCESS) {
1231 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
1232 goto exit;
1233 }
1234
1235 res = TEE_SetOperationKey(mac_op, obj);
1236 if (res != TEE_SUCCESS) {
1237 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
1238 goto exit;
1239 }
1240
1241 TEE_MACInit(mac_op, iv, iv_len);
1242 res = TEE_MACComputeFinal(mac_op, in, in_len, out, &out_size);
1243 if (res != TEE_SUCCESS) {
1244 EMSG("TEE_MACComputeFinal failed with code 0x%x", res);
1245 goto exit;
1246 }
1247
1248 *out_len = out_size;
1249 exit:
1250 TEE_FreeTransientObject(obj);
1251 TEE_FreeOperation(mac_op);
1252
1253 return res;
1254 }
1255
rk_mac_begin(crypto_ctx_t * ctx,uint8_t * key,uint32_t key_len,uint8_t * iv,uint32_t algo)1256 TEE_Result rk_mac_begin(crypto_ctx_t *ctx, uint8_t *key, uint32_t key_len,
1257 uint8_t *iv, uint32_t algo)
1258 {
1259 TEE_OperationHandle mac_op = NULL;
1260 TEE_ObjectHandle obj = NULL;
1261 TEE_Attribute attr;
1262 TEE_Result res = 0;
1263 uint32_t obj_type = 0;
1264 uint32_t iv_len = 0;
1265 uint32_t max_key_size = 0;
1266 uint32_t key_block[MAX_HASH_BLOCK_SIZE];
1267 uint32_t key_block_len = 0;
1268 uint32_t block_size = 0;
1269 uint32_t hash_algo;
1270
1271 if (ctx == NULL || key == NULL || key_len == 0)
1272 return TEE_ERROR_BAD_PARAMETERS;
1273
1274 #if CRYPTO_DEBUG
1275 IMSG("key is 0x%x; key_len is %d; iv_len is %d; algo is %08x",
1276 *key, key_len, iv_len, algo);
1277 if (iv)
1278 IMSG("iv is 0x%x", *iv);
1279 #endif
1280
1281 TEE_MemFill(key_block, 0, sizeof(key_block));
1282
1283 switch (algo) {
1284 case TEE_ALG_AES_CMAC:
1285 obj_type = TEE_TYPE_AES;
1286 iv_len = AES_BLOCK_SIZE;
1287 max_key_size = key_len * 8;
1288 if (max_key_size != 128 &&
1289 max_key_size != 192 &&
1290 max_key_size != 256)
1291 return TEE_ERROR_BAD_PARAMETERS;
1292 TEE_MemMove(key_block, key, key_len);
1293 key_block_len = key_len;
1294 break;
1295 case TEE_ALG_HMAC_SHA1:
1296 obj_type = TEE_TYPE_HMAC_SHA1;
1297 block_size = 64;
1298 hash_algo = TEE_ALG_SHA1;
1299 key_block_len = SHA1_HASH_SIZE;
1300 break;
1301 case TEE_ALG_HMAC_SHA224:
1302 obj_type = TEE_TYPE_HMAC_SHA224;
1303 block_size = 64;
1304 key_block_len = SHA224_HASH_SIZE;
1305 hash_algo = TEE_ALG_SHA224;
1306 break;
1307 case TEE_ALG_HMAC_SHA256:
1308 obj_type = TEE_TYPE_HMAC_SHA256;
1309 block_size = 64;
1310 key_block_len = SHA256_HASH_SIZE;
1311 hash_algo = TEE_ALG_SHA256;
1312 break;
1313 case TEE_ALG_HMAC_SHA384:
1314 obj_type = TEE_TYPE_HMAC_SHA384;
1315 block_size = 128;
1316 key_block_len = SHA384_HASH_SIZE;
1317 hash_algo = TEE_ALG_SHA384;
1318 break;
1319 case TEE_ALG_HMAC_SHA512:
1320 obj_type = TEE_TYPE_HMAC_SHA512;
1321 block_size = 128;
1322 key_block_len = SHA512_HASH_SIZE;
1323 hash_algo = TEE_ALG_SHA512;
1324 break;
1325 case TEE_ALG_HMAC_MD5:
1326 obj_type = TEE_TYPE_HMAC_MD5;
1327 block_size = 64;
1328 key_block_len = MD5_HASH_SIZE;
1329 hash_algo = TEE_ALG_MD5;
1330 break;
1331 case TEE_ALG_HMAC_SM3:
1332 obj_type = TEE_TYPE_HMAC_SM3;
1333 block_size = 64;
1334 hash_algo = TEE_ALG_SM3;
1335 key_block_len = SM3_HASH_SIZE;
1336 break;
1337 default:
1338 return TEE_ERROR_BAD_PARAMETERS;
1339 }
1340
1341 if (!iv)
1342 iv_len = 0;
1343
1344 /* handle the key size for HMAC */
1345 if (algo != TEE_ALG_AES_CMAC) {
1346 iv_len = 0;
1347 /* Long keys are hashed. */
1348 if (key_len > block_size) {
1349 res = rk_hash_crypto(key, (uint8_t *)key_block, key_len, key_block_len,
1350 hash_algo);
1351 if (res) {
1352 EMSG("Hash long keys failed.");
1353 return res;
1354 }
1355 /* Min key size is set as 64 bits in OS. */
1356 } else if (key_len < 8) {
1357 TEE_MemMove(key_block, key, key_len);
1358 key_block_len = 8;
1359 } else {
1360 if (key_len <= sizeof(key_block)) {
1361 TEE_MemMove(key_block, key, key_len);
1362 key_block_len = key_len;
1363 } else {
1364 EMSG("Check key len failed.");
1365 res = TEE_ERROR_GENERIC;
1366 return res;
1367 }
1368 }
1369 max_key_size = key_block_len * 8;
1370 }
1371
1372 TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key_block, key_block_len);
1373
1374 res = TEE_AllocateTransientObject(obj_type, max_key_size, &obj);
1375 if (res != TEE_SUCCESS) {
1376 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
1377 goto exit;
1378 }
1379
1380 res = TEE_PopulateTransientObject(obj, &attr, 1);
1381 if (res != TEE_SUCCESS) {
1382 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
1383 goto exit;
1384 }
1385
1386 res = TEE_AllocateOperation(&mac_op, algo, TEE_MODE_MAC, max_key_size);
1387 if (res != TEE_SUCCESS) {
1388 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
1389 goto exit;
1390 }
1391
1392 res = TEE_SetOperationKey(mac_op, obj);
1393 if (res != TEE_SUCCESS) {
1394 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
1395 goto exit;
1396 }
1397
1398 TEE_MACInit(mac_op, iv, iv_len);
1399
1400 ctx->obj = obj;
1401 ctx->op = mac_op;
1402 ctx->algo = algo;
1403
1404 return TEE_SUCCESS;
1405
1406 exit:
1407 if (obj)
1408 TEE_FreeTransientObject(obj);
1409 if (mac_op)
1410 TEE_FreeOperation(mac_op);
1411
1412 return res;
1413 }
1414
rk_mac_update(crypto_ctx_t * ctx,uint8_t * in,uint32_t in_len)1415 TEE_Result rk_mac_update(crypto_ctx_t *ctx, uint8_t *in, uint32_t in_len)
1416 {
1417 if (ctx == NULL || (in == NULL && in_len != 0))
1418 return TEE_ERROR_BAD_PARAMETERS;
1419
1420 if (ctx->obj == NULL || ctx->op == NULL)
1421 return TEE_ERROR_BAD_PARAMETERS;
1422
1423 #if CRYPTO_DEBUG
1424 IMSG("ctx->obj: 0x%x;ctx->op: 0x%x;ctx->algo: 0x%x",
1425 (uint32_t)ctx->obj, (uint32_t)ctx->op, ctx->algo);
1426 IMSG("in is 0x%x; in_len is %d", *in, in_len);
1427 #endif
1428
1429 TEE_MACUpdate(ctx->op, in, in_len);
1430
1431 return TEE_SUCCESS;
1432 }
1433
rk_mac_finish(crypto_ctx_t * ctx,uint8_t * in,uint8_t * mac,uint32_t in_len,uint32_t * mac_len,rk_mac_mode_t mode)1434 TEE_Result rk_mac_finish(crypto_ctx_t *ctx, uint8_t *in, uint8_t *mac,
1435 uint32_t in_len, uint32_t *mac_len, rk_mac_mode_t mode)
1436 {
1437 TEE_Result res = 0;
1438 uint32_t out_size = 0;
1439
1440 if (ctx == NULL ||
1441 (in == NULL && in_len != 0) ||
1442 mac_len == NULL ||
1443 mac == NULL)
1444 return TEE_ERROR_BAD_PARAMETERS;
1445
1446 if (ctx->obj == NULL || ctx->op == NULL)
1447 return TEE_ERROR_BAD_PARAMETERS;
1448
1449 #if CRYPTO_DEBUG
1450 IMSG("ctx->obj: 0x%x;ctx->op: 0x%x;ctx->algo: 0x%x",
1451 (uint32_t)ctx->obj, (uint32_t)ctx->op, ctx->algo);
1452 IMSG("mac is 0x%x; in_len is %d; mac_len is %d",
1453 *mac, in_len, *mac_len);
1454 if (in)
1455 IMSG("in is 0x%x", *in);
1456 #endif
1457
1458 switch (ctx->algo) {
1459 case TEE_ALG_AES_CMAC:
1460 out_size = AES_BLOCK_SIZE;
1461 break;
1462 case TEE_ALG_HMAC_SHA1:
1463 out_size = SHA1_HASH_SIZE;
1464 break;
1465 case TEE_ALG_HMAC_SHA224:
1466 out_size = SHA224_HASH_SIZE;
1467 break;
1468 case TEE_ALG_HMAC_SHA256:
1469 out_size = SHA256_HASH_SIZE;
1470 break;
1471 case TEE_ALG_HMAC_SHA384:
1472 out_size = SHA384_HASH_SIZE;
1473 break;
1474 case TEE_ALG_HMAC_SHA512:
1475 out_size = SHA512_HASH_SIZE;
1476 break;
1477 case TEE_ALG_HMAC_MD5:
1478 out_size = MD5_HASH_SIZE;
1479 break;
1480 case TEE_ALG_HMAC_SM3:
1481 out_size = SM3_HASH_SIZE;
1482 break;
1483 default:
1484 return TEE_ERROR_BAD_PARAMETERS;
1485 }
1486
1487 if (mode == RK_MAC_SIGN) {
1488 res = TEE_MACComputeFinal(ctx->op, in, in_len, mac, &out_size);
1489 if (res != TEE_SUCCESS) {
1490 EMSG("TEE_MACComputeFinal failed with code 0x%x", res);
1491 return res;
1492 }
1493 *mac_len = out_size;
1494 } else if (mode == RK_MAC_VERIFY) {
1495 res = TEE_MACCompareFinal(ctx->op, in, in_len, mac, *mac_len);
1496 if (res != TEE_SUCCESS) {
1497 EMSG("TEE_MACCompareFinal failed with code 0x%x", res);
1498 return res;
1499 }
1500 } else {
1501 EMSG("Unsupport mode: 0x%x", mode);
1502 return TEE_ERROR_BAD_PARAMETERS;
1503 }
1504
1505 return TEE_SUCCESS;
1506 }
1507
rk_rsa_begin(crypto_ctx_t * ctx,rsa_key_t * key,uint32_t algo,TEE_OperationMode mode)1508 TEE_Result rk_rsa_begin(crypto_ctx_t *ctx, rsa_key_t *key, uint32_t algo,
1509 TEE_OperationMode mode)
1510 {
1511 TEE_Result res = 0;
1512 TEE_OperationHandle rsa_op = NULL;
1513 TEE_ObjectHandle obj = NULL;
1514 TEE_Attribute attr[3];
1515 uint32_t max_key_size = 0;
1516
1517 if (!key || !ctx)
1518 return TEE_ERROR_BAD_PARAMETERS;
1519
1520 if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT &&
1521 mode != TEE_MODE_SIGN && mode != TEE_MODE_VERIFY)
1522 return TEE_ERROR_BAD_PARAMETERS;
1523
1524 if (TEE_ALG_GET_MAIN_ALG(algo) != TEE_MAIN_ALGO_RSA)
1525 return TEE_ERROR_BAD_PARAMETERS;
1526
1527 #if CRYPTO_DEBUG
1528 IMSG("key->n is 0x%x; key->e is 0x%x; key->d is 0x%x",
1529 *(key->n), *(key->e), *(key->d));
1530 IMSG("key->key_len is %d; algo is 0x%x; mode is 0x%x",
1531 key->key_len, algo, mode);
1532 #endif
1533
1534 max_key_size = key->key_len * 8;
1535
1536 TEE_InitRefAttribute(&attr[0], TEE_ATTR_RSA_MODULUS, key->n, key->key_len);
1537 TEE_InitRefAttribute(&attr[1], TEE_ATTR_RSA_PUBLIC_EXPONENT, key->e,
1538 key->e_len);
1539 TEE_InitRefAttribute(&attr[2], TEE_ATTR_RSA_PRIVATE_EXPONENT, key->d,
1540 key->d_len);
1541
1542 res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, max_key_size, &obj);
1543 if (res != TEE_SUCCESS) {
1544 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
1545 return res;
1546 }
1547
1548 res = TEE_PopulateTransientObject(obj, attr, 3);
1549 if (res != TEE_SUCCESS) {
1550 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
1551 goto exit;
1552 }
1553
1554 res = TEE_AllocateOperation(&rsa_op, algo, mode, max_key_size);
1555 if (res != TEE_SUCCESS) {
1556 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
1557 goto exit;
1558 }
1559
1560 res = TEE_SetOperationKey(rsa_op, obj);
1561 if (res != TEE_SUCCESS) {
1562 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
1563 goto exit;
1564 }
1565
1566 ctx->obj = obj;
1567 ctx->op = rsa_op;
1568 ctx->algo = algo;
1569 ctx->mode = mode;
1570
1571 return TEE_SUCCESS;
1572
1573 exit:
1574 if (obj)
1575 TEE_FreeTransientObject(obj);
1576 if (rsa_op)
1577 TEE_FreeOperation(rsa_op);
1578
1579 return res;
1580 }
1581
rk_rsa_finish(crypto_ctx_t * ctx,uint8_t * in,uint8_t * out,uint32_t in_len,uint32_t * out_len,uint32_t salt_len)1582 TEE_Result rk_rsa_finish(crypto_ctx_t *ctx, uint8_t *in, uint8_t *out,
1583 uint32_t in_len,
1584 uint32_t *out_len, uint32_t salt_len)
1585 {
1586 TEE_Result res = 0;
1587 TEE_Attribute attr;
1588
1589 if (ctx == NULL ||
1590 (in == NULL && in_len != 0) ||
1591 out_len == NULL ||
1592 (out == NULL && *out_len != 0))
1593 return TEE_ERROR_BAD_PARAMETERS;
1594 if (ctx->obj == NULL || ctx->op == NULL)
1595 return TEE_ERROR_BAD_PARAMETERS;
1596
1597 #if CRYPTO_DEBUG
1598 IMSG("ctx->obj: 0x%x;ctx->op: 0x%x;ctx->algo: 0x%x",
1599 (uint32_t)ctx->obj, (uint32_t)ctx->op, ctx->algo);
1600 IMSG("salt_len is %d", salt_len);
1601 if (in != NULL && in_len != 0)
1602 IMSG("in is 0x%x; in_len is %d; ", *in, in_len);
1603 if (out != NULL && *out_len != 0)
1604 IMSG("out is 0x%x; out_len is %d;", *out, *out_len);
1605 #endif
1606
1607 TEE_InitValueAttribute(&attr, TEE_ATTR_RSA_PSS_SALT_LENGTH, salt_len, 0);
1608
1609 switch (ctx->mode) {
1610 case TEE_MODE_ENCRYPT:
1611 res = TEE_AsymmetricEncrypt(ctx->op, NULL, 0, in, in_len, out, out_len);
1612 if (res != TEE_SUCCESS) {
1613 EMSG("TEE_AsymmetricEncrypt failed with code 0x%x", res);
1614 return res;
1615 }
1616 break;
1617 case TEE_MODE_DECRYPT:
1618 res = TEE_AsymmetricDecrypt(ctx->op, NULL, 0, in, in_len, out, out_len);
1619 if (res != TEE_SUCCESS) {
1620 EMSG("TEE_AsymmetricDecrypt failed with code 0x%x", res);
1621 return res;
1622 }
1623 break;
1624 case TEE_MODE_SIGN:
1625 if (ctx->sign_mode == SIGN_DIGEST) {
1626 res = TEE_AsymmetricSignDigest(ctx->op, &attr, 1, in, in_len, out, out_len);
1627 } else if (ctx->sign_mode == SIGN_DATA) {
1628 res = TEE_AsymmetricPrivateEncrypt(ctx->op, NULL, 0, in, in_len, out, out_len);
1629 } else {
1630 EMSG("Error sign mode!");
1631 res = TEE_ERROR_BAD_PARAMETERS;
1632 }
1633
1634 if (res != TEE_SUCCESS) {
1635 EMSG("TEE_AsymmetricSignDigest failed with code 0x%x", res);
1636 return res;
1637 }
1638 break;
1639 case TEE_MODE_VERIFY:
1640 if (ctx->sign_mode == SIGN_DIGEST) {
1641 res = TEE_AsymmetricVerifyDigest(ctx->op, &attr, 1, in, in_len, out, *out_len);
1642 } else if (ctx->sign_mode == SIGN_DATA) {
1643 res = TEE_AsymmetricPublicDecrypt(ctx->op, NULL, 0, in, in_len, out, out_len);
1644 } else {
1645 EMSG("Error sign mode!");
1646 res = TEE_ERROR_BAD_PARAMETERS;
1647 }
1648
1649 if (res != TEE_SUCCESS) {
1650 if (res == TEE_ERROR_SIGNATURE_INVALID) {
1651 EMSG("Verify failed!!!The signature is invalid!!!");
1652 } else {
1653 EMSG("TEE_AsymmetricVerifyDigest failed with code 0x%x", res);
1654 }
1655 return res;
1656 }
1657 break;
1658 default:
1659 EMSG("Unknown mode!!!");
1660 return TEE_ERROR_BAD_PARAMETERS;
1661 }
1662
1663 #if CRYPTO_DEBUG
1664 IMSG("out[0] is 0x%x; out_len is %d; in_len is %d",
1665 *out, *out_len, in_len);
1666 #endif
1667
1668 return TEE_SUCCESS;
1669 }
1670
rk_rsa_crypto(uint8_t * in,uint8_t * out,uint32_t len,rsa_key_t * key,uint32_t algo,TEE_OperationMode mode)1671 TEE_Result rk_rsa_crypto(uint8_t *in, uint8_t *out, uint32_t len,
1672 rsa_key_t *key, uint32_t algo, TEE_OperationMode mode)
1673 {
1674 TEE_Result res = 0;
1675 TEE_OperationHandle rsa_op;
1676 TEE_ObjectHandle obj;
1677 TEE_Attribute attr[3];
1678 uint32_t out_size = 0;
1679 uint32_t max_key_size = 0;
1680
1681 if (!in || !out || !key || !len)
1682 return TEE_ERROR_BAD_PARAMETERS;
1683
1684 if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT)
1685 return TEE_ERROR_BAD_PARAMETERS;
1686
1687 if (TEE_ALG_GET_MAIN_ALG(algo) != TEE_MAIN_ALGO_RSA)
1688 return TEE_ERROR_BAD_PARAMETERS;
1689 #if CRYPTO_DEBUG
1690 IMSG("in is 0x%x; out is 0x%x; len is %d; key_len is 0x%x",
1691 *in, *out, len, key->key_len);
1692 #endif
1693
1694 out_size = key->key_len;
1695
1696 max_key_size = key->key_len * 8;
1697
1698 TEE_InitRefAttribute(&attr[0], TEE_ATTR_RSA_MODULUS, key->n, key->key_len);
1699 TEE_InitRefAttribute(&attr[1], TEE_ATTR_RSA_PUBLIC_EXPONENT, key->e, 3);
1700 TEE_InitRefAttribute(&attr[2], TEE_ATTR_RSA_PRIVATE_EXPONENT, key->d,
1701 key->d_len);
1702
1703 res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, max_key_size, &obj);
1704 if (res != TEE_SUCCESS) {
1705 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
1706 goto exit;
1707 }
1708
1709 res = TEE_PopulateTransientObject(obj, attr, 3);
1710 if (res != TEE_SUCCESS) {
1711 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
1712 goto exit;
1713 }
1714
1715 res = TEE_AllocateOperation(&rsa_op, algo, mode, max_key_size);
1716 if (res != TEE_SUCCESS) {
1717 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
1718 goto exit;
1719 }
1720
1721 res = TEE_SetOperationKey(rsa_op, obj);
1722 if (res != TEE_SUCCESS) {
1723 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
1724 goto exit;
1725 }
1726
1727 if (mode == TEE_MODE_ENCRYPT) {
1728 res = TEE_AsymmetricEncrypt(rsa_op, NULL, 0, in, len, out, &out_size);
1729 if (res != TEE_SUCCESS) {
1730 EMSG("TEE_AsymmetricEncrypt failed with code 0x%x", res);
1731 goto exit;
1732 }
1733 } else {
1734 res = TEE_AsymmetricDecrypt(rsa_op, NULL, 0, in, len, out, &out_size);
1735 if (res != TEE_SUCCESS) {
1736 EMSG("TEE_AsymmetricDecrypt failed with code 0x%x", res);
1737 goto exit;
1738 }
1739 }
1740
1741 #if CRYPTO_DEBUG
1742 IMSG("out[0] is 0x%x; out_size is %d; len is %d",
1743 *out, out_size, len);
1744 #endif
1745
1746 exit:
1747 TEE_FreeTransientObject(obj);
1748 TEE_FreeOperation(rsa_op);
1749
1750 return res;
1751 }
1752
rk_rsa_sign(uint8_t * digest,uint8_t * signature,uint32_t digest_len,uint32_t * signature_len,rsa_key_t * key,uint32_t salt_len,uint32_t algo,TEE_OperationMode mode)1753 TEE_Result rk_rsa_sign(uint8_t *digest, uint8_t *signature, uint32_t digest_len,
1754 uint32_t *signature_len, rsa_key_t *key, uint32_t salt_len,
1755 uint32_t algo, TEE_OperationMode mode)
1756 {
1757 TEE_Result res = 0;
1758 TEE_OperationHandle rsa_op;
1759 TEE_ObjectHandle obj;
1760 TEE_Attribute attr[4];
1761 uint32_t out_size = 0;
1762 uint32_t max_key_size = 0;
1763
1764 if (!digest || !signature || !signature_len || !key)
1765 return TEE_ERROR_BAD_PARAMETERS;
1766
1767 if (mode != TEE_MODE_SIGN && mode != TEE_MODE_VERIFY)
1768 return TEE_ERROR_BAD_PARAMETERS;
1769
1770 if (TEE_ALG_GET_MAIN_ALG(algo) != TEE_MAIN_ALGO_RSA)
1771 return TEE_ERROR_BAD_PARAMETERS;
1772
1773 #if CRYPTO_DEBUG
1774 IMSG("digest is 0x%x; signature is 0x%x; digest_len is %d; salt_len is %d",
1775 *digest, *signature, digest_len, salt_len);
1776 IMSG("key->n is 0x%x; key->e is 0x%x; key->d is 0x%x",
1777 *key->n, *key->e, *key->d);
1778 #endif
1779 out_size = *signature_len;
1780 max_key_size = key->key_len * 8;
1781
1782 TEE_InitRefAttribute(&attr[0], TEE_ATTR_RSA_MODULUS, key->n, key->key_len);
1783 TEE_InitRefAttribute(&attr[1], TEE_ATTR_RSA_PUBLIC_EXPONENT, key->e, 3);
1784 TEE_InitRefAttribute(&attr[2], TEE_ATTR_RSA_PRIVATE_EXPONENT, key->d,
1785 key->d_len);
1786 TEE_InitValueAttribute(&attr[3], TEE_ATTR_RSA_PSS_SALT_LENGTH, salt_len, 0);
1787
1788 res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, max_key_size, &obj);
1789 if (res != TEE_SUCCESS) {
1790 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
1791 goto exit;
1792 }
1793
1794 res = TEE_PopulateTransientObject(obj, attr, 3);
1795 if (res != TEE_SUCCESS) {
1796 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
1797 goto exit;
1798 }
1799
1800 res = TEE_AllocateOperation(&rsa_op, algo, mode, max_key_size);
1801 if (res != TEE_SUCCESS) {
1802 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
1803 goto exit;
1804 }
1805
1806 res = TEE_SetOperationKey(rsa_op, obj);
1807 if (res != TEE_SUCCESS) {
1808 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
1809 goto exit;
1810 }
1811
1812 if (mode == TEE_MODE_SIGN) {
1813 res = TEE_AsymmetricSignDigest(rsa_op, &attr[3], 1, digest, digest_len,
1814 signature, &out_size);
1815 if (res != TEE_SUCCESS) {
1816 EMSG("TEE_AsymmetricSignDigest failed with code 0x%x", res);
1817 goto exit;
1818 }
1819 *signature_len = out_size;
1820 } else {
1821 res = TEE_AsymmetricVerifyDigest(rsa_op, &attr[3], 1, digest, digest_len,
1822 signature, out_size);
1823 if (res != TEE_SUCCESS) {
1824 if (res == TEE_ERROR_SIGNATURE_INVALID) {
1825 EMSG("Verify failed!!!The signature is invalid!!!");
1826 } else {
1827 EMSG("TEE_AsymmetricVerifyDigest failed with code 0x%x", res);
1828 }
1829 }
1830 }
1831
1832 exit:
1833 TEE_FreeTransientObject(obj);
1834 TEE_FreeOperation(rsa_op);
1835
1836 return res;
1837 }
1838
rk_ecdsa_sign(uint8_t * digest,uint8_t * signature,uint32_t digest_len,uint32_t * signature_len,ec_key_t * key,uint32_t algo,TEE_OperationMode mode)1839 TEE_Result rk_ecdsa_sign(uint8_t *digest, uint8_t *signature,
1840 uint32_t digest_len, uint32_t *signature_len,
1841 ec_key_t *key, uint32_t algo, TEE_OperationMode mode)
1842 {
1843 TEE_Result res = 0;
1844 TEE_OperationHandle ecdsa_op;
1845 TEE_ObjectHandle obj;
1846 TEE_Attribute attr[4];
1847 uint32_t out_size = 0;
1848 uint32_t max_key_size = 0;
1849
1850 if (!digest || !signature || !signature_len || !key)
1851 return TEE_ERROR_BAD_PARAMETERS;
1852
1853 if (mode != TEE_MODE_SIGN && mode != TEE_MODE_VERIFY)
1854 return TEE_ERROR_BAD_PARAMETERS;
1855
1856 if (TEE_ALG_GET_MAIN_ALG(algo) != TEE_MAIN_ALGO_ECDSA)
1857 return TEE_ERROR_BAD_PARAMETERS;
1858
1859 #if CRYPTO_DEBUG
1860 IMSG("digest is 0x%x; signature is 0x%x; digest_len is %d; signature_len is %d",
1861 *digest, *signature, digest_len, *signature_len);
1862 IMSG("key->d is 0x%x; key->x is 0x%x; key->y is 0x%x",
1863 *key->d, *key->x, *key->y);
1864 IMSG("key->d_len is %d; key->x_len is %d; key->y_len is %d",
1865 key->d_len, key->x_len, key->y_len);
1866 IMSG("key->curve is 0x%x; key->key_len is %d; algo is 0x%x; mode is 0x%x",
1867 key->curve, key->key_len, algo, mode);
1868 #endif
1869 out_size = *signature_len;
1870 max_key_size = key->key_len;
1871
1872 TEE_InitRefAttribute(&attr[0], TEE_ATTR_ECC_PUBLIC_VALUE_X, key->x, key->x_len);
1873 TEE_InitRefAttribute(&attr[1], TEE_ATTR_ECC_PUBLIC_VALUE_Y, key->y, key->y_len);
1874 TEE_InitRefAttribute(&attr[2], TEE_ATTR_ECC_PRIVATE_VALUE, key->d, key->d_len);
1875 TEE_InitValueAttribute(&attr[3], TEE_ATTR_ECC_CURVE, key->curve, 0);
1876
1877 res = TEE_AllocateTransientObject(TEE_TYPE_ECDSA_KEYPAIR, max_key_size, &obj);
1878 if (res != TEE_SUCCESS) {
1879 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
1880 return res;
1881 }
1882
1883 res = TEE_PopulateTransientObject(obj, attr, 4);
1884 if (res != TEE_SUCCESS) {
1885 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
1886 goto exit;
1887 }
1888
1889 res = TEE_AllocateOperation(&ecdsa_op, algo, mode, max_key_size);
1890 if (res != TEE_SUCCESS) {
1891 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
1892 goto exit;
1893 }
1894
1895 res = TEE_SetOperationKey(ecdsa_op, obj);
1896 if (res != TEE_SUCCESS) {
1897 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
1898 goto exit;
1899 }
1900
1901 if (mode == TEE_MODE_SIGN) {
1902 res = TEE_AsymmetricSignDigest(ecdsa_op, NULL, 0, digest, digest_len, signature,
1903 &out_size);
1904 if (res != TEE_SUCCESS) {
1905 EMSG("TEE_AsymmetricSignDigest failed with code 0x%x", res);
1906 goto exit;
1907 }
1908 *signature_len = out_size;
1909 } else {
1910 res = TEE_AsymmetricVerifyDigest(ecdsa_op, NULL, 0, digest, digest_len,
1911 signature, out_size);
1912 if (res != TEE_SUCCESS) {
1913 if (res == TEE_ERROR_SIGNATURE_INVALID) {
1914 EMSG("Verify failed!!!The signature is invalid!!!");
1915 } else {
1916 EMSG("TEE_AsymmetricVerifyDigest failed with code 0x%x", res);
1917 }
1918 }
1919 }
1920
1921 exit:
1922 TEE_FreeTransientObject(obj);
1923 TEE_FreeOperation(ecdsa_op);
1924
1925 return res;
1926 }
1927
rk_sm2_pke(uint8_t * in,uint32_t in_len,uint8_t * out,uint32_t * out_len,ec_key_t * key,uint32_t algo,TEE_OperationMode mode)1928 TEE_Result rk_sm2_pke(uint8_t *in, uint32_t in_len, uint8_t *out,
1929 uint32_t *out_len,
1930 ec_key_t *key, uint32_t algo, TEE_OperationMode mode)
1931 {
1932 TEE_Result res = TEE_ERROR_GENERIC;
1933 TEE_OperationHandle ecdsa_op = NULL;
1934 TEE_ObjectHandle obj = NULL;
1935 TEE_Attribute attr[4];
1936 uint32_t out_size = 0;
1937 uint32_t max_key_size = 0;
1938
1939 if (!in || !out || !out_len || !key)
1940 return TEE_ERROR_BAD_PARAMETERS;
1941
1942 #if CRYPTO_DEBUG
1943 IMSG("in is 0x%x; out is 0x%x; in_len is %d; out_len is %d",
1944 *in, *out, in_len, *out_len);
1945 IMSG("key->d is 0x%x; key->x is 0x%x; key->y is 0x%x",
1946 *key->d, *key->x, *key->y);
1947 IMSG("key->d_len is %d; key->x_len is %d; key->y_len is %d",
1948 key->d_len, key->x_len, key->y_len);
1949 IMSG("key->curve is 0x%x; key->key_len is %d; algo is 0x%x; mode is 0x%x",
1950 key->curve, key->key_len, algo, mode);
1951 #endif
1952
1953 if (key->curve != TEE_ECC_CURVE_SM2) {
1954 EMSG("curve = %08x != TEE_ECC_CURVE_SM2", key->curve);
1955 return TEE_ERROR_BAD_PARAMETERS;
1956 }
1957
1958 if (algo != TEE_ALG_SM2_PKE) {
1959 EMSG("algo = %08x != TEE_ALG_SM2_PKE", algo);
1960 return TEE_ERROR_BAD_PARAMETERS;
1961 }
1962
1963 if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT)
1964 return TEE_ERROR_BAD_PARAMETERS;
1965
1966 out_size = *out_len;
1967 max_key_size = key->key_len;
1968
1969 TEE_InitRefAttribute(&attr[0], TEE_ATTR_ECC_PUBLIC_VALUE_X, key->x, key->x_len);
1970 TEE_InitRefAttribute(&attr[1], TEE_ATTR_ECC_PUBLIC_VALUE_Y, key->y, key->y_len);
1971 TEE_InitRefAttribute(&attr[2], TEE_ATTR_ECC_PRIVATE_VALUE, key->d, key->d_len);
1972 TEE_InitValueAttribute(&attr[3], TEE_ATTR_ECC_CURVE, key->curve, 0);
1973
1974 res = TEE_AllocateTransientObject(TEE_TYPE_SM2_PKE_KEYPAIR, max_key_size, &obj);
1975 if (res != TEE_SUCCESS) {
1976 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
1977 return res;
1978 }
1979
1980 res = TEE_PopulateTransientObject(obj, attr, 4);
1981 if (res != TEE_SUCCESS) {
1982 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
1983 goto exit;
1984 }
1985
1986 res = TEE_AllocateOperation(&ecdsa_op, algo, mode, max_key_size);
1987 if (res != TEE_SUCCESS) {
1988 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
1989 goto exit;
1990 }
1991
1992 res = TEE_SetOperationKey(ecdsa_op, obj);
1993 if (res != TEE_SUCCESS) {
1994 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
1995 goto exit;
1996 }
1997
1998 if (mode == TEE_MODE_ENCRYPT) {
1999 res = TEE_AsymmetricEncrypt(ecdsa_op, NULL, 0, in, in_len, out, &out_size);
2000 if (res != TEE_SUCCESS) {
2001 EMSG("TEE_AsymmetricEncrypt failed with code 0x%x", res);
2002 goto exit;
2003 }
2004 } else {
2005 res = TEE_AsymmetricDecrypt(ecdsa_op, NULL, 0, in, in_len, out, &out_size);
2006 if (res != TEE_SUCCESS) {
2007 EMSG("TEE_AsymmetricDecrypt failed with code 0x%x", res);
2008 goto exit;
2009 }
2010 }
2011
2012 *out_len = out_size;
2013
2014 exit:
2015 if (obj)
2016 TEE_FreeTransientObject(obj);
2017 if (ecdsa_op)
2018 TEE_FreeOperation(ecdsa_op);
2019
2020 return res;
2021 }
2022
rk_sm2_dsa_sm3(uint8_t * digest,uint32_t digest_len,uint8_t * signature,uint32_t * signature_len,ec_key_t * key,uint32_t algo,TEE_OperationMode mode)2023 TEE_Result rk_sm2_dsa_sm3(uint8_t *digest, uint32_t digest_len,
2024 uint8_t *signature, uint32_t *signature_len,
2025 ec_key_t *key, uint32_t algo, TEE_OperationMode mode)
2026 {
2027 TEE_Result res = TEE_ERROR_GENERIC;
2028 TEE_OperationHandle ecdsa_op = NULL;
2029 TEE_ObjectHandle obj = NULL;
2030 TEE_Attribute attr[4];
2031 uint32_t sign_len = 0;
2032 uint32_t max_key_size = 0;
2033
2034 if (!digest || digest_len != SM3_HASH_SIZE || !signature || !signature_len
2035 || !key)
2036 return TEE_ERROR_BAD_PARAMETERS;
2037
2038 #if CRYPTO_DEBUG
2039 IMSG("digest is 0x%x; signature is 0x%x; digest_len is %d; signature_len is %d",
2040 *digest, *signature, digest_len, *signature_len);
2041 IMSG("key->d is 0x%x; key->x is 0x%x; key->y is 0x%x",
2042 *key->d, *key->x, *key->y);
2043 IMSG("key->d_len is %d; key->x_len is %d; key->y_len is %d",
2044 key->d_len, key->x_len, key->y_len);
2045 IMSG("key->curve is 0x%x; key->key_len is %d; algo is 0x%x; mode is 0x%x",
2046 key->curve, key->key_len, algo, mode);
2047 #endif
2048
2049 if (key->curve != TEE_ECC_CURVE_SM2) {
2050 EMSG("curve = %08x != TEE_ECC_CURVE_SM2", key->curve);
2051 return TEE_ERROR_BAD_PARAMETERS;
2052 }
2053
2054 if (algo != TEE_ALG_SM2_DSA_SM3) {
2055 EMSG("algo = %08x != TEE_ALG_SM2_DSA_SM3", algo);
2056 return TEE_ERROR_BAD_PARAMETERS;
2057 }
2058
2059 if (mode != TEE_MODE_SIGN && mode != TEE_MODE_VERIFY)
2060 return TEE_ERROR_BAD_PARAMETERS;
2061
2062 sign_len = *signature_len;
2063 max_key_size = key->key_len;
2064
2065 TEE_InitRefAttribute(&attr[0], TEE_ATTR_ECC_PUBLIC_VALUE_X, key->x, key->x_len);
2066 TEE_InitRefAttribute(&attr[1], TEE_ATTR_ECC_PUBLIC_VALUE_Y, key->y, key->y_len);
2067 TEE_InitRefAttribute(&attr[2], TEE_ATTR_ECC_PRIVATE_VALUE, key->d, key->d_len);
2068 TEE_InitValueAttribute(&attr[3], TEE_ATTR_ECC_CURVE, key->curve, 0);
2069
2070 res = TEE_AllocateTransientObject(TEE_TYPE_SM2_DSA_KEYPAIR, max_key_size, &obj);
2071 if (res != TEE_SUCCESS) {
2072 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
2073 return res;
2074 }
2075
2076 res = TEE_PopulateTransientObject(obj, attr, 4);
2077 if (res != TEE_SUCCESS) {
2078 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
2079 goto exit;
2080 }
2081
2082 res = TEE_AllocateOperation(&ecdsa_op, algo, mode, max_key_size);
2083 if (res != TEE_SUCCESS) {
2084 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
2085 goto exit;
2086 }
2087
2088 res = TEE_SetOperationKey(ecdsa_op, obj);
2089 if (res != TEE_SUCCESS) {
2090 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
2091 goto exit;
2092 }
2093
2094 if (mode == TEE_MODE_SIGN) {
2095 res = TEE_AsymmetricSignDigest(ecdsa_op, NULL, 0, digest, digest_len, signature,
2096 &sign_len);
2097 if (res != TEE_SUCCESS) {
2098 EMSG("TEE_AsymmetricSignDigest failed with code 0x%x", res);
2099 goto exit;
2100 }
2101 *signature_len = sign_len;
2102 } else {
2103 res = TEE_AsymmetricVerifyDigest(ecdsa_op, NULL, 0, digest, digest_len,
2104 signature, sign_len);
2105 if (res != TEE_SUCCESS) {
2106 if (res == TEE_ERROR_SIGNATURE_INVALID) {
2107 EMSG("Verify failed!!!The signature is invalid!!!");
2108 } else {
2109 EMSG("TEE_AsymmetricVerifyDigest failed with code 0x%x", res);
2110 }
2111 }
2112 }
2113
2114 exit:
2115 if (obj)
2116 TEE_FreeTransientObject(obj);
2117 if (ecdsa_op)
2118 TEE_FreeOperation(ecdsa_op);
2119
2120 return res;
2121 }
2122
2123 /* eph means ephemeral public key */
rk_sm2_kep_genkey(rk_sm2_kep_parms * kep_parms,uint8_t * share_key,uint32_t share_key_len,uint8_t * conf_out)2124 TEE_Result rk_sm2_kep_genkey(rk_sm2_kep_parms *kep_parms, uint8_t *share_key,
2125 uint32_t share_key_len, uint8_t *conf_out)
2126 {
2127 TEE_Result res = TEE_SUCCESS;
2128 TEE_OperationHandle derive_op = NULL;
2129 TEE_ObjectHandle keyA = NULL, eph_keyA = NULL;
2130 TEE_ObjectHandle sv_handle = NULL;
2131 TEE_Attribute params[9];
2132 ec_key_t *my_key, *my_eph_key;
2133 ec_pub_key_t *pub_B, *eph_pub_B;
2134 uint32_t param_count = 0;
2135 uint32_t algo = TEE_ALG_SM2_KEP;
2136 uint32_t curve = TEE_ECC_CURVE_SM2;
2137 uint32_t keysize = 256;
2138
2139 if (!kep_parms || !share_key)
2140 return TEE_ERROR_BAD_PARAMETERS;
2141
2142 my_key = &kep_parms->my_key;
2143 my_eph_key = &kep_parms->my_eph_key;
2144 pub_B = &kep_parms->pub_B;
2145 eph_pub_B = &kep_parms->eph_pub_B;
2146
2147 res = TEE_AllocateOperation(&derive_op, algo, TEE_MODE_DERIVE, keysize * 2);
2148 if (res != TEE_SUCCESS) {
2149 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
2150 goto exit;
2151 }
2152
2153 /* set keyA */
2154 res = TEE_AllocateTransientObject(TEE_TYPE_SM2_KEP_KEYPAIR, keysize, &keyA);
2155 if (res != TEE_SUCCESS) {
2156 EMSG("TEE_AllocateTransientObject keyA failed with code 0x%x", res);
2157 goto exit;
2158 }
2159
2160 param_count = 0;
2161
2162 TEE_InitValueAttribute(¶ms[param_count], TEE_ATTR_ECC_CURVE, curve, 0);
2163 param_count++;
2164
2165 TEE_InitRefAttribute(¶ms[param_count], TEE_ATTR_ECC_PRIVATE_VALUE,
2166 my_key->d, my_key->d_len);
2167 param_count++;
2168
2169 TEE_InitRefAttribute(¶ms[param_count], TEE_ATTR_ECC_PUBLIC_VALUE_X,
2170 my_key->x, my_key->x_len);
2171 param_count++;
2172
2173 TEE_InitRefAttribute(¶ms[param_count], TEE_ATTR_ECC_PUBLIC_VALUE_Y,
2174 my_key->y, my_key->y_len);
2175 param_count++;
2176
2177 res = TEE_PopulateTransientObject(keyA, params, param_count);
2178 if (res != TEE_SUCCESS) {
2179 EMSG("TEE_PopulateTransientObject keyA failed with code 0x%x", res);
2180 goto exit;
2181 }
2182
2183 /* set eph keyA */
2184 res = TEE_AllocateTransientObject(TEE_TYPE_SM2_KEP_KEYPAIR, keysize, &eph_keyA);
2185 if (res != TEE_SUCCESS) {
2186 EMSG("TEE_AllocateTransientObject eph_keyA failed with code 0x%x", res);
2187 goto exit;
2188 }
2189
2190 param_count = 0;
2191
2192 TEE_InitValueAttribute(¶ms[param_count], TEE_ATTR_ECC_CURVE, curve, 0);
2193 param_count++;
2194
2195 TEE_InitRefAttribute(¶ms[param_count], TEE_ATTR_ECC_PRIVATE_VALUE,
2196 my_eph_key->d, my_eph_key->d_len);
2197 param_count++;
2198
2199 TEE_InitRefAttribute(¶ms[param_count], TEE_ATTR_ECC_PUBLIC_VALUE_X,
2200 my_eph_key->x, my_eph_key->x_len);
2201 param_count++;
2202
2203 TEE_InitRefAttribute(¶ms[param_count], TEE_ATTR_ECC_PUBLIC_VALUE_Y,
2204 my_eph_key->y, my_eph_key->y_len);
2205 param_count++;
2206
2207 res = TEE_PopulateTransientObject(eph_keyA, params, param_count);
2208 if (res != TEE_SUCCESS) {
2209 EMSG("TEE_PopulateTransientObject eph_keyA failed with code 0x%x", res);
2210 goto exit;
2211 }
2212
2213 res = TEE_SetOperationKey2(derive_op, keyA, eph_keyA);
2214 if (res != TEE_SUCCESS) {
2215 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
2216 goto exit;
2217 }
2218
2219 TEE_FreeTransientObject(keyA);
2220 keyA = NULL;
2221 TEE_FreeTransientObject(eph_keyA);
2222 eph_keyA = NULL;
2223
2224 res = TEE_AllocateTransientObject(TEE_TYPE_GENERIC_SECRET, share_key_len,
2225 &sv_handle);
2226 if (res != TEE_SUCCESS) {
2227 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
2228 goto exit;
2229 }
2230 params[0].attributeID = TEE_ATTR_SM2_KEP_USER;
2231 params[0].content.value.a = !kep_parms->is_initiator;
2232 params[0].content.value.b = 0; /* Not used */
2233 param_count = 1;
2234
2235 TEE_InitRefAttribute(¶ms[param_count],
2236 TEE_ATTR_ECC_PUBLIC_VALUE_X,
2237 pub_B->x, pub_B->x_len);
2238 param_count++;
2239
2240 TEE_InitRefAttribute(¶ms[param_count],
2241 TEE_ATTR_ECC_PUBLIC_VALUE_Y,
2242 pub_B->y, pub_B->y_len);
2243 param_count++;
2244
2245 TEE_InitRefAttribute(¶ms[param_count],
2246 TEE_ATTR_ECC_EPHEMERAL_PUBLIC_VALUE_X,
2247 eph_pub_B->x, eph_pub_B->x_len);
2248 param_count++;
2249
2250 TEE_InitRefAttribute(¶ms[param_count],
2251 TEE_ATTR_ECC_EPHEMERAL_PUBLIC_VALUE_Y,
2252 eph_pub_B->y, eph_pub_B->y_len);
2253 param_count++;
2254
2255 if (kep_parms->id_a_len) {
2256 TEE_InitRefAttribute(¶ms[param_count],
2257 TEE_ATTR_SM2_ID_INITIATOR,
2258 kep_parms->id_a, kep_parms->id_a_len);
2259 param_count++;
2260 }
2261
2262 if (kep_parms->id_b_len) {
2263 TEE_InitRefAttribute(¶ms[param_count],
2264 TEE_ATTR_SM2_ID_RESPONDER,
2265 kep_parms->id_b, kep_parms->id_b_len);
2266 param_count++;
2267 }
2268
2269 if (kep_parms->conf_in_len) {
2270 TEE_InitRefAttribute(¶ms[param_count],
2271 TEE_ATTR_SM2_KEP_CONFIRMATION_IN,
2272 kep_parms->conf_in, kep_parms->conf_in_len);
2273 param_count++;
2274 }
2275
2276 if (conf_out) {
2277 TEE_InitRefAttribute(¶ms[param_count],
2278 TEE_ATTR_SM2_KEP_CONFIRMATION_OUT,
2279 conf_out, SM3_HASH_SIZE);
2280 param_count++;
2281 }
2282
2283 TEE_DeriveKey(derive_op, params, param_count, sv_handle);
2284
2285 res = TEE_GetObjectBufferAttribute(sv_handle, TEE_ATTR_SECRET_VALUE, share_key,
2286 &share_key_len);
2287 if (res != TEE_SUCCESS) {
2288 EMSG("TEE_GetObjectBufferAttribute failed with code 0x%x", res);
2289 goto exit;
2290 }
2291
2292 exit:
2293 if (keyA)
2294 TEE_FreeTransientObject(keyA);
2295 if (eph_keyA)
2296 TEE_FreeTransientObject(eph_keyA);
2297 if (sv_handle)
2298 TEE_FreeTransientObject(sv_handle);
2299 if (derive_op)
2300 TEE_FreeOperation(derive_op);
2301
2302 return res;
2303 }
2304
rk_ecdsa_begin(crypto_ctx_t * ctx,ec_key_t * key,uint32_t algo,TEE_OperationMode mode)2305 TEE_Result rk_ecdsa_begin(crypto_ctx_t *ctx, ec_key_t *key, uint32_t algo,
2306 TEE_OperationMode mode)
2307 {
2308 TEE_Result res = TEE_ERROR_GENERIC;
2309 TEE_OperationHandle ecdsa_op = NULL;
2310 TEE_ObjectHandle obj = NULL;
2311 TEE_Attribute attr[4];
2312 uint32_t max_key_size = 0;
2313
2314 if (!key || !ctx)
2315 return TEE_ERROR_BAD_PARAMETERS;
2316
2317 if (mode != TEE_MODE_SIGN && mode != TEE_MODE_VERIFY)
2318 return TEE_ERROR_BAD_PARAMETERS;
2319
2320 if (TEE_ALG_GET_MAIN_ALG(algo) != TEE_MAIN_ALGO_ECDSA)
2321 return TEE_ERROR_BAD_PARAMETERS;
2322
2323 #if CRYPTO_DEBUG
2324 IMSG("key->d is 0x%x; key->x is 0x%x; key->y is 0x%x",
2325 *key->d, *key->x, *key->y);
2326 IMSG("key->d_len is %d; key->x_len is %d; key->y_len is %d",
2327 key->d_len, key->x_len, key->y_len);
2328 IMSG("key->curve is 0x%x; key->key_len is %d; algo is 0x%x; mode is 0x%x",
2329 key->curve, key->key_len, algo, mode);
2330 #endif
2331
2332 max_key_size = key->key_len;
2333
2334 TEE_InitRefAttribute(&attr[0], TEE_ATTR_ECC_PUBLIC_VALUE_X, key->x, key->x_len);
2335 TEE_InitRefAttribute(&attr[1], TEE_ATTR_ECC_PUBLIC_VALUE_Y, key->y, key->y_len);
2336 TEE_InitRefAttribute(&attr[2], TEE_ATTR_ECC_PRIVATE_VALUE, key->d, key->d_len);
2337 TEE_InitValueAttribute(&attr[3], TEE_ATTR_ECC_CURVE, key->curve, 0);
2338
2339 res = TEE_AllocateTransientObject(TEE_TYPE_ECDSA_KEYPAIR, max_key_size, &obj);
2340 if (res != TEE_SUCCESS) {
2341 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
2342 goto exit;
2343 }
2344
2345 res = TEE_PopulateTransientObject(obj, attr, 4);
2346 if (res != TEE_SUCCESS) {
2347 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
2348 goto exit;
2349 }
2350
2351 res = TEE_AllocateOperation(&ecdsa_op, algo, mode, max_key_size);
2352 if (res != TEE_SUCCESS) {
2353 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
2354 goto exit;
2355 }
2356
2357 res = TEE_SetOperationKey(ecdsa_op, obj);
2358 if (res != TEE_SUCCESS) {
2359 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
2360 goto exit;
2361 }
2362
2363 ctx->obj = obj;
2364 ctx->op = ecdsa_op;
2365 ctx->algo = algo;
2366 ctx->mode = mode;
2367
2368 return TEE_SUCCESS;
2369
2370 exit:
2371 if (obj)
2372 TEE_FreeTransientObject(obj);
2373 if (ecdsa_op)
2374 TEE_FreeOperation(ecdsa_op);
2375
2376 return res;
2377 }
2378
rk_ecdsa_finish(crypto_ctx_t * ctx,uint8_t * digest,uint8_t * sign,uint32_t digest_len,uint32_t * sign_len)2379 TEE_Result rk_ecdsa_finish(crypto_ctx_t *ctx, uint8_t *digest, uint8_t *sign,
2380 uint32_t digest_len, uint32_t *sign_len)
2381 {
2382 TEE_Result res = 0;
2383
2384 if (ctx == NULL ||
2385 (digest == NULL && digest_len != 0) ||
2386 sign_len == NULL ||
2387 (sign == NULL && *sign_len != 0))
2388 return TEE_ERROR_BAD_PARAMETERS;
2389
2390 if (ctx->obj == NULL || ctx->op == NULL)
2391 return TEE_ERROR_BAD_PARAMETERS;
2392
2393 #if CRYPTO_DEBUG
2394 IMSG("ctx->obj: 0x%x;ctx->op: 0x%x;ctx->algo: 0x%x",
2395 (uint32_t)ctx->obj, (uint32_t)ctx->op, ctx->algo);
2396 #endif
2397
2398 switch (ctx->mode) {
2399 case TEE_MODE_SIGN:
2400 res = TEE_AsymmetricSignDigest(ctx->op, NULL, 0, digest, digest_len, sign,
2401 sign_len);
2402 if (res != TEE_SUCCESS) {
2403 EMSG("TEE_AsymmetricSignDigest failed with code 0x%x", res);
2404 return res;
2405 }
2406 break;
2407 case TEE_MODE_VERIFY:
2408 res = TEE_AsymmetricVerifyDigest(ctx->op, NULL, 0, digest, digest_len, sign,
2409 *sign_len);
2410 if (res != TEE_SUCCESS) {
2411 if (res == TEE_ERROR_SIGNATURE_INVALID) {
2412 EMSG("Verify failed!!!The asn1_sign is invalid!!!");
2413 } else {
2414 EMSG("TEE_AsymmetricVerifyDigest failed with code 0x%x", res);
2415 }
2416 return res;
2417 }
2418 break;
2419 default:
2420 EMSG("Unknown mode: 0x%x", ctx->mode);
2421 return TEE_ERROR_BAD_PARAMETERS;
2422 }
2423
2424 return TEE_SUCCESS;
2425 }
2426
rk_pkcs5_pbkdf2_hmac(uint8_t * password,uint32_t password_len,uint8_t * salt,uint32_t salt_len,uint32_t iterations,uint32_t algo,uint32_t key_len,uint8_t * out_key)2427 TEE_Result rk_pkcs5_pbkdf2_hmac(uint8_t *password, uint32_t password_len,
2428 uint8_t *salt, uint32_t salt_len, uint32_t iterations,
2429 uint32_t algo, uint32_t key_len, uint8_t *out_key)
2430 {
2431 TEE_Result res = 0;
2432 TEE_OperationHandle derive_op = NULL;
2433 TEE_ObjectHandle password_obj = NULL;
2434 TEE_ObjectHandle key_obj = NULL;
2435 TEE_Attribute params[4];
2436 uint32_t param_count = 0;
2437 uint32_t out_len = 0;
2438
2439 if (out_key == NULL && key_len != 0)
2440 return TEE_ERROR_BAD_PARAMETERS;
2441 if (TEE_ALG_GET_MAIN_ALG(algo) != TEE_MAIN_ALGO_PBKDF2)
2442 return TEE_ERROR_BAD_PARAMETERS;
2443 if (password_len > 512)
2444 return TEE_ERROR_BAD_PARAMETERS;
2445
2446 #if CRYPTO_DEBUG
2447 IMSG("password_len is %d; salt_len is %d; iterations is %d; key_len is %d",
2448 password_len, salt_len, iterations, key_len);
2449 #endif
2450
2451 TEE_InitRefAttribute(params, TEE_ATTR_PBKDF2_PASSWORD, password, password_len);
2452 param_count = 1;
2453
2454 res = TEE_AllocateTransientObject(TEE_TYPE_PBKDF2_PASSWORD, password_len * 8,
2455 &password_obj);
2456 if (res != TEE_SUCCESS) {
2457 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
2458 goto exit;
2459 }
2460
2461 res = TEE_PopulateTransientObject(password_obj, params, param_count);
2462 if (res != TEE_SUCCESS) {
2463 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
2464 goto exit;
2465 }
2466
2467 res = TEE_AllocateOperation(&derive_op, algo, TEE_MODE_DERIVE,
2468 password_len * 8);
2469 if (res != TEE_SUCCESS) {
2470 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
2471 goto exit;
2472 }
2473
2474 res = TEE_SetOperationKey(derive_op, password_obj);
2475 if (res != TEE_SUCCESS) {
2476 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
2477 goto exit;
2478 }
2479
2480 res = TEE_AllocateTransientObject(TEE_TYPE_GENERIC_SECRET, key_len * 8,
2481 &key_obj);
2482 if (res != TEE_SUCCESS) {
2483 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
2484 goto exit;
2485 }
2486 param_count = 0;
2487
2488 if (salt) {
2489 TEE_InitRefAttribute(¶ms[param_count], TEE_ATTR_PBKDF2_SALT, salt,
2490 salt_len);
2491 param_count++;
2492 }
2493 TEE_InitValueAttribute(¶ms[param_count], TEE_ATTR_PBKDF2_DKM_LENGTH,
2494 key_len, 0);
2495 param_count++;
2496 TEE_InitValueAttribute(¶ms[param_count], TEE_ATTR_PBKDF2_ITERATION_COUNT,
2497 iterations, 0);
2498 param_count++;
2499
2500 TEE_DeriveKey(derive_op, params, param_count, key_obj);
2501
2502 out_len = key_len;
2503 res = TEE_GetObjectBufferAttribute(key_obj, TEE_ATTR_SECRET_VALUE, out_key,
2504 &out_len);
2505 if (res != TEE_SUCCESS) {
2506 EMSG("TEE_GetObjectBufferAttribute for RSA_n failed with code 0x%x", res);
2507 goto exit;
2508 }
2509
2510 exit:
2511 if (password_obj)
2512 TEE_FreeTransientObject(password_obj);
2513 if (key_obj)
2514 TEE_FreeTransientObject(key_obj);
2515 if (derive_op)
2516 TEE_FreeOperation(derive_op);
2517
2518 return res;
2519 }
2520
rk_hkdf_genkey(uint8_t * ikm,uint32_t ikm_len,uint8_t * salt,uint32_t salt_len,uint32_t * info,uint32_t info_len,uint32_t algo,uint32_t okm_len,uint8_t * okm)2521 TEE_Result rk_hkdf_genkey(uint8_t *ikm, uint32_t ikm_len,
2522 uint8_t *salt, uint32_t salt_len, uint32_t *info, uint32_t info_len,
2523 uint32_t algo, uint32_t okm_len, uint8_t *okm)
2524 {
2525 TEE_Result res = 0;
2526 TEE_OperationHandle derive_op = NULL;
2527 TEE_ObjectHandle password_obj = NULL;
2528 TEE_ObjectHandle key_obj = NULL;
2529 TEE_Attribute params[4];
2530 uint32_t param_count = 0;
2531 uint32_t out_len = 0;
2532
2533 if (okm == NULL && okm_len != 0)
2534 return TEE_ERROR_BAD_PARAMETERS;
2535 if (ikm == NULL && ikm_len != 0)
2536 return TEE_ERROR_BAD_PARAMETERS;
2537 if (salt == NULL && salt_len != 0)
2538 return TEE_ERROR_BAD_PARAMETERS;
2539 if (info == NULL && info_len != 0)
2540 return TEE_ERROR_BAD_PARAMETERS;
2541 if (TEE_ALG_GET_MAIN_ALG(algo) != TEE_MAIN_ALGO_HKDF)
2542 return TEE_ERROR_BAD_PARAMETERS;
2543 if (ikm_len > 512)
2544 return TEE_ERROR_BAD_PARAMETERS;
2545
2546 #if CRYPTO_DEBUG
2547 IMSG("ikm_len is %d; salt_len is %d; okm_len is %d; info_len is %d; algo is 0x%x",
2548 ikm_len, salt_len, okm_len, info_len, algo);
2549 #endif
2550
2551 TEE_InitRefAttribute(params, TEE_ATTR_HKDF_IKM, ikm, ikm_len);
2552 param_count = 1;
2553
2554 res = TEE_AllocateTransientObject(TEE_TYPE_HKDF_IKM, ikm_len * 8,
2555 &password_obj);
2556 if (res != TEE_SUCCESS) {
2557 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
2558 goto exit;
2559 }
2560
2561 res = TEE_PopulateTransientObject(password_obj, params, param_count);
2562 if (res != TEE_SUCCESS) {
2563 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
2564 goto exit;
2565 }
2566
2567 res = TEE_AllocateOperation(&derive_op, algo, TEE_MODE_DERIVE, ikm_len * 8);
2568 if (res != TEE_SUCCESS) {
2569 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
2570 goto exit;
2571 }
2572
2573 res = TEE_SetOperationKey(derive_op, password_obj);
2574 if (res != TEE_SUCCESS) {
2575 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
2576 goto exit;
2577 }
2578
2579 res = TEE_AllocateTransientObject(TEE_TYPE_GENERIC_SECRET, okm_len * 8,
2580 &key_obj);
2581 if (res != TEE_SUCCESS) {
2582 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
2583 goto exit;
2584 }
2585 param_count = 0;
2586
2587 if (salt) {
2588 TEE_InitRefAttribute(¶ms[param_count], TEE_ATTR_HKDF_SALT, salt, salt_len);
2589 param_count++;
2590 }
2591
2592 TEE_InitValueAttribute(¶ms[param_count], TEE_ATTR_HKDF_OKM_LENGTH, okm_len,
2593 0);
2594 param_count++;
2595
2596 TEE_InitRefAttribute(¶ms[param_count], TEE_ATTR_HKDF_INFO, info, info_len);
2597 param_count++;
2598
2599 TEE_DeriveKey(derive_op, params, param_count, key_obj);
2600
2601 out_len = okm_len;
2602 res = TEE_GetObjectBufferAttribute(key_obj, TEE_ATTR_SECRET_VALUE, okm,
2603 &out_len);
2604 if (res != TEE_SUCCESS) {
2605 EMSG("TEE_GetObjectBufferAttribute for RSA_n failed with code 0x%x", res);
2606 goto exit;
2607 }
2608
2609 exit:
2610 if (password_obj)
2611 TEE_FreeTransientObject(password_obj);
2612 if (key_obj)
2613 TEE_FreeTransientObject(key_obj);
2614 if (derive_op)
2615 TEE_FreeOperation(derive_op);
2616
2617 return res;
2618 }
2619
rk_ecdh_genkey(uint8_t * private,uint8_t * publicx,uint32_t * publicy,uint32_t algo,uint32_t curve,uint32_t keysize,uint8_t * out)2620 TEE_Result rk_ecdh_genkey(uint8_t *private, uint8_t *publicx, uint32_t *publicy,
2621 uint32_t algo, uint32_t curve, uint32_t keysize, uint8_t *out)
2622 {
2623 TEE_Result res = 0;
2624 TEE_OperationHandle derive_op = NULL;
2625 TEE_ObjectHandle password_obj = NULL;
2626 TEE_ObjectHandle key_obj = NULL;
2627 TEE_Attribute params[4];
2628 uint32_t param_count = 0;
2629 uint32_t out_len = 0;
2630 uint32_t size_byte = (keysize + 7) / 8;
2631
2632 if (private == NULL || publicx == NULL || publicy == NULL)
2633 return TEE_ERROR_BAD_PARAMETERS;
2634 if (TEE_ALG_GET_MAIN_ALG(algo) != TEE_MAIN_ALGO_ECDH)
2635 return TEE_ERROR_BAD_PARAMETERS;
2636 if (keysize != 192 && keysize != 224 && keysize != 256 &&
2637 keysize != 384 && keysize != 521)
2638 return TEE_ERROR_BAD_PARAMETERS;
2639
2640 #if CRYPTO_DEBUG
2641 IMSG("algo is %d; curve is %d; keysize is %d", algo, curve, keysize);
2642 #endif
2643
2644 res = TEE_AllocateOperation(&derive_op, algo, TEE_MODE_DERIVE, keysize);
2645 if (res != TEE_SUCCESS) {
2646 EMSG("TEE_AllocateOperation failed with code 0x%x", res);
2647 goto exit;
2648 }
2649
2650 res = TEE_AllocateTransientObject(TEE_TYPE_ECDH_KEYPAIR, keysize,
2651 &password_obj);
2652 if (res != TEE_SUCCESS) {
2653 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
2654 goto exit;
2655 }
2656
2657 TEE_InitValueAttribute(¶ms[param_count], TEE_ATTR_ECC_CURVE, curve, 0);
2658 param_count++;
2659
2660 TEE_InitRefAttribute(¶ms[param_count], TEE_ATTR_ECC_PRIVATE_VALUE, private,
2661 size_byte);
2662 param_count++;
2663
2664 TEE_InitRefAttribute(¶ms[param_count], TEE_ATTR_ECC_PUBLIC_VALUE_X, private,
2665 size_byte);
2666 param_count++;
2667
2668 TEE_InitRefAttribute(¶ms[param_count], TEE_ATTR_ECC_PUBLIC_VALUE_Y, private,
2669 size_byte);
2670 param_count++;
2671
2672 res = TEE_PopulateTransientObject(password_obj, params, param_count);
2673 if (res != TEE_SUCCESS) {
2674 EMSG("TEE_PopulateTransientObject failed with code 0x%x", res);
2675 goto exit;
2676 }
2677
2678 res = TEE_SetOperationKey(derive_op, password_obj);
2679 if (res != TEE_SUCCESS) {
2680 EMSG("TEE_SetOperationKey failed with code 0x%x", res);
2681 goto exit;
2682 }
2683
2684 res = TEE_AllocateTransientObject(TEE_TYPE_GENERIC_SECRET, size_byte * 8,
2685 &key_obj);
2686 if (res != TEE_SUCCESS) {
2687 EMSG("TEE_AllocateTransientObject failed with code 0x%x", res);
2688 goto exit;
2689 }
2690 param_count = 0;
2691
2692 TEE_InitRefAttribute(¶ms[param_count], TEE_ATTR_ECC_PUBLIC_VALUE_X, publicx,
2693 size_byte);
2694 param_count++;
2695
2696 TEE_InitRefAttribute(¶ms[param_count], TEE_ATTR_ECC_PUBLIC_VALUE_Y, publicy,
2697 size_byte);
2698 param_count++;
2699
2700 TEE_DeriveKey(derive_op, params, param_count, key_obj);
2701
2702 out_len = size_byte;
2703 res = TEE_GetObjectBufferAttribute(key_obj, TEE_ATTR_SECRET_VALUE, out,
2704 &out_len);
2705 if (res != TEE_SUCCESS) {
2706 EMSG("TEE_GetObjectBufferAttribute failed with code 0x%x", res);
2707 goto exit;
2708 }
2709
2710 exit:
2711 if (password_obj)
2712 TEE_FreeTransientObject(password_obj);
2713 if (key_obj)
2714 TEE_FreeTransientObject(key_obj);
2715 if (derive_op)
2716 TEE_FreeOperation(derive_op);
2717
2718 return res;
2719 }
2720
2721