69
69
#include <tee/tee_cryp_utl.h>
70
70
#include <utee_defines.h>
71
71
#include <util.h>
72
- #if defined(CFG_CRYPTO_DSA )
72
+ #if defined(CFG_CRYPTO_DSA ) || defined(CFG_CRYPTO_XTS ) || \
73
+ defined(CFG_CRYPTO_CTS )
73
74
#include <tomcrypt.h>
74
75
#if defined(CFG_WITH_VFP )
75
76
#include <tomcrypt_arm_neon.h>
76
77
#include <kernel/thread.h>
77
78
#endif
78
79
#endif
79
80
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
+
80
109
#if defined(CFG_CRYPTO_AES ) || defined(_CFG_CRYPTO_WITH_MAC ) \
81
110
|| defined(_CFG_CRYPTO_WITH_ACIPHER ) || defined(CFG_CRYPTO_ECC )
82
111
/* Translate mbedtls result to TEE result */
@@ -1913,6 +1942,37 @@ TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key,
1913
1942
* Symmetric ciphers
1914
1943
******************************************************************************/
1915
1944
#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
1916
1976
1917
1977
static TEE_Result cipher_get_ctx_size (uint32_t algo , size_t * size )
1918
1978
{
@@ -1934,11 +1994,13 @@ static TEE_Result cipher_get_ctx_size(uint32_t algo, size_t *size)
1934
1994
#endif
1935
1995
#if defined(CFG_CRYPTO_XTS )
1936
1996
case TEE_ALG_AES_XTS :
1937
- return TEE_ERROR_NOT_SUPPORTED ;
1997
+ * size = sizeof (struct tee_symmetric_xts );
1998
+ break ;
1938
1999
#endif
1939
2000
#if defined(CFG_CRYPTO_CTS )
1940
2001
case TEE_ALG_AES_CTS :
1941
- return TEE_ERROR_NOT_SUPPORTED ;
2002
+ * size = sizeof (struct tee_symmetric_cts );
2003
+ break ;
1942
2004
#endif
1943
2005
#if defined(CFG_CRYPTO_ECB )
1944
2006
case TEE_ALG_DES_ECB_NOPAD :
@@ -1991,11 +2053,11 @@ TEE_Result crypto_cipher_alloc_ctx(void **ctx_ret, uint32_t algo)
1991
2053
#endif
1992
2054
#if defined(CFG_CRYPTO_XTS )
1993
2055
case TEE_ALG_AES_XTS :
1994
- return TEE_ERROR_NOT_SUPPORTED ;
2056
+ break ;
1995
2057
#endif
1996
2058
#if defined(CFG_CRYPTO_CTS )
1997
2059
case TEE_ALG_AES_CTS :
1998
- return TEE_ERROR_NOT_SUPPORTED ;
2060
+ break ;
1999
2061
#endif
2000
2062
#if defined(CFG_CRYPTO_ECB )
2001
2063
case TEE_ALG_DES_ECB_NOPAD :
@@ -2019,7 +2081,7 @@ TEE_Result crypto_cipher_alloc_ctx(void **ctx_ret, uint32_t algo)
2019
2081
return TEE_ERROR_NOT_SUPPORTED ;
2020
2082
}
2021
2083
2022
- if (!cipher_info )
2084
+ if (algo != TEE_ALG_AES_XTS && algo != TEE_ALG_AES_CTS && !cipher_info )
2023
2085
return TEE_ERROR_NOT_SUPPORTED ;
2024
2086
2025
2087
res = cipher_get_ctx_size (algo , & ctx_size );
@@ -2030,6 +2092,10 @@ TEE_Result crypto_cipher_alloc_ctx(void **ctx_ret, uint32_t algo)
2030
2092
if (!ctx )
2031
2093
return TEE_ERROR_OUT_OF_MEMORY ;
2032
2094
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
2033
2099
mbedtls_cipher_init (ctx );
2034
2100
2035
2101
lmd_res = mbedtls_cipher_setup (ctx , cipher_info );
@@ -2043,7 +2109,7 @@ TEE_Result crypto_cipher_alloc_ctx(void **ctx_ret, uint32_t algo)
2043
2109
return TEE_SUCCESS ;
2044
2110
}
2045
2111
2046
- void crypto_cipher_free_ctx (void * ctx , uint32_t algo __maybe_unused )
2112
+ void crypto_cipher_free_ctx (void * ctx , uint32_t algo )
2047
2113
{
2048
2114
size_t ctx_size __maybe_unused ;
2049
2115
@@ -2052,13 +2118,25 @@ void crypto_cipher_free_ctx(void *ctx, uint32_t algo __maybe_unused)
2052
2118
* could never have succeded above.
2053
2119
*/
2054
2120
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 );
2056
2123
free (ctx );
2057
2124
}
2058
2125
2059
2126
void crypto_cipher_copy_state (void * dst_ctx , void * src_ctx ,
2060
2127
uint32_t algo __unused )
2061
2128
{
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
2062
2140
if (mbedtls_cipher_clone (dst_ctx , src_ctx ) != 0 )
2063
2141
panic ();
2064
2142
}
@@ -2074,6 +2152,50 @@ TEE_Result crypto_cipher_init(void *ctx, uint32_t algo,
2074
2152
const mbedtls_cipher_info_t * cipher_info = NULL ;
2075
2153
int lmd_res ;
2076
2154
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
2077
2199
2078
2200
if (!ctx )
2079
2201
return TEE_ERROR_BAD_PARAMETERS ;
@@ -2130,6 +2252,9 @@ TEE_Result crypto_cipher_update(void *ctx, uint32_t algo,
2130
2252
int lmd_res ;
2131
2253
size_t olen ;
2132
2254
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 ;
2133
2258
2134
2259
if (!ctx )
2135
2260
return TEE_ERROR_BAD_PARAMETERS ;
@@ -2195,11 +2320,25 @@ TEE_Result crypto_cipher_update(void *ctx, uint32_t algo,
2195
2320
#endif
2196
2321
#if defined(CFG_CRYPTO_XTS )
2197
2322
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 ;
2199
2335
#endif
2200
2336
#if defined(CFG_CRYPTO_CTS )
2201
2337
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 );
2203
2342
#endif
2204
2343
default :
2205
2344
return TEE_ERROR_NOT_SUPPORTED ;
@@ -2215,6 +2354,19 @@ TEE_Result crypto_cipher_update(void *ctx, uint32_t algo,
2215
2354
2216
2355
void crypto_cipher_final (void * ctx __unused , uint32_t algo __unused )
2217
2356
{
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
2218
2370
}
2219
2371
#endif /* _CFG_CRYPTO_WITH_CIPHER */
2220
2372
0 commit comments