xref: /optee_os/core/tee/tee_cryp_utl.c (revision 6e954a6e42bd37911605d3b4cd22e4d1d23c2372)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, Linaro Limited
4  */
5 
6 #include <crypto/crypto.h>
7 #include <initcall.h>
8 #include <kernel/panic.h>
9 #include <kernel/tee_time.h>
10 #include <rng_support.h>
11 #include <stdlib.h>
12 #include <string_ext.h>
13 #include <string.h>
14 #include <tee/tee_cryp_utl.h>
15 #include <trace.h>
16 #include <utee_defines.h>
17 
18 #if !defined(CFG_WITH_SOFTWARE_PRNG)
19 TEE_Result get_rng_array(void *buffer, int len)
20 {
21 	char *buf_char = buffer;
22 	int i;
23 
24 
25 	if (buf_char == NULL)
26 		return TEE_ERROR_BAD_PARAMETERS;
27 
28 	for (i = 0; i < len; i++)
29 		buf_char[i] = hw_get_random_byte();
30 
31 	return TEE_SUCCESS;
32 }
33 #endif
34 
35 TEE_Result tee_hash_get_digest_size(uint32_t algo, size_t *size)
36 {
37 	switch (algo) {
38 	case TEE_ALG_MD5:
39 	case TEE_ALG_HMAC_MD5:
40 		*size = TEE_MD5_HASH_SIZE;
41 		break;
42 	case TEE_ALG_SHA1:
43 	case TEE_ALG_HMAC_SHA1:
44 	case TEE_ALG_DSA_SHA1:
45 		*size = TEE_SHA1_HASH_SIZE;
46 		break;
47 	case TEE_ALG_SHA224:
48 	case TEE_ALG_HMAC_SHA224:
49 	case TEE_ALG_DSA_SHA224:
50 		*size = TEE_SHA224_HASH_SIZE;
51 		break;
52 	case TEE_ALG_SHA256:
53 	case TEE_ALG_HMAC_SHA256:
54 	case TEE_ALG_DSA_SHA256:
55 		*size = TEE_SHA256_HASH_SIZE;
56 		break;
57 	case TEE_ALG_SHA384:
58 	case TEE_ALG_HMAC_SHA384:
59 		*size = TEE_SHA384_HASH_SIZE;
60 		break;
61 	case TEE_ALG_SHA512:
62 	case TEE_ALG_HMAC_SHA512:
63 		*size = TEE_SHA512_HASH_SIZE;
64 		break;
65 	default:
66 		return TEE_ERROR_NOT_SUPPORTED;
67 	}
68 
69 	return TEE_SUCCESS;
70 }
71 
72 TEE_Result tee_hash_createdigest(uint32_t algo, const uint8_t *data,
73 				 size_t datalen, uint8_t *digest,
74 				 size_t digestlen)
75 {
76 	TEE_Result res;
77 	void *ctx = NULL;
78 
79 	res = crypto_hash_alloc_ctx(&ctx, algo);
80 	if (res)
81 		return res;
82 
83 	res = crypto_hash_init(ctx, algo);
84 	if (res)
85 		goto out;
86 
87 	if (datalen != 0) {
88 		res = crypto_hash_update(ctx, algo, data, datalen);
89 		if (res)
90 			goto out;
91 	}
92 
93 	res = crypto_hash_final(ctx, algo, digest, digestlen);
94 out:
95 	crypto_hash_free_ctx(ctx, algo);
96 
97 	return res;
98 }
99 
100 TEE_Result tee_mac_get_digest_size(uint32_t algo, size_t *size)
101 {
102 	switch (algo) {
103 	case TEE_ALG_HMAC_MD5:
104 	case TEE_ALG_HMAC_SHA224:
105 	case TEE_ALG_HMAC_SHA1:
106 	case TEE_ALG_HMAC_SHA256:
107 	case TEE_ALG_HMAC_SHA384:
108 	case TEE_ALG_HMAC_SHA512:
109 		return tee_hash_get_digest_size(algo, size);
110 	case TEE_ALG_AES_CBC_MAC_NOPAD:
111 	case TEE_ALG_AES_CBC_MAC_PKCS5:
112 	case TEE_ALG_AES_CMAC:
113 		*size = TEE_AES_BLOCK_SIZE;
114 		return TEE_SUCCESS;
115 	case TEE_ALG_DES_CBC_MAC_NOPAD:
116 	case TEE_ALG_DES_CBC_MAC_PKCS5:
117 	case TEE_ALG_DES3_CBC_MAC_NOPAD:
118 	case TEE_ALG_DES3_CBC_MAC_PKCS5:
119 		*size = TEE_DES_BLOCK_SIZE;
120 		return TEE_SUCCESS;
121 	default:
122 		return TEE_ERROR_NOT_SUPPORTED;
123 	}
124 }
125 
126 TEE_Result tee_cipher_get_block_size(uint32_t algo, size_t *size)
127 {
128 	switch (algo) {
129 	case TEE_ALG_AES_CBC_MAC_NOPAD:
130 	case TEE_ALG_AES_CBC_MAC_PKCS5:
131 	case TEE_ALG_AES_CMAC:
132 	case TEE_ALG_AES_ECB_NOPAD:
133 	case TEE_ALG_AES_CBC_NOPAD:
134 	case TEE_ALG_AES_CTR:
135 	case TEE_ALG_AES_CTS:
136 	case TEE_ALG_AES_XTS:
137 	case TEE_ALG_AES_CCM:
138 	case TEE_ALG_AES_GCM:
139 		*size = 16;
140 		break;
141 
142 	case TEE_ALG_DES_CBC_MAC_NOPAD:
143 	case TEE_ALG_DES_CBC_MAC_PKCS5:
144 	case TEE_ALG_DES_ECB_NOPAD:
145 	case TEE_ALG_DES_CBC_NOPAD:
146 	case TEE_ALG_DES3_CBC_MAC_NOPAD:
147 	case TEE_ALG_DES3_CBC_MAC_PKCS5:
148 	case TEE_ALG_DES3_ECB_NOPAD:
149 	case TEE_ALG_DES3_CBC_NOPAD:
150 		*size = 8;
151 		break;
152 
153 	default:
154 		return TEE_ERROR_NOT_SUPPORTED;
155 	}
156 
157 	return TEE_SUCCESS;
158 }
159 
160 TEE_Result tee_do_cipher_update(void *ctx, uint32_t algo,
161 				TEE_OperationMode mode, bool last_block,
162 				const uint8_t *data, size_t len, uint8_t *dst)
163 {
164 	TEE_Result res;
165 	size_t block_size;
166 
167 	if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT)
168 		return TEE_ERROR_BAD_PARAMETERS;
169 
170 	/*
171 	 * Check that the block contains the correct number of data, apart
172 	 * for the last block in some XTS / CTR / XTS mode
173 	 */
174 	res = tee_cipher_get_block_size(algo, &block_size);
175 	if (res != TEE_SUCCESS)
176 		return res;
177 	if ((len % block_size) != 0) {
178 		if (!last_block && algo != TEE_ALG_AES_CTR)
179 			return TEE_ERROR_BAD_PARAMETERS;
180 
181 		switch (algo) {
182 		case TEE_ALG_AES_ECB_NOPAD:
183 		case TEE_ALG_DES_ECB_NOPAD:
184 		case TEE_ALG_DES3_ECB_NOPAD:
185 		case TEE_ALG_AES_CBC_NOPAD:
186 		case TEE_ALG_DES_CBC_NOPAD:
187 		case TEE_ALG_DES3_CBC_NOPAD:
188 			return TEE_ERROR_BAD_PARAMETERS;
189 
190 		case TEE_ALG_AES_CTR:
191 		case TEE_ALG_AES_XTS:
192 		case TEE_ALG_AES_CTS:
193 			/*
194 			 * These modes doesn't require padding for the last
195 			 * block.
196 			 *
197 			 * This isn't entirely true, both XTS and CTS can only
198 			 * encrypt minimum one block and also they need at least
199 			 * one complete block in the last update to finish the
200 			 * encryption. The algorithms are supposed to detect
201 			 * that, we're only making sure that all data fed up to
202 			 * that point consists of complete blocks.
203 			 */
204 			break;
205 
206 		default:
207 			return TEE_ERROR_NOT_SUPPORTED;
208 		}
209 	}
210 
211 	return crypto_cipher_update(ctx, algo, mode, last_block, data, len,
212 				    dst);
213 }
214 
215 /*
216  * From http://en.wikipedia.org/wiki/Ciphertext_stealing
217  * CBC ciphertext stealing encryption using a standard
218  * CBC interface:
219  *	1. Pad the last partial plaintext block with 0.
220  *	2. Encrypt the whole padded plaintext using the
221  *	   standard CBC mode.
222  *	3. Swap the last two ciphertext blocks.
223  *	4. Truncate the ciphertext to the length of the
224  *	   original plaintext.
225  *
226  * CBC ciphertext stealing decryption using a standard
227  * CBC interface
228  *	1. Dn = Decrypt (K, Cn-1). Decrypt the second to last
229  *	   ciphertext block.
230  *	2. Cn = Cn || Tail (Dn, B-M). Pad the ciphertext to the
231  *	   nearest multiple of the block size using the last
232  *	   B-M bits of block cipher decryption of the
233  *	   second-to-last ciphertext block.
234  *	3. Swap the last two ciphertext blocks.
235  *	4. Decrypt the (modified) ciphertext using the standard
236  *	   CBC mode.
237  *	5. Truncate the plaintext to the length of the original
238  *	   ciphertext.
239  */
240 TEE_Result tee_aes_cbc_cts_update(void *cbc_ctx, void *ecb_ctx,
241 				  TEE_OperationMode mode, bool last_block,
242 				  const uint8_t *data, size_t len,
243 				  uint8_t *dst)
244 {
245 	TEE_Result res;
246 	int nb_blocks, len_last_block, block_size = 16;
247 	uint8_t tmp_block[64], tmp2_block[64];
248 
249 	if (!last_block)
250 		return tee_do_cipher_update(cbc_ctx, TEE_ALG_AES_CBC_NOPAD,
251 					     mode, last_block, data, len, dst);
252 
253 	/* Compute the last block length and check constraints */
254 	nb_blocks = ((len + block_size - 1) / block_size);
255 	if (nb_blocks < 2)
256 		return TEE_ERROR_BAD_STATE;
257 	len_last_block = len % block_size;
258 	if (len_last_block == 0)
259 		len_last_block = block_size;
260 
261 	if (mode == TEE_MODE_ENCRYPT) {
262 		memcpy(tmp_block,
263 		       data + ((nb_blocks - 1) * block_size),
264 		       len_last_block);
265 		memset(tmp_block + len_last_block,
266 		       0,
267 		       block_size - len_last_block);
268 
269 		res = tee_do_cipher_update(cbc_ctx, TEE_ALG_AES_CBC_NOPAD,
270 					   mode, 0, data,
271 					   (nb_blocks - 1) * block_size, dst);
272 		if (res != TEE_SUCCESS)
273 			return res;
274 
275 		memcpy(dst + (nb_blocks - 1) * block_size,
276 		       dst + (nb_blocks - 2) * block_size,
277 		       len_last_block);
278 
279 		res = tee_do_cipher_update(cbc_ctx, TEE_ALG_AES_CBC_NOPAD,
280 					   mode, 0, tmp_block, block_size,
281 					   dst + (nb_blocks - 2) * block_size);
282 		if (res != TEE_SUCCESS)
283 			return res;
284 	} else {
285 		/* 1. Decrypt the second to last ciphertext block */
286 		res = tee_do_cipher_update(ecb_ctx, TEE_ALG_AES_ECB_NOPAD,
287 					   mode, 0,
288 					   data + (nb_blocks - 2) * block_size,
289 					   block_size, tmp2_block);
290 		if (res != TEE_SUCCESS)
291 			return res;
292 
293 		/* 2. Cn = Cn || Tail (Dn, B-M) */
294 		memcpy(tmp_block, data + ((nb_blocks - 1) * block_size),
295 		       len_last_block);
296 		memcpy(tmp_block + len_last_block, tmp2_block + len_last_block,
297 		       block_size - len_last_block);
298 
299 		/* 3. Swap the last two ciphertext blocks */
300 		/* done by passing the correct buffers in step 4. */
301 
302 		/* 4. Decrypt the (modified) ciphertext */
303 		if (nb_blocks > 2) {
304 			res = tee_do_cipher_update(cbc_ctx,
305 						   TEE_ALG_AES_CBC_NOPAD, mode,
306 						   0, data,
307 						   (nb_blocks - 2) *
308 						   block_size, dst);
309 			if (res != TEE_SUCCESS)
310 				return res;
311 		}
312 
313 		res = tee_do_cipher_update(cbc_ctx, TEE_ALG_AES_CBC_NOPAD,
314 					   mode, 0, tmp_block, block_size,
315 					   dst +
316 					   ((nb_blocks - 2) * block_size));
317 		if (res != TEE_SUCCESS)
318 			return res;
319 
320 		res = tee_do_cipher_update(cbc_ctx, TEE_ALG_AES_CBC_NOPAD,
321 					   mode, 0, data +
322 					   ((nb_blocks - 2) * block_size),
323 					   block_size, tmp_block);
324 		if (res != TEE_SUCCESS)
325 			return res;
326 
327 		/* 5. Truncate the plaintext */
328 		memcpy(dst + (nb_blocks - 1) * block_size, tmp_block,
329 		       len_last_block);
330 	}
331 	return TEE_SUCCESS;
332 }
333 
334 /*
335  * Override this in your platform code to feed the PRNG platform-specific
336  * jitter entropy. This implementation does not efficiently deliver entropy
337  * and is here for backwards-compatibility.
338  */
339 __weak void plat_prng_add_jitter_entropy(enum crypto_rng_src sid,
340 					 unsigned int *pnum)
341 {
342 	TEE_Time current;
343 
344 #ifdef CFG_SECURE_TIME_SOURCE_REE
345 	if (CRYPTO_RNG_SRC_IS_QUICK(sid))
346 		return; /* Can't read REE time here */
347 #endif
348 
349 	if (tee_time_get_sys_time(&current) == TEE_SUCCESS)
350 		crypto_rng_add_event(sid, pnum, &current, sizeof(current));
351 }
352 
353 __weak void plat_rng_init(void)
354 {
355 	TEE_Result res = TEE_SUCCESS;
356 	TEE_Time t;
357 
358 #ifndef CFG_SECURE_TIME_SOURCE_REE
359 	/*
360 	 * This isn't much of a seed. Ideally we should either get a seed from
361 	 * a hardware RNG or from a previously saved seed.
362 	 *
363 	 * Seeding with hardware RNG is currently up to the platform to
364 	 * override this function.
365 	 *
366 	 * Seeding with a saved seed will require cooperation from normal
367 	 * world, this is still TODO.
368 	 */
369 	res = tee_time_get_sys_time(&t);
370 #else
371 	EMSG("Warning: seeding RNG with zeroes");
372 	memset(&t, 0, sizeof(t));
373 #endif
374 	if (!res)
375 		res = crypto_rng_init(&t, sizeof(t));
376 	if (res) {
377 		EMSG("Failed to initialize RNG: %#" PRIx32, res);
378 		panic();
379 	}
380 }
381 
382 static TEE_Result tee_cryp_init(void)
383 {
384 	TEE_Result res = crypto_init();
385 
386 	res = crypto_init();
387 	if (res) {
388 		EMSG("Failed to initialize crypto API: %#" PRIx32, res);
389 		panic();
390 	}
391 	plat_rng_init();
392 
393 	return TEE_SUCCESS;
394 }
395 service_init(tee_cryp_init);
396