Move DATA_V2 framing sizes to the protocol header and factor request
allocation and header construction into helpers. This prepares the
transmit path for an out-of-place encryption destination without
changing packet handling.

Signed-off-by: Ralf Lici <[email protected]>
---
No changes since RFC v4 
https://lore.kernel.org/openvpn-devel/f075b9782b14d64756c84e132c138482f08287b9.1789558856.git.r...@mandelbit.com/

 drivers/net/ovpn/crypto_aead.c | 97 ++++++++++++++++++++--------------
 drivers/net/ovpn/io.h          |  3 +-
 drivers/net/ovpn/proto.h       |  4 ++
 3 files changed, 63 insertions(+), 41 deletions(-)

diff --git a/drivers/net/ovpn/crypto_aead.c b/drivers/net/ovpn/crypto_aead.c
index 2af493fd5735..30299581422d 100644
--- a/drivers/net/ovpn/crypto_aead.c
+++ b/drivers/net/ovpn/crypto_aead.c
@@ -24,9 +24,6 @@
 #include "proto.h"
 #include "skb.h"
 
-#define OVPN_AUTH_TAG_SIZE     16
-#define OVPN_AAD_SIZE          (OVPN_OPCODE_SIZE + OVPN_NONCE_WIRE_SIZE)
-
 #define ALG_NAME_AES           "gcm(aes)"
 #define ALG_NAME_CHACHAPOLY    "rfc7539(chacha20,poly1305)"
 
@@ -42,7 +39,7 @@ static int ovpn_aead_encap_overhead(const struct 
ovpn_crypto_key_slot *ks)
  *                            an AEAD request structure with extra space for SG
  *                            and IV.
  * @tfm: the AEAD cipher handle
- * @nfrags: the number of fragments in the skb
+ * @nents: the number of scatterlist entries
  *
  * This function calculates the size of a contiguous memory block that includes
  * the initialization vector (IV), the AEAD request, and an array of 
scatterlist
@@ -54,7 +51,7 @@ static int ovpn_aead_encap_overhead(const struct 
ovpn_crypto_key_slot *ks)
  * Return: the size of the temporary memory that needs to be allocated
  */
 static unsigned int ovpn_aead_crypto_tmp_size(struct crypto_aead *tfm,
-                                             const unsigned int nfrags)
+                                             const unsigned int nents)
 {
        unsigned int len = OVPN_NONCE_SIZE;
 
@@ -70,8 +67,8 @@ static unsigned int ovpn_aead_crypto_tmp_size(struct 
crypto_aead *tfm,
        /* round up to the next multiple of the scatterlist alignment */
        len = ALIGN(len, __alignof__(struct scatterlist));
 
-       /* add enough space for nfrags + 2 scatterlist entries */
-       len += array_size(sizeof(struct scatterlist), nfrags + 2);
+       /* add enough space for the scatterlist entries */
+       len += array_size(sizeof(struct scatterlist), nents);
        return len;
 }
 
@@ -135,6 +132,53 @@ static struct scatterlist *ovpn_aead_crypto_req_sg(struct 
crypto_aead *aead,
                             __alignof__(struct scatterlist));
 }
 
