Skip to content

Commit

Permalink
macsec: allocate sg and iv on the heap
Browse files Browse the repository at this point in the history
For the crypto callbacks to work properly, we cannot have sg and iv on
the stack.  Use kmalloc instead, with a single allocation for
aead_request + scatterlist + iv.

Fixes: c09440f ("macsec: introduce IEEE 802.1AE driver")
Signed-off-by: Sabrina Dubroca <[email protected]>
Acked-by: Hannes Frederic Sowa <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
qsn authored and davem330 committed Jun 15, 2016
1 parent b196c22 commit 5d9649b
Showing 1 changed file with 37 additions and 9 deletions.
46 changes: 37 additions & 9 deletions drivers/net/macsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,12 +605,41 @@ static void macsec_encrypt_done(struct crypto_async_request *base, int err)
dev_put(dev);
}

static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm,
unsigned char **iv,
struct scatterlist **sg)
{
size_t size, iv_offset, sg_offset;
struct aead_request *req;
void *tmp;

size = sizeof(struct aead_request) + crypto_aead_reqsize(tfm);
iv_offset = size;
size += GCM_AES_IV_LEN;

size = ALIGN(size, __alignof__(struct scatterlist));
sg_offset = size;
size += sizeof(struct scatterlist) * (MAX_SKB_FRAGS + 1);

tmp = kmalloc(size, GFP_ATOMIC);
if (!tmp)
return NULL;

*iv = (unsigned char *)(tmp + iv_offset);
*sg = (struct scatterlist *)(tmp + sg_offset);
req = tmp;

aead_request_set_tfm(req, tfm);

return req;
}

static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
struct net_device *dev)
{
int ret;
struct scatterlist sg[MAX_SKB_FRAGS + 1];
unsigned char iv[GCM_AES_IV_LEN];
struct scatterlist *sg;
unsigned char *iv;
struct ethhdr *eth;
struct macsec_eth_header *hh;
size_t unprotected_len;
Expand Down Expand Up @@ -668,8 +697,6 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
macsec_fill_sectag(hh, secy, pn);
macsec_set_shortlen(hh, unprotected_len - 2 * ETH_ALEN);

macsec_fill_iv(iv, secy->sci, pn);

skb_put(skb, secy->icv_len);

if (skb->len - ETH_HLEN > macsec_priv(dev)->real_dev->mtu) {
Expand All @@ -684,13 +711,15 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
return ERR_PTR(-EINVAL);
}

req = aead_request_alloc(tx_sa->key.tfm, GFP_ATOMIC);
req = macsec_alloc_req(tx_sa->key.tfm, &iv, &sg);
if (!req) {
macsec_txsa_put(tx_sa);
kfree_skb(skb);
return ERR_PTR(-ENOMEM);
}

macsec_fill_iv(iv, secy->sci, pn);

sg_init_table(sg, MAX_SKB_FRAGS + 1);
skb_to_sgvec(skb, sg, 0, skb->len);

Expand Down Expand Up @@ -861,7 +890,6 @@ static void macsec_decrypt_done(struct crypto_async_request *base, int err)
out:
macsec_rxsa_put(rx_sa);
dev_put(dev);
return;
}

static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
Expand All @@ -871,8 +899,8 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
struct macsec_secy *secy)
{
int ret;
struct scatterlist sg[MAX_SKB_FRAGS + 1];
unsigned char iv[GCM_AES_IV_LEN];
struct scatterlist *sg;
unsigned char *iv;
struct aead_request *req;
struct macsec_eth_header *hdr;
u16 icv_len = secy->icv_len;
Expand All @@ -882,7 +910,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
if (!skb)
return ERR_PTR(-ENOMEM);

req = aead_request_alloc(rx_sa->key.tfm, GFP_ATOMIC);
req = macsec_alloc_req(rx_sa->key.tfm, &iv, &sg);
if (!req) {
kfree_skb(skb);
return ERR_PTR(-ENOMEM);
Expand Down

0 comments on commit 5d9649b

Please sign in to comment.