xref: /optee_os/core/tee/tee_cryp_utl.c (revision fbffc8ada5922710c194abe22e8b3584c9bc1cff)
11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2ffe04039SJerome Forissier /*
33de8f0deSEtienne Carriere  * Copyright (c) 2014-2021, Linaro Limited
4eee637e7SAlexander Zakharov  * Copyright (c) 2021, SumUp Services GmbH
5ffe04039SJerome Forissier  */
6ffe04039SJerome Forissier 
7e1770e71SJens Wiklander #include <crypto/crypto.h>
8e1770e71SJens Wiklander #include <initcall.h>
93de8f0deSEtienne Carriere #include <kernel/dt_driver.h>
106e954a6eSJens Wiklander #include <kernel/panic.h>
112a5e2ec6SAndy Green #include <kernel/tee_time.h>
12e1770e71SJens Wiklander #include <stdlib.h>
13e1770e71SJens Wiklander #include <string_ext.h>
14e1770e71SJens Wiklander #include <string.h>
15e1770e71SJens Wiklander #include <tee/tee_cryp_utl.h>
166e954a6eSJens Wiklander #include <trace.h>
17e1770e71SJens Wiklander #include <utee_defines.h>
18ffe04039SJerome Forissier 
tee_alg_get_digest_size(uint32_t algo,size_t * size)197c767434SAlbert Schwarzkopf TEE_Result tee_alg_get_digest_size(uint32_t algo, size_t *size)
20ffe04039SJerome Forissier {
217c767434SAlbert Schwarzkopf 	size_t digest_size = TEE_ALG_GET_DIGEST_SIZE(algo);
227c767434SAlbert Schwarzkopf 
237c767434SAlbert Schwarzkopf 	if (!digest_size)
24ffe04039SJerome Forissier 		return TEE_ERROR_NOT_SUPPORTED;
257c767434SAlbert Schwarzkopf 
267c767434SAlbert Schwarzkopf 	*size = digest_size;
27ffe04039SJerome Forissier 
28ffe04039SJerome Forissier 	return TEE_SUCCESS;
29ffe04039SJerome Forissier }
30ffe04039SJerome Forissier 
tee_hash_createdigest(uint32_t algo,const uint8_t * data,size_t datalen,uint8_t * digest,size_t digestlen)31ffe04039SJerome Forissier TEE_Result tee_hash_createdigest(uint32_t algo, const uint8_t *data,
32ffe04039SJerome Forissier 				 size_t datalen, uint8_t *digest,
33ffe04039SJerome Forissier 				 size_t digestlen)
34ffe04039SJerome Forissier {
35ecf2e014SJens Wiklander 	TEE_Result res;
36ffe04039SJerome Forissier 	void *ctx = NULL;
37ffe04039SJerome Forissier 
38ecf2e014SJens Wiklander 	res = crypto_hash_alloc_ctx(&ctx, algo);
39ecf2e014SJens Wiklander 	if (res)
40ecf2e014SJens Wiklander 		return res;
41ffe04039SJerome Forissier 
426b3a371cSJens Wiklander 	res = crypto_hash_init(ctx);
43ecf2e014SJens Wiklander 	if (res)
44ffe04039SJerome Forissier 		goto out;
45ffe04039SJerome Forissier 
46ffe04039SJerome Forissier 	if (datalen != 0) {
476b3a371cSJens Wiklander 		res = crypto_hash_update(ctx, data, datalen);
48ecf2e014SJens Wiklander 		if (res)
49ffe04039SJerome Forissier 			goto out;
50ffe04039SJerome Forissier 	}
51ffe04039SJerome Forissier 
526b3a371cSJens Wiklander 	res = crypto_hash_final(ctx, digest, digestlen);
53ffe04039SJerome Forissier out:
546b3a371cSJens Wiklander 	crypto_hash_free_ctx(ctx);
55ffe04039SJerome Forissier 
56ffe04039SJerome Forissier 	return res;
57ffe04039SJerome Forissier }
58ffe04039SJerome Forissier 
tee_cipher_get_block_size(uint32_t algo,size_t * size)59ffe04039SJerome Forissier TEE_Result tee_cipher_get_block_size(uint32_t algo, size_t *size)
60ffe04039SJerome Forissier {
61ffe04039SJerome Forissier 	switch (algo) {
62ffe04039SJerome Forissier 	case TEE_ALG_AES_CBC_MAC_NOPAD:
63ffe04039SJerome Forissier 	case TEE_ALG_AES_CBC_MAC_PKCS5:
64ffe04039SJerome Forissier 	case TEE_ALG_AES_CMAC:
65ffe04039SJerome Forissier 	case TEE_ALG_AES_ECB_NOPAD:
66ffe04039SJerome Forissier 	case TEE_ALG_AES_CBC_NOPAD:
67ffe04039SJerome Forissier 	case TEE_ALG_AES_CTR:
68ffe04039SJerome Forissier 	case TEE_ALG_AES_CTS:
69ffe04039SJerome Forissier 	case TEE_ALG_AES_XTS:
70ffe04039SJerome Forissier 	case TEE_ALG_AES_CCM:
71ffe04039SJerome Forissier 	case TEE_ALG_AES_GCM:
72ade6f848SJerome Forissier 	case TEE_ALG_SM4_ECB_NOPAD:
73ade6f848SJerome Forissier 	case TEE_ALG_SM4_CBC_NOPAD:
74696f56acSPingan Xie 	case TEE_ALG_SM4_XTS:
75ade6f848SJerome Forissier 	case TEE_ALG_SM4_CTR:
76ffe04039SJerome Forissier 		*size = 16;
77ffe04039SJerome Forissier 		break;
78ffe04039SJerome Forissier 
79ffe04039SJerome Forissier 	case TEE_ALG_DES_CBC_MAC_NOPAD:
80ffe04039SJerome Forissier 	case TEE_ALG_DES_CBC_MAC_PKCS5:
81ffe04039SJerome Forissier 	case TEE_ALG_DES_ECB_NOPAD:
82ffe04039SJerome Forissier 	case TEE_ALG_DES_CBC_NOPAD:
83ffe04039SJerome Forissier 	case TEE_ALG_DES3_CBC_MAC_NOPAD:
84ffe04039SJerome Forissier 	case TEE_ALG_DES3_CBC_MAC_PKCS5:
85ffe04039SJerome Forissier 	case TEE_ALG_DES3_ECB_NOPAD:
86ffe04039SJerome Forissier 	case TEE_ALG_DES3_CBC_NOPAD:
87eee637e7SAlexander Zakharov 	case TEE_ALG_DES3_CMAC:
88ffe04039SJerome Forissier 		*size = 8;
89ffe04039SJerome Forissier 		break;
90ffe04039SJerome Forissier 
91ffe04039SJerome Forissier 	default:
92ffe04039SJerome Forissier 		return TEE_ERROR_NOT_SUPPORTED;
93ffe04039SJerome Forissier 	}
94ffe04039SJerome Forissier 
95ffe04039SJerome Forissier 	return TEE_SUCCESS;
96ffe04039SJerome Forissier }
97ffe04039SJerome Forissier 
tee_do_cipher_update(void * ctx,uint32_t algo,TEE_OperationMode mode,bool last_block,const uint8_t * data,size_t len,uint8_t * dst)98ffe04039SJerome Forissier TEE_Result tee_do_cipher_update(void *ctx, uint32_t algo,
99ffe04039SJerome Forissier 				TEE_OperationMode mode, bool last_block,
100ffe04039SJerome Forissier 				const uint8_t *data, size_t len, uint8_t *dst)
101ffe04039SJerome Forissier {
102ffe04039SJerome Forissier 	TEE_Result res;
103ffe04039SJerome Forissier 	size_t block_size;
104ffe04039SJerome Forissier 
105ffe04039SJerome Forissier 	if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT)
106ffe04039SJerome Forissier 		return TEE_ERROR_BAD_PARAMETERS;
107ffe04039SJerome Forissier 
108ffe04039SJerome Forissier 	/*
109ffe04039SJerome Forissier 	 * Check that the block contains the correct number of data, apart
110ffe04039SJerome Forissier 	 * for the last block in some XTS / CTR / XTS mode
111ffe04039SJerome Forissier 	 */
112ffe04039SJerome Forissier 	res = tee_cipher_get_block_size(algo, &block_size);
113ffe04039SJerome Forissier 	if (res != TEE_SUCCESS)
114ffe04039SJerome Forissier 		return res;
115ffe04039SJerome Forissier 	if ((len % block_size) != 0) {
11657aabac5SBogdan Liulko 		if (!last_block && algo != TEE_ALG_AES_CTR)
117ffe04039SJerome Forissier 			return TEE_ERROR_BAD_PARAMETERS;
118ffe04039SJerome Forissier 
119ffe04039SJerome Forissier 		switch (algo) {
120ffe04039SJerome Forissier 		case TEE_ALG_AES_ECB_NOPAD:
121ffe04039SJerome Forissier 		case TEE_ALG_DES_ECB_NOPAD:
122ffe04039SJerome Forissier 		case TEE_ALG_DES3_ECB_NOPAD:
123ffe04039SJerome Forissier 		case TEE_ALG_AES_CBC_NOPAD:
124ffe04039SJerome Forissier 		case TEE_ALG_DES_CBC_NOPAD:
125ffe04039SJerome Forissier 		case TEE_ALG_DES3_CBC_NOPAD:
126ade6f848SJerome Forissier 		case TEE_ALG_SM4_ECB_NOPAD:
127ade6f848SJerome Forissier 		case TEE_ALG_SM4_CBC_NOPAD:
128ffe04039SJerome Forissier 			return TEE_ERROR_BAD_PARAMETERS;
129ffe04039SJerome Forissier 
130ffe04039SJerome Forissier 		case TEE_ALG_AES_CTR:
131ffe04039SJerome Forissier 		case TEE_ALG_AES_XTS:
132ffe04039SJerome Forissier 		case TEE_ALG_AES_CTS:
133696f56acSPingan Xie 		case TEE_ALG_SM4_XTS:
134ffe04039SJerome Forissier 			/*
135ffe04039SJerome Forissier 			 * These modes doesn't require padding for the last
136ffe04039SJerome Forissier 			 * block.
137ffe04039SJerome Forissier 			 *
138ffe04039SJerome Forissier 			 * This isn't entirely true, both XTS and CTS can only
139ffe04039SJerome Forissier 			 * encrypt minimum one block and also they need at least
140ffe04039SJerome Forissier 			 * one complete block in the last update to finish the
141ffe04039SJerome Forissier 			 * encryption. The algorithms are supposed to detect
142ffe04039SJerome Forissier 			 * that, we're only making sure that all data fed up to
143ffe04039SJerome Forissier 			 * that point consists of complete blocks.
144ffe04039SJerome Forissier 			 */
145ffe04039SJerome Forissier 			break;
146ffe04039SJerome Forissier 
147ffe04039SJerome Forissier 		default:
148ffe04039SJerome Forissier 			return TEE_ERROR_NOT_SUPPORTED;
149ffe04039SJerome Forissier 		}
150ffe04039SJerome Forissier 	}
151ffe04039SJerome Forissier 
152cbda7091SJens Wiklander 	return crypto_cipher_update(ctx, mode, last_block, data, len, dst);
153ffe04039SJerome Forissier }
15450814cf6SPascal Brand 
1554f448dffSAndy Green /*
1562a5e2ec6SAndy Green  * Override this in your platform code to feed the PRNG platform-specific
1572a5e2ec6SAndy Green  * jitter entropy. This implementation does not efficiently deliver entropy
1582a5e2ec6SAndy Green  * and is here for backwards-compatibility.
1594f448dffSAndy Green  */
plat_prng_add_jitter_entropy(enum crypto_rng_src sid,unsigned int * pnum)1606e954a6eSJens Wiklander __weak void plat_prng_add_jitter_entropy(enum crypto_rng_src sid,
1616e954a6eSJens Wiklander 					 unsigned int *pnum)
1624f448dffSAndy Green {
1632a5e2ec6SAndy Green 	TEE_Time current;
1642a5e2ec6SAndy Green 
1656e954a6eSJens Wiklander #ifdef CFG_SECURE_TIME_SOURCE_REE
1666e954a6eSJens Wiklander 	if (CRYPTO_RNG_SRC_IS_QUICK(sid))
1676e954a6eSJens Wiklander 		return; /* Can't read REE time here */
1686e954a6eSJens Wiklander #endif
1696e954a6eSJens Wiklander 
1702a5e2ec6SAndy Green 	if (tee_time_get_sys_time(&current) == TEE_SUCCESS)
1716e954a6eSJens Wiklander 		crypto_rng_add_event(sid, pnum, &current, sizeof(current));
1724f448dffSAndy Green }
1734f448dffSAndy Green 
__plat_rng_init(void)174dcb51b21SThomas Bourgoin void __plat_rng_init(void)
175b72716ceSJerome Forissier {
1766e954a6eSJens Wiklander 	TEE_Result res = TEE_SUCCESS;
1776e954a6eSJens Wiklander 	TEE_Time t;
1786e954a6eSJens Wiklander 
179b72716ceSJerome Forissier #ifndef CFG_SECURE_TIME_SOURCE_REE
1806e954a6eSJens Wiklander 	/*
1816e954a6eSJens Wiklander 	 * This isn't much of a seed. Ideally we should either get a seed from
1826e954a6eSJens Wiklander 	 * a hardware RNG or from a previously saved seed.
1836e954a6eSJens Wiklander 	 *
1846e954a6eSJens Wiklander 	 * Seeding with hardware RNG is currently up to the platform to
1856e954a6eSJens Wiklander 	 * override this function.
1866e954a6eSJens Wiklander 	 *
1876e954a6eSJens Wiklander 	 * Seeding with a saved seed will require cooperation from normal
1886e954a6eSJens Wiklander 	 * world, this is still TODO.
1896e954a6eSJens Wiklander 	 */
1906e954a6eSJens Wiklander 	res = tee_time_get_sys_time(&t);
1916e954a6eSJens Wiklander #else
1926e954a6eSJens Wiklander 	EMSG("Warning: seeding RNG with zeroes");
1936e954a6eSJens Wiklander 	memset(&t, 0, sizeof(t));
194b72716ceSJerome Forissier #endif
1956e954a6eSJens Wiklander 	if (!res)
1966e954a6eSJens Wiklander 		res = crypto_rng_init(&t, sizeof(t));
1976e954a6eSJens Wiklander 	if (res) {
1986e954a6eSJens Wiklander 		EMSG("Failed to initialize RNG: %#" PRIx32, res);
1996e954a6eSJens Wiklander 		panic();
2006e954a6eSJens Wiklander 	}
201b72716ceSJerome Forissier }
202b72716ceSJerome Forissier 
203*fbffc8adSSascha Hauer /*
204*fbffc8adSSascha Hauer  * Override this in your platform code. This default implementation only seeds
205*fbffc8adSSascha Hauer  * the random number generator from an easily predictable timestamp value or a
206*fbffc8adSSascha Hauer  * constant value. It is not suitable for a secure environment.
207*fbffc8adSSascha Hauer  */
208*fbffc8adSSascha Hauer #ifdef CFG_INSECURE
209dcb51b21SThomas Bourgoin void plat_rng_init(void) __weak __alias("__plat_rng_init");
210*fbffc8adSSascha Hauer #endif
211dcb51b21SThomas Bourgoin 
tee_cryp_init(void)212855171e1SJerome Forissier static TEE_Result tee_cryp_init(void)
21350814cf6SPascal Brand {
2146e954a6eSJens Wiklander 	TEE_Result res = crypto_init();
215855171e1SJerome Forissier 
2166e954a6eSJens Wiklander 	if (res) {
2176e954a6eSJens Wiklander 		EMSG("Failed to initialize crypto API: %#" PRIx32, res);
2186e954a6eSJens Wiklander 		panic();
2196e954a6eSJens Wiklander 	}
2206e954a6eSJens Wiklander 	plat_rng_init();
2216e954a6eSJens Wiklander 
2223de8f0deSEtienne Carriere 	dt_driver_crypt_init_complete();
2233de8f0deSEtienne Carriere 
2246e954a6eSJens Wiklander 	return TEE_SUCCESS;
2256e954a6eSJens Wiklander }
226420f1125SJens Wiklander service_init_crypto(tee_cryp_init);
227