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