Skip to content

Commit b936fa9

Browse files
author
Edison Ai
committed
libmbedtls: Support cipher CTS and XTS algorithm
Cipher CTS and XTS are not supported in MbedTLS, call libtomcrypt directly. Signed-off-by: Edison Ai <[email protected]>
1 parent 7ce9f54 commit b936fa9

File tree

2 files changed

+164
-11
lines changed

2 files changed

+164
-11
lines changed

lib/libmbedtls/core/sub.mk

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ cflags-lib-$(CFG_CRYPTO_SIZE_OPTIMIZATION) += -Os
22

33
srcs-y += tee_lmd_provider.c
44

5-
ifneq (,$(filter y, $(CFG_CRYPTO_DSA)))
5+
ifneq (,$(filter y, $(CFG_CRYPTO_DSA) $(CFG_CRYPTO_CTR) $(CFG_CRYPTO_XTS)))
66

77
ifeq ($(CFG_CRYPTO_DSA),y)
88
CFG_MBEDTLS_WITH_TOMCRYPT := y
@@ -16,5 +16,6 @@ srcs-$(CFG_CRYPTO_DSA) += $(TOMCRYPTO_LIB_PATH)/src/mpi_desc.c
1616
subdirs-y += $(TOMCRYPTO_LIB_PATH)/src/hashes
1717
subdirs-$(_CFG_CRYPTO_WITH_ACIPHER) += $(TOMCRYPTO_LIB_PATH)/src/math
1818
subdirs-y += $(TOMCRYPTO_LIB_PATH)/src/misc
19+
subdirs-y += $(TOMCRYPTO_LIB_PATH)/src/modes
1920
subdirs-$(_CFG_CRYPTO_WITH_ACIPHER) += $(TOMCRYPTO_LIB_PATH)/src/pk
2021
endif

lib/libmbedtls/core/tee_lmd_provider.c

+162-10
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,43 @@
6969
#include <tee/tee_cryp_utl.h>
7070
#include <utee_defines.h>
7171
#include <util.h>
72-
#if defined(CFG_CRYPTO_DSA)
72+
#if defined(CFG_CRYPTO_DSA) || defined(CFG_CRYPTO_XTS) || \
73+
defined(CFG_CRYPTO_CTS)
7374
#include <tomcrypt.h>
7475
#if defined(CFG_WITH_VFP)
7576
#include <tomcrypt_arm_neon.h>
7677
#include <kernel/thread.h>
7778
#endif
7879
#endif
7980

