diff options
Diffstat (limited to 'drivers/net/macsec.c')
-rw-r--r-- | drivers/net/macsec.c | 49 |
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 | ||
608 | static 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 | |||
608 | static struct sk_buff *macsec_encrypt(struct sk_buff *skb, | 637 | static 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) | |||
861 | out: | 890 | out: |
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 | ||
867 | static struct sk_buff *macsec_decrypt(struct sk_buff *skb, | 895 | static 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 | ||
3366 | module_init(macsec_init); | 3395 | module_init(macsec_init); |