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