81+
#if defined(CFG_CRYPTO_XTS) || defined(CFG_CRYPTO_CTS)
82+
/*
83+
* Compute the LibTomCrypt "cipherindex" given a TEE Algorithm "algo"
84+
* Return
85+
* - TEE_SUCCESS in case of success,
86+
* - TEE_ERROR_BAD_PARAMETERS in case algo is not a valid algo
87+
* - TEE_ERROR_NOT_SUPPORTED in case algo is not supported by LTC
88+
* Return -1 in case of error
89+
*/
90+
static TEE_Result tee_algo_to_ltc_cipherindex(uint32_t algo,
91+
int *ltc_cipherindex)
92+
{
93+
switch (algo) {
94+
case TEE_ALG_AES_CTS:
95+
case TEE_ALG_AES_XTS:
96+
*ltc_cipherindex = find_cipher("aes");
97+
break;
98+
default:
99+
return TEE_ERROR_BAD_PARAMETERS;
100+
}
101+
102+
if (*ltc_cipherindex < 0)
103+
return TEE_ERROR_NOT_SUPPORTED;
104+
else
105+
return TEE_SUCCESS;
106+
}
107+
#endif /* defined(CFG_CRYPTO_XTS) || defined(CFG_CRYPTO_CTS) */
108+
80109
#if defined(CFG_CRYPTO_AES) || defined(_CFG_CRYPTO_WITH_MAC) \
81110
|| defined(_CFG_CRYPTO_WITH_ACIPHER) || defined(CFG_CRYPTO_ECC)
82111
/* Translate mbedtls result to TEE result */
@@ -1913,6 +1942,37 @@ TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key,
19131942
* Symmetric ciphers
19141943
******************************************************************************/
19151944
#if defined(_CFG_CRYPTO_WITH_CIPHER)
1945+
/* From libtomcrypt doc:
1946+
* Ciphertext stealing is a method of dealing with messages
1947+
* in CBC mode which are not a multiple of the block
1948+
* length. This is accomplished by encrypting the last
1949+
* ciphertext block in ECB mode, and XOR'ing the output
1950+
* against the last partial block of plaintext. LibTomCrypt
1951+
* does not support this mode directly but it is fairly
1952+
* easy to emulate with a call to the cipher's
1953+
* ecb encrypt() callback function.
1954+
* The more sane way to deal with partial blocks is to pad
1955+
* them with zeroes, and then use CBC normally
1956+
*/
1957+
1958+
/*
1959+
* From Global Platform: CTS = CBC-CS3
1960+
*/
1961+
1962+
#if defined(CFG_CRYPTO_CTS)
1963+
struct tee_symmetric_cts {
1964+
symmetric_ECB ecb;
1965+
symmetric_CBC cbc;
1966+
};
1967+
#endif
1968+
1969+
#if defined(CFG_CRYPTO_XTS)
1970+
#define XTS_TWEAK_SIZE 16
1971+
struct tee_symmetric_xts {
1972+
symmetric_xts ctx;
1973+
uint8_t tweak[XTS_TWEAK_SIZE];
1974+
};
1975+
#endif
19161976

19171977
static TEE_Result cipher_get_ctx_size(uint32_t algo, size_t *size)
19181978
{
@@ -1934,11 +1994,13 @@ static TEE_Result cipher_get_ctx_size(uint32_t algo, size_t *size)
19341994
#endif
19351995
#if defined(CFG_CRYPTO_XTS)
19361996
case TEE_ALG_AES_XTS:
1937-
return TEE_ERROR_NOT_SUPPORTED;
1997+
*size = sizeof(struct tee_symmetric_xts);
1998+
break;
19381999
#endif
19392000
#if defined(CFG_CRYPTO_CTS)
19402001
case TEE_ALG_AES_CTS:
1941-
return TEE_ERROR_NOT_SUPPORTED;
2002+
*size = sizeof(struct tee_symmetric_cts);
2003+
break;
19422004
#endif
19432005
#if defined(CFG_CRYPTO_ECB)
19442006
case TEE_ALG_DES_ECB_NOPAD:
@@ -1991,11 +2053,11 @@ TEE_Result crypto_cipher_alloc_ctx(void **ctx_ret, uint32_t algo)
19912053
#endif
19922054
#if defined(CFG_CRYPTO_XTS)
19932055
case TEE_ALG_AES_XTS:
1994-
return TEE_ERROR_NOT_SUPPORTED;
2056+
break;
19952057
#endif
19962058
#if defined(CFG_CRYPTO_CTS)
19972059
case TEE_ALG_AES_CTS:
1998-
return TEE_ERROR_NOT_SUPPORTED;
2060+
break;
19992061
#endif
20002062
#if defined(CFG_CRYPTO_ECB)
20012063
case TEE_ALG_DES_ECB_NOPAD:
@@ -2019,7 +2081,7 @@ TEE_Result crypto_cipher_alloc_ctx(void **ctx_ret, uint32_t algo)
20192081
return TEE_ERROR_NOT_SUPPORTED;
20202082
}
20212083

2022-
if (!cipher_info)
2084+
if (algo != TEE_ALG_AES_XTS && algo != TEE_ALG_AES_CTS && !cipher_info)
20232085
return TEE_ERROR_NOT_SUPPORTED;
20242086

