Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/net/ipv6/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  tcp_ao.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * INET An implementation of the TCP Authentication Option (TCP-AO).
 * See RFC5925.
 *
 * Authors: Dmitry Safonov <dima@arista.com>
 * Francesco Ruggeri <fruggeri@arista.com>
 * Salam Noureddine <noureddine@arista.com>
 */

#include <crypto/hash.h>
#include <linux/tcp.h>

#include <net/tcp.h>
#include <net/ipv6.h>

static int tcp_v6_ao_calc_key(struct tcp_ao_key *mkt, u8 *key,
         const struct in6_addr *saddr,
         const struct in6_addr *daddr,
         __be16 sport, __be16 dport,
         __be32 sisn, __be32 disn)
{
 struct kdf_input_block {
  u8   counter;
  u8   label[6];
  struct tcp6_ao_context ctx;
  __be16   outlen;
 } __packed * tmp;
 struct tcp_sigpool hp;
 int err;

 err = tcp_sigpool_start(mkt->tcp_sigpool_id, &hp);
 if (err)
  return err;

 tmp = hp.scratch;
 tmp->counter = 1;
 memcpy(tmp->label, "TCP-AO", 6);
 tmp->ctx.saddr = *saddr;
 tmp->ctx.daddr = *daddr;
 tmp->ctx.sport = sport;
 tmp->ctx.dport = dport;
 tmp->ctx.sisn = sisn;
 tmp->ctx.disn = disn;
 tmp->outlen = htons(tcp_ao_digest_size(mkt) * 8); /* in bits */

 err = tcp_ao_calc_traffic_key(mkt, key, tmp, sizeof(*tmp), &hp);
 tcp_sigpool_end(&hp);

 return err;
}

int tcp_v6_ao_calc_key_skb(struct tcp_ao_key *mkt, u8 *key,
      const struct sk_buff *skb,
      __be32 sisn, __be32 disn)
{
 const struct ipv6hdr *iph = ipv6_hdr(skb);
 const struct tcphdr *th = tcp_hdr(skb);

 return tcp_v6_ao_calc_key(mkt, key, &iph->saddr,
      &iph->daddr, th->source,
      th->dest, sisn, disn);
}

int tcp_v6_ao_calc_key_sk(struct tcp_ao_key *mkt, u8 *key,
     const struct sock *sk, __be32 sisn,
     __be32 disn, bool send)
{
 if (send)
  return tcp_v6_ao_calc_key(mkt, key, &sk->sk_v6_rcv_saddr,
       &sk->sk_v6_daddr, htons(sk->sk_num),
       sk->sk_dport, sisn, disn);
 else
  return tcp_v6_ao_calc_key(mkt, key, &sk->sk_v6_daddr,
       &sk->sk_v6_rcv_saddr, sk->sk_dport,
       htons(sk->sk_num), disn, sisn);
}

int tcp_v6_ao_calc_key_rsk(struct tcp_ao_key *mkt, u8 *key,
      struct request_sock *req)
{
 struct inet_request_sock *ireq = inet_rsk(req);

 return tcp_v6_ao_calc_key(mkt, key,
   &ireq->ir_v6_loc_addr, &ireq->ir_v6_rmt_addr,
   htons(ireq->ir_num), ireq->ir_rmt_port,
   htonl(tcp_rsk(req)->snt_isn),
   htonl(tcp_rsk(req)->rcv_isn));
}

struct tcp_ao_key *tcp_v6_ao_lookup(const struct sock *sk,
        struct sock *addr_sk,
        int sndid, int rcvid)
{
 int l3index = l3mdev_master_ifindex_by_index(sock_net(sk),
           addr_sk->sk_bound_dev_if);
 struct in6_addr *addr = &addr_sk->sk_v6_daddr;

 return tcp_ao_do_lookup(sk, l3index, (union tcp_ao_addr *)addr,
    AF_INET6, sndid, rcvid);
}

struct tcp_ao_key *tcp_v6_ao_lookup_rsk(const struct sock *sk,
     struct request_sock *req,
     int sndid, int rcvid)
{
 struct inet_request_sock *ireq = inet_rsk(req);
 struct in6_addr *addr = &ireq->ir_v6_rmt_addr;
 int l3index;

 l3index = l3mdev_master_ifindex_by_index(sock_net(sk), ireq->ir_iif);
 return tcp_ao_do_lookup(sk, l3index, (union tcp_ao_addr *)addr,
    AF_INET6, sndid, rcvid);
}

int tcp_v6_ao_hash_pseudoheader(struct tcp_sigpool *hp,
    const struct in6_addr *daddr,
    const struct in6_addr *saddr, int nbytes)
{
 struct tcp6_pseudohdr *bp;
 struct scatterlist sg;

 bp = hp->scratch;
 /* 1. TCP pseudo-header (RFC2460) */
 bp->saddr = *saddr;
 bp->daddr = *daddr;
 bp->len = cpu_to_be32(nbytes);
 bp->protocol = cpu_to_be32(IPPROTO_TCP);

 sg_init_one(&sg, bp, sizeof(*bp));
 ahash_request_set_crypt(hp->req, &sg, NULL, sizeof(*bp));
 return crypto_ahash_update(hp->req);
}

int tcp_v6_ao_hash_skb(char *ao_hash, struct tcp_ao_key *key,
         const struct sock *sk, const struct sk_buff *skb,
         const u8 *tkey, int hash_offset, u32 sne)
{
 return tcp_ao_hash_skb(AF_INET6, ao_hash, key, sk, skb, tkey,
   hash_offset, sne);
}

int tcp_v6_parse_ao(struct sock *sk, int cmd,
      sockptr_t optval, int optlen)
{
 return tcp_parse_ao(sk, cmd, AF_INET6, optval, optlen);
}

int tcp_v6_ao_synack_hash(char *ao_hash, struct tcp_ao_key *ao_key,
     struct request_sock *req, const struct sk_buff *skb,
     int hash_offset, u32 sne)
{
 void *hash_buf = NULL;
 int err;

 hash_buf = kmalloc(tcp_ao_digest_size(ao_key), GFP_ATOMIC);
 if (!hash_buf)
  return -ENOMEM;

 err = tcp_v6_ao_calc_key_rsk(ao_key, hash_buf, req);
 if (err)
  goto out;

 err = tcp_ao_hash_skb(AF_INET6, ao_hash, ao_key, req_to_sk(req), skb,
         hash_buf, hash_offset, sne);
out:
 kfree(hash_buf);
 return err;
}

Messung V0.5
C=92 H=95 G=93

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.