xref: /optee_os/core/drivers/crypto/caam/acipher/caam_math.c (revision 1bd5ecaf75a8e84a8bb21de0e81bd9726862f45f)
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