Some AEAD packet layout constants are currently named as DATA_V2 helpers. DATA_V2 is the opcode used by OpenVPN data packets, but the layout represented by these constants is the direct-key AEAD layout: opcode, 32-bit packet ID, prepended authentication tag, and payload.
Rename the helpers after the direct-key format they describe. This gives the direct layout clear scope before adding another data-channel key format that keeps the DATA_V2 opcode but uses different packet fields. Signed-off-by: Ralf Lici <[email protected]> --- drivers/net/ovpn/crypto_aead.c | 38 +++++++++++++++------------------- drivers/net/ovpn/io.c | 10 ++++----- drivers/net/ovpn/io.h | 8 +++---- drivers/net/ovpn/proto.h | 30 +++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 31 deletions(-) diff --git a/drivers/net/ovpn/crypto_aead.c b/drivers/net/ovpn/crypto_aead.c index 9e34a553f59a..d2e3532934fb 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)" #define OVPN_AEAD_DECRYPT_FAILURE_NOTIFY BIT_ULL(35) @@ -51,9 +48,7 @@ bool ovpn_aead_decrypt_failure_record(struct ovpn_crypto_key_slot *ks) static int ovpn_aead_encap_overhead(const struct ovpn_crypto_key_slot *ks) { - return OVPN_OPCODE_SIZE + /* OP header size */ - sizeof(u32) + /* Packet ID */ - crypto_aead_authsize(ks->encrypt); /* Auth Tag */ + return OVPN_AEAD_DIRECT_AAD_SIZE + crypto_aead_authsize(ks->encrypt); } /** @@ -163,6 +158,7 @@ int ovpn_aead_encrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, struct sk_buff *trailer; struct scatterlist *sg; int nfrags, ret; + u64 aead_blocks; u32 pktid, op; void *tmp; u8 *iv; @@ -205,7 +201,7 @@ int ovpn_aead_encrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, sg = ovpn_aead_crypto_req_sg(ks->encrypt, req); /* sg table: - * 0: op, wire nonce (AD, len=OVPN_OP_SIZE_V2+OVPN_NONCE_WIRE_SIZE), + * 0: op, wire nonce (AD, len=OVPN_AEAD_DIRECT_AAD_SIZE), * 1, 2, 3, ..., n: payload, * n+1: auth_tag (len=tag_size) */ @@ -226,12 +222,11 @@ int ovpn_aead_encrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, /* obtain packet ID, which is used both as a first * 4 bytes of nonce and last 4 bytes of associated data. */ + aead_blocks = ovpn_aead_limit_blocks(ks->cipher_alg, + OVPN_AEAD_DIRECT_AAD_SIZE, + plaintext_len); ret = ovpn_pktid_xmit_next(&ks->pid_xmit, &ks->usage_xmit, - &ks->usage_limit, - ovpn_aead_limit_blocks(ks->cipher_alg, - OVPN_AAD_SIZE, - plaintext_len), - &pktid); + &ks->usage_limit, aead_blocks, &pktid); if (unlikely(ret < 0)) return ret; if (unlikely(ret > 0)) @@ -253,14 +248,14 @@ int ovpn_aead_encrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, *((__force __be32 *)skb->data) = htonl(op); /* AEAD Additional data */ - sg_set_buf(sg, skb->data, OVPN_AAD_SIZE); + sg_set_buf(sg, skb->data, OVPN_AEAD_DIRECT_AAD_SIZE); /* setup async crypto operation */ aead_request_set_tfm(req, ks->encrypt); aead_request_set_callback(req, 0, ovpn_encrypt_post, skb); aead_request_set_crypt(req, sg, sg, skb->len - ovpn_aead_encap_overhead(ks), iv); - aead_request_set_ad(req, OVPN_AAD_SIZE); + aead_request_set_ad(req, OVPN_AEAD_DIRECT_AAD_SIZE); /* encrypt it */ return crypto_aead_encrypt(req); @@ -278,7 +273,7 @@ int ovpn_aead_decrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, void *tmp; u8 *iv; - payload_offset = OVPN_AAD_SIZE + tag_size; + payload_offset = ovpn_aead_direct_payload_offset(tag_size); payload_len = skb->len - payload_offset; ovpn_skb_cb(skb)->payload_offset = payload_offset; @@ -320,14 +315,14 @@ int ovpn_aead_decrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, sg = ovpn_aead_crypto_req_sg(ks->decrypt, req); /* sg table: - * 0: op, wire nonce (AD, len=OVPN_OPCODE_SIZE+OVPN_NONCE_WIRE_SIZE), + * 0: op, wire nonce (AD, len=OVPN_AEAD_DIRECT_AAD_SIZE), * 1, 2, 3, ..., n: payload, * n+1: auth_tag (len=tag_size) */ sg_init_table(sg, nfrags + 2); /* packet op is head of additional data */ - sg_set_buf(sg, skb->data, OVPN_AAD_SIZE); + sg_set_buf(sg, skb->data, OVPN_AEAD_DIRECT_AAD_SIZE); /* build scatterlist to decrypt packet payload */ ret = skb_to_sgvec_nomark(skb, sg + 1, payload_offset, payload_len); @@ -338,10 +333,11 @@ int ovpn_aead_decrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, } /* append auth_tag onto scatterlist */ - sg_set_buf(sg + ret + 1, skb->data + OVPN_AAD_SIZE, tag_size); + sg_set_buf(sg + ret + 1, skb->data + OVPN_AEAD_DIRECT_TAG_OFFSET, + tag_size); /* copy nonce into IV buffer */ - memcpy(iv, skb->data + OVPN_OPCODE_SIZE, OVPN_NONCE_WIRE_SIZE); + memcpy(iv, ovpn_aead_direct_wire_nonce(skb), OVPN_NONCE_WIRE_SIZE); memcpy(iv + OVPN_NONCE_WIRE_SIZE, ks->nonce_tail_recv, OVPN_NONCE_TAIL_SIZE); @@ -350,7 +346,7 @@ int ovpn_aead_decrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, aead_request_set_callback(req, 0, ovpn_decrypt_post, skb); aead_request_set_crypt(req, sg, sg, payload_len + tag_size, iv); - aead_request_set_ad(req, OVPN_AAD_SIZE); + aead_request_set_ad(req, OVPN_AEAD_DIRECT_AAD_SIZE); /* decrypt it */ return crypto_aead_decrypt(req); @@ -380,7 +376,7 @@ static struct crypto_aead *ovpn_aead_init(const char *title, goto error; } - ret = crypto_aead_setauthsize(aead, OVPN_AUTH_TAG_SIZE); + ret = crypto_aead_setauthsize(aead, OVPN_AEAD_TAG_SIZE); if (ret) { pr_err("%s crypto_aead_setauthsize failed, err=%d\n", title, ret); diff --git a/drivers/net/ovpn/io.c b/drivers/net/ovpn/io.c index 8085cc345c59..6f3396f6f72e 100644 --- a/drivers/net/ovpn/io.c +++ b/drivers/net/ovpn/io.c @@ -114,7 +114,7 @@ void ovpn_decrypt_post(void *data, int ret) struct ovpn_peer *peer; u64 aead_blocks; __be16 proto; - __be32 *pid; + u32 pktid; /* crypto is happening asynchronously. this function will be called * again later by the crypto callback with a proper return code @@ -138,9 +138,8 @@ void ovpn_decrypt_post(void *data, int ret) if (unlikely(ret < 0)) goto drop; - /* PID sits after the op */ - pid = (__force __be32 *)(skb->data + OVPN_OPCODE_SIZE); - ret = ovpn_pktid_recv(&ks->pid_recv, ntohl(*pid), 0); + pktid = ovpn_aead_direct_pktid(skb); + ret = ovpn_pktid_recv(&ks->pid_recv, pktid, 0); if (unlikely(ret < 0)) { net_err_ratelimited("%s: PKT ID RX error for peer %u: %d\n", netdev_name(peer->ovpn->dev), peer->id, @@ -149,8 +148,7 @@ void ovpn_decrypt_post(void *data, int ret) } aead_blocks = ovpn_aead_limit_blocks(ks->cipher_alg, - OVPN_OPCODE_SIZE + - OVPN_NONCE_WIRE_SIZE, + OVPN_AEAD_DIRECT_AAD_SIZE, skb->len - payload_offset); if (unlikely(ovpn_pktid_recv_update_aead(&ks->pid_recv, &ks->usage_recv, diff --git a/drivers/net/ovpn/io.h b/drivers/net/ovpn/io.h index db9e10f9077c..fa795573c797 100644 --- a/drivers/net/ovpn/io.h +++ b/drivers/net/ovpn/io.h @@ -10,10 +10,10 @@ #ifndef _NET_OVPN_OVPN_H_ #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 */ + \ - max(sizeof(struct udphdr), sizeof(struct tcphdr)) +\ +/* headroom needed by directly installed AEAD keys */ +#define OVPN_HEAD_ROOM (OVPN_AEAD_DIRECT_AAD_SIZE + \ + OVPN_AEAD_TAG_SIZE + \ + max(sizeof(struct udphdr), sizeof(struct tcphdr)) + \ max(sizeof(struct ipv6hdr), sizeof(struct iphdr))) /* max padding required by encryption */ diff --git a/drivers/net/ovpn/proto.h b/drivers/net/ovpn/proto.h index b7d285b4d9c1..5fa053584b15 100644 --- a/drivers/net/ovpn/proto.h +++ b/drivers/net/ovpn/proto.h @@ -47,8 +47,38 @@ #define OVPN_DATA_V1 6 /* data channel v1 packet */ #define OVPN_DATA_V2 9 /* data channel v2 packet */ +/* direct-key AEAD packet layout */ +#define OVPN_AEAD_TAG_SIZE 16 +#define OVPN_AEAD_DIRECT_OP_OFFSET 0 +#define OVPN_AEAD_DIRECT_PKTID_OFFSET (OVPN_AEAD_DIRECT_OP_OFFSET + \ + OVPN_OPCODE_SIZE) +#define OVPN_AEAD_DIRECT_TAG_OFFSET (OVPN_AEAD_DIRECT_PKTID_OFFSET + \ + OVPN_NONCE_WIRE_SIZE) +#define OVPN_AEAD_DIRECT_AAD_SIZE OVPN_AEAD_DIRECT_TAG_OFFSET + #define OVPN_PEER_ID_UNDEF 0x00FFFFFF +static inline unsigned int +ovpn_aead_direct_payload_offset(unsigned int tag_size) +{ + return OVPN_AEAD_DIRECT_TAG_OFFSET + tag_size; +} + +static inline u32 ovpn_aead_direct_pktid(const struct sk_buff *skb) +{ + const __be32 *pktid; + + pktid = (__force const __be32 *)(skb->data + + OVPN_AEAD_DIRECT_PKTID_OFFSET); + + return be32_to_cpu(*pktid); +} + +static inline u8 *ovpn_aead_direct_wire_nonce(struct sk_buff *skb) +{ + return skb->data + OVPN_AEAD_DIRECT_PKTID_OFFSET; +} + /** * ovpn_opcode_from_skb - extract OP code from skb at specified offset * @skb: the packet to extract the OP code from -- 2.54.0 _______________________________________________ Openvpn-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openvpn-devel
