xref: /optee_os/core/drivers/crypto/caam/hal/common/hal_ctrl.c (revision b7815eeda2ffa172aee1349aeec9ba746bc8082c)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2018-2020 NXP
4  *
5  * Brief   CAAM Controller Hardware Abstration Layer.
6  *         Implementation of primitives to access HW.
7  */
8 #include <caam_hal_ctrl.h>
9 #include <caam_io.h>
10 #include <caam_trace.h>
11 #include <config.h>
12 #include <drivers/imx_snvs.h>
13 #include <platform_config.h>
14 #include <registers/ctrl_regs.h>
15 #include <registers/jr_regs.h>
16 #include <registers/version_regs.h>
17 #include <kernel/panic.h>
18 
caam_hal_ctrl_era(vaddr_t baseaddr)19 uint8_t caam_hal_ctrl_era(vaddr_t baseaddr)
20 {
21 	/* Read the number of instance */
22 	uint32_t val = io_caam_read32(baseaddr + CCBVID);
23 
24 	return GET_CCBVID_CAAM_ERA(val);
25 }
26 
caam_hal_ctrl_jrnum(vaddr_t baseaddr)27 uint8_t caam_hal_ctrl_jrnum(vaddr_t baseaddr)
28 {
29 	uint32_t val = 0;
30 	uint8_t jrnum = 0;
31 
32 	if (caam_hal_ctrl_era(baseaddr) < 10) {
33 		val = io_caam_read32(baseaddr + CHANUM_MS);
34 		jrnum = GET_CHANUM_MS_JRNUM(val);
35 	} else {
36 		val = io_caam_read32(baseaddr + JR_VERSION);
37 		jrnum = GET_JR_VERSION_JRNUM(val);
38 	}
39 
40 	return jrnum;
41 }
42 
caam_hal_ctrl_hash_limit(vaddr_t baseaddr)43 uint8_t caam_hal_ctrl_hash_limit(vaddr_t baseaddr)
44 {
45 	uint32_t val = 0;
46 
47 	if (caam_hal_ctrl_era(baseaddr) < 10) {
48 		/* Read the number of instance */
49 		val = io_caam_read32(baseaddr + CHANUM_LS);
50 
51 		if (GET_CHANUM_LS_MDNUM(val)) {
52 			/* Hashing is supported */
53 			val = io_caam_read32(baseaddr + CHAVID_LS);
54 			val &= BM_CHAVID_LS_MDVID;
55 			if (val == CHAVID_LS_MDVID_LP256)
56 				return TEE_MAIN_ALGO_SHA256;
57 
58 			return TEE_MAIN_ALGO_SHA512;
59 		}
60 	} else {
61 		/* Read the number of instance */
62 		val = io_caam_read32(baseaddr + MDHA_VERSION);
63 
64 		if (GET_MDHA_VERSION_MDNUM(val)) {
65 			/* Hashing is supported */
66 			val &= BM_MDHA_VERSION_MDVID;
67 			if (val == MDHA_VERSION_MDVID_LP256)
68 				return TEE_MAIN_ALGO_SHA256;
69 
70 			return TEE_MAIN_ALGO_SHA512;
71 		}
72 	}
73 
74 	return UINT8_MAX;
75 }
76 
caam_hal_ctrl_splitkey_support(vaddr_t baseaddr)77 bool caam_hal_ctrl_splitkey_support(vaddr_t baseaddr)
78 {
79 	uint32_t val = io_caam_read32(baseaddr + CTPR_LS);
80 
81 	return GET_CTPR_LS_SPLIT_KEY(val);
82 }
83 
caam_hal_ctrl_pknum(vaddr_t baseaddr)84 uint8_t caam_hal_ctrl_pknum(vaddr_t baseaddr)
85 {
86 	uint32_t val = 0;
87 	uint8_t pknum = 0;
88 
89 	if (caam_hal_ctrl_era(baseaddr) < 10) {
90 		val = io_caam_read32(baseaddr + CHANUM_LS);
91 		pknum = GET_CHANUM_LS_PKNUM(val);
92 	} else {
93 		val = io_caam_read32(baseaddr + PKHA_VERSION);
94 		pknum = GET_PKHA_VERSION_PKNUM(val);
95 	}
96 
97 	return pknum;
98 }
99 
100 #define PRIBLOB_MASK	GENMASK_32(1, 0)
101 
caam_hal_ctrl_inc_priblob(vaddr_t baseaddr)102 void caam_hal_ctrl_inc_priblob(vaddr_t baseaddr)
103 {
104 	uint32_t val = 0;
105 	uint32_t blob = 0;
106 
107 	if (!IS_ENABLED(CFG_CAAM_INC_PRIBLOB))
108 		return;
109 
110 	val = io_caam_read32(baseaddr + SCFGR);
111 	val &= PRIBLOB_MASK;
112 	CTRL_TRACE("Reading CAAM PRIBLOB: 0x%"PRIx32, val);
113 
114 	if (val == 0 || val == 2)
115 		blob = val + 1;
116 	else if (val == 1)
117 		blob = val + 2;
118 	else
119 		panic("Error locking PRIBLOB, PRIBLOB =3");
120 
121 	CTRL_TRACE("New CAAM PRIBLOB value: 0x%"PRIx32, blob);
122 
123 	val = io_caam_read32(baseaddr + SCFGR);
124 	val |= blob;
125 	io_caam_write32(baseaddr + SCFGR, val);
126 
127 	val = io_caam_read32(baseaddr + SCFGR);
128 	val &= PRIBLOB_MASK;
129 	CTRL_TRACE("Checking: CAAM PRIBLOB: 0x%"PRIx32 " want: 0x%"PRIx32, val,
130 		   blob);
131 	if (val != blob)
132 		panic("Written PRIBLOB and read PRIBLOB do not match!");
133 }
134 
135 #ifdef CFG_NXP_CAAM_MP_DRV
caam_hal_ctrl_get_mpcurve(vaddr_t ctrl_addr)136 uint8_t caam_hal_ctrl_get_mpcurve(vaddr_t ctrl_addr)
137 {
138 	uint32_t val_scfgr = 0;
139 
140 	/*
141 	 * On i.MX8MQ B0, the MP is not usable, hence
142 	 * return UINT8_MAX
143 	 */
144 	if (soc_is_imx8mq_b0_layer())
145 		return UINT8_MAX;
146 
147 	/*
148 	 * Verify if the device is closed or not
149 	 * If device is closed, check get the MPCurve
150 	 */
151 	if (snvs_is_device_closed()) {
152 		/* Get the SCFGR content */
153 		val_scfgr = io_caam_read32(ctrl_addr + SCFGR);
154 
155 		/* Get the MPCurve field value - 4 bits */
156 		val_scfgr = (val_scfgr & BM_SCFGR_MPCURVE) >> BS_SCFGR_MPCURVE;
157 
158 		/*
159 		 * If the device is closed and the MPCurve field is 0
160 		 * return UINT8_MAX indicating that there is a problem and the
161 		 * MP can not be supported.
162 		 */
163 		if (!val_scfgr)
164 			return UINT8_MAX;
165 	}
166 
167 	return val_scfgr;
168 }
169 
caam_hal_ctrl_read_mpmr(vaddr_t ctrl_addr,struct caambuf * mpmr)170 TEE_Result caam_hal_ctrl_read_mpmr(vaddr_t ctrl_addr, struct caambuf *mpmr)
171 {
172 	unsigned int i = 0;
173 	uint32_t val = 0;
174 
175 	if (mpmr->length < MPMR_NB_REG) {
176 		mpmr->length = MPMR_NB_REG;
177 		return TEE_ERROR_SHORT_BUFFER;
178 	}
179 
180 	/* MPMR endianness is reverted between write and read */
181 	for (i = 0; i < MPMR_NB_REG; i += 4) {
182 		val = io_caam_read32(ctrl_addr + MPMR + i);
183 		mpmr->data[i] = (uint8_t)(val >> 24);
184 		mpmr->data[i + 1] = (uint8_t)(val >> 16);
185 		mpmr->data[i + 2] = (uint8_t)(val >> 8);
186 		mpmr->data[i + 3] = (uint8_t)val;
187 	}
188 
189 	mpmr->length = MPMR_NB_REG;
190 	return TEE_SUCCESS;
191 }
192 
caam_hal_ctrl_is_mp_set(vaddr_t ctrl_addr)193 bool caam_hal_ctrl_is_mp_set(vaddr_t ctrl_addr)
194 {
195 	return io_caam_read32(ctrl_addr + SCFGR) & BM_SCFGR_MPMRL;
196 }
197 
caam_hal_ctrl_fill_mpmr(vaddr_t ctrl_addr,struct caambuf * msg_mpmr)198 void caam_hal_ctrl_fill_mpmr(vaddr_t ctrl_addr, struct caambuf *msg_mpmr)
199 {
200 	size_t i = 0;
201 	vaddr_t reg = ctrl_addr + MPMR;
202 	bool is_filled = false;
203 	uint32_t val = 0;
204 	size_t min_size = 0;
205 	size_t remain_size = 0;
206 
207 	/* check if the MPMR is filled */
208 	is_filled = caam_hal_ctrl_is_mp_set(ctrl_addr);
209 
210 	DMSG("is_filled = %s", is_filled ? "true" : "false");
211 
212 	if (!is_filled) {
213 		/*
214 		 * Fill the MPMR with the most significant input value and
215 		 * complete with 0's if value too short.
216 		 */
217 		min_size = MIN(msg_mpmr->length, (size_t)MPMR_NB_REG);
218 		remain_size = min_size % 4;
219 
220 		for (i = 0; i < min_size - remain_size; i += 4, reg += 4) {
221 			val = msg_mpmr->data[i] | msg_mpmr->data[i + 1] << 8 |
222 			      msg_mpmr->data[i + 2] << 16 |
223 			      msg_mpmr->data[i + 3] << 24;
224 			io_caam_write32(reg, val);
225 		}
226 
227 		/* Last input bytes value */
228 		if (remain_size) {
229 			val = 0;
230 
231 			/*
232 			 * Fill the MPMR with the 8 bits values
233 			 * until the end of the message length
234 			 */
235 			for (i = 0; i < remain_size; i++)
236 				val |= msg_mpmr->data[i] << (i * 8);
237 			io_caam_write32(reg, val);
238 			reg += 4;
239 		}
240 
241 		/* Complete with 0's */
242 		remain_size = (MPMR_NB_REG - ROUNDUP(msg_mpmr->length, 4)) / 4;
243 		for (i = 0; i < remain_size; i++, reg += 4)
244 			io_caam_write32(reg, 0x0);
245 
246 		/*
247 		 * Locks the MPMR for writing and remains locked until
248 		 * the next power-on session.
249 		 */
250 		io_caam_write32(ctrl_addr + SCFGR,
251 				io_caam_read32(ctrl_addr + SCFGR) |
252 				BM_SCFGR_MPMRL);
253 
254 		DMSG("val_scfgr = %#"PRIx32, io_caam_read32(ctrl_addr + SCFGR));
255 	}
256 }
257 #endif /* CFG_NXP_CAAM_MP_DRV */
258 
259 #ifdef CFG_NXP_CAAM_SM_DRV
caam_hal_ctrl_get_smvaddr(vaddr_t ctrl_addr,paddr_t jr_offset)260 vaddr_t caam_hal_ctrl_get_smvaddr(vaddr_t ctrl_addr, paddr_t jr_offset)
261 {
262 	/*
263 	 * The Secure Memory Virtual Base Address contains only the upper
264 	 * bits of the base address of Secure Memory in this Job Ring's virtual
265 	 * address space. Since the base address of Secure Memory must be on a
266 	 * 64 kbyte boundary, the least significant 16 bits are omitted.
267 	 */
268 	return io_caam_read32(ctrl_addr + JRX_SMVBAR(JRX_IDX(jr_offset))) << 16;
269 }
270 #endif /* CFG_NXP_CAAM_SM_DRV */
271