Skip to content

Commit fcc6a08

Browse files
author
Edison Ai
committed
libmbedtls: Support CBC MAC algorithm
CBC MAC supported in MbedTLS, implement is by using cipher. Signed-off-by: Edison Ai <[email protected]>
1 parent b936fa9 commit fcc6a08

File tree

2 files changed

+208
-10
lines changed

2 files changed

+208
-10
lines changed

lib/libmbedtls/core/sub.mk

+1-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) $(CFG_CRYPTO_CTR) $(CFG_CRYPTO_XTS)))
5+
ifneq (,$(filter y, $(CFG_CRYPTO_DSA) $(CFG_CRYPTO_CTR) $(CFG_CRYPTO_XTS) $(CFG_CRYPTO_CBC_MAC)))
66

77
ifeq ($(CFG_CRYPTO_DSA),y)
88
CFG_MBEDTLS_WITH_TOMCRYPT := y

lib/libmbedtls/core/tee_lmd_provider.c

+207-9
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,20 @@ static const mbedtls_cipher_info_t *get_cipher_info(uint32_t algo,
217217
case TEE_ALG_AES_XTS:
218218
case TEE_ALG_AES_CCM:
219219
case TEE_ALG_AES_GCM:
220+
return NULL;
220221
case TEE_ALG_AES_CBC_MAC_NOPAD:
221222
case TEE_ALG_AES_CBC_MAC_PKCS5:
222-
return NULL;
223+
if (key_len == 128)
224+
return mbedtls_cipher_info_from_type(
225+
MBEDTLS_CIPHER_AES_128_CBC);
226+
else if (key_len == 192)
227+
return mbedtls_cipher_info_from_type(
228+
MBEDTLS_CIPHER_AES_192_CBC);
229+
else if (key_len == 256)
230+
return mbedtls_cipher_info_from_type(
231+
MBEDTLS_CIPHER_AES_256_CBC);
232+
else
233+
return NULL;
223234
#endif
224235
#if defined(CFG_CRYPTO_DES)
225236
case TEE_ALG_DES_ECB_NOPAD:
@@ -230,7 +241,8 @@ static const mbedtls_cipher_info_t *get_cipher_info(uint32_t algo,
230241
return NULL;
231242
case TEE_ALG_DES_CBC_MAC_NOPAD:
232243
case TEE_ALG_DES_CBC_MAC_PKCS5:
233-
return NULL;
244+
return mbedtls_cipher_info_from_type(
245+
MBEDTLS_CIPHER_DES_CBC);
234246
case TEE_ALG_DES_CBC_NOPAD:
235247
if (key_len == 64)
236248
return mbedtls_cipher_info_from_type(
@@ -248,7 +260,8 @@ static const mbedtls_cipher_info_t *get_cipher_info(uint32_t algo,
248260
return NULL;
249261
case TEE_ALG_DES3_CBC_MAC_NOPAD:
250262
case TEE_ALG_DES3_CBC_MAC_PKCS5:
251-
return NULL;
263+
return mbedtls_cipher_info_from_type(
264+
MBEDTLS_CIPHER_DES_EDE3_CBC);
252265
case TEE_ALG_DES3_CBC_NOPAD:
253266
if (key_len == 128)
254267
return mbedtls_cipher_info_from_type(
@@ -2374,6 +2387,46 @@ void crypto_cipher_final(void *ctx __unused, uint32_t algo __unused)
23742387
* Message Authentication Code functions
23752388
*****************************************************************************/
23762389
#if defined(_CFG_CRYPTO_WITH_MAC)
2390+
2391+
#if defined(CFG_CRYPTO_CBC_MAC)
2392+
/*
2393+
* CBC-MAC is not implemented in mbedtls
2394+
* This is implemented here as being the plain text which is encoded with IV=0.
2395+
* Result of the CBC-MAC is the last 16-bytes cipher.
2396+
*/
2397+
2398+
#define CBCMAC_MAX_BLOCK_LEN 16
2399+
struct cbc_state {
2400+
mbedtls_cipher_context_t ctx;
2401+
uint8_t block[CBCMAC_MAX_BLOCK_LEN];
2402+
uint8_t digest[CBCMAC_MAX_BLOCK_LEN];
2403+
size_t current_block_len, block_len;
2404+
int is_computed;
2405+
};
2406+
2407+
static void get_des2_key(const uint8_t *key, size_t key_len,
2408+
uint8_t *key_intermediate,
2409+
uint8_t **real_key, size_t *real_key_len)
2410+
{
2411+
if (key_len == 16) {
2412+
/*
2413+
* This corresponds to a 2DES key. The 2DES encryption
2414+
* algorithm is similar to 3DES. Both perform and
2415+
* encryption step, then a decryption step, followed
2416+
* by another encryption step (EDE). However 2DES uses
2417+
* the same key for both of the encryption (E) steps.
2418+
*/
2419+
memcpy(key_intermediate, key, 16);
2420+
memcpy(key_intermediate+16, key, 8);
2421+
*real_key = key_intermediate;
2422+
*real_key_len = 24;
2423+
} else {
2424+
*real_key = (uint8_t *)key;
2425+
*real_key_len = key_len;
2426+
}
2427+
}
2428+
#endif
2429+
23772430
static TEE_Result mac_get_ctx_size(uint32_t algo, size_t *size)
23782431
{
23792432
switch (algo) {
@@ -2394,7 +2447,8 @@ static TEE_Result mac_get_ctx_size(uint32_t algo, size_t *size)
23942447
case TEE_ALG_DES_CBC_MAC_PKCS5:
23952448
case TEE_ALG_DES3_CBC_MAC_NOPAD:
23962449
case TEE_ALG_DES3_CBC_MAC_PKCS5:
2397-
return TEE_ERROR_NOT_SUPPORTED;
2450+
*size = sizeof(struct cbc_state);
2451+
break;
23982452
#endif
23992453
#if defined(CFG_CRYPTO_CMAC)
24002454
case TEE_ALG_AES_CMAC:
@@ -2456,8 +2510,19 @@ TEE_Result crypto_mac_alloc_ctx(void **ctx_ret, uint32_t algo)
24562510
case TEE_ALG_DES_CBC_MAC_PKCS5:
24572511
case TEE_ALG_DES3_CBC_MAC_NOPAD:
24582512
case TEE_ALG_DES3_CBC_MAC_PKCS5:
2459-
res = TEE_ERROR_NOT_SUPPORTED;
2460-
goto err;
2513+
cipher_info = get_cipher_info(algo, 128);
2514+
if (!cipher_info) {
2515+
res = TEE_ERROR_NOT_SUPPORTED;
2516+
goto err;
2517+
}
2518+
mbedtls_cipher_init(ctx);
2519+
lmd_res = mbedtls_cipher_setup(ctx, cipher_info);
2520+
if (lmd_res != 0) {
2521+
FMSG("cipher setup failed, res is 0x%x", -lmd_res);
2522+
res = get_tee_result(lmd_res);
2523+
goto err;
2524+
}
2525+
break;
24612526
#endif
24622527
#if defined(CFG_CRYPTO_CMAC)
24632528
case TEE_ALG_AES_CMAC:
@@ -2529,6 +2594,7 @@ void crypto_mac_free_ctx(void *ctx, uint32_t algo __maybe_unused)
25292594
case TEE_ALG_DES_CBC_MAC_PKCS5:
25302595
case TEE_ALG_DES3_CBC_MAC_NOPAD:
25312596
case TEE_ALG_DES3_CBC_MAC_PKCS5:
2597+
mbedtls_cipher_free(ctx);
25322598
break;
25332599
#endif
25342600
#if defined(CFG_CRYPTO_CMAC)
@@ -2545,6 +2611,8 @@ void crypto_mac_free_ctx(void *ctx, uint32_t algo __maybe_unused)
25452611
void crypto_mac_copy_state(void *dst_ctx, void *src_ctx, uint32_t algo)
25462612
{
25472613
int lmd_res __maybe_unused;
2614+
struct cbc_state *dst_cbc __maybe_unused;
2615+
struct cbc_state *src_cbc __maybe_unused;
25482616

25492617
switch (algo) {
25502618
#if defined(CFG_CRYPTO_HMAC)
@@ -2568,6 +2636,18 @@ void crypto_mac_copy_state(void *dst_ctx, void *src_ctx, uint32_t algo)
25682636
case TEE_ALG_DES_CBC_MAC_PKCS5:
25692637
case TEE_ALG_DES3_CBC_MAC_NOPAD:
25702638
case TEE_ALG_DES3_CBC_MAC_PKCS5:
2639+
dst_cbc = dst_ctx;
2640+
src_cbc = src_ctx;
2641+
memcpy(dst_cbc->block, src_cbc->block, CBCMAC_MAX_BLOCK_LEN);
2642+
memcpy(dst_cbc->digest, src_cbc->digest, CBCMAC_MAX_BLOCK_LEN);
2643+
dst_cbc->current_block_len = src_cbc->current_block_len;
2644+
dst_cbc->block_len = src_cbc->block_len;
2645+
dst_cbc->is_computed = src_cbc->is_computed;
2646+
lmd_res = mbedtls_cipher_clone(&dst_cbc->ctx, &src_cbc->ctx);
2647+
if (lmd_res != 0) {
2648+
FMSG("cmac clone failed, res is 0x%x", -lmd_res);
2649+
panic();
2650+
}
25712651
break;
25722652
#endif
25732653
#if defined(CFG_CRYPTO_CMAC)
@@ -2589,6 +2669,11 @@ TEE_Result crypto_mac_init(void *ctx, uint32_t algo, const uint8_t *key,
25892669
{
25902670
int lmd_res __maybe_unused;
25912671
const mbedtls_cipher_info_t *cipher_info __maybe_unused;
2672+
uint8_t *real_key __maybe_unused;
2673+
uint8_t key_array[24] __maybe_unused;
2674+
size_t real_key_len __maybe_unused;
2675+
uint8_t iv[CBCMAC_MAX_BLOCK_LEN] __maybe_unused;
2676+
struct cbc_state *cbc __maybe_unused;
25922677

25932678
if (!ctx)
25942679
return TEE_ERROR_BAD_PARAMETERS;
@@ -2620,7 +2705,49 @@ TEE_Result crypto_mac_init(void *ctx, uint32_t algo, const uint8_t *key,
26202705
case TEE_ALG_DES_CBC_MAC_PKCS5:
26212706
case TEE_ALG_DES3_CBC_MAC_NOPAD:
26222707
case TEE_ALG_DES3_CBC_MAC_PKCS5:
2623-
return TEE_ERROR_NOT_SUPPORTED;
2708+
cbc = (struct cbc_state *)ctx;
2709+
2710+
/* Re-set the cipher info according the really key length. */
2711+
cipher_info = get_cipher_info(algo, len * 8);
2712+
if (!cipher_info)
2713+
return TEE_ERROR_NOT_SUPPORTED;
2714+
2715+
lmd_res = mbedtls_cipher_setup_info(&cbc->ctx, cipher_info);
2716+
if (lmd_res != 0) {
2717+
FMSG("setup info failed, res is 0x%x", -lmd_res);
2718+
return get_tee_result(lmd_res);
2719+
}
2720+
2721+
cbc->block_len = mbedtls_cipher_get_block_size(&cbc->ctx);
2722+
if (CBCMAC_MAX_BLOCK_LEN < cbc->block_len)
2723+
return TEE_ERROR_BAD_PARAMETERS;
2724+
memset(iv, 0, cbc->block_len);
2725+
2726+
if (algo == TEE_ALG_DES3_CBC_MAC_NOPAD ||
2727+
algo == TEE_ALG_DES3_CBC_MAC_PKCS5) {
2728+
get_des2_key(key, len, key_array,
2729+
&real_key, &real_key_len);
2730+
key = real_key;
2731+
len = real_key_len;
2732+
}
2733+
2734+
lmd_res = mbedtls_cipher_setkey(&cbc->ctx, key, len * 8,
2735+
MBEDTLS_ENCRYPT);
2736+
if (lmd_res != 0) {
2737+
FMSG("setkey failed, res is 0x%x", -lmd_res);
2738+
return get_tee_result(lmd_res);
2739+
}
2740+
2741+
lmd_res = mbedtls_cipher_reset(&cbc->ctx);
2742+
if (lmd_res != 0) {
2743+
FMSG("mbedtls_cipher_reset failed, res is 0x%x",
2744+
-lmd_res);
2745+
return get_tee_result(lmd_res);
2746+
}
2747+
2748+
cbc->is_computed = 0;
2749+
cbc->current_block_len = 0;
2750+
break;
26242751
#endif
26252752
#if defined(CFG_CRYPTO_CMAC)
26262753
case TEE_ALG_AES_CMAC:
@@ -2658,6 +2785,9 @@ TEE_Result crypto_mac_update(void *ctx, uint32_t algo, const uint8_t *data,
26582785
size_t len)
26592786
{
26602787
int lmd_res __maybe_unused;
2788+
struct cbc_state *cbc __maybe_unused;
2789+
size_t pad_len __maybe_unused;
2790+
size_t olen __maybe_unused;
26612791

26622792
if (!data || !len)
26632793
return TEE_SUCCESS;
@@ -2684,7 +2814,42 @@ TEE_Result crypto_mac_update(void *ctx, uint32_t algo, const uint8_t *data,
26842814
case TEE_ALG_DES_CBC_MAC_PKCS5:
26852815
case TEE_ALG_DES3_CBC_MAC_NOPAD:
26862816
case TEE_ALG_DES3_CBC_MAC_PKCS5:
2687-
return TEE_ERROR_NOT_SUPPORTED;
2817+
cbc = ctx;
2818+
2819+
if ((cbc->current_block_len > 0) &&
2820+
(len + cbc->current_block_len >= cbc->block_len)) {
2821+
pad_len = cbc->block_len - cbc->current_block_len;
2822+
memcpy(cbc->block + cbc->current_block_len,
2823+
data, pad_len);
2824+
data += pad_len;
2825+
len -= pad_len;
2826+
lmd_res = mbedtls_cipher_update(&cbc->ctx, cbc->block,
2827+
cbc->block_len,
2828+
cbc->digest, &olen);
2829+
if (lmd_res != 0) {
2830+
FMSG("update failed, res is 0x%x", -lmd_res);
2831+
return get_tee_result(lmd_res);
2832+
}
2833+
cbc->is_computed = 1;
2834+
}
2835+
2836+
while (len >= cbc->block_len) {
2837+
lmd_res = mbedtls_cipher_update(&cbc->ctx, cbc->block,
2838+
cbc->block_len,
2839+
cbc->digest, &olen);
2840+
if (lmd_res != 0) {
2841+
FMSG("update failed, res is 0x%x", -lmd_res);
2842+
return get_tee_result(lmd_res);
2843+
}
2844+
cbc->is_computed = 1;
2845+
data += cbc->block_len;
2846+
len -= cbc->block_len;
2847+
}
2848+
2849+
if (len > 0)
2850+
memcpy(cbc->block, data, len);
2851+
cbc->current_block_len = len;
2852+
break;
26882853
#endif
26892854
#if defined(CFG_CRYPTO_CMAC)
26902855
case TEE_ALG_AES_CMAC:
@@ -2708,6 +2873,9 @@ TEE_Result crypto_mac_final(void *ctx, uint32_t algo, uint8_t *digest,
27082873
int lmd_res __maybe_unused;
27092874
size_t block_size __maybe_unused;
27102875
mbedtls_md_context_t *md_ctx __maybe_unused;
2876+
struct cbc_state *cbc __maybe_unused;
2877+
size_t pad_len __maybe_unused;
2878+
size_t olen __maybe_unused;
27112879

27122880
switch (algo) {
27132881
#if defined(CFG_CRYPTO_HMAC)
@@ -2735,7 +2903,37 @@ TEE_Result crypto_mac_final(void *ctx, uint32_t algo, uint8_t *digest,
27352903
case TEE_ALG_DES_CBC_MAC_PKCS5:
27362904
case TEE_ALG_DES3_CBC_MAC_NOPAD:
27372905
case TEE_ALG_DES3_CBC_MAC_PKCS5:
2738-
return TEE_ERROR_NOT_SUPPORTED;
2906+
cbc = (struct cbc_state *)ctx;
2907+
2908+
/* Padding is required */
2909+
switch (algo) {
2910+
case TEE_ALG_AES_CBC_MAC_PKCS5:
2911+
case TEE_ALG_DES_CBC_MAC_PKCS5:
2912+
case TEE_ALG_DES3_CBC_MAC_PKCS5:
2913+
/*
2914+
* Padding is in whole bytes. The value of each added
2915+
* byte is the number of bytes that are added, i.e. N
2916+
* bytes, each of value N are added
2917+
*/
2918+
pad_len = cbc->block_len - cbc->current_block_len;
2919+
memset(cbc->block + cbc->current_block_len,
2920+
pad_len, pad_len);
2921+
cbc->current_block_len = 0;
2922+
if (TEE_SUCCESS != crypto_mac_update(ctx, algo,
2923+
cbc->block,
2924+
cbc->block_len))
2925+
return TEE_ERROR_BAD_STATE;
2926+
break;
2927+
default:
2928+
/* nothing to do */
2929+
break;
2930+
}
2931+
2932+
if ((!cbc->is_computed) || (cbc->current_block_len != 0))
2933+
return TEE_ERROR_BAD_STATE;
2934+
2935+
memcpy(digest, cbc->digest, MIN(digest_len, cbc->block_len));
2936+
break;
27392937
#endif
27402938
#if defined(CFG_CRYPTO_CMAC)
27412939
case TEE_ALG_AES_CMAC:

0 commit comments

Comments
 (0)