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