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