xref: /optee_os/core/drivers/crypto/stm32/cipher.c (revision 209c34dc03563af70f1e406f304008495dae7a5e)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
4  */
5 
6 #include <assert.h>
7 #include <crypto/crypto.h>
8 #include <crypto/crypto_impl.h>
9 #include <drvcrypt.h>
10 #include <drvcrypt_cipher.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <tee_api_types.h>
14 #include <util.h>
15 
16 #include "common.h"
17 #include "stm32_cryp.h"
18 #include "stm32_saes.h"
19 
20 #define DES3_KEY_SIZE		24
21 
22 struct cryp_ctx {
23 	struct stm32_cryp_context ctx;
24 	enum stm32_cryp_algo_mode algo;
25 };
26 
27 struct saes_ctx {
28 	struct stm32_saes_context ctx;
29 	enum stm32_saes_chaining_mode algo;
30 	/* Fallback to software implementation on 192bit AES key */
31 	bool use_fallback;
32 	struct crypto_cipher_ctx *fallback_ctx;
33 };
34 
35 /*
36  * Internal peripheral context
37  * SAES and CRYP are registered under the same ID in the crypto framework.
38  * Therefore, only one of them can be registered.
39  */
40 
41 union ip_ctx {
42 	struct saes_ctx saes;
43 	struct cryp_ctx cryp;
44 };
45 
46 /* Internal Peripheral cipher ops*/
47 struct ip_cipher_ops {
48 	TEE_Result (*init)(union ip_ctx *ctx, bool is_decrypt,
49 			   const uint8_t *key, size_t key_len,
50 			   const uint8_t *iv, size_t iv_len);
51 	TEE_Result (*update)(union ip_ctx *ctx, bool last_block, uint8_t *src,
52 			     uint8_t *dst, size_t len);
53 	void (*final)(union ip_ctx *ctx);
54 	void (*copy_state)(union ip_ctx *dst_ctx, union ip_ctx *src_ctx);
55 };
56 
57 struct stm32_cipher_ctx {
58 	struct crypto_cipher_ctx c_ctx;
59 	union ip_ctx ip_ctx;
60 	const struct ip_cipher_ops *ops;
61 };
62 
63 static TEE_Result cryp_init(union ip_ctx *ip_ctx, bool is_decrypt,
64 			    const uint8_t *key, size_t key_len,
65 			    const uint8_t *iv, size_t iv_len)
66 {
67 	uint8_t temp_key[DES3_KEY_SIZE] = { };
68 
69 	if (!IS_ENABLED(CFG_STM32_CRYP))
70 		return TEE_ERROR_NOT_IMPLEMENTED;
71 
72 	if (key_len == 16 &&
73 	    (ip_ctx->cryp.algo == STM32_CRYP_MODE_TDES_ECB ||
74 	     ip_ctx->cryp.algo == STM32_CRYP_MODE_TDES_CBC)) {
75 		/* Manage DES2: i.e. K=K1.K2.K1 */
76 		memcpy(temp_key, key, key_len);
77 		memcpy(temp_key + key_len, key, key_len / 2);
78 		key_len = DES3_KEY_SIZE;
79 		key = temp_key;
80 	}
81 
82 	return stm32_cryp_init(&ip_ctx->cryp.ctx, is_decrypt, ip_ctx->cryp.algo,
83 			       key, key_len, iv, iv_len);
84 }
85 
86 static TEE_Result cryp_update(union ip_ctx *ip_ctx, bool last_block,
87 			      uint8_t *src, uint8_t *dst, size_t len)
88 {
89 	if (!IS_ENABLED(CFG_STM32_CRYP))
90 		return TEE_ERROR_NOT_IMPLEMENTED;
91 
92 	return stm32_cryp_update(&ip_ctx->cryp.ctx, last_block, src, dst, len);
93 }
94 
95 static void cryp_copy_state(union ip_ctx *dst_ip_ctx, union ip_ctx *src_ip_ctx)
96 {
97 	assert(IS_ENABLED(CFG_STM32_CRYP));
98 
99 	memcpy(&dst_ip_ctx->cryp, &src_ip_ctx->cryp, sizeof(dst_ip_ctx->cryp));
100 }
101 
102 static const struct ip_cipher_ops cryp_ops = {
103 	.init = cryp_init,
104 	.update = cryp_update,
105 	.copy_state = cryp_copy_state,
106 };
107 
108 static TEE_Result saes_init(union ip_ctx *ip_ctx, bool is_decrypt,
109 			    const uint8_t *key, size_t key_len,
110 			    const uint8_t *iv, size_t iv_len)
111 {
112 	enum stm32_saes_key_selection key_sel = STM32_SAES_KEY_SOFT;
113 
114 	if (!IS_ENABLED(CFG_STM32_SAES))
115 		return TEE_ERROR_NOT_IMPLEMENTED;
116 
117 	if (key_len == AES_KEYSIZE_192) {
118 		struct crypto_cipher_ctx *ctx = ip_ctx->saes.fallback_ctx;
119 		TEE_OperationMode mode = TEE_MODE_ILLEGAL_VALUE;
120 		TEE_Result res = TEE_ERROR_GENERIC;
121 
122 		if (!IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK)) {
123 			EMSG("STM32 SAES does not support 192bit keys");
124 
125 			return TEE_ERROR_NOT_IMPLEMENTED;
126 		}
127 
128 		if (is_decrypt)
129 			mode = TEE_MODE_DECRYPT;
130 		else
131 			mode = TEE_MODE_ENCRYPT;
132 
133 		res = ctx->ops->init(ctx, mode, key, key_len, NULL, 0, iv,
134 				     iv_len);
135 		if (res)
136 			return res;
137 
138 		ip_ctx->saes.use_fallback = true;
139 
140 		return TEE_SUCCESS;
141 	}
142 
143 	ip_ctx->saes.use_fallback = false;
144 
145 	return stm32_saes_init(&ip_ctx->saes.ctx, is_decrypt, ip_ctx->saes.algo,
146 			       key_sel, key, key_len, iv, iv_len);
147 }
148 
149 static TEE_Result saes_update(union ip_ctx *ip_ctx, bool last_block,
150 			      uint8_t *src, uint8_t *dst, size_t len)
151 {
152 	if (!IS_ENABLED(CFG_STM32_SAES))
153 		return TEE_ERROR_NOT_IMPLEMENTED;
154 
155 	if (ip_ctx->saes.use_fallback) {
156 		struct crypto_cipher_ctx *ctx = ip_ctx->saes.fallback_ctx;
157 
158 		assert(IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK));
159 
160 		return ctx->ops->update(ctx, last_block, src, len, dst);
161 	}
162 
163 	return stm32_saes_update(&ip_ctx->saes.ctx, last_block, src, dst, len);
164 }
165 
166 static void saes_final(union ip_ctx *ip_ctx)
167 {
168 	struct crypto_cipher_ctx *ctx = ip_ctx->saes.fallback_ctx;
169 
170 	assert(IS_ENABLED(CFG_STM32_SAES));
171 
172 	if (ip_ctx->saes.use_fallback) {
173 		assert(IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK));
174 		ctx->ops->final(ctx);
175 	}
176 }
177 
178 static void saes_copy_state(union ip_ctx *dst_ip_ctx, union ip_ctx *src_ip_ctx)
179 {
180 	struct saes_ctx *src_ctx = &src_ip_ctx->saes;
181 	struct crypto_cipher_ctx *fb_ctx = src_ctx->fallback_ctx;
182 
183 	assert(IS_ENABLED(CFG_STM32_SAES));
184 
185 	memcpy(&dst_ip_ctx->saes.ctx, &src_ctx->ctx, sizeof(src_ctx->ctx));
186 
187 	dst_ip_ctx->saes.algo = src_ctx->algo;
188 	dst_ip_ctx->saes.use_fallback = src_ctx->use_fallback;
189 
190 	if (src_ctx->use_fallback) {
191 		assert(IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK));
192 		fb_ctx->ops->copy_state(dst_ip_ctx->saes.fallback_ctx, fb_ctx);
193 	}
194 }
195 
196 static const struct ip_cipher_ops saes_ops = {
197 	.init = saes_init,
198 	.update = saes_update,
199 	.final = saes_final,
200 	.copy_state = saes_copy_state,
201 };
202 
203 static struct stm32_cipher_ctx *
204 to_stm32_cipher_ctx(struct crypto_cipher_ctx *ctx)
205 {
206 	assert(ctx);
207 
208 	return container_of(ctx, struct stm32_cipher_ctx, c_ctx);
209 }
210 
211 static TEE_Result stm32_cipher_initialize(struct drvcrypt_cipher_init *dinit)
212 {
213 	struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(dinit->ctx);
214 
215 	return c->ops->init(&c->ip_ctx, !dinit->encrypt, dinit->key1.data,
216 			    dinit->key1.length, dinit->iv.data,
217 			    dinit->iv.length);
218 }
219 
220 static TEE_Result stm32_cipher_update(struct drvcrypt_cipher_update *dupdate)
221 {
222 	struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(dupdate->ctx);
223 	size_t len = MIN(dupdate->src.length, dupdate->dst.length);
224 
225 	return c->ops->update(&c->ip_ctx, dupdate->last, dupdate->src.data,
226 			      dupdate->dst.data, len);
227 }
228 
229 static void stm32_cipher_final(void *ctx __unused)
230 {
231 	struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(ctx);
232 
233 	if (c->ops->final)
234 		c->ops->final(&c->ip_ctx);
235 }
236 
237 static void stm32_cipher_copy_state(void *dst_ctx, void *src_ctx)
238 {
239 	struct stm32_cipher_ctx *src_c = to_stm32_cipher_ctx(src_ctx);
240 	struct stm32_cipher_ctx *dst_c = to_stm32_cipher_ctx(dst_ctx);
241 
242 	src_c->ops->copy_state(&dst_c->ip_ctx, &src_c->ip_ctx);
243 }
244 
245 static TEE_Result alloc_cryp_ctx(void **ctx, enum stm32_cryp_algo_mode algo)
246 {
247 	struct stm32_cipher_ctx *c = calloc(1, sizeof(*c));
248 
249 	if (!c)
250 		return TEE_ERROR_OUT_OF_MEMORY;
251 
252 	FMSG("Using CRYP %d", algo);
253 	c->ip_ctx.cryp.algo = algo;
254 	c->ops = &cryp_ops;
255 	*ctx = &c->c_ctx;
256 
257 	return TEE_SUCCESS;
258 }
259 
260 static TEE_Result stm32_cryp_cipher_allocate(void **ctx, uint32_t algo)
261 {
262 	/*
263 	 * Convert TEE_ALGO id to internal id
264 	 */
265 	switch (algo) {
266 	case TEE_ALG_DES_ECB_NOPAD:
267 		return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_DES_ECB);
268 	case TEE_ALG_DES_CBC_NOPAD:
269 		return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_DES_CBC);
270 	case TEE_ALG_DES3_ECB_NOPAD:
271 		return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_TDES_ECB);
272 	case TEE_ALG_DES3_CBC_NOPAD:
273 		return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_TDES_CBC);
274 	case TEE_ALG_AES_ECB_NOPAD:
275 		return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_AES_ECB);
276 	case TEE_ALG_AES_CBC_NOPAD:
277 		return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_AES_CBC);
278 	case TEE_ALG_AES_CTR:
279 		return alloc_cryp_ctx(ctx, STM32_CRYP_MODE_AES_CTR);
280 	default:
281 		return TEE_ERROR_NOT_IMPLEMENTED;
282 	}
283 }
284 
285 static void stm32_cryp_cipher_free(void *ctx)
286 {
287 	struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(ctx);
288 
289 	free(c);
290 }
291 
292 static TEE_Result stm32_saes_cipher_allocate(void **ctx, uint32_t algo)
293 {
294 	enum stm32_saes_chaining_mode saes_algo = STM32_SAES_MODE_ECB;
295 	struct crypto_cipher_ctx *fallback_ctx = NULL;
296 	struct stm32_cipher_ctx *saes_ctx = NULL;
297 	TEE_Result res = TEE_SUCCESS;
298 
299 	switch (algo) {
300 	case TEE_ALG_AES_ECB_NOPAD:
301 		saes_algo = STM32_SAES_MODE_ECB;
302 		if (IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK))
303 			res = crypto_aes_ecb_alloc_ctx(&fallback_ctx);
304 		break;
305 	case TEE_ALG_AES_CBC_NOPAD:
306 		saes_algo = STM32_SAES_MODE_CBC;
307 		if (IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK))
308 			res = crypto_aes_cbc_alloc_ctx(&fallback_ctx);
309 		break;
310 	case TEE_ALG_AES_CTR:
311 		saes_algo = STM32_SAES_MODE_CTR;
312 		if (IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK))
313 			res = crypto_aes_ctr_alloc_ctx(&fallback_ctx);
314 		break;
315 	default:
316 		return TEE_ERROR_NOT_IMPLEMENTED;
317 	}
318 	if (res)
319 		return res;
320 
321 	saes_ctx = calloc(1, sizeof(*saes_ctx));
322 	if (!saes_ctx) {
323 		if (IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK))
324 			fallback_ctx->ops->free_ctx(fallback_ctx);
325 
326 		return TEE_ERROR_OUT_OF_MEMORY;
327 	}
328 
329 	FMSG("Using SAES %d", saes_algo);
330 	saes_ctx->ip_ctx.saes.algo = saes_algo;
331 	saes_ctx->ops = &saes_ops;
332 	saes_ctx->ip_ctx.saes.fallback_ctx = fallback_ctx;
333 	*ctx = &saes_ctx->c_ctx;
334 
335 	return TEE_SUCCESS;
336 }
337 
338 static void stm32_saes_cipher_free(void *ctx)
339 {
340 	struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(ctx);
341 
342 	if (IS_ENABLED(CFG_STM32_SAES_SW_FALLBACK)) {
343 		struct crypto_cipher_ctx *fb_ctx = c->ip_ctx.saes.fallback_ctx;
344 
345 		fb_ctx->ops->free_ctx(fb_ctx);
346 	}
347 
348 	free(c);
349 }
350 
351 static struct drvcrypt_cipher driver_cipher_cryp = {
352 	.alloc_ctx = stm32_cryp_cipher_allocate,
353 	.free_ctx = stm32_cryp_cipher_free,
354 	.init = stm32_cipher_initialize,
355 	.update = stm32_cipher_update,
356 	.final = stm32_cipher_final,
357 	.copy_state = stm32_cipher_copy_state,
358 };
359 
360 static struct drvcrypt_cipher driver_cipher_saes = {
361 	.alloc_ctx = stm32_saes_cipher_allocate,
362 	.free_ctx = stm32_saes_cipher_free,
363 	.init = stm32_cipher_initialize,
364 	.update = stm32_cipher_update,
365 	.final = stm32_cipher_final,
366 	.copy_state = stm32_cipher_copy_state,
367 };
368 
369 TEE_Result stm32_register_cipher(enum stm32_cipher_ip_id cipher_ip)
370 {
371 	if (cipher_ip == SAES_IP)
372 		return drvcrypt_register_cipher(&driver_cipher_saes);
373 	else if (cipher_ip == CRYP_IP)
374 		return drvcrypt_register_cipher(&driver_cipher_cryp);
375 	else
376 		return TEE_ERROR_BAD_PARAMETERS;
377 }
378