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