20252087
res = cipher_get_ctx_size(algo, &ctx_size);
@@ -2030,6 +2092,10 @@ TEE_Result crypto_cipher_alloc_ctx(void **ctx_ret, uint32_t algo)
20302092
if (!ctx)
20312093
return TEE_ERROR_OUT_OF_MEMORY;
20322094

2095+
#if defined(CFG_CRYPTO_XTS) || defined(CFG_CRYPTO_CTS)
2096+
if (algo == TEE_ALG_AES_XTS || algo == TEE_ALG_AES_CTS)
2097+
return TEE_SUCCESS;
2098+
#endif
20332099
mbedtls_cipher_init(ctx);
20342100

20352101
lmd_res = mbedtls_cipher_setup(ctx, cipher_info);
@@ -2043,7 +2109,7 @@ TEE_Result crypto_cipher_alloc_ctx(void **ctx_ret, uint32_t algo)
20432109
return TEE_SUCCESS;
20442110
}
20452111

2046-
void crypto_cipher_free_ctx(void *ctx, uint32_t algo __maybe_unused)
2112+
void crypto_cipher_free_ctx(void *ctx, uint32_t algo)
20472113
{
20482114
size_t ctx_size __maybe_unused;
20492115

@@ -2052,13 +2118,25 @@ void crypto_cipher_free_ctx(void *ctx, uint32_t algo __maybe_unused)
20522118
* could never have succeded above.
20532119
*/
20542120
assert(!cipher_get_ctx_size(algo, &ctx_size));
2055-
mbedtls_cipher_free(ctx);
2121+
if (algo != TEE_ALG_AES_XTS && algo != TEE_ALG_AES_CTS)
2122+
mbedtls_cipher_free(ctx);
20562123
free(ctx);
20572124
}
20582125

