44 * Copyright (C) 2022 Marvell.
55 */
66
7+ #include <crypto/skcipher.h>
78#include <linux/rtnetlink.h>
89#include <linux/bitfield.h>
910#include "otx2_common.h"
4243#define MCS_TCI_E 0x08 /* encryption */
4344#define MCS_TCI_C 0x04 /* changed text */
4445
46+ #define CN10K_MAX_HASH_LEN 16
47+ #define CN10K_MAX_SAK_LEN 32
48+
49+ static int cn10k_ecb_aes_encrypt (struct otx2_nic * pfvf , u8 * sak ,
50+ u16 sak_len , u8 * hash )
51+ {
52+ u8 data [CN10K_MAX_HASH_LEN ] = { 0 };
53+ struct skcipher_request * req = NULL ;
54+ struct scatterlist sg_src , sg_dst ;
55+ struct crypto_skcipher * tfm ;
56+ DECLARE_CRYPTO_WAIT (wait );
57+ int err ;
58+
59+ tfm = crypto_alloc_skcipher ("ecb(aes)" , 0 , 0 );
60+ if (IS_ERR (tfm )) {
61+ dev_err (pfvf -> dev , "failed to allocate transform for ecb-aes\n" );
62+ return PTR_ERR (tfm );
63+ }
64+
65+ req = skcipher_request_alloc (tfm , GFP_KERNEL );
66+ if (!req ) {
67+ dev_err (pfvf -> dev , "failed to allocate request for skcipher\n" );
68+ err = - ENOMEM ;
69+ goto free_tfm ;
70+ }
71+
72+ err = crypto_skcipher_setkey (tfm , sak , sak_len );
73+ if (err ) {
74+ dev_err (pfvf -> dev , "failed to set key for skcipher\n" );
75+ goto free_req ;
76+ }
77+
78+ /* build sg list */
79+ sg_init_one (& sg_src , data , CN10K_MAX_HASH_LEN );
80+ sg_init_one (& sg_dst , hash , CN10K_MAX_HASH_LEN );
81+
82+ skcipher_request_set_callback (req , 0 , crypto_req_done , & wait );
83+ skcipher_request_set_crypt (req , & sg_src , & sg_dst ,
84+ CN10K_MAX_HASH_LEN , NULL );
85+
86+ err = crypto_skcipher_encrypt (req );
87+ err = crypto_wait_req (err , & wait );
88+
89+ free_req :
90+ skcipher_request_free (req );
91+ free_tfm :
92+ crypto_free_skcipher (tfm );
93+ return err ;
94+ }
95+
4596static struct cn10k_mcs_txsc * cn10k_mcs_get_txsc (struct cn10k_mcs_cfg * cfg ,
4697 struct macsec_secy * secy )
4798{
@@ -330,19 +381,53 @@ static int cn10k_mcs_write_sc_cam(struct otx2_nic *pfvf,
330381 return ret ;
331382}
332383
384+ static int cn10k_mcs_write_keys (struct otx2_nic * pfvf ,
385+ struct macsec_secy * secy ,
386+ struct mcs_sa_plcy_write_req * req ,
387+ u8 * sak , u8 * salt , ssci_t ssci )
388+ {
389+ u8 hash_rev [CN10K_MAX_HASH_LEN ];
390+ u8 sak_rev [CN10K_MAX_SAK_LEN ];
391+ u8 salt_rev [MACSEC_SALT_LEN ];
392+ u8 hash [CN10K_MAX_HASH_LEN ];
393+ u32 ssci_63_32 ;
394+ int err , i ;
395+
396+ err = cn10k_ecb_aes_encrypt (pfvf , sak , secy -> key_len , hash );
397+ if (err ) {
398+ dev_err (pfvf -> dev , "Generating hash using ECB(AES) failed\n" );
399+ return err ;
400+ }
401+
402+ for (i = 0 ; i < secy -> key_len ; i ++ )
403+ sak_rev [i ] = sak [secy -> key_len - 1 - i ];
404+
405+ for (i = 0 ; i < CN10K_MAX_HASH_LEN ; i ++ )
406+ hash_rev [i ] = hash [CN10K_MAX_HASH_LEN - 1 - i ];
407+
408+ for (i = 0 ; i < MACSEC_SALT_LEN ; i ++ )
409+ salt_rev [i ] = salt [MACSEC_SALT_LEN - 1 - i ];
410+
411+ ssci_63_32 = (__force u32 )cpu_to_be32 ((__force u32 )ssci );
412+
413+ memcpy (& req -> plcy [0 ][0 ], sak_rev , secy -> key_len );
414+ memcpy (& req -> plcy [0 ][4 ], hash_rev , CN10K_MAX_HASH_LEN );
415+ memcpy (& req -> plcy [0 ][6 ], salt_rev , MACSEC_SALT_LEN );
416+ req -> plcy [0 ][7 ] |= (u64 )ssci_63_32 << 32 ;
417+
418+ return 0 ;
419+ }
420+
333421static int cn10k_mcs_write_rx_sa_plcy (struct otx2_nic * pfvf ,
334422 struct macsec_secy * secy ,
335423 struct cn10k_mcs_rxsc * rxsc ,
336424 u8 assoc_num , bool sa_in_use )
337425{
338- unsigned char * src = rxsc -> sa_key [assoc_num ];
339426 struct mcs_sa_plcy_write_req * plcy_req ;
340- u8 * salt_p = rxsc -> salt [assoc_num ];
427+ u8 * sak = rxsc -> sa_key [assoc_num ];
428+ u8 * salt = rxsc -> salt [assoc_num ];
341429 struct mcs_rx_sc_sa_map * map_req ;
342430 struct mbox * mbox = & pfvf -> mbox ;
343- u64 ssci_salt_95_64 = 0 ;
344- u8 reg , key_len ;
345- u64 salt_63_0 ;
346431 int ret ;
347432
348433 mutex_lock (& mbox -> lock );
@@ -360,20 +445,10 @@ static int cn10k_mcs_write_rx_sa_plcy(struct otx2_nic *pfvf,
360445 goto fail ;
361446 }
362447
363- for (reg = 0 , key_len = 0 ; key_len < secy -> key_len ; key_len += 8 ) {
364- memcpy ((u8 * )& plcy_req -> plcy [0 ][reg ],
365- (src + reg * 8 ), 8 );
366- reg ++ ;
367- }
368-
369- if (secy -> xpn ) {
370- memcpy ((u8 * )& salt_63_0 , salt_p , 8 );
371- memcpy ((u8 * )& ssci_salt_95_64 , salt_p + 8 , 4 );
372- ssci_salt_95_64 |= (__force u64 )rxsc -> ssci [assoc_num ] << 32 ;
373-
374- plcy_req -> plcy [0 ][6 ] = salt_63_0 ;
375- plcy_req -> plcy [0 ][7 ] = ssci_salt_95_64 ;
376- }
448+ ret = cn10k_mcs_write_keys (pfvf , secy , plcy_req , sak ,
449+ salt , rxsc -> ssci [assoc_num ]);
450+ if (ret )
451+ goto fail ;
377452
378453 plcy_req -> sa_index [0 ] = rxsc -> hw_sa_id [assoc_num ];
379454 plcy_req -> sa_cnt = 1 ;
@@ -586,13 +661,10 @@ static int cn10k_mcs_write_tx_sa_plcy(struct otx2_nic *pfvf,
586661 struct cn10k_mcs_txsc * txsc ,
587662 u8 assoc_num )
588663{
589- unsigned char * src = txsc -> sa_key [assoc_num ];
590664 struct mcs_sa_plcy_write_req * plcy_req ;
591- u8 * salt_p = txsc -> salt [assoc_num ];
665+ u8 * sak = txsc -> sa_key [assoc_num ];
666+ u8 * salt = txsc -> salt [assoc_num ];
592667 struct mbox * mbox = & pfvf -> mbox ;
593- u64 ssci_salt_95_64 = 0 ;
594- u8 reg , key_len ;
595- u64 salt_63_0 ;
596668 int ret ;
597669
598670 mutex_lock (& mbox -> lock );
@@ -603,19 +675,10 @@ static int cn10k_mcs_write_tx_sa_plcy(struct otx2_nic *pfvf,
603675 goto fail ;
604676 }
605677
606- for (reg = 0 , key_len = 0 ; key_len < secy -> key_len ; key_len += 8 ) {
607- memcpy ((u8 * )& plcy_req -> plcy [0 ][reg ], (src + reg * 8 ), 8 );
608- reg ++ ;
609- }
610-
611- if (secy -> xpn ) {
612- memcpy ((u8 * )& salt_63_0 , salt_p , 8 );
613- memcpy ((u8 * )& ssci_salt_95_64 , salt_p + 8 , 4 );
614- ssci_salt_95_64 |= (__force u64 )txsc -> ssci [assoc_num ] << 32 ;
615-
616- plcy_req -> plcy [0 ][6 ] = salt_63_0 ;
617- plcy_req -> plcy [0 ][7 ] = ssci_salt_95_64 ;
618- }
678+ ret = cn10k_mcs_write_keys (pfvf , secy , plcy_req , sak ,
679+ salt , txsc -> ssci [assoc_num ]);
680+ if (ret )
681+ goto fail ;
619682
620683 plcy_req -> plcy [0 ][8 ] = assoc_num ;
621684 plcy_req -> sa_index [0 ] = txsc -> hw_sa_id [assoc_num ];
0 commit comments