~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/ipv6/tcp_ao.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * INET         An implementation of the TCP Authentication Option (TCP-AO).
  4  *              See RFC5925.
  5  *
  6  * Authors:     Dmitry Safonov <dima@arista.com>
  7  *              Francesco Ruggeri <fruggeri@arista.com>
  8  *              Salam Noureddine <noureddine@arista.com>
  9  */
 10 #include <crypto/hash.h>
 11 #include <linux/tcp.h>
 12 
 13 #include <net/tcp.h>
 14 #include <net/ipv6.h>
 15 
 16 static int tcp_v6_ao_calc_key(struct tcp_ao_key *mkt, u8 *key,
 17                               const struct in6_addr *saddr,
 18                               const struct in6_addr *daddr,
 19                               __be16 sport, __be16 dport,
 20                               __be32 sisn, __be32 disn)
 21 {
 22         struct kdf_input_block {
 23                 u8                      counter;
 24                 u8                      label[6];
 25                 struct tcp6_ao_context  ctx;
 26                 __be16                  outlen;
 27         } __packed * tmp;
 28         struct tcp_sigpool hp;
 29         int err;
 30 
 31         err = tcp_sigpool_start(mkt->tcp_sigpool_id, &hp);
 32         if (err)
 33                 return err;
 34 
 35         tmp = hp.scratch;
 36         tmp->counter    = 1;
 37         memcpy(tmp->label, "TCP-AO", 6);
 38         tmp->ctx.saddr  = *saddr;
 39         tmp->ctx.daddr  = *daddr;
 40         tmp->ctx.sport  = sport;
 41         tmp->ctx.dport  = dport;
 42         tmp->ctx.sisn   = sisn;
 43         tmp->ctx.disn   = disn;
 44         tmp->outlen     = htons(tcp_ao_digest_size(mkt) * 8); /* in bits */
 45 
 46         err = tcp_ao_calc_traffic_key(mkt, key, tmp, sizeof(*tmp), &hp);
 47         tcp_sigpool_end(&hp);
 48 
 49         return err;
 50 }
 51 
 52 int tcp_v6_ao_calc_key_skb(struct tcp_ao_key *mkt, u8 *key,
 53                            const struct sk_buff *skb,
 54                            __be32 sisn, __be32 disn)
 55 {
 56         const struct ipv6hdr *iph = ipv6_hdr(skb);
 57         const struct tcphdr *th = tcp_hdr(skb);
 58 
 59         return tcp_v6_ao_calc_key(mkt, key, &iph->saddr,
 60                                   &iph->daddr, th->source,
 61                                   th->dest, sisn, disn);
 62 }
 63 
 64 int tcp_v6_ao_calc_key_sk(struct tcp_ao_key *mkt, u8 *key,
 65                           const struct sock *sk, __be32 sisn,
 66                           __be32 disn, bool send)
 67 {
 68         if (send)
 69                 return tcp_v6_ao_calc_key(mkt, key, &sk->sk_v6_rcv_saddr,
 70                                           &sk->sk_v6_daddr, htons(sk->sk_num),
 71                                           sk->sk_dport, sisn, disn);
 72         else
 73                 return tcp_v6_ao_calc_key(mkt, key, &sk->sk_v6_daddr,
 74                                           &sk->sk_v6_rcv_saddr, sk->sk_dport,
 75                                           htons(sk->sk_num), disn, sisn);
 76 }
 77 
 78 int tcp_v6_ao_calc_key_rsk(struct tcp_ao_key *mkt, u8 *key,
 79                            struct request_sock *req)
 80 {
 81         struct inet_request_sock *ireq = inet_rsk(req);
 82 
 83         return tcp_v6_ao_calc_key(mkt, key,
 84                         &ireq->ir_v6_loc_addr, &ireq->ir_v6_rmt_addr,
 85                         htons(ireq->ir_num), ireq->ir_rmt_port,
 86                         htonl(tcp_rsk(req)->snt_isn),
 87                         htonl(tcp_rsk(req)->rcv_isn));
 88 }
 89 
 90 struct tcp_ao_key *tcp_v6_ao_lookup(const struct sock *sk,
 91                                     struct sock *addr_sk,
 92                                     int sndid, int rcvid)
 93 {
 94         int l3index = l3mdev_master_ifindex_by_index(sock_net(sk),
 95                                                      addr_sk->sk_bound_dev_if);
 96         struct in6_addr *addr = &addr_sk->sk_v6_daddr;
 97 
 98         return tcp_ao_do_lookup(sk, l3index, (union tcp_ao_addr *)addr,
 99                                 AF_INET6, sndid, rcvid);
100 }
101 
102 struct tcp_ao_key *tcp_v6_ao_lookup_rsk(const struct sock *sk,
103                                         struct request_sock *req,
104                                         int sndid, int rcvid)
105 {
106         struct inet_request_sock *ireq = inet_rsk(req);
107         struct in6_addr *addr = &ireq->ir_v6_rmt_addr;
108         int l3index;
109 
110         l3index = l3mdev_master_ifindex_by_index(sock_net(sk), ireq->ir_iif);
111         return tcp_ao_do_lookup(sk, l3index, (union tcp_ao_addr *)addr,
112                                 AF_INET6, sndid, rcvid);
113 }
114 
115 int tcp_v6_ao_hash_pseudoheader(struct tcp_sigpool *hp,
116                                 const struct in6_addr *daddr,
117                                 const struct in6_addr *saddr, int nbytes)
118 {
119         struct tcp6_pseudohdr *bp;
120         struct scatterlist sg;
121 
122         bp = hp->scratch;
123         /* 1. TCP pseudo-header (RFC2460) */
124         bp->saddr = *saddr;
125         bp->daddr = *daddr;
126         bp->len = cpu_to_be32(nbytes);
127         bp->protocol = cpu_to_be32(IPPROTO_TCP);
128 
129         sg_init_one(&sg, bp, sizeof(*bp));
130         ahash_request_set_crypt(hp->req, &sg, NULL, sizeof(*bp));
131         return crypto_ahash_update(hp->req);
132 }
133 
134 int tcp_v6_ao_hash_skb(char *ao_hash, struct tcp_ao_key *key,
135                        const struct sock *sk, const struct sk_buff *skb,
136                        const u8 *tkey, int hash_offset, u32 sne)
137 {
138         return tcp_ao_hash_skb(AF_INET6, ao_hash, key, sk, skb, tkey,
139                         hash_offset, sne);
140 }
141 
142 int tcp_v6_parse_ao(struct sock *sk, int cmd,
143                     sockptr_t optval, int optlen)
144 {
145         return tcp_parse_ao(sk, cmd, AF_INET6, optval, optlen);
146 }
147 
148 int tcp_v6_ao_synack_hash(char *ao_hash, struct tcp_ao_key *ao_key,
149                           struct request_sock *req, const struct sk_buff *skb,
150                           int hash_offset, u32 sne)
151 {
152         void *hash_buf = NULL;
153         int err;
154 
155         hash_buf = kmalloc(tcp_ao_digest_size(ao_key), GFP_ATOMIC);
156         if (!hash_buf)
157                 return -ENOMEM;
158 
159         err = tcp_v6_ao_calc_key_rsk(ao_key, hash_buf, req);
160         if (err)
161                 goto out;
162 
163         err = tcp_ao_hash_skb(AF_INET6, ao_hash, ao_key, req_to_sk(req), skb,
164                               hash_buf, hash_offset, sne);
165 out:
166         kfree(hash_buf);
167         return err;
168 }
169 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php