xref: /optee_os/core/drivers/crypto/stm32/authenc.c (revision ba2a6adb764f1310ad3c3091d89de84274f86b02)
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 <crypto/internal_aes-gcm.h>
10 #include <drvcrypt.h>
11 #include <drvcrypt_authenc.h>
12 #include <initcall.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <string_ext.h>
16 #include <tee_api_types.h>
17 #include <utee_defines.h>
18 #include <util.h>
19 
20 #include "common.h"
21 #include "stm32_cryp.h"
22 
23 #define TOBE32(x)			TEE_U32_BSWAP(x)
24 #define FROMBE32(x)			TEE_U32_BSWAP(x)
25 
26 #define MAX_TAG_SIZE			16U
27 
28 struct stm32_ae_ctx {
29 	struct crypto_authenc_ctx a_ctx;
30 	struct stm32_cryp_context cryp;
31 	enum stm32_cryp_algo_mode algo;
32 	uint8_t tag_mask[MAX_TAG_SIZE];
33 };
34 
35 static void xor_vec(uint8_t *r, uint8_t *a, uint8_t *b, size_t len)
36 {
37 	size_t i = 0;
38 
39 	for (i = 0; i < len; i++)
40 		r[i] = a[i] ^ b[i];
41 }
42 
43 static struct stm32_ae_ctx *to_stm32_ae_ctx(struct crypto_authenc_ctx *ctx)
44 {
45 	assert(ctx);
46 
47 	return container_of(ctx, struct stm32_ae_ctx, a_ctx);
48 }
49 
50 static TEE_Result stm32_ae_gcm_generate_iv(struct stm32_ae_ctx *c,
51 					   uint32_t *iv,
52 					   struct drvcrypt_authenc_init *dinit)
53 {
54 	TEE_Result res = TEE_SUCCESS;
55 	uint8_t tag1[MAX_TAG_SIZE] = { 0 };
56 	uint8_t tag2[MAX_TAG_SIZE] = { 0 };
57 	uint32_t j0[MAX_TAG_SIZE / sizeof(uint32_t)] = { 0 };
58 	uint8_t dummy_iv[MAX_TAG_SIZE] = { 0 };
59 	struct stm32_cryp_context ctx = { };
60 	uint8_t *data_out = NULL;
61 
62 	if (dinit->nonce.length == 12) {
63 		memcpy(iv, dinit->nonce.data, dinit->nonce.length);
64 		iv[3] = TOBE32(2);
65 		return TEE_SUCCESS;
66 	}
67 
68 	/* Calculate GHASH(dinit->nonce.data) */
69 	dummy_iv[15] = 2;
70 
71 	res = stm32_cryp_init(&ctx, true, STM32_CRYP_MODE_AES_GCM,
72 			      dinit->key.data, dinit->key.length,
73 			      dummy_iv, sizeof(dummy_iv));
74 	if (res)
75 		return res;
76 
77 	res = stm32_cryp_final(&ctx, tag1, sizeof(tag1));
78 	if (res)
79 		return res;
80 
81 	memset(&ctx, 0, sizeof(ctx));
82 	res = stm32_cryp_init(&ctx, true, STM32_CRYP_MODE_AES_GCM,
83 			      dinit->key.data, dinit->key.length,
84 			      dummy_iv, sizeof(dummy_iv));
85 	if (res)
86 		return res;
87 
88 	data_out = malloc(dinit->nonce.length);
89 	if (!data_out)
90 		return TEE_ERROR_OUT_OF_MEMORY;
91 
92 	res = stm32_cryp_update_load(&ctx, dinit->nonce.data, data_out,
93 				     dinit->nonce.length);
94 	free(data_out);
95 
96 	if (res)
97 		return res;
98 
99 	res = stm32_cryp_final(&ctx, tag2, sizeof(tag2));
100 	if (res)
101 		return res;
102 
103 	xor_vec((uint8_t *)j0, tag1, tag2, sizeof(tag1));
104 
105 	memcpy(iv, j0, sizeof(j0));
106 	iv[3] = TOBE32(FROMBE32(iv[3]) + 1);
107 
108 	/* Compute first mask=AES_ECB(J0_real) into tag1 */
109 	memset(&ctx, 0, sizeof(ctx));
110 	res = stm32_cryp_init(&ctx, false, STM32_CRYP_MODE_AES_ECB,
111 			      dinit->key.data, dinit->key.length,
112 			      NULL, 0);
113 	if (res)
114 		return res;
115 
116 	res = stm32_cryp_update(&ctx, true, (uint8_t *)j0, tag1,
117 				sizeof(tag1));
118 	if (res)
119 		return res;
120 
121 	/* Compute second mask=AES_ECB(J0_used_by_HW) into tag2 */
122 	memset(&ctx, 0, sizeof(ctx));
123 	j0[3] = TOBE32(1);
124 	res = stm32_cryp_init(&ctx, false, STM32_CRYP_MODE_AES_ECB,
125 			      dinit->key.data, dinit->key.length,
126 			      NULL, 0);
127 	if (res)
128 		return res;
129 
130 	res = stm32_cryp_update(&ctx, true, (uint8_t *)j0, tag2,
131 				sizeof(tag2));
132 	if (res)
133 		return res;
134 
135 	/*
136 	 * Save the mask we will apply in {enc,dec}_final() to the
137 	 * (wrongly) computed tag to get the expected one.
138 	 */
139 	xor_vec(c->tag_mask, tag1, tag2, sizeof(c->tag_mask));
140 
141 	return TEE_SUCCESS;
142 }
143 
144 static void stm32_ae_ccm_generate_b0(uint8_t *b0,
145 				     struct drvcrypt_authenc_init *dinit)
146 {
147 	size_t m = dinit->tag_len;
148 	size_t l = 15 - dinit->nonce.length;
149 	size_t payload_len = dinit->payload_len;
150 	size_t i = 15;
151 
152 	/* The tag_len should be 4, 6, 8, 10, 12, 14 or 16 */
153 	assert(m >= 4 && m <= 16 && (m % 2) == 0);
154 
155 	memset(b0, 0, TEE_AES_BLOCK_SIZE);
156 	/* Flags: (Adata << 6) | (M' << 3) | L' */
157 	b0[0] = ((dinit->aad_len ? 1 : 0) << 6) |
158 		(((m - 2) / 2) << 3) |
159 		(l - 1);
160 
161 	/* Nonce */
162 	memcpy(b0 + 1, dinit->nonce.data, dinit->nonce.length);
163 
164 	/* Payload length */
165 	for (i = 15; i >= 15 - l + 1; i--, payload_len >>= 8)
166 		b0[i] = payload_len & 0xFF;
167 }
168 
169 static TEE_Result stm32_ae_ccm_push_b1(struct stm32_ae_ctx *c,
170 				       struct drvcrypt_authenc_init *dinit)
171 {
172 	uint8_t b1[TEE_AES_BLOCK_SIZE] = { 0 };
173 	size_t len = 0;
174 
175 	if (dinit->aad_len == 0)
176 		return TEE_SUCCESS;
177 
178 	if (dinit->aad_len < 0x100) {
179 		b1[1] = dinit->aad_len;
180 		len = 2;
181 	} else if (dinit->aad_len < 0xFF00) {
182 		b1[0] = dinit->aad_len / 0x100;
183 		b1[1] = dinit->aad_len % 0x100;
184 		len = 2;
185 	} else if  (dinit->aad_len <= UINT32_MAX) {
186 		b1[0] = 0xFF;
187 		b1[1] = 0xFE;
188 		b1[2] = dinit->aad_len & GENMASK_32(7, 0);
189 		b1[3] = (dinit->aad_len & GENMASK_32(15, 8)) >> 8;
190 		b1[4] = (dinit->aad_len & GENMASK_32(23, 16)) >> 16;
191 		b1[5] = (dinit->aad_len & GENMASK_32(31, 24)) >> 24;
192 		len = 6;
193 	} else {
194 		b1[0] = 0xFF;
195 		b1[1] = 0xFF;
196 		b1[2] = dinit->aad_len & GENMASK_64(7, 0);
197 		b1[3] = (dinit->aad_len & GENMASK_64(15, 8)) >> 8;
198 		b1[4] = (dinit->aad_len & GENMASK_64(23, 16)) >> 16;
199 		b1[5] = (dinit->aad_len & GENMASK_64(31, 24)) >> 24;
200 		b1[6] = (dinit->aad_len & GENMASK_64(39, 32)) >> 32;
201 		b1[7] = (dinit->aad_len & GENMASK_64(47, 40)) >> 40;
202 		b1[8] = (dinit->aad_len & GENMASK_64(55, 48)) >> 48;
203 		b1[9] = (dinit->aad_len & GENMASK_64(63, 56)) >> 56;
204 		len = 10;
205 	}
206 
207 	return stm32_cryp_update_assodata(&c->cryp, b1, len);
208 }
209 
210 static TEE_Result stm32_ae_initialize(struct drvcrypt_authenc_init *dinit)
211 {
212 	TEE_Result res = TEE_SUCCESS;
213 	uint32_t iv[4] = { 0 };
214 	struct stm32_ae_ctx *c = to_stm32_ae_ctx(dinit->ctx);
215 
216 	if (c->algo == STM32_CRYP_MODE_AES_GCM) {
217 		res = stm32_ae_gcm_generate_iv(c, iv, dinit);
218 		if (res)
219 			return res;
220 	} else if (c->algo == STM32_CRYP_MODE_AES_CCM) {
221 		stm32_ae_ccm_generate_b0((uint8_t *)iv, dinit);
222 	}
223 
224 	res = stm32_cryp_init(&c->cryp, !dinit->encrypt, c->algo,
225 			      dinit->key.data, dinit->key.length, iv,
226 			      sizeof(iv));
227 	if (res)
228 		return res;
229 
230 	if (c->algo == STM32_CRYP_MODE_AES_CCM)
231 		return stm32_ae_ccm_push_b1(c, dinit);
232 
233 	return TEE_SUCCESS;
234 }
235 
236 static TEE_Result
237 stm32_ae_update_aad(struct drvcrypt_authenc_update_aad *dupdate)
238 {
239 	struct stm32_ae_ctx *c = to_stm32_ae_ctx(dupdate->ctx);
240 
241 	return stm32_cryp_update_assodata(&c->cryp, dupdate->aad.data,
242 					  dupdate->aad.length);
243 }
244 
245 static TEE_Result
246 stm32_ae_update_payload(struct drvcrypt_authenc_update_payload *dupdate)
247 {
248 	struct stm32_ae_ctx *c = to_stm32_ae_ctx(dupdate->ctx);
249 	size_t len = MIN(dupdate->src.length, dupdate->dst.length);
250 
251 	return stm32_cryp_update_load(&c->cryp, dupdate->src.data,
252 				      dupdate->dst.data, len);
253 }
254 
255 static TEE_Result stm32_ae_encdec_final(struct stm32_ae_ctx *c, uint8_t *tag,
256 					size_t tag_size)
257 {
258 	TEE_Result res = TEE_SUCCESS;
259 	uint8_t t[MAX_TAG_SIZE] = { 0 };
260 
261 	res = stm32_cryp_final(&c->cryp, t, sizeof(t));
262 	if (res)
263 		return res;
264 
265 	xor_vec(tag, t, c->tag_mask, tag_size);
266 
267 	return TEE_SUCCESS;
268 }
269 
270 static TEE_Result stm32_ae_enc_final(struct drvcrypt_authenc_final *dfinal)
271 {
272 	TEE_Result res = TEE_SUCCESS;
273 	struct stm32_ae_ctx *c = to_stm32_ae_ctx(dfinal->ctx);
274 	size_t len = MIN(dfinal->src.length, dfinal->dst.length);
275 
276 	res = stm32_cryp_update_load(&c->cryp, dfinal->src.data,
277 				     dfinal->dst.data, len);
278 	if (res)
279 		return res;
280 
281 	return stm32_ae_encdec_final(c, dfinal->tag.data, dfinal->tag.length);
282 }
283 
284 static TEE_Result stm32_ae_dec_final(struct drvcrypt_authenc_final *dfinal)
285 {
286 	TEE_Result res = TEE_SUCCESS;
287 	struct stm32_ae_ctx *c = to_stm32_ae_ctx(dfinal->ctx);
288 	size_t len = MIN(dfinal->src.length, dfinal->dst.length);
289 	unsigned char tag_buf[MAX_TAG_SIZE] = { 0 };
290 
291 	res = stm32_cryp_update_load(&c->cryp, dfinal->src.data,
292 				     dfinal->dst.data, len);
293 	if (res)
294 		return res;
295 
296 	res = stm32_ae_encdec_final(c, tag_buf, sizeof(tag_buf));
297 	if (res)
298 		return res;
299 
300 	if (consttime_memcmp(tag_buf, dfinal->tag.data, dfinal->tag.length))
301 		return TEE_ERROR_MAC_INVALID;
302 
303 	return TEE_SUCCESS;
304 }
305 
306 static void stm32_ae_final(void *ctx __unused)
307 {
308 }
309 
310 static void stm32_ae_free(void *ctx)
311 {
312 	struct stm32_ae_ctx *c = to_stm32_ae_ctx(ctx);
313 
314 	free(c);
315 }
316 
317 static void stm32_ae_copy_state(void *dst_ctx, void *src_ctx)
318 {
319 	struct stm32_ae_ctx *src = to_stm32_ae_ctx(src_ctx);
320 	struct stm32_ae_ctx *dst = to_stm32_ae_ctx(dst_ctx);
321 
322 	memcpy(dst, src, sizeof(*dst));
323 }
324 
325 static TEE_Result alloc_ctx(void **ctx, enum stm32_cryp_algo_mode algo)
326 {
327 	struct stm32_ae_ctx *c = calloc(1, sizeof(*c));
328 
329 	if (!c)
330 		return TEE_ERROR_OUT_OF_MEMORY;
331 
332 	c->algo = algo;
333 	*ctx = &c->a_ctx;
334 
335 	return TEE_SUCCESS;
336 }
337 
338 /*
339  * Allocate the SW authenc data context
340  *
341  * @ctx   [out] Caller context variable
342  * @algo  Algorithm ID of the context
343  */
344 static TEE_Result stm32_ae_allocate(void **ctx, uint32_t algo)
345 {
346 	/* Convert TEE_ALGO id to CRYP id */
347 	switch (algo) {
348 	case TEE_ALG_AES_CCM:
349 		return alloc_ctx(ctx, STM32_CRYP_MODE_AES_CCM);
350 	case TEE_ALG_AES_GCM:
351 		return alloc_ctx(ctx, STM32_CRYP_MODE_AES_GCM);
352 	default:
353 		return TEE_ERROR_NOT_IMPLEMENTED;
354 	}
355 }
356 
357 /*
358  * Registration of the Authenc Driver
359  */
360 static struct drvcrypt_authenc driver_authenc = {
361 	.alloc_ctx = &stm32_ae_allocate,
362 	.free_ctx = &stm32_ae_free,
363 	.init = &stm32_ae_initialize,
364 	.update_aad = &stm32_ae_update_aad,
365 	.update_payload = &stm32_ae_update_payload,
366 	.enc_final = &stm32_ae_enc_final,
367 	.dec_final = &stm32_ae_dec_final,
368 	.final = &stm32_ae_final,
369 	.copy_state = &stm32_ae_copy_state,
370 };
371 
372 TEE_Result stm32_register_authenc(void)
373 {
374 	return drvcrypt_register_authenc(&driver_authenc);
375 }
376