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