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