Skip to content

Commit e7002b3

Browse files
Subbaraya Sundeepkuba-moo
authored andcommitted
octeontx2-pf: mcs: Generate hash key using ecb(aes)
Hardware generated encryption and ICV tags are found to be wrong when tested with IEEE MACSEC test vectors. This is because as per the HRM, the hash key (derived by AES-ECB block encryption of an all 0s block with the SAK) has to be programmed by the software in MCSX_RS_MCS_CPM_TX_SLAVE_SA_PLCY_MEM_4X register. Hence fix this by generating hash key in software and configuring in hardware. Fixes: c54ffc7 ("octeontx2-pf: mcs: Introduce MACSEC hardware offloading") Signed-off-by: Subbaraya Sundeep <[email protected]> Reviewed-by: Kalesh AP <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 78adb4b commit e7002b3

File tree

1 file changed

+100
-37
lines changed

1 file changed

+100
-37
lines changed

drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c

Lines changed: 100 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
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"
@@ -42,6 +43,56 @@
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+
4596
static 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+
333421
static 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

Comments
 (0)