xref: /optee_os/core/tee/tee_cryp_utl.c (revision 43be6453dd3e98d39721c8bc6725416772f4205c)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, Linaro Limited
4  */
5 
6 #include <crypto/crypto.h>
7 #include <initcall.h>
8 #include <kernel/panic.h>
9 #include <kernel/tee_time.h>
10 #include <rng_support.h>
11 #include <stdlib.h>
12 #include <string_ext.h>
13 #include <string.h>
14 #include <tee/tee_cryp_utl.h>
15 #include <trace.h>
16 #include <utee_defines.h>
17 
18 TEE_Result tee_hash_get_digest_size(uint32_t algo, size_t *size)
19 {
20 	switch (algo) {
21 	case TEE_ALG_MD5:
22 	case TEE_ALG_HMAC_MD5:
23 		*size = TEE_MD5_HASH_SIZE;
24 		break;
25 	case TEE_ALG_SHA1:
26 	case TEE_ALG_HMAC_SHA1:
27 	case TEE_ALG_DSA_SHA1:
28 		*size = TEE_SHA1_HASH_SIZE;
29 		break;
30 	case TEE_ALG_SHA224:
31 	case TEE_ALG_HMAC_SHA224:
32 	case TEE_ALG_DSA_SHA224:
33 		*size = TEE_SHA224_HASH_SIZE;
34 		break;
35 	case TEE_ALG_SHA256:
36 	case TEE_ALG_HMAC_SHA256:
37 	case TEE_ALG_DSA_SHA256:
38 		*size = TEE_SHA256_HASH_SIZE;
39 		break;
40 	case TEE_ALG_SHA384:
41 	case TEE_ALG_HMAC_SHA384:
42 		*size = TEE_SHA384_HASH_SIZE;
43 		break;
44 	case TEE_ALG_SHA512:
45 	case TEE_ALG_HMAC_SHA512:
46 		*size = TEE_SHA512_HASH_SIZE;
47 		break;
48 	case TEE_ALG_SM3:
49 	case TEE_ALG_HMAC_SM3:
50 		*size = TEE_SM3_HASH_SIZE;
51 		break;
52 	default:
53 		return TEE_ERROR_NOT_SUPPORTED;
54 	}
55 
56 	return TEE_SUCCESS;
57 }
58 
59 TEE_Result tee_hash_createdigest(uint32_t algo, const uint8_t *data,
60 				 size_t datalen, uint8_t *digest,
61 				 size_t digestlen)
62 {
63 	TEE_Result res;
64 	void *ctx = NULL;
65 
66 	res = crypto_hash_alloc_ctx(&ctx, algo);
67 	if (res)
68 		return res;
69 
70 	res = crypto_hash_init(ctx);
71 	if (res)
72 		goto out;
73 
74 	if (datalen != 0) {
75 		res = crypto_hash_update(ctx, data, datalen);
76 		if (res)
77 			goto out;
78 	}
79 
80 	res = crypto_hash_final(ctx, digest, digestlen);
81 out:
82 	crypto_hash_free_ctx(ctx);
83 
84 	return res;
85 }
86 
87 TEE_Result tee_mac_get_digest_size(uint32_t algo, size_t *size)
88 {
89 	switch (algo) {
90 	case TEE_ALG_HMAC_MD5:
91 	case TEE_ALG_HMAC_SHA224:
92 	case TEE_ALG_HMAC_SHA1:
93 	case TEE_ALG_HMAC_SHA256:
94 	case TEE_ALG_HMAC_SHA384:
95 	case TEE_ALG_HMAC_SHA512:
96 	case TEE_ALG_HMAC_SM3:
97 		return tee_hash_get_digest_size(algo, size);
98 	case TEE_ALG_AES_CBC_MAC_NOPAD:
99 	case TEE_ALG_AES_CBC_MAC_PKCS5:
100 	case TEE_ALG_AES_CMAC:
101 		*size = TEE_AES_BLOCK_SIZE;
102 		return TEE_SUCCESS;
103 	case TEE_ALG_DES_CBC_MAC_NOPAD:
104 	case TEE_ALG_DES_CBC_MAC_PKCS5:
105 	case TEE_ALG_DES3_CBC_MAC_NOPAD:
106 	case TEE_ALG_DES3_CBC_MAC_PKCS5:
107 		*size = TEE_DES_BLOCK_SIZE;
108 		return TEE_SUCCESS;
109 	default:
110 		return TEE_ERROR_NOT_SUPPORTED;
111 	}
112 }
113 
114 TEE_Result tee_cipher_get_block_size(uint32_t algo, size_t *size)
115 {
116 	switch (algo) {
117 	case TEE_ALG_AES_CBC_MAC_NOPAD:
118 	case TEE_ALG_AES_CBC_MAC_PKCS5:
119 	case TEE_ALG_AES_CMAC:
120 	case TEE_ALG_AES_ECB_NOPAD:
121 	case TEE_ALG_AES_CBC_NOPAD:
122 	case TEE_ALG_AES_CTR:
123 	case TEE_ALG_AES_CTS:
124 	case TEE_ALG_AES_XTS:
125 	case TEE_ALG_AES_CCM:
126 	case TEE_ALG_AES_GCM:
127 	case TEE_ALG_SM4_ECB_NOPAD:
128 	case TEE_ALG_SM4_CBC_NOPAD:
129 	case TEE_ALG_SM4_CTR:
130 		*size = 16;
131 		break;
132 
133 	case TEE_ALG_DES_CBC_MAC_NOPAD:
134 	case TEE_ALG_DES_CBC_MAC_PKCS5:
135 	case TEE_ALG_DES_ECB_NOPAD:
136 	case TEE_ALG_DES_CBC_NOPAD:
137 	case TEE_ALG_DES3_CBC_MAC_NOPAD:
138 	case TEE_ALG_DES3_CBC_MAC_PKCS5:
139 	case TEE_ALG_DES3_ECB_NOPAD:
140 	case TEE_ALG_DES3_CBC_NOPAD:
141 		*size = 8;
142 		break;
143 
144 	default:
145 		return TEE_ERROR_NOT_SUPPORTED;
146 	}
147 
148 	return TEE_SUCCESS;
149 }
150 
151 TEE_Result tee_do_cipher_update(void *ctx, uint32_t algo,
152 				TEE_OperationMode mode, bool last_block,
153 				const uint8_t *data, size_t len, uint8_t *dst)
154 {
155 	TEE_Result res;
156 	size_t block_size;
157 
158 	if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT)
159 		return TEE_ERROR_BAD_PARAMETERS;
160 
161 	/*
162 	 * Check that the block contains the correct number of data, apart
163 	 * for the last block in some XTS / CTR / XTS mode
164 	 */
165 	res = tee_cipher_get_block_size(algo, &block_size);
166 	if (res != TEE_SUCCESS)
167 		return res;
168 	if ((len % block_size) != 0) {
169 		if (!last_block && algo != TEE_ALG_AES_CTR)
170 			return TEE_ERROR_BAD_PARAMETERS;
171 
172 		switch (algo) {
173 		case TEE_ALG_AES_ECB_NOPAD:
174 		case TEE_ALG_DES_ECB_NOPAD:
175 		case TEE_ALG_DES3_ECB_NOPAD:
176 		case TEE_ALG_AES_CBC_NOPAD:
177 		case TEE_ALG_DES_CBC_NOPAD:
178 		case TEE_ALG_DES3_CBC_NOPAD:
179 		case TEE_ALG_SM4_ECB_NOPAD:
180 		case TEE_ALG_SM4_CBC_NOPAD:
181 			return TEE_ERROR_BAD_PARAMETERS;
182 
183 		case TEE_ALG_AES_CTR:
184 		case TEE_ALG_AES_XTS:
185 		case TEE_ALG_AES_CTS:
186 			/*
187 			 * These modes doesn't require padding for the last
188 			 * block.
189 			 *
190 			 * This isn't entirely true, both XTS and CTS can only
191 			 * encrypt minimum one block and also they need at least
192 			 * one complete block in the last update to finish the
193 			 * encryption. The algorithms are supposed to detect
194 			 * that, we're only making sure that all data fed up to
195 			 * that point consists of complete blocks.
196 			 */
197 			break;
198 
199 		default:
200 			return TEE_ERROR_NOT_SUPPORTED;
201 		}
202 	}
203 
204 	return crypto_cipher_update(ctx, mode, last_block, data, len, dst);
205 }
206 
207 /*
208  * Override this in your platform code to feed the PRNG platform-specific
209  * jitter entropy. This implementation does not efficiently deliver entropy
210  * and is here for backwards-compatibility.
211  */
212 __weak void plat_prng_add_jitter_entropy(enum crypto_rng_src sid,
213 					 unsigned int *pnum)
214 {
215 	TEE_Time current;
216 
217 #ifdef CFG_SECURE_TIME_SOURCE_REE
218 	if (CRYPTO_RNG_SRC_IS_QUICK(sid))
219 		return; /* Can't read REE time here */
220 #endif
221 
222 	if (tee_time_get_sys_time(&current) == TEE_SUCCESS)
223 		crypto_rng_add_event(sid, pnum, &current, sizeof(current));
224 }
225 
226 __weak void plat_rng_init(void)
227 {
228 	TEE_Result res = TEE_SUCCESS;
229 	TEE_Time t;
230 
231 #ifndef CFG_SECURE_TIME_SOURCE_REE
232 	/*
233 	 * This isn't much of a seed. Ideally we should either get a seed from
234 	 * a hardware RNG or from a previously saved seed.
235 	 *
236 	 * Seeding with hardware RNG is currently up to the platform to
237 	 * override this function.
238 	 *
239 	 * Seeding with a saved seed will require cooperation from normal
240 	 * world, this is still TODO.
241 	 */
242 	res = tee_time_get_sys_time(&t);
243 #else
244 	EMSG("Warning: seeding RNG with zeroes");
245 	memset(&t, 0, sizeof(t));
246 #endif
247 	if (!res)
248 		res = crypto_rng_init(&t, sizeof(t));
249 	if (res) {
250 		EMSG("Failed to initialize RNG: %#" PRIx32, res);
251 		panic();
252 	}
253 }
254 
255 static TEE_Result tee_cryp_init(void)
256 {
257 	TEE_Result res = crypto_init();
258 
259 	if (res) {
260 		EMSG("Failed to initialize crypto API: %#" PRIx32, res);
261 		panic();
262 	}
263 	plat_rng_init();
264 
265 	return TEE_SUCCESS;
266 }
267 service_init(tee_cryp_init);
268