1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2018-2021 NXP
4 *
5 * CAAM Mathematical Operation manager.
6 * Implementation of Mathematical operation using CAAM's MATH function
7 */
8 #include <caam_acipher.h>
9 #include <caam_common.h>
10 #include <caam_hal_ctrl.h>
11 #include <caam_jr.h>
12 #include <caam_utils_mem.h>
13 #include <caam_utils_status.h>
14 #include <drvcrypt.h>
15 #include <drvcrypt_math.h>
16 #include <mm/core_memprot.h>
17
18 /*
19 * MATH operation A xor B modulus n
20 *
21 * @data [in/out] operation data
22 */
do_xor_mod_n(struct drvcrypt_mod_op * data)23 static TEE_Result do_xor_mod_n(struct drvcrypt_mod_op *data)
24 {
25 TEE_Result ret = TEE_ERROR_GENERIC;
26 enum caam_status retstatus = CAAM_FAILURE;
27 struct caam_jobctx jobctx = { };
28 uint32_t *desc = NULL;
29 struct caamdmaobj res = { };
30 struct caamdmaobj data_a = { };
31 struct caamdmaobj data_b = { };
32
33 RSA_TRACE("(A xor B) mod n");
34
35 ret = caam_dmaobj_input_sgtbuf(&data_a, data->a.data, data->a.length);
36 if (ret)
37 return ret;
38
39 ret = caam_dmaobj_input_sgtbuf(&data_b, data->b.data, data->b.length);
40 if (ret)
41 goto out;
42
43 /*
44 * ReAllocate the result buffer with a maximum size
45 * of the Key Modulus's size (N) if not cache aligned
46 */
47 ret = caam_dmaobj_output_sgtbuf(&res, data->result.data,
48 data->result.length,
49 data->result.length);
50 if (ret)
51 goto out;
52
53 #ifdef CFG_CAAM_64BIT
54 #define XOR_OP_DESC_SIZE 14
55 #else
56 #define XOR_OP_DESC_SIZE 11
57 #endif
58 /* Allocate the job descriptor */
59 desc = caam_calloc_desc(XOR_OP_DESC_SIZE);
60 if (!desc) {
61 ret = TEE_ERROR_OUT_OF_MEMORY;
62 goto out;
63 }
64
65 /* Load in N Modulus Size */
66 caam_desc_init(desc);
67 caam_desc_add_word(desc, DESC_HEADER(0));
68 caam_desc_add_word(desc, LD_IMM(CLASS_1, REG_PKHA_N_SIZE, 4));
69 caam_desc_add_word(desc, data->n.length);
70
71 /* Load in A f irst value */
72 caam_desc_fifo_load(desc, &data_a, CLASS_1, PKHA_A, NOACTION);
73 caam_desc_fifo_load(desc, &data_b, CLASS_1, PKHA_B, NOACTION);
74
75 /* Operation B = A xor B mod n */
76 caam_desc_add_word(desc, PKHA_F2M_OP(MOD_ADD_A_B, B));
77
78 /* Store the result */
79 caam_desc_fifo_store(desc, &res, PKHA_B);
80
81 caam_dmaobj_cache_push(&data_a);
82 caam_dmaobj_cache_push(&data_b);
83 caam_dmaobj_cache_push(&res);
84
85 RSA_DUMPDESC(desc);
86
87 jobctx.desc = desc;
88 retstatus = caam_jr_enqueue(&jobctx, NULL);
89
90 if (retstatus == CAAM_NO_ERROR) {
91 caam_dmaobj_copy_to_orig(&res);
92 RSA_DUMPBUF("Output", data->result.data, data->result.length);
93 ret = caam_status_to_tee_result(retstatus);
94 } else {
95 RSA_TRACE("CAAM Status 0x%08" PRIx32, jobctx.status);
96 ret = job_status_to_tee_result(jobctx.status);
97 }
98
99 out:
100 caam_free_desc(&desc);
101 caam_dmaobj_free(&data_a);
102 caam_dmaobj_free(&data_b);
103 caam_dmaobj_free(&res);
104
105 return ret;
106 }
107
108 /*
109 * Registration of the MATH Driver
110 */
111 static const struct drvcrypt_math driver_math = {
112 .xor_mod_n = &do_xor_mod_n,
113 };
114
caam_math_init(struct caam_jrcfg * caam_jrcfg)115 enum caam_status caam_math_init(struct caam_jrcfg *caam_jrcfg)
116 {
117 enum caam_status retstatus = CAAM_FAILURE;
118 vaddr_t jr_base = caam_jrcfg->base + caam_jrcfg->offset;
119
120 if (caam_hal_ctrl_pknum(jr_base))
121 if (!drvcrypt_register_math(&driver_math))
122 retstatus = CAAM_NO_ERROR;
123
124 return retstatus;
125 }
126