1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2022-2024 HiSilicon Limited.
4 * Kunpeng hardware accelerator sec authenc algorithm implementation.
5 */
6
7 #include <crypto/crypto_impl.h>
8 #include <drvcrypt.h>
9 #include <drvcrypt_authenc.h>
10 #include <initcall.h>
11 #include <tee_api_types.h>
12 #include <trace.h>
13 #include <utee_defines.h>
14
15 #include "sec_authenc.h"
16 #include "sec_cipher.h"
17 #include "sec_hash.h"
18 #include "sec_main.h"
19
sec_aead_bd_fill(void * bd,void * msg)20 static enum hisi_drv_status sec_aead_bd_fill(void *bd, void *msg)
21 {
22 struct authenc_ctx *ae_ctx = msg;
23 struct hisi_sec_sqe *sqe = bd;
24 uint8_t scene = 0;
25 uint8_t de = 0;
26
27 sqe->type_auth_cipher = BD_TYPE2 | SHIFT_U32(NO_AUTH, SEC_AUTH_OFFSET);
28 scene = SHIFT_U32(SCENE_NOTHING, SEC_SCENE_OFFSET);
29 de = SHIFT_U32(DATA_DST_ADDR_ENABLE, SEC_DE_OFFSET);
30 sqe->sds_sa_type = de | scene;
31 sqe->type2.cipher_src_offset = ae_ctx->aad.length;
32 sqe->type2.icvw_kmode = SHIFT_U32(ae_ctx->c_key_len, SEC_CKEY_OFFSET) |
33 SHIFT_U32(ae_ctx->mode, SEC_CMODE_OFFSET) |
34 ae_ctx->tag_len;
35 sqe->type2.clen_ivhlen = ae_ctx->payload_len;
36 sqe->type2.alen_ivllen = ae_ctx->aad.length;
37 sqe->type2.c_alg = ae_ctx->algo;
38
39 if (ae_ctx->encrypt) {
40 sqe->type_auth_cipher |= SHIFT_U32(CIPHER_ENCRYPT,
41 SEC_CIPHER_OFFSET);
42 sqe->sds_sa_type |= SEC_CIPHER_THEN_DIGEST;
43 } else {
44 sqe->type_auth_cipher |= SHIFT_U32(CIPHER_DECRYPT,
45 SEC_CIPHER_OFFSET);
46 sqe->sds_sa_type |= SEC_DIGEST_THEN_CIPHER;
47 }
48
49 sqe->type2.data_dst_addr = ae_ctx->dst_dma;
50 sqe->type2.data_src_addr = ae_ctx->src_dma;
51 sqe->type2.c_ivin_addr = ae_ctx->civ_dma;
52 sqe->type2.c_key_addr = ae_ctx->key_dma;
53 sqe->type2.mac_addr = ae_ctx->tag_dma;
54 sqe->type2.a_ivin_addr = ae_ctx->aiv_dma;
55
56 return HISI_QM_DRVCRYPT_NO_ERR;
57 }
58
sec_aead_bd_parse(void * bd,void * msg)59 static enum hisi_drv_status sec_aead_bd_parse(void *bd, void *msg)
60 {
61 struct hisi_sec_sqe *sqe = bd;
62 struct authenc_ctx *ctx = msg;
63 uint16_t done = 0;
64
65 ctx->result = SEC_GET_FIELD(sqe->type2.done_flag, SEC_ICV_MASK, 1);
66 done = SEC_GET_FIELD(sqe->type2.done_flag, SEC_DONE_MASK, 0);
67 if (done != SEC_HW_TASK_DONE || sqe->type2.error_type) {
68 EMSG("SEC BD2 fail! done=%#"PRIx16", etype=%#"PRIx8,
69 done, sqe->type2.error_type);
70 return HISI_QM_DRVCRYPT_IN_EPARA;
71 }
72
73 return HISI_QM_DRVCRYPT_NO_ERR;
74 }
75
sec_aead_bd3_fill(void * bd,void * msg)76 static enum hisi_drv_status sec_aead_bd3_fill(void *bd, void *msg)
77 {
78 struct authenc_ctx *ae_ctx = msg;
79 struct hisi_sec_bd3_sqe *sqe = bd;
80
81 sqe->bd_param = BD_TYPE3 | SHIFT_U32(SCENE_NOTHING,
82 SEC_SCENE_OFFSET_V3) |
83 SHIFT_U32(DATA_DST_ADDR_ENABLE, SEC_DE_OFFSET_V3);
84 sqe->auth_mac_key = NO_AUTH;
85 sqe->cipher_src_offset = ae_ctx->aad.length;
86 sqe->c_icv_key = SHIFT_U32(ae_ctx->c_key_len, SEC_CKEY_OFFSET_V3) |
87 SHIFT_U32(ae_ctx->tag_len, SEC_ICV_LEN_OFFSET_V3);
88 sqe->c_len_ivin = ae_ctx->payload_len;
89
90 sqe->a_len_key = ae_ctx->aad.length;
91 sqe->c_mode_alg = ae_ctx->mode |
92 SHIFT_U32(ae_ctx->algo, SEC_CALG_OFFSET_V3);
93
94 if (ae_ctx->encrypt) {
95 sqe->c_icv_key |= CIPHER_ENCRYPT;
96 sqe->huk_iv_seq = SHIFT_U32(SEC_CIPHER_THEN_DIGEST,
97 SEC_SEQ_OFFSET_V3);
98 } else {
99 sqe->c_icv_key |= CIPHER_DECRYPT;
100 sqe->huk_iv_seq = SHIFT_U32(SEC_DIGEST_THEN_CIPHER,
101 SEC_SEQ_OFFSET_V3);
102 }
103
104 sqe->no_scene.c_ivin_addr = ae_ctx->civ_dma;
105 sqe->data_dst_addr = ae_ctx->dst_dma;
106 sqe->data_src_addr = ae_ctx->src_dma;
107 sqe->c_key_addr = ae_ctx->key_dma;
108 sqe->mac_addr = ae_ctx->tag_dma;
109 sqe->a_ivin_addr = ae_ctx->aiv_dma;
110
111 return HISI_QM_DRVCRYPT_NO_ERR;
112 }
113
sec_aead_bd3_parse(void * bd,void * msg)114 static enum hisi_drv_status sec_aead_bd3_parse(void *bd, void *msg)
115 {
116 struct hisi_sec_bd3_sqe *sqe = bd;
117 struct authenc_ctx *ctx = msg;
118 uint16_t done = 0;
119
120 ctx->result = SEC_GET_FIELD(sqe->done_flag, SEC_ICV_MASK, 1);
121 done = SEC_GET_FIELD(sqe->done_flag, SEC_DONE_MASK, 0);
122 if (done != SEC_HW_TASK_DONE || sqe->error_type) {
123 EMSG("SEC BD3 fail! done=%#"PRIx16", etype=%#"PRIx8,
124 done, sqe->error_type);
125 return HISI_QM_DRVCRYPT_IN_EPARA;
126 }
127
128 return HISI_QM_DRVCRYPT_NO_ERR;
129 }
130
sec_do_aead_task(struct hisi_qp * qp,void * msg)131 static TEE_Result sec_do_aead_task(struct hisi_qp *qp, void *msg)
132 {
133 enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
134
135 ret = hisi_qp_send(qp, msg);
136 if (ret) {
137 EMSG("Fail to send task, ret=%d", ret);
138 return TEE_ERROR_BAD_STATE;
139 }
140
141 ret = hisi_qp_recv_sync(qp, msg);
142 if (ret) {
143 EMSG("Recv task error, ret=%d", ret);
144 return TEE_ERROR_BAD_STATE;
145 }
146
147 return TEE_SUCCESS;
148 }
149
authenc_algo_check(uint32_t algo)150 static TEE_Result authenc_algo_check(uint32_t algo)
151 {
152 switch (algo) {
153 case TEE_ALG_AES_GCM:
154 case TEE_ALG_AES_CCM:
155 return TEE_SUCCESS;
156 default:
157 return TEE_ERROR_NOT_IMPLEMENTED;
158 }
159 }
160
crypto_set_alg(uint32_t alg)161 static uint8_t crypto_set_alg(uint32_t alg)
162 {
163 switch (alg) {
164 case TEE_MAIN_ALGO_AES:
165 return C_ALG_AES;
166 default:
167 return 0;
168 }
169 }
170
crypto_set_mode(uint32_t mode)171 static uint8_t crypto_set_mode(uint32_t mode)
172 {
173 switch (mode) {
174 case TEE_CHAIN_MODE_CCM:
175 return C_MODE_CCM;
176 case TEE_CHAIN_MODE_GCM:
177 return C_MODE_GCM;
178 default:
179 return 0;
180 }
181 }
182
sec_authenc_ctx_allocate(void ** ctx,uint32_t algo)183 static TEE_Result sec_authenc_ctx_allocate(void **ctx, uint32_t algo)
184 {
185 struct crypto_authenc_ctx *ae_soft_ctx = NULL;
186 struct authenc_ctx *ae_drv_ctx = NULL;
187 TEE_Result ret = TEE_SUCCESS;
188
189 if (!ctx) {
190 EMSG("ctx is NULL");
191 return TEE_ERROR_BAD_PARAMETERS;
192 }
193
194 ret = authenc_algo_check(algo);
195 if (ret)
196 return ret;
197
198 ae_drv_ctx = calloc(1, sizeof(struct authenc_ctx));
199 if (!ae_drv_ctx) {
200 EMSG("Fail to calloc ae_drv_ctx");
201 return TEE_ERROR_OUT_OF_MEMORY;
202 }
203
204 ae_drv_ctx->algo = crypto_set_alg(TEE_ALG_GET_MAIN_ALG(algo));
205 ae_drv_ctx->mode = crypto_set_mode(TEE_ALG_GET_CHAIN_MODE(algo));
206
207 ret = crypto_aes_gcm_alloc_ctx(&ae_soft_ctx);
208 if (ret) {
209 EMSG("soft ctx is NULL");
210 goto free_ctx;
211 }
212
213 ae_drv_ctx->ae_soft_ctx = ae_soft_ctx;
214 ae_drv_ctx->is_hw_supported = true;
215
216 ae_drv_ctx->qp = sec_create_qp(HISI_QM_CHANNEL_TYPE0);
217 if (!ae_drv_ctx->qp) {
218 ret = TEE_ERROR_BUSY;
219 goto free_soft_ctx;
220 }
221
222 if (ae_drv_ctx->qp->qm->version == HISI_QM_HW_V2) {
223 ae_drv_ctx->qp->fill_sqe = sec_aead_bd_fill;
224 ae_drv_ctx->qp->parse_sqe = sec_aead_bd_parse;
225 } else {
226 ae_drv_ctx->qp->fill_sqe = sec_aead_bd3_fill;
227 ae_drv_ctx->qp->parse_sqe = sec_aead_bd3_parse;
228 }
229
230 *ctx = ae_drv_ctx;
231
232 return TEE_SUCCESS;
233
234 free_soft_ctx:
235 ae_soft_ctx->ops->free_ctx(ae_soft_ctx);
236 free_ctx:
237 free(ae_drv_ctx);
238 return ret;
239 }
240
sec_authenc_ctx_free(void * ctx)241 static void sec_authenc_ctx_free(void *ctx)
242 {
243 struct authenc_ctx *ae_drv_ctx = ctx;
244
245 if (!ae_drv_ctx)
246 return;
247
248 ae_drv_ctx->ae_soft_ctx->ops->free_ctx(ae_drv_ctx->ae_soft_ctx);
249
250 hisi_qm_release_qp(ae_drv_ctx->qp);
251 memzero_explicit(ae_drv_ctx->key, ae_drv_ctx->key_len);
252
253 if (ae_drv_ctx->src.data) {
254 free(ae_drv_ctx->src.data);
255 ae_drv_ctx->src.data = NULL;
256 }
257
258 if (ae_drv_ctx->dst.data) {
259 free(ae_drv_ctx->dst.data);
260 ae_drv_ctx->dst.data = NULL;
261 }
262
263 free(ae_drv_ctx);
264 }
265
authenc_init_params_check(struct drvcrypt_authenc_init * dinit)266 static TEE_Result authenc_init_params_check(struct drvcrypt_authenc_init *dinit)
267 {
268 if (!dinit) {
269 EMSG("dinit is NULL");
270 return TEE_ERROR_BAD_PARAMETERS;
271 }
272
273 if (!dinit->ctx) {
274 EMSG("ctx is NULL");
275 return TEE_ERROR_BAD_PARAMETERS;
276 }
277
278 if (!dinit->key.length || !dinit->key.data) {
279 EMSG("key is NULL");
280 return TEE_ERROR_BAD_PARAMETERS;
281 }
282
283 if (!dinit->nonce.data || !dinit->nonce.length) {
284 EMSG("iv is NULL");
285 return TEE_ERROR_BAD_PARAMETERS;
286 }
287
288 return TEE_SUCCESS;
289 }
290
is_hw_supported(struct drvcrypt_authenc_init * dinit)291 static bool is_hw_supported(struct drvcrypt_authenc_init *dinit)
292 {
293 struct authenc_ctx *ae_drv_ctx = dinit->ctx;
294
295 if (ae_drv_ctx->mode == C_MODE_GCM) {
296 if (dinit->nonce.length != GCM_IV_SIZE)
297 return false;
298
299 if (dinit->aad_len > MAX_GCM_AAD_SIZE) {
300 EMSG("Invalid aad len");
301 return false;
302 }
303
304 if (dinit->tag_len < SEC_MIN_GCM_TAG_LEN ||
305 dinit->tag_len > SEC_MAX_TAG_LEN) {
306 EMSG("Invalid tag len");
307 return false;
308 }
309 } else {
310 if (dinit->nonce.length < MIN_CCM_NONCE_SIZE ||
311 dinit->nonce.length > MAX_CCM_NONCE_SIZE) {
312 EMSG("Invalid nonce len");
313 return false;
314 }
315
316 if (dinit->aad_len > MAX_CCM_AAD_SIZE) {
317 EMSG("Invalid aad len");
318 return false;
319 }
320
321 if (dinit->tag_len < SEC_MIN_CCM_TAG_LEN ||
322 dinit->tag_len > SEC_MAX_TAG_LEN ||
323 dinit->tag_len % TAG_ALIGN) {
324 EMSG("Invalid tag len");
325 return false;
326 }
327 }
328
329 if (dinit->payload_len + dinit->aad_len > SEC_MAX_AEAD_LENGTH ||
330 (ae_drv_ctx->qp->qm->version == HISI_QM_HW_V2 &&
331 dinit->payload_len == 0)) {
332 EMSG("Invalid src len");
333 return false;
334 }
335
336 return true;
337 }
338
sec_aead_set_key(struct drvcrypt_authenc_init * dinit)339 static TEE_Result sec_aead_set_key(struct drvcrypt_authenc_init *dinit)
340 {
341 struct authenc_ctx *ae_drv_ctx = dinit->ctx;
342
343 ae_drv_ctx->key_len = dinit->key.length;
344
345 switch (ae_drv_ctx->key_len) {
346 case AES_KEYSIZE_128:
347 ae_drv_ctx->c_key_len = CKEY_LEN_128_BIT;
348 break;
349 case AES_KEYSIZE_192:
350 ae_drv_ctx->c_key_len = CKEY_LEN_192_BIT;
351 break;
352 case AES_KEYSIZE_256:
353 ae_drv_ctx->c_key_len = CKEY_LEN_256_BIT;
354 break;
355 default:
356 EMSG("Invalid AES key size");
357 return TEE_ERROR_BAD_PARAMETERS;
358 }
359
360 memcpy(ae_drv_ctx->key, dinit->key.data, dinit->key.length);
361
362 return TEE_SUCCESS;
363 }
364
sec_aead_set_iv(struct drvcrypt_authenc_init * dinit)365 static TEE_Result sec_aead_set_iv(struct drvcrypt_authenc_init *dinit)
366 {
367 struct authenc_ctx *ae_drv_ctx = dinit->ctx;
368 uint32_t data_size = dinit->payload_len;
369 uint8_t adata = 0;
370 uint8_t flags = 0;
371 uint8_t cm = 0;
372 uint8_t cl = 0;
373
374 ae_drv_ctx->civ_len = MAX_IV_SIZE;
375 if (ae_drv_ctx->mode == C_MODE_GCM) {
376 ae_drv_ctx->civ_len = dinit->nonce.length;
377 memcpy(ae_drv_ctx->civ, dinit->nonce.data, dinit->nonce.length);
378 return TEE_SUCCESS;
379 }
380
381 if (dinit->aad_len)
382 adata = AAD_NOT_NULL;
383
384 cm = ((dinit->tag_len - IV_CM_CAL_NUM) / IV_CM_CAL_NUM) & IV_CL_MASK;
385 cl = IV_CL_CAL_NUM - dinit->nonce.length;
386 flags = cl | SHIFT_U32(cm, IV_CM_OFFSET) |
387 SHIFT_U32(adata, IV_FLAGS_OFFSET);
388
389 memcpy(ae_drv_ctx->civ + NONCE_OFFSET, dinit->nonce.data,
390 dinit->nonce.length);
391 memcpy(ae_drv_ctx->aiv + NONCE_OFFSET, dinit->nonce.data,
392 dinit->nonce.length);
393
394 ae_drv_ctx->aiv[0] = flags;
395 ae_drv_ctx->aiv[IV_LAST_BYTE1] = data_size & IV_LAST_BYTE_MASK;
396 data_size >>= IV_BYTE_OFFSET;
397 ae_drv_ctx->aiv[IV_LAST_BYTE2] = data_size & IV_LAST_BYTE_MASK;
398 data_size >>= IV_BYTE_OFFSET;
399 ae_drv_ctx->aiv[IV_LAST_BYTE3] = data_size & IV_LAST_BYTE_MASK;
400
401 ae_drv_ctx->civ[0] = cl;
402 ae_drv_ctx->civ[MAX_IV_SIZE - 1] = IV_CTR_INIT;
403
404 return TEE_SUCCESS;
405 }
406
sec_aead_get_dma(struct authenc_ctx * ae_drv_ctx)407 static TEE_Result sec_aead_get_dma(struct authenc_ctx *ae_drv_ctx)
408 {
409 ae_drv_ctx->key_dma = virt_to_phys(ae_drv_ctx->key);
410 ae_drv_ctx->civ_dma = virt_to_phys(ae_drv_ctx->civ);
411 ae_drv_ctx->tag_dma = virt_to_phys(ae_drv_ctx->tag);
412 ae_drv_ctx->src_dma = virt_to_phys(ae_drv_ctx->src.data);
413 ae_drv_ctx->dst_dma = virt_to_phys(ae_drv_ctx->dst.data);
414
415 if (ae_drv_ctx->mode == C_MODE_GCM)
416 return TEE_SUCCESS;
417 ae_drv_ctx->aiv_dma = virt_to_phys(ae_drv_ctx->aiv);
418
419 return TEE_SUCCESS;
420 }
421
sec_aead_data_alloc(struct authenc_ctx * ae_drv_ctx)422 static TEE_Result sec_aead_data_alloc(struct authenc_ctx *ae_drv_ctx)
423 {
424 ae_drv_ctx->src.length = ae_drv_ctx->payload_len +
425 ae_drv_ctx->aad.length;
426 ae_drv_ctx->src.data = malloc(ae_drv_ctx->src.length);
427 if (!ae_drv_ctx->src.data) {
428 EMSG("Fail to malloc src");
429 return TEE_ERROR_OUT_OF_MEMORY;
430 }
431
432 ae_drv_ctx->dst.length = ae_drv_ctx->src.length;
433 ae_drv_ctx->dst.data = malloc(ae_drv_ctx->dst.length);
434 if (!ae_drv_ctx->dst.data) {
435 EMSG("Fail to malloc dst");
436 free(ae_drv_ctx->src.data);
437 ae_drv_ctx->src.data = NULL;
438 return TEE_ERROR_OUT_OF_MEMORY;
439 }
440
441 return TEE_SUCCESS;
442 }
443
ae_soft_calc_init(struct authenc_ctx * ae_drv_ctx,struct drvcrypt_authenc_init * dinit)444 static TEE_Result ae_soft_calc_init(struct authenc_ctx *ae_drv_ctx,
445 struct drvcrypt_authenc_init *dinit)
446 {
447 struct crypto_authenc_ctx *ae_soft_ctx = NULL;
448 TEE_Result ret = TEE_SUCCESS;
449 TEE_OperationMode mode = 0;
450
451 if (ae_drv_ctx->algo == C_ALG_AES && ae_drv_ctx->mode == C_MODE_GCM) {
452 ae_drv_ctx->is_hw_supported = false;
453 ae_soft_ctx = ae_drv_ctx->ae_soft_ctx;
454 if (!dinit->encrypt)
455 mode = 1;
456 ret = ae_soft_ctx->ops->init(ae_soft_ctx, mode,
457 dinit->key.data, dinit->key.length,
458 dinit->nonce.data, dinit->nonce.length,
459 dinit->tag_len, dinit->aad_len,
460 dinit->payload_len);
461 if (ret)
462 EMSG("Fail to init by soft ctx");
463
464 return ret;
465 }
466
467 return TEE_ERROR_NOT_IMPLEMENTED;
468 }
469
sec_authenc_initialize(struct drvcrypt_authenc_init * dinit)470 static TEE_Result sec_authenc_initialize(struct drvcrypt_authenc_init *dinit)
471 {
472 struct authenc_ctx *ae_drv_ctx = NULL;
473 TEE_Result ret = TEE_SUCCESS;
474 bool hw_support = false;
475
476 ret = authenc_init_params_check(dinit);
477 if (ret)
478 return ret;
479
480 ae_drv_ctx = dinit->ctx;
481 hw_support = is_hw_supported(dinit);
482 if (!hw_support)
483 return ae_soft_calc_init(ae_drv_ctx, dinit);
484
485 ae_drv_ctx->encrypt = dinit->encrypt;
486 ae_drv_ctx->payload_len = dinit->payload_len;
487 ae_drv_ctx->aad.length = dinit->aad_len;
488 ae_drv_ctx->tag_len = dinit->tag_len;
489
490 ret = sec_aead_set_key(dinit);
491 if (ret)
492 return ret;
493
494 ret = sec_aead_set_iv(dinit);
495 if (ret)
496 goto clean_key;
497
498 ret = sec_aead_data_alloc(ae_drv_ctx);
499 if (ret)
500 goto clean_key;
501
502 ret = sec_aead_get_dma(ae_drv_ctx);
503 if (ret)
504 goto free_data;
505
506 return TEE_SUCCESS;
507 free_data:
508 if (ae_drv_ctx->src.data) {
509 free(ae_drv_ctx->src.data);
510 ae_drv_ctx->src.data = NULL;
511 }
512 if (ae_drv_ctx->dst.data) {
513 free(ae_drv_ctx->dst.data);
514 ae_drv_ctx->src.data = NULL;
515 }
516 clean_key:
517 memzero_explicit(ae_drv_ctx->key, sizeof(ae_drv_ctx->key));
518 return ret;
519 }
520
521 static TEE_Result
sec_authenc_update_aad(struct drvcrypt_authenc_update_aad * dupdate)522 sec_authenc_update_aad(struct drvcrypt_authenc_update_aad *dupdate)
523 {
524 struct crypto_authenc_ctx *ae_soft_ctx = NULL;
525 struct authenc_ctx *ae_drv_ctx = NULL;
526 TEE_Result ret = TEE_SUCCESS;
527
528 if (!dupdate || !dupdate->ctx) {
529 EMSG("Invalid input parameters");
530 return TEE_ERROR_BAD_PARAMETERS;
531 }
532
533 ae_drv_ctx = dupdate->ctx;
534 if (!ae_drv_ctx->is_hw_supported) {
535 ae_soft_ctx = ae_drv_ctx->ae_soft_ctx;
536 ret = ae_soft_ctx->ops->update_aad(ae_soft_ctx,
537 dupdate->aad.data, dupdate->aad.length);
538 if (ret)
539 EMSG("Fail to update aad by soft ctx");
540
541 return ret;
542 }
543
544 if (dupdate->aad.length + ae_drv_ctx->src_offset >
545 ae_drv_ctx->src.length) {
546 EMSG("Invalid aad length");
547 return TEE_ERROR_BAD_PARAMETERS;
548 }
549 /*
550 * Both aad and ptx need to be filled in the src field.
551 * Here, aad is placed in the header of the src field.
552 */
553 memcpy(ae_drv_ctx->src.data + ae_drv_ctx->src_offset,
554 dupdate->aad.data, dupdate->aad.length);
555 ae_drv_ctx->src_offset += dupdate->aad.length;
556
557 return TEE_SUCCESS;
558 }
559
update_params_check(struct drvcrypt_authenc_update_payload * d)560 static TEE_Result update_params_check(struct drvcrypt_authenc_update_payload *d)
561 {
562 struct authenc_ctx *ae_drv_ctx = NULL;
563
564 ae_drv_ctx = d->ctx;
565 if (!ae_drv_ctx->src.data || !ae_drv_ctx->dst.data) {
566 EMSG("Invalid input/output data");
567 return TEE_ERROR_BAD_PARAMETERS;
568 }
569
570 if (d->src.length + ae_drv_ctx->src_offset > ae_drv_ctx->src.length) {
571 EMSG("Invalid update src length");
572 return TEE_ERROR_BAD_PARAMETERS;
573 }
574
575 if (d->dst.length + ae_drv_ctx->src_offset > ae_drv_ctx->dst.length) {
576 EMSG("Invalid update dst length");
577 return TEE_ERROR_BAD_PARAMETERS;
578 }
579
580 return TEE_SUCCESS;
581 }
582
583 static TEE_Result
sec_authenc_update_payload(struct drvcrypt_authenc_update_payload * d)584 sec_authenc_update_payload(struct drvcrypt_authenc_update_payload *d)
585 {
586 struct crypto_authenc_ctx *ae_soft_ctx = NULL;
587 struct authenc_ctx *ae_drv_ctx = NULL;
588 TEE_Result ret = TEE_SUCCESS;
589
590 if (!d || !d->ctx) {
591 EMSG("Invalid input parameters");
592 return TEE_ERROR_BAD_PARAMETERS;
593 }
594
595 ae_drv_ctx = d->ctx;
596 if (!ae_drv_ctx->is_hw_supported) {
597 ae_soft_ctx = ae_drv_ctx->ae_soft_ctx;
598 ret = ae_soft_ctx->ops->update_payload(ae_soft_ctx,
599 (TEE_OperationMode)(d->encrypt == 0),
600 d->src.data, d->src.length, d->dst.data);
601 if (ret)
602 EMSG("Fail to update payload by soft ctx");
603
604 return ret;
605 }
606
607 ret = update_params_check(d);
608 if (ret)
609 return ret;
610
611 memcpy(ae_drv_ctx->src.data + ae_drv_ctx->src_offset,
612 d->src.data, d->src.length);
613
614 ret = sec_do_aead_task(ae_drv_ctx->qp, ae_drv_ctx);
615 if (ret)
616 return ret;
617
618 memcpy(d->dst.data, ae_drv_ctx->dst.data + ae_drv_ctx->src_offset,
619 d->dst.length);
620 ae_drv_ctx->src_offset += d->src.length;
621
622 return TEE_SUCCESS;
623 }
624
final_params_check(struct drvcrypt_authenc_final * dfinal)625 static TEE_Result final_params_check(struct drvcrypt_authenc_final *dfinal)
626 {
627 struct authenc_ctx *ae_drv_ctx = dfinal->ctx;
628
629 if (!ae_drv_ctx->src.data || !ae_drv_ctx->dst.data) {
630 EMSG("Invalid input/output data");
631 return TEE_ERROR_BAD_PARAMETERS;
632 }
633
634 if (dfinal->src.length + ae_drv_ctx->src_offset >
635 ae_drv_ctx->src.length) {
636 EMSG("Invalid dfinal src length");
637 return TEE_ERROR_BAD_PARAMETERS;
638 }
639
640 if (dfinal->dst.length + ae_drv_ctx->src_offset >
641 ae_drv_ctx->dst.length) {
642 EMSG("Invalid dfinal dst length");
643 return TEE_ERROR_BAD_PARAMETERS;
644 }
645
646 if (dfinal->tag.length > SEC_MAX_TAG_LEN) {
647 EMSG("Invalid dfinal tag length");
648 return TEE_ERROR_BAD_PARAMETERS;
649 }
650
651 return TEE_SUCCESS;
652 }
653
sec_authenc_enc_final(struct drvcrypt_authenc_final * dfinal)654 static TEE_Result sec_authenc_enc_final(struct drvcrypt_authenc_final *dfinal)
655 {
656 struct crypto_authenc_ctx *ae_soft_ctx = NULL;
657 struct authenc_ctx *ae_drv_ctx = NULL;
658 TEE_Result ret = TEE_SUCCESS;
659
660 if (!dfinal || !dfinal->ctx) {
661 EMSG("Invalid input parameters");
662 return TEE_ERROR_BAD_PARAMETERS;
663 }
664
665 ae_drv_ctx = dfinal->ctx;
666 if (!ae_drv_ctx->is_hw_supported) {
667 ae_soft_ctx = ae_drv_ctx->ae_soft_ctx;
668 ret = ae_soft_ctx->ops->enc_final(ae_soft_ctx,
669 dfinal->src.data, dfinal->src.length,
670 dfinal->dst.data, dfinal->tag.data,
671 &dfinal->tag.length);
672 if (ret)
673 EMSG("Fail to do enc final by soft ctx");
674
675 return ret;
676 }
677
678 ret = final_params_check(dfinal);
679 if (ret)
680 return ret;
681 memcpy(ae_drv_ctx->src.data + ae_drv_ctx->src_offset, dfinal->src.data,
682 dfinal->src.length);
683
684 ret = sec_do_aead_task(ae_drv_ctx->qp, ae_drv_ctx);
685
686 memcpy(dfinal->tag.data, ae_drv_ctx->tag, dfinal->tag.length);
687 memcpy(dfinal->dst.data, ae_drv_ctx->dst.data + ae_drv_ctx->src_offset,
688 dfinal->dst.length);
689
690 return ret;
691 }
692
sec_authenc_dec_final(struct drvcrypt_authenc_final * dfinal)693 static TEE_Result sec_authenc_dec_final(struct drvcrypt_authenc_final *dfinal)
694 {
695 struct crypto_authenc_ctx *ae_soft_ctx = NULL;
696 struct authenc_ctx *ae_drv_ctx = NULL;
697 TEE_Result ret = TEE_SUCCESS;
698
699 if (!dfinal || !dfinal->ctx) {
700 EMSG("Invalid input parameters");
701 return TEE_ERROR_BAD_PARAMETERS;
702 }
703
704 ae_drv_ctx = dfinal->ctx;
705 if (!ae_drv_ctx->is_hw_supported) {
706 ae_soft_ctx = ae_drv_ctx->ae_soft_ctx;
707 ret = ae_soft_ctx->ops->dec_final(ae_soft_ctx,
708 dfinal->src.data, dfinal->src.length,
709 dfinal->dst.data, dfinal->tag.data,
710 dfinal->tag.length);
711 if (ret)
712 EMSG("Fail to do dec final by soft ctx");
713
714 return ret;
715 }
716
717 ret = final_params_check(dfinal);
718 if (ret)
719 return ret;
720 memcpy(ae_drv_ctx->src.data + ae_drv_ctx->src_offset, dfinal->src.data,
721 dfinal->src.length);
722 memcpy(ae_drv_ctx->tag, dfinal->tag.data, dfinal->tag.length);
723
724 ret = sec_do_aead_task(ae_drv_ctx->qp, ae_drv_ctx);
725 if (ret)
726 return ret;
727
728 memcpy(dfinal->dst.data, ae_drv_ctx->dst.data + ae_drv_ctx->src_offset,
729 dfinal->dst.length);
730 if (ae_drv_ctx->result == SEC_TAG_ERR) {
731 EMSG("Integrity check failed");
732 return TEE_ERROR_BAD_STATE;
733 }
734
735 return TEE_SUCCESS;
736 }
737
sec_authenc_do_final(void * ctx __unused)738 static void sec_authenc_do_final(void *ctx __unused)
739 {
740 }
741
sec_authenc_copy_state(void * dst_ctx,void * src_ctx)742 static void sec_authenc_copy_state(void *dst_ctx, void *src_ctx)
743 {
744 struct authenc_ctx *dst = dst_ctx;
745 struct authenc_ctx *src = src_ctx;
746 TEE_Result ret = TEE_SUCCESS;
747
748 if (!src->is_hw_supported) {
749 dst->is_hw_supported = false;
750 src->ae_soft_ctx->ops->copy_state(dst->ae_soft_ctx,
751 src->ae_soft_ctx);
752 return;
753 }
754
755 dst->algo = src->algo;
756 dst->mode = src->mode;
757 dst->encrypt = src->encrypt;
758 dst->key_len = src->key_len;
759 dst->tag_len = src->tag_len;
760 dst->c_key_len = src->c_key_len;
761 dst->aad.length = src->aad.length;
762 dst->src_offset = src->src_offset;
763 dst->payload_len = src->payload_len;
764 dst->is_hw_supported = src->is_hw_supported;
765 memcpy(dst->key, src->key, src->key_len);
766 memcpy(dst->civ, src->civ, src->civ_len);
767 /* The len of aiv is always MAX_IV_SIZE */
768 memcpy(dst->aiv, src->aiv, MAX_IV_SIZE);
769 ret = sec_aead_data_alloc(dst);
770 if (ret)
771 return;
772 memcpy(dst->src.data, src->src.data,
773 src->aad.length + src->payload_len);
774 memcpy(dst->dst.data, src->dst.data,
775 src->aad.length + src->payload_len);
776
777 ret = sec_aead_get_dma(dst);
778 if (ret) {
779 memzero_explicit(dst->key, dst->key_len);
780 free(dst->src.data);
781 dst->src.data = NULL;
782 free(dst->dst.data);
783 dst->dst.data = NULL;
784 }
785 }
786
787 static struct drvcrypt_authenc driver_authenc = {
788 .alloc_ctx = sec_authenc_ctx_allocate,
789 .free_ctx = sec_authenc_ctx_free,
790 .init = sec_authenc_initialize,
791 .update_aad = sec_authenc_update_aad,
792 .update_payload = sec_authenc_update_payload,
793 .enc_final = sec_authenc_enc_final,
794 .dec_final = sec_authenc_dec_final,
795 .final = sec_authenc_do_final,
796 .copy_state = sec_authenc_copy_state,
797 };
798
sec_authenc_init(void)799 static TEE_Result sec_authenc_init(void)
800 {
801 TEE_Result ret = TEE_SUCCESS;
802
803 ret = drvcrypt_register_authenc(&driver_authenc);
804 if (ret)
805 EMSG("Sec authenc register to crypto fail ret=%#"PRIx32, ret);
806
807 return ret;
808 }
809 driver_init(sec_authenc_init);
810