@@ -217,9 +217,20 @@ static const mbedtls_cipher_info_t *get_cipher_info(uint32_t algo,
217
217
case TEE_ALG_AES_XTS :
218
218
case TEE_ALG_AES_CCM :
219
219
case TEE_ALG_AES_GCM :
220
+ return NULL ;
220
221
case TEE_ALG_AES_CBC_MAC_NOPAD :
221
222
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 ;
223
234
#endif
224
235
#if defined(CFG_CRYPTO_DES )
225
236
case TEE_ALG_DES_ECB_NOPAD :
@@ -230,7 +241,8 @@ static const mbedtls_cipher_info_t *get_cipher_info(uint32_t algo,
230
241
return NULL ;
231
242
case TEE_ALG_DES_CBC_MAC_NOPAD :
232
243
case TEE_ALG_DES_CBC_MAC_PKCS5 :
233
- return NULL ;
244
+ return mbedtls_cipher_info_from_type (
245
+ MBEDTLS_CIPHER_DES_CBC );
234
246
case TEE_ALG_DES_CBC_NOPAD :
235
247
if (key_len == 64 )
236
248
return mbedtls_cipher_info_from_type (
@@ -248,7 +260,8 @@ static const mbedtls_cipher_info_t *get_cipher_info(uint32_t algo,
248
260
return NULL ;
249
261
case TEE_ALG_DES3_CBC_MAC_NOPAD :
250
262
case TEE_ALG_DES3_CBC_MAC_PKCS5 :
251
- return NULL ;
263
+ return mbedtls_cipher_info_from_type (
264
+ MBEDTLS_CIPHER_DES_EDE3_CBC );
252
265
case TEE_ALG_DES3_CBC_NOPAD :
253
266
if (key_len == 128 )
254
267
return mbedtls_cipher_info_from_type (
@@ -2374,6 +2387,46 @@ void crypto_cipher_final(void *ctx __unused, uint32_t algo __unused)
2374
2387
* Message Authentication Code functions
2375
2388
*****************************************************************************/
2376
2389
#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
+
2377
2430
static TEE_Result mac_get_ctx_size (uint32_t algo , size_t * size )
2378
2431
{
2379
2432
switch (algo ) {
@@ -2394,7 +2447,8 @@ static TEE_Result mac_get_ctx_size(uint32_t algo, size_t *size)
2394
2447
case TEE_ALG_DES_CBC_MAC_PKCS5 :
2395
2448
case TEE_ALG_DES3_CBC_MAC_NOPAD :
2396
2449
case TEE_ALG_DES3_CBC_MAC_PKCS5 :
2397
- return TEE_ERROR_NOT_SUPPORTED ;
2450
+ * size = sizeof (struct cbc_state );
2451
+ break ;
2398
2452
#endif
2399
2453
#if defined(CFG_CRYPTO_CMAC )
2400
2454
case TEE_ALG_AES_CMAC :
@@ -2456,8 +2510,19 @@ TEE_Result crypto_mac_alloc_ctx(void **ctx_ret, uint32_t algo)
2456
2510
case TEE_ALG_DES_CBC_MAC_PKCS5 :
2457
2511
case TEE_ALG_DES3_CBC_MAC_NOPAD :
2458
2512
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 ;
2461
2526
#endif
2462
2527
#if defined(CFG_CRYPTO_CMAC )
2463
2528
case TEE_ALG_AES_CMAC :
@@ -2529,6 +2594,7 @@ void crypto_mac_free_ctx(void *ctx, uint32_t algo __maybe_unused)
2529
2594
case TEE_ALG_DES_CBC_MAC_PKCS5 :
2530
2595
case TEE_ALG_DES3_CBC_MAC_NOPAD :
2531
2596
case TEE_ALG_DES3_CBC_MAC_PKCS5 :
2597
+ mbedtls_cipher_free (ctx );
2532
2598
break ;
2533
2599
#endif
2534
2600
#if defined(CFG_CRYPTO_CMAC )
@@ -2545,6 +2611,8 @@ void crypto_mac_free_ctx(void *ctx, uint32_t algo __maybe_unused)
2545
2611
void crypto_mac_copy_state (void * dst_ctx , void * src_ctx , uint32_t algo )
2546
2612
{
2547
2613
int lmd_res __maybe_unused ;
2614
+ struct cbc_state * dst_cbc __maybe_unused ;
2615
+ struct cbc_state * src_cbc __maybe_unused ;
2548
2616
2549
2617
switch (algo ) {
2550
2618
#if defined(CFG_CRYPTO_HMAC )
@@ -2568,6 +2636,18 @@ void crypto_mac_copy_state(void *dst_ctx, void *src_ctx, uint32_t algo)
2568
2636
case TEE_ALG_DES_CBC_MAC_PKCS5 :
2569
2637
case TEE_ALG_DES3_CBC_MAC_NOPAD :
2570
2638
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
+ }
2571
2651
break ;
2572
2652
#endif
2573
2653
#if defined(CFG_CRYPTO_CMAC )
@@ -2589,6 +2669,11 @@ TEE_Result crypto_mac_init(void *ctx, uint32_t algo, const uint8_t *key,
2589
2669
{
2590
2670
int lmd_res __maybe_unused ;
2591
2671
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 ;
2592
2677
2593
2678
if (!ctx )
2594
2679
return TEE_ERROR_BAD_PARAMETERS ;
@@ -2620,7 +2705,49 @@ TEE_Result crypto_mac_init(void *ctx, uint32_t algo, const uint8_t *key,
2620
2705
case TEE_ALG_DES_CBC_MAC_PKCS5 :
2621
2706
case TEE_ALG_DES3_CBC_MAC_NOPAD :
2622
2707
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 ;
2624
2751
#endif
2625
2752
#if defined(CFG_CRYPTO_CMAC )
2626
2753
case TEE_ALG_AES_CMAC :
@@ -2658,6 +2785,9 @@ TEE_Result crypto_mac_update(void *ctx, uint32_t algo, const uint8_t *data,
2658
2785
size_t len )
2659
2786
{
2660
2787
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 ;
2661
2791
2662
2792
if (!data || !len )
2663
2793
return TEE_SUCCESS ;
@@ -2684,7 +2814,42 @@ TEE_Result crypto_mac_update(void *ctx, uint32_t algo, const uint8_t *data,
2684
2814
case TEE_ALG_DES_CBC_MAC_PKCS5 :
2685
2815
case TEE_ALG_DES3_CBC_MAC_NOPAD :
2686
2816
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 ;
2688
2853
#endif
2689
2854
#if defined(CFG_CRYPTO_CMAC )
2690
2855
case TEE_ALG_AES_CMAC :
@@ -2708,6 +2873,9 @@ TEE_Result crypto_mac_final(void *ctx, uint32_t algo, uint8_t *digest,
2708
2873
int lmd_res __maybe_unused ;
2709
2874
size_t block_size __maybe_unused ;
2710
2875
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 ;
2711
2879
2712
2880
switch (algo ) {
2713
2881
#if defined(CFG_CRYPTO_HMAC )
@@ -2735,7 +2903,37 @@ TEE_Result crypto_mac_final(void *ctx, uint32_t algo, uint8_t *digest,
2735
2903
case TEE_ALG_DES_CBC_MAC_PKCS5 :
2736
2904
case TEE_ALG_DES3_CBC_MAC_NOPAD :
2737
2905
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 ;
2739
2937
#endif
2740
2938
#if defined(CFG_CRYPTO_CMAC )
2741
2939
case TEE_ALG_AES_CMAC :
0 commit comments