+static struct aead_request *ovpn_aead_request_alloc(struct crypto_aead *aead,
+                                                   struct sk_buff *skb,
+                                                   unsigned int nents, u8 **iv)
+{
+       struct aead_request *req;
+       void *tmp;
+
+       /* allocate IV, request and scatterlist entries in one block */
+       tmp = kmalloc(ovpn_aead_crypto_tmp_size(aead, nents), GFP_ATOMIC);
+       if (unlikely(!tmp))
+               return ERR_PTR(-ENOMEM);
+
+       ovpn_skb_cb(skb)->crypto_tmp = tmp;
+       *iv = ovpn_aead_crypto_tmp_iv(aead, tmp);
+       req = ovpn_aead_crypto_tmp_req(aead, *iv);
+
+       return req;
+}
+
+static int ovpn_aead_encrypt_header(struct ovpn_peer *peer,
+                                   struct ovpn_crypto_key_slot *ks,
+                                   u8 *iv, u8 *data)
+{
+       u32 pktid, op;
+       int ret;
+
+       /* obtain packet ID, which is used both as a first
+        * 4 bytes of nonce and last 4 bytes of associated data.
+        */
+       ret = ovpn_pktid_xmit_next(&ks->pid_xmit, &pktid);
+       if (unlikely(ret < 0))
+               return ret;
+
+       /* concat 4 bytes packet id and 8 bytes nonce tail into 12 bytes
+        * nonce
+        */
+       ovpn_pktid_aead_write(pktid, ks->nonce_tail_xmit, iv);
+
+       /* add the packet opcode and wire nonce as associated data */
+       op = ovpn_opcode_compose(OVPN_DATA_V2, ks->key_id, peer->tx_id);
+       BUILD_BUG_ON(sizeof(op) != OVPN_OPCODE_SIZE);
+       *(__force __be32 *)data = htonl(op);
+       memcpy(data + OVPN_OPCODE_SIZE, iv, OVPN_NONCE_WIRE_SIZE);
+
+       return 0;
+}
+
 int ovpn_aead_encrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks,
                      struct sk_buff *skb)
 {
@@ -143,8 +187,6 @@ int ovpn_aead_encrypt(struct ovpn_peer *peer, struct 
ovpn_crypto_key_slot *ks,
        struct sk_buff *trailer;
        struct scatterlist *sg;
        int nfrags, ret;
-       u32 pktid, op;
-       void *tmp;
        u8 *iv;
 
        ovpn_skb_cb(skb)->peer = peer;
@@ -175,16 +217,9 @@ int ovpn_aead_encrypt(struct ovpn_peer *peer, struct 
ovpn_crypto_key_slot *ks,
                nfrags = 1;
        }
 
-       /* allocate temporary memory for iv, sg and req */
-       tmp = kmalloc(ovpn_aead_crypto_tmp_size(ks->encrypt, nfrags),
-                     GFP_ATOMIC);
-       if (unlikely(!tmp))
-               return -ENOMEM;
-
-       ovpn_skb_cb(skb)->crypto_tmp = tmp;
-
-       iv = ovpn_aead_crypto_tmp_iv(ks->encrypt, tmp);
-       req = ovpn_aead_crypto_tmp_req(ks->encrypt, iv);
+       req = ovpn_aead_request_alloc(ks->encrypt, skb, nfrags + 2, &iv);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
        sg = ovpn_aead_crypto_req_sg(ks->encrypt, req);
 
        /* sg table:
@@ -206,28 +241,12 @@ int ovpn_aead_encrypt(struct ovpn_peer *peer, struct 
ovpn_crypto_key_slot *ks,
        __skb_push(skb, tag_size);
        sg_set_buf(sg + ret + 1, skb->data, tag_size);
 
-       /* obtain packet ID, which is used both as a first
-        * 4 bytes of nonce and last 4 bytes of associated data.
-        */
-       ret = ovpn_pktid_xmit_next(&ks->pid_xmit, &pktid);
+       /* make space for the additional data and push it to the front */
+       __skb_push(skb, OVPN_AAD_SIZE);
+       ret = ovpn_aead_encrypt_header(peer, ks, iv, skb->data);
        if (unlikely(ret < 0))
                return ret;
 
-       /* concat 4 bytes packet id and 8 bytes nonce tail into 12 bytes
-        * nonce
-        */
-       ovpn_pktid_aead_write(pktid, ks->nonce_tail_xmit, iv);
-
-       /* make space for packet id and push it to the front */
-       __skb_push(skb, OVPN_NONCE_WIRE_SIZE);
-       memcpy(skb->data, iv, OVPN_NONCE_WIRE_SIZE);
-
-       /* add packet op as head of additional data */
-       op = ovpn_opcode_compose(OVPN_DATA_V2, ks->key_id, peer->tx_id);
-       __skb_push(skb, OVPN_OPCODE_SIZE);
-       BUILD_BUG_ON(sizeof(op) != OVPN_OPCODE_SIZE);
-       *((__force __be32 *)skb->data) = htonl(op);
-
        /* AEAD Additional data */
        sg_set_buf(sg, skb->data, OVPN_AAD_SIZE);
 
@@ -281,7 +300,7 @@ int ovpn_aead_decrypt(struct ovpn_peer *peer, struct 
ovpn_crypto_key_slot *ks,
                return -ENOSPC;
 
        /* allocate temporary memory for iv, sg and req */
-       tmp = kmalloc(ovpn_aead_crypto_tmp_size(ks->decrypt, nfrags),
+       tmp = kmalloc(ovpn_aead_crypto_tmp_size(ks->decrypt, nfrags + 2),
                      GFP_ATOMIC);
        if (unlikely(!tmp))
                return -ENOMEM;
diff --git a/drivers/net/ovpn/io.h b/drivers/net/ovpn/io.h
index db9e10f9077c..1a94f0fda1d1 100644
--- a/drivers/net/ovpn/io.h
+++ b/drivers/net/ovpn/io.h
@@ -11,8 +11,7 @@
 #define _NET_OVPN_OVPN_H_
 
 /* DATA_V2 header size with AEAD encryption */
-#define OVPN_HEAD_ROOM (OVPN_OPCODE_SIZE + OVPN_NONCE_WIRE_SIZE +         \
-                       16 /* AEAD TAG length */ +                         \
+#define OVPN_HEAD_ROOM (OVPN_DATA_V2_OVERHEAD +                                
   \
                        max(sizeof(struct udphdr), sizeof(struct tcphdr)) +\
                        max(sizeof(struct ipv6hdr), sizeof(struct iphdr)))
 
diff --git a/drivers/net/ovpn/proto.h b/drivers/net/ovpn/proto.h
index b7d285b4d9c1..f3b305cbefe5 100644
--- a/drivers/net/ovpn/proto.h
+++ b/drivers/net/ovpn/proto.h
@@ -39,6 +39,10 @@
 #define OVPN_NONCE_WIRE_SIZE (OVPN_NONCE_SIZE - OVPN_NONCE_TAIL_SIZE)
 
 #define OVPN_OPCODE_SIZE               4 /* DATA_V2 opcode size */
+#define OVPN_AUTH_TAG_SIZE             16
+#define OVPN_AAD_SIZE                  (OVPN_OPCODE_SIZE + \
+                                        OVPN_NONCE_WIRE_SIZE)
+#define OVPN_DATA_V2_OVERHEAD          (OVPN_AAD_SIZE + OVPN_AUTH_TAG_SIZE)
 #define OVPN_OPCODE_KEYID_MASK         0x07000000
 #define OVPN_OPCODE_PKTTYPE_MASK       0xF8000000
 #define OVPN_OPCODE_PEERID_MASK                0x00FFFFFF
-- 
2.55.0



_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to