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