aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/macsec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/macsec.c')
-rw-r--r--drivers/net/macsec.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index 47ee2c840b55..0e7eff7f1cd2 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -605,12 +605,41 @@ static void macsec_encrypt_done(struct crypto_async_request *base, int err)
605 dev_put(dev); 605 dev_put(dev);
606} 606}
607 607
608static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm,
609 unsigned char **iv,
610 struct scatterlist **sg)
611{
612 size_t size, iv_offset, sg_offset;
613 struct aead_request *req;
614 void *tmp;
615
616 size = sizeof(struct aead_request) + crypto_aead_reqsize(tfm);
617 iv_offset = size;
618 size += GCM_AES_IV_LEN;
619
620 size = ALIGN(size, __alignof__(struct scatterlist));
621 sg_offset = size;
622 size += sizeof(struct scatterlist) * (MAX_SKB_FRAGS + 1);
623
624 tmp = kmalloc(size, GFP_ATOMIC);
625 if (!tmp)
626 return NULL;
627
628 *iv = (unsigned char *)(tmp + iv_offset);
629 *sg = (struct scatterlist *)(tmp + sg_offset);
630 req = tmp;
631
632 aead_request_set_tfm(req, tfm);
633
634 return req;
635}
636
608static struct sk_buff *macsec_encrypt(struct sk_buff *skb, 637static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
609 struct net_device *dev) 638 struct net_device *dev)
610{ 639{
611 int ret; 640 int ret;
612 struct scatterlist sg[MAX_SKB_FRAGS + 1]; 641 struct scatterlist *sg;
613 unsigned char iv[GCM_AES_IV_LEN]; 642 unsigned char *iv;
614 struct ethhdr *eth; 643 struct ethhdr *eth;
615 struct macsec_eth_header *hh; 644 struct macsec_eth_header *hh;
616 size_t unprotected_len; 645 size_t unprotected_len;
@@ -668,8 +697,6 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
668 macsec_fill_sectag(hh, secy, pn); 697 macsec_fill_sectag(hh, secy, pn);
669 macsec_set_shortlen(hh, unprotected_len - 2 * ETH_ALEN); 698 macsec_set_shortlen(hh, unprotected_len - 2 * ETH_ALEN);
670 699
671 macsec_fill_iv(iv, secy->sci, pn);
672
673 skb_put(skb, secy->icv_len); 700 skb_put(skb, secy->icv_len);
674 701
675 if (skb->len - ETH_HLEN > macsec_priv(dev)->real_dev->mtu) { 702 if (skb->len - ETH_HLEN > macsec_priv(dev)->real_dev->mtu) {
@@ -684,13 +711,15 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
684 return ERR_PTR(-EINVAL); 711 return ERR_PTR(-EINVAL);
685 } 712 }
686 713
687 req = aead_request_alloc(tx_sa->key.tfm, GFP_ATOMIC); 714 req = macsec_alloc_req(tx_sa->key.tfm, &iv, &sg);
688 if (!req) { 715 if (!req) {
689 macsec_txsa_put(tx_sa); 716 macsec_txsa_put(tx_sa);
690 kfree_skb(skb); 717 kfree_skb(skb);
691 return ERR_PTR(-ENOMEM); 718 return ERR_PTR(-ENOMEM);
692 } 719 }
693 720
721 macsec_fill_iv(iv, secy->sci, pn);
722
694 sg_init_table(sg, MAX_SKB_FRAGS + 1); 723 sg_init_table(sg, MAX_SKB_FRAGS + 1);
695 skb_to_sgvec(skb, sg, 0, skb->len); 724 skb_to_sgvec(skb, sg, 0, skb->len);
696 725
@@ -861,7 +890,6 @@ static void macsec_decrypt_done(struct crypto_async_request *base, int err)
861out: 890out:
862 macsec_rxsa_put(rx_sa); 891 macsec_rxsa_put(rx_sa);
863 dev_put(dev); 892 dev_put(dev);
864 return;
865} 893}
866 894
867static struct sk_buff *macsec_decrypt(struct sk_buff *skb, 895static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
@@ -871,8 +899,8 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
871 struct macsec_secy *secy) 899 struct macsec_secy *secy)
872{ 900{
873 int ret; 901 int ret;
874 struct scatterlist sg[MAX_SKB_FRAGS + 1]; 902 struct scatterlist *sg;
875 unsigned char iv[GCM_AES_IV_LEN]; 903 unsigned char *iv;
876 struct aead_request *req; 904 struct aead_request *req;
877 struct macsec_eth_header *hdr; 905 struct macsec_eth_header *hdr;
878 u16 icv_len = secy->icv_len; 906 u16 icv_len = secy->icv_len;
@@ -882,7 +910,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
882 if (!skb) 910 if (!skb)
883 return ERR_PTR(-ENOMEM); 911 return ERR_PTR(-ENOMEM);
884 912
885 req = aead_request_alloc(rx_sa->key.tfm, GFP_ATOMIC); 913 req = macsec_alloc_req(rx_sa->key.tfm, &iv, &sg);
886 if (!req) { 914 if (!req) {
887 kfree_skb(skb); 915 kfree_skb(skb);
888 return ERR_PTR(-ENOMEM); 916 return ERR_PTR(-ENOMEM);
@@ -1234,7 +1262,7 @@ static struct crypto_aead *macsec_alloc_tfm(char *key, int key_len, int icv_len)
1234 struct crypto_aead *tfm; 1262 struct crypto_aead *tfm;
1235 int ret; 1263 int ret;
1236 1264
1237 tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC); 1265 tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
1238 if (!tfm || IS_ERR(tfm)) 1266 if (!tfm || IS_ERR(tfm))
1239 return NULL; 1267 return NULL;
1240 1268
@@ -3361,6 +3389,7 @@ static void __exit macsec_exit(void)
3361 genl_unregister_family(&macsec_fam); 3389 genl_unregister_family(&macsec_fam);
3362 rtnl_link_unregister(&macsec_link_ops); 3390 rtnl_link_unregister(&macsec_link_ops);
3363 unregister_netdevice_notifier(&macsec_notifier); 3391 unregister_netdevice_notifier(&macsec_notifier);
3392 rcu_barrier();
3364} 3393}
3365 3394
3366module_init(macsec_init); 3395module_init(macsec_init);