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