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