20592126
void crypto_cipher_copy_state(void *dst_ctx, void *src_ctx,
20602127
uint32_t algo __unused)
20612128
{
2129+
TEE_Result res __maybe_unused;
2130+
size_t ctx_size __maybe_unused;
2131+
2132+
#if defined(CFG_CRYPTO_XTS) || defined(CFG_CRYPTO_CTS)
2133+
if (algo == TEE_ALG_AES_XTS || algo == TEE_ALG_AES_CTS) {
2134+
res = cipher_get_ctx_size(algo, &ctx_size);
2135+
assert(!res);
2136+
memcpy(dst_ctx, src_ctx, ctx_size);
2137+
return;
2138+
}
2139+
#endif
20622140
if (mbedtls_cipher_clone(dst_ctx, src_ctx) != 0)
20632141
panic();
20642142
}
@@ -2074,6 +2152,50 @@ TEE_Result crypto_cipher_init(void *ctx, uint32_t algo,
20742152
const mbedtls_cipher_info_t *cipher_info = NULL;
20752153
int lmd_res;
20762154
int lmd_mode;
2155+
TEE_Result res __maybe_unused;
2156+
int ltc_res __maybe_unused;
2157+
int ltc_cipherindex __maybe_unused;
2158+
2159+
#if defined(CFG_CRYPTO_CTS)
2160+
if (algo == TEE_ALG_AES_CTS) {
2161+
struct tee_symmetric_cts *cts = ctx;
2162+
2163+
res = crypto_cipher_init((void *)(&(cts->ecb)),
2164+
TEE_ALG_AES_ECB_NOPAD, mode, key1,
2165+
key1_len, key2, key2_len, iv, iv_len);
2166+
if (res != TEE_SUCCESS)
2167+
return res;
2168+
res = crypto_cipher_init((void *)(&(cts->cbc)),
2169+
TEE_ALG_AES_CBC_NOPAD, mode, key1,
2170+
key1_len, key2, key2_len, iv, iv_len);
2171+
return res;
2172+
}
2173+
#endif
2174+
#if defined(CFG_CRYPTO_XTS)
2175+
if (algo == TEE_ALG_AES_XTS) {
2176+
struct tee_symmetric_xts *xts = ctx;
2177+
2178+
res = tee_algo_to_ltc_cipherindex(algo, &ltc_cipherindex);
2179+
if (res != TEE_SUCCESS)
2180+
return TEE_ERROR_NOT_SUPPORTED;
2181+
2182+
if (key1_len != key2_len)
2183+
return TEE_ERROR_BAD_PARAMETERS;
2184+
if (iv) {
2185+
if (iv_len != XTS_TWEAK_SIZE)
2186+
return TEE_ERROR_BAD_PARAMETERS;
2187+
memcpy(xts->tweak, iv, iv_len);
2188+
} else {
2189+
memset(xts->tweak, 0, XTS_TWEAK_SIZE);
2190+
}
2191+
ltc_res = xts_start(ltc_cipherindex, key1, key2, key1_len,
2192+
0, &xts->ctx);
2193+
if (ltc_res == CRYPT_OK)
2194+
return TEE_SUCCESS;
2195+
else
2196+
return TEE_ERROR_BAD_STATE;
2197+
}
2198+
#endif
20772199

20782200
if (!ctx)
20792201
return TEE_ERROR_BAD_PARAMETERS;
@@ -2130,6 +2252,9 @@ TEE_Result crypto_cipher_update(void *ctx, uint32_t algo,
21302252
int lmd_res;
21312253
size_t olen;
21322254
size_t finish_olen;
2255+
struct tee_symmetric_xts *xts __maybe_unused;
2256+
struct tee_symmetric_cts *cts __maybe_unused;
2257+
int ltc_res __maybe_unused;
21332258

21342259
if (!ctx)
21352260
return TEE_ERROR_BAD_PARAMETERS;
@@ -2195,11 +2320,25 @@ TEE_Result crypto_cipher_update(void *ctx, uint32_t algo,
21952320
#endif
21962321
#if defined(CFG_CRYPTO_XTS)
21972322
case TEE_ALG_AES_XTS:
2198-
return TEE_ERROR_NOT_SUPPORTED;
2323+
xts = ctx;
2324+
2325+
if (mode == TEE_MODE_ENCRYPT)
2326+
ltc_res = xts_encrypt(data, len, dst, xts->tweak,
2327+
&xts->ctx);
2328+
else
2329+
ltc_res = xts_decrypt(data, len, dst, xts->tweak,
2330+
&xts->ctx);
2331+
if (ltc_res == CRYPT_OK)
2332+
return TEE_SUCCESS;
2333+
else
2334+
return TEE_ERROR_BAD_STATE;
21992335
#endif
22002336
#if defined(CFG_CRYPTO_CTS)
22012337
case TEE_ALG_AES_CTS:
2202-
return TEE_ERROR_NOT_SUPPORTED;
2338+
cts = ctx;
2339+
2340+
return tee_aes_cbc_cts_update(&cts->cbc, &cts->ecb, mode,
2341+
last_block, data, len, dst);
22032342
#endif
22042343
default:
22052344
return TEE_ERROR_NOT_SUPPORTED;
@@ -2215,6 +2354,19 @@ TEE_Result crypto_cipher_update(void *ctx, uint32_t algo,
22152354

22162355
void crypto_cipher_final(void *ctx __unused, uint32_t algo __unused)
22172356
{
2357+
#if defined(CFG_CRYPTO_XTS)
2358+
if (algo == TEE_ALG_AES_XTS) {
2359+
xts_done(&(((struct tee_symmetric_xts *)ctx)->ctx));
2360+
return;
2361+
}
2362+
#endif
2363+
#if defined(CFG_CRYPTO_CTS)
2364+
if (algo == TEE_ALG_AES_CTS) {
2365+
cbc_done(&(((struct tee_symmetric_cts *)ctx)->cbc));
2366+
ecb_done(&(((struct tee_symmetric_cts *)ctx)->ecb));
2367+
return;
2368+
}
2369+
#endif
22182370
}
22192371
#endif /* _CFG_CRYPTO_WITH_CIPHER */
22202372

0 commit comments

Comments
 (0)