The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/wg/wg_noise.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* SPDX-License-Identifier: ISC
    2  *
    3  * Copyright (C) 2015-2021 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
    4  * Copyright (C) 2019-2021 Matt Dunwoodie <ncon@noconroy.net>
    5  * Copyright (c) 2022 The FreeBSD Foundation
    6  */
    7 
    8 #include <sys/param.h>
    9 #include <sys/systm.h>
   10 #include <sys/ck.h>
   11 #include <sys/endian.h>
   12 #include <sys/epoch.h>
   13 #include <sys/kernel.h>
   14 #include <sys/lock.h>
   15 #include <sys/malloc.h>
   16 #include <sys/mutex.h>
   17 #include <sys/refcount.h>
   18 #include <sys/rwlock.h>
   19 #include <crypto/siphash/siphash.h>
   20 
   21 #include "crypto.h"
   22 #include "wg_noise.h"
   23 
   24 /* Protocol string constants */
   25 #define NOISE_HANDSHAKE_NAME    "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"
   26 #define NOISE_IDENTIFIER_NAME   "WireGuard v1 zx2c4 Jason@zx2c4.com"
   27 
   28 /* Constants for the counter */
   29 #define COUNTER_BITS_TOTAL      8192
   30 #ifdef __LP64__
   31 #define COUNTER_ORDER           6
   32 #define COUNTER_BITS            64
   33 #else
   34 #define COUNTER_ORDER           5
   35 #define COUNTER_BITS            32
   36 #endif
   37 #define COUNTER_REDUNDANT_BITS  COUNTER_BITS
   38 #define COUNTER_WINDOW_SIZE     (COUNTER_BITS_TOTAL - COUNTER_REDUNDANT_BITS)
   39 
   40 /* Constants for the keypair */
   41 #define REKEY_AFTER_MESSAGES    (1ull << 60)
   42 #define REJECT_AFTER_MESSAGES   (UINT64_MAX - COUNTER_WINDOW_SIZE - 1)
   43 #define REKEY_AFTER_TIME        120
   44 #define REKEY_AFTER_TIME_RECV   165
   45 #define REJECT_INTERVAL         (1000000000 / 50) /* fifty times per sec */
   46 /* 24 = floor(log2(REJECT_INTERVAL)) */
   47 #define REJECT_INTERVAL_MASK    (~((1ull<<24)-1))
   48 #define TIMER_RESET             (SBT_1S * -(REKEY_TIMEOUT+1))
   49 
   50 #define HT_INDEX_SIZE           (1 << 13)
   51 #define HT_INDEX_MASK           (HT_INDEX_SIZE - 1)
   52 #define HT_REMOTE_SIZE          (1 << 11)
   53 #define HT_REMOTE_MASK          (HT_REMOTE_SIZE - 1)
   54 #define MAX_REMOTE_PER_LOCAL    (1 << 20)
   55 
   56 struct noise_index {
   57         CK_LIST_ENTRY(noise_index)       i_entry;
   58         uint32_t                         i_local_index;
   59         uint32_t                         i_remote_index;
   60         int                              i_is_keypair;
   61 };
   62 
   63 struct noise_keypair {
   64         struct noise_index               kp_index;
   65         u_int                            kp_refcnt;
   66         bool                             kp_can_send;
   67         bool                             kp_is_initiator;
   68         sbintime_t                       kp_birthdate; /* sbinuptime */
   69         struct noise_remote             *kp_remote;
   70 
   71         uint8_t                          kp_send[NOISE_SYMMETRIC_KEY_LEN];
   72         uint8_t                          kp_recv[NOISE_SYMMETRIC_KEY_LEN];
   73 
   74         /* Counter elements */
   75         struct rwlock                    kp_nonce_lock;
   76         uint64_t                         kp_nonce_send;
   77         uint64_t                         kp_nonce_recv;
   78         unsigned long                    kp_backtrack[COUNTER_BITS_TOTAL / COUNTER_BITS];
   79 
   80         struct epoch_context             kp_smr;
   81 };
   82 
   83 struct noise_handshake {
   84         uint8_t                          hs_e[NOISE_PUBLIC_KEY_LEN];
   85         uint8_t                          hs_hash[NOISE_HASH_LEN];
   86         uint8_t                          hs_ck[NOISE_HASH_LEN];
   87 };
   88 
   89 enum noise_handshake_state {
   90         HANDSHAKE_DEAD,
   91         HANDSHAKE_INITIATOR,
   92         HANDSHAKE_RESPONDER,
   93 };
   94 
   95 struct noise_remote {
   96         struct noise_index               r_index;
   97 
   98         CK_LIST_ENTRY(noise_remote)      r_entry;
   99         bool                             r_entry_inserted;
  100         uint8_t                          r_public[NOISE_PUBLIC_KEY_LEN];
  101 
  102         struct rwlock                    r_handshake_lock;
  103         struct noise_handshake           r_handshake;
  104         enum noise_handshake_state       r_handshake_state;
  105         sbintime_t                       r_last_sent; /* sbinuptime */
  106         sbintime_t                       r_last_init_recv; /* sbinuptime */
  107         uint8_t                          r_timestamp[NOISE_TIMESTAMP_LEN];
  108         uint8_t                          r_psk[NOISE_SYMMETRIC_KEY_LEN];
  109         uint8_t                          r_ss[NOISE_PUBLIC_KEY_LEN];
  110 
  111         u_int                            r_refcnt;
  112         struct noise_local              *r_local;
  113         void                            *r_arg;
  114 
  115         struct mtx                       r_keypair_mtx;
  116         struct noise_keypair            *r_next, *r_current, *r_previous;
  117 
  118         struct epoch_context             r_smr;
  119         void                            (*r_cleanup)(struct noise_remote *);
  120 };
  121 
  122 struct noise_local {
  123         struct rwlock                    l_identity_lock;
  124         bool                             l_has_identity;
  125         uint8_t                          l_public[NOISE_PUBLIC_KEY_LEN];
  126         uint8_t                          l_private[NOISE_PUBLIC_KEY_LEN];
  127 
  128         u_int                            l_refcnt;
  129         uint8_t                          l_hash_key[SIPHASH_KEY_LENGTH];
  130         void                            *l_arg;
  131         void                            (*l_cleanup)(struct noise_local *);
  132 
  133         struct mtx                       l_remote_mtx;
  134         size_t                           l_remote_num;
  135         CK_LIST_HEAD(,noise_remote)      l_remote_hash[HT_REMOTE_SIZE];
  136 
  137         struct mtx                       l_index_mtx;
  138         CK_LIST_HEAD(,noise_index)       l_index_hash[HT_INDEX_SIZE];
  139 };
  140 
  141 static void     noise_precompute_ss(struct noise_local *, struct noise_remote *);
  142 
  143 static void     noise_remote_index_insert(struct noise_local *, struct noise_remote *);
  144 static struct noise_remote *
  145                 noise_remote_index_lookup(struct noise_local *, uint32_t, bool);
  146 static int      noise_remote_index_remove(struct noise_local *, struct noise_remote *);
  147 static void     noise_remote_expire_current(struct noise_remote *);
  148 
  149 static void     noise_add_new_keypair(struct noise_local *, struct noise_remote *, struct noise_keypair *);
  150 static int      noise_begin_session(struct noise_remote *);
  151 static void     noise_keypair_drop(struct noise_keypair *);
  152 
  153 static void     noise_kdf(uint8_t *, uint8_t *, uint8_t *, const uint8_t *,
  154                     size_t, size_t, size_t, size_t,
  155                     const uint8_t [NOISE_HASH_LEN]);
  156 static int      noise_mix_dh(uint8_t [NOISE_HASH_LEN], uint8_t [NOISE_SYMMETRIC_KEY_LEN],
  157                     const uint8_t [NOISE_PUBLIC_KEY_LEN],
  158                     const uint8_t [NOISE_PUBLIC_KEY_LEN]);
  159 static int      noise_mix_ss(uint8_t ck[NOISE_HASH_LEN], uint8_t [NOISE_SYMMETRIC_KEY_LEN],
  160                     const uint8_t [NOISE_PUBLIC_KEY_LEN]);
  161 static void     noise_mix_hash(uint8_t [NOISE_HASH_LEN], const uint8_t *, size_t);
  162 static void     noise_mix_psk(uint8_t [NOISE_HASH_LEN], uint8_t [NOISE_HASH_LEN],
  163                     uint8_t [NOISE_SYMMETRIC_KEY_LEN], const uint8_t [NOISE_SYMMETRIC_KEY_LEN]);
  164 static void     noise_param_init(uint8_t [NOISE_HASH_LEN], uint8_t [NOISE_HASH_LEN],
  165                     const uint8_t [NOISE_PUBLIC_KEY_LEN]);
  166 static void     noise_msg_encrypt(uint8_t *, const uint8_t *, size_t,
  167                     uint8_t [NOISE_SYMMETRIC_KEY_LEN], uint8_t [NOISE_HASH_LEN]);
  168 static int      noise_msg_decrypt(uint8_t *, const uint8_t *, size_t,
  169                     uint8_t [NOISE_SYMMETRIC_KEY_LEN], uint8_t [NOISE_HASH_LEN]);
  170 static void     noise_msg_ephemeral(uint8_t [NOISE_HASH_LEN], uint8_t [NOISE_HASH_LEN],
  171                     const uint8_t [NOISE_PUBLIC_KEY_LEN]);
  172 static void     noise_tai64n_now(uint8_t [NOISE_TIMESTAMP_LEN]);
  173 static int      noise_timer_expired(sbintime_t, uint32_t, uint32_t);
  174 static uint64_t siphash24(const uint8_t [SIPHASH_KEY_LENGTH], const void *, size_t);
  175 
  176 MALLOC_DEFINE(M_NOISE, "NOISE", "wgnoise");
  177 
  178 /* Local configuration */
  179 struct noise_local *
  180 noise_local_alloc(void *arg)
  181 {
  182         struct noise_local *l;
  183         size_t i;
  184 
  185         l = malloc(sizeof(*l), M_NOISE, M_WAITOK | M_ZERO);
  186 
  187         rw_init(&l->l_identity_lock, "noise_identity");
  188         l->l_has_identity = false;
  189         bzero(l->l_public, NOISE_PUBLIC_KEY_LEN);
  190         bzero(l->l_private, NOISE_PUBLIC_KEY_LEN);
  191 
  192         refcount_init(&l->l_refcnt, 1);
  193         arc4random_buf(l->l_hash_key, sizeof(l->l_hash_key));
  194         l->l_arg = arg;
  195         l->l_cleanup = NULL;
  196 
  197         mtx_init(&l->l_remote_mtx, "noise_remote", NULL, MTX_DEF);
  198         l->l_remote_num = 0;
  199         for (i = 0; i < HT_REMOTE_SIZE; i++)
  200                 CK_LIST_INIT(&l->l_remote_hash[i]);
  201 
  202         mtx_init(&l->l_index_mtx, "noise_index", NULL, MTX_DEF);
  203         for (i = 0; i < HT_INDEX_SIZE; i++)
  204                 CK_LIST_INIT(&l->l_index_hash[i]);
  205 
  206         return (l);
  207 }
  208 
  209 struct noise_local *
  210 noise_local_ref(struct noise_local *l)
  211 {
  212         refcount_acquire(&l->l_refcnt);
  213         return (l);
  214 }
  215 
  216 void
  217 noise_local_put(struct noise_local *l)
  218 {
  219         if (refcount_release(&l->l_refcnt)) {
  220                 if (l->l_cleanup != NULL)
  221                         l->l_cleanup(l);
  222                 rw_destroy(&l->l_identity_lock);
  223                 mtx_destroy(&l->l_remote_mtx);
  224                 mtx_destroy(&l->l_index_mtx);
  225                 zfree(l, M_NOISE);
  226         }
  227 }
  228 
  229 void
  230 noise_local_free(struct noise_local *l, void (*cleanup)(struct noise_local *))
  231 {
  232         l->l_cleanup = cleanup;
  233         noise_local_put(l);
  234 }
  235 
  236 void *
  237 noise_local_arg(struct noise_local *l)
  238 {
  239         return (l->l_arg);
  240 }
  241 
  242 void
  243 noise_local_private(struct noise_local *l, const uint8_t private[NOISE_PUBLIC_KEY_LEN])
  244 {
  245         struct epoch_tracker et;
  246         struct noise_remote *r;
  247         size_t i;
  248 
  249         rw_wlock(&l->l_identity_lock);
  250         memcpy(l->l_private, private, NOISE_PUBLIC_KEY_LEN);
  251         curve25519_clamp_secret(l->l_private);
  252         l->l_has_identity = curve25519_generate_public(l->l_public, l->l_private);
  253 
  254         NET_EPOCH_ENTER(et);
  255         for (i = 0; i < HT_REMOTE_SIZE; i++) {
  256                 CK_LIST_FOREACH(r, &l->l_remote_hash[i], r_entry) {
  257                         noise_precompute_ss(l, r);
  258                         noise_remote_expire_current(r);
  259                 }
  260         }
  261         NET_EPOCH_EXIT(et);
  262         rw_wunlock(&l->l_identity_lock);
  263 }
  264 
  265 int
  266 noise_local_keys(struct noise_local *l, uint8_t public[NOISE_PUBLIC_KEY_LEN],
  267     uint8_t private[NOISE_PUBLIC_KEY_LEN])
  268 {
  269         int has_identity;
  270         rw_rlock(&l->l_identity_lock);
  271         if ((has_identity = l->l_has_identity)) {
  272                 if (public != NULL)
  273                         memcpy(public, l->l_public, NOISE_PUBLIC_KEY_LEN);
  274                 if (private != NULL)
  275                         memcpy(private, l->l_private, NOISE_PUBLIC_KEY_LEN);
  276         }
  277         rw_runlock(&l->l_identity_lock);
  278         return (has_identity ? 0 : ENXIO);
  279 }
  280 
  281 static void
  282 noise_precompute_ss(struct noise_local *l, struct noise_remote *r)
  283 {
  284         rw_wlock(&r->r_handshake_lock);
  285         if (!l->l_has_identity ||
  286             !curve25519(r->r_ss, l->l_private, r->r_public))
  287                 bzero(r->r_ss, NOISE_PUBLIC_KEY_LEN);
  288         rw_wunlock(&r->r_handshake_lock);
  289 }
  290 
  291 /* Remote configuration */
  292 struct noise_remote *
  293 noise_remote_alloc(struct noise_local *l, void *arg,
  294     const uint8_t public[NOISE_PUBLIC_KEY_LEN])
  295 {
  296         struct noise_remote *r;
  297 
  298         r = malloc(sizeof(*r), M_NOISE, M_WAITOK | M_ZERO);
  299         memcpy(r->r_public, public, NOISE_PUBLIC_KEY_LEN);
  300 
  301         rw_init(&r->r_handshake_lock, "noise_handshake");
  302         r->r_handshake_state = HANDSHAKE_DEAD;
  303         r->r_last_sent = TIMER_RESET;
  304         r->r_last_init_recv = TIMER_RESET;
  305         noise_precompute_ss(l, r);
  306 
  307         refcount_init(&r->r_refcnt, 1);
  308         r->r_local = noise_local_ref(l);
  309         r->r_arg = arg;
  310 
  311         mtx_init(&r->r_keypair_mtx, "noise_keypair", NULL, MTX_DEF);
  312 
  313         return (r);
  314 }
  315 
  316 int
  317 noise_remote_enable(struct noise_remote *r)
  318 {
  319         struct noise_local *l = r->r_local;
  320         uint64_t idx;
  321         int ret = 0;
  322 
  323         /* Insert to hashtable */
  324         idx = siphash24(l->l_hash_key, r->r_public, NOISE_PUBLIC_KEY_LEN) & HT_REMOTE_MASK;
  325 
  326         mtx_lock(&l->l_remote_mtx);
  327         if (!r->r_entry_inserted) {
  328                 if (l->l_remote_num < MAX_REMOTE_PER_LOCAL) {
  329                         r->r_entry_inserted = true;
  330                         l->l_remote_num++;
  331                         CK_LIST_INSERT_HEAD(&l->l_remote_hash[idx], r, r_entry);
  332                 } else {
  333                         ret = ENOSPC;
  334                 }
  335         }
  336         mtx_unlock(&l->l_remote_mtx);
  337 
  338         return ret;
  339 }
  340 
  341 void
  342 noise_remote_disable(struct noise_remote *r)
  343 {
  344         struct noise_local *l = r->r_local;
  345         /* remove from hashtable */
  346         mtx_lock(&l->l_remote_mtx);
  347         if (r->r_entry_inserted) {
  348                 r->r_entry_inserted = false;
  349                 CK_LIST_REMOVE(r, r_entry);
  350                 l->l_remote_num--;
  351         };
  352         mtx_unlock(&l->l_remote_mtx);
  353 }
  354 
  355 struct noise_remote *
  356 noise_remote_lookup(struct noise_local *l, const uint8_t public[NOISE_PUBLIC_KEY_LEN])
  357 {
  358         struct epoch_tracker et;
  359         struct noise_remote *r, *ret = NULL;
  360         uint64_t idx;
  361 
  362         idx = siphash24(l->l_hash_key, public, NOISE_PUBLIC_KEY_LEN) & HT_REMOTE_MASK;
  363 
  364         NET_EPOCH_ENTER(et);
  365         CK_LIST_FOREACH(r, &l->l_remote_hash[idx], r_entry) {
  366                 if (timingsafe_bcmp(r->r_public, public, NOISE_PUBLIC_KEY_LEN) == 0) {
  367                         if (refcount_acquire_if_not_zero(&r->r_refcnt))
  368                                 ret = r;
  369                         break;
  370                 }
  371         }
  372         NET_EPOCH_EXIT(et);
  373         return (ret);
  374 }
  375 
  376 static void
  377 noise_remote_index_insert(struct noise_local *l, struct noise_remote *r)
  378 {
  379         struct noise_index *i, *r_i = &r->r_index;
  380         struct epoch_tracker et;
  381         uint32_t idx;
  382 
  383         noise_remote_index_remove(l, r);
  384 
  385         NET_EPOCH_ENTER(et);
  386 assign_id:
  387         r_i->i_local_index = arc4random();
  388         idx = r_i->i_local_index & HT_INDEX_MASK;
  389         CK_LIST_FOREACH(i, &l->l_index_hash[idx], i_entry) {
  390                 if (i->i_local_index == r_i->i_local_index)
  391                         goto assign_id;
  392         }
  393 
  394         mtx_lock(&l->l_index_mtx);
  395         CK_LIST_FOREACH(i, &l->l_index_hash[idx], i_entry) {
  396                 if (i->i_local_index == r_i->i_local_index) {
  397                         mtx_unlock(&l->l_index_mtx);
  398                         goto assign_id;
  399                 }
  400         }
  401         CK_LIST_INSERT_HEAD(&l->l_index_hash[idx], r_i, i_entry);
  402         mtx_unlock(&l->l_index_mtx);
  403 
  404         NET_EPOCH_EXIT(et);
  405 }
  406 
  407 static struct noise_remote *
  408 noise_remote_index_lookup(struct noise_local *l, uint32_t idx0, bool lookup_keypair)
  409 {
  410         struct epoch_tracker et;
  411         struct noise_index *i;
  412         struct noise_keypair *kp;
  413         struct noise_remote *r, *ret = NULL;
  414         uint32_t idx = idx0 & HT_INDEX_MASK;
  415 
  416         NET_EPOCH_ENTER(et);
  417         CK_LIST_FOREACH(i, &l->l_index_hash[idx], i_entry) {
  418                 if (i->i_local_index == idx0) {
  419                         if (!i->i_is_keypair) {
  420                                 r = (struct noise_remote *) i;
  421                         } else if (lookup_keypair) {
  422                                 kp = (struct noise_keypair *) i;
  423                                 r = kp->kp_remote;
  424                         } else {
  425                                 break;
  426                         }
  427                         if (refcount_acquire_if_not_zero(&r->r_refcnt))
  428                                 ret = r;
  429                         break;
  430                 }
  431         }
  432         NET_EPOCH_EXIT(et);
  433         return (ret);
  434 }
  435 
  436 struct noise_remote *
  437 noise_remote_index(struct noise_local *l, uint32_t idx)
  438 {
  439         return noise_remote_index_lookup(l, idx, true);
  440 }
  441 
  442 static int
  443 noise_remote_index_remove(struct noise_local *l, struct noise_remote *r)
  444 {
  445         rw_assert(&r->r_handshake_lock, RA_WLOCKED);
  446         if (r->r_handshake_state != HANDSHAKE_DEAD) {
  447                 mtx_lock(&l->l_index_mtx);
  448                 r->r_handshake_state = HANDSHAKE_DEAD;
  449                 CK_LIST_REMOVE(&r->r_index, i_entry);
  450                 mtx_unlock(&l->l_index_mtx);
  451                 return (1);
  452         }
  453         return (0);
  454 }
  455 
  456 struct noise_remote *
  457 noise_remote_ref(struct noise_remote *r)
  458 {
  459         refcount_acquire(&r->r_refcnt);
  460         return (r);
  461 }
  462 
  463 static void
  464 noise_remote_smr_free(struct epoch_context *smr)
  465 {
  466         struct noise_remote *r;
  467         r = __containerof(smr, struct noise_remote, r_smr);
  468         if (r->r_cleanup != NULL)
  469                 r->r_cleanup(r);
  470         noise_local_put(r->r_local);
  471         rw_destroy(&r->r_handshake_lock);
  472         mtx_destroy(&r->r_keypair_mtx);
  473         zfree(r, M_NOISE);
  474 }
  475 
  476 void
  477 noise_remote_put(struct noise_remote *r)
  478 {
  479         if (refcount_release(&r->r_refcnt))
  480                 NET_EPOCH_CALL(noise_remote_smr_free, &r->r_smr);
  481 }
  482 
  483 void
  484 noise_remote_free(struct noise_remote *r, void (*cleanup)(struct noise_remote *))
  485 {
  486         r->r_cleanup = cleanup;
  487         noise_remote_disable(r);
  488 
  489         /* now clear all keypairs and handshakes, then put this reference */
  490         noise_remote_handshake_clear(r);
  491         noise_remote_keypairs_clear(r);
  492         noise_remote_put(r);
  493 }
  494 
  495 struct noise_local *
  496 noise_remote_local(struct noise_remote *r)
  497 {
  498         return (noise_local_ref(r->r_local));
  499 }
  500 
  501 void *
  502 noise_remote_arg(struct noise_remote *r)
  503 {
  504         return (r->r_arg);
  505 }
  506 
  507 void
  508 noise_remote_set_psk(struct noise_remote *r,
  509     const uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])
  510 {
  511         rw_wlock(&r->r_handshake_lock);
  512         if (psk == NULL)
  513                 bzero(r->r_psk, NOISE_SYMMETRIC_KEY_LEN);
  514         else
  515                 memcpy(r->r_psk, psk, NOISE_SYMMETRIC_KEY_LEN);
  516         rw_wunlock(&r->r_handshake_lock);
  517 }
  518 
  519 int
  520 noise_remote_keys(struct noise_remote *r, uint8_t public[NOISE_PUBLIC_KEY_LEN],
  521     uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])
  522 {
  523         static uint8_t null_psk[NOISE_SYMMETRIC_KEY_LEN];
  524         int ret;
  525 
  526         if (public != NULL)
  527                 memcpy(public, r->r_public, NOISE_PUBLIC_KEY_LEN);
  528 
  529         rw_rlock(&r->r_handshake_lock);
  530         if (psk != NULL)
  531                 memcpy(psk, r->r_psk, NOISE_SYMMETRIC_KEY_LEN);
  532         ret = timingsafe_bcmp(r->r_psk, null_psk, NOISE_SYMMETRIC_KEY_LEN);
  533         rw_runlock(&r->r_handshake_lock);
  534 
  535         return (ret ? 0 : ENOENT);
  536 }
  537 
  538 int
  539 noise_remote_initiation_expired(struct noise_remote *r)
  540 {
  541         int expired;
  542         rw_rlock(&r->r_handshake_lock);
  543         expired = noise_timer_expired(r->r_last_sent, REKEY_TIMEOUT, 0);
  544         rw_runlock(&r->r_handshake_lock);
  545         return (expired);
  546 }
  547 
  548 void
  549 noise_remote_handshake_clear(struct noise_remote *r)
  550 {
  551         rw_wlock(&r->r_handshake_lock);
  552         if (noise_remote_index_remove(r->r_local, r))
  553                 bzero(&r->r_handshake, sizeof(r->r_handshake));
  554         r->r_last_sent = TIMER_RESET;
  555         rw_wunlock(&r->r_handshake_lock);
  556 }
  557 
  558 void
  559 noise_remote_keypairs_clear(struct noise_remote *r)
  560 {
  561         struct noise_keypair *kp;
  562 
  563         mtx_lock(&r->r_keypair_mtx);
  564         kp = atomic_load_ptr(&r->r_next);
  565         atomic_store_ptr(&r->r_next, NULL);
  566         noise_keypair_drop(kp);
  567 
  568         kp = atomic_load_ptr(&r->r_current);
  569         atomic_store_ptr(&r->r_current, NULL);
  570         noise_keypair_drop(kp);
  571 
  572         kp = atomic_load_ptr(&r->r_previous);
  573         atomic_store_ptr(&r->r_previous, NULL);
  574         noise_keypair_drop(kp);
  575         mtx_unlock(&r->r_keypair_mtx);
  576 }
  577 
  578 static void
  579 noise_remote_expire_current(struct noise_remote *r)
  580 {
  581         struct epoch_tracker et;
  582         struct noise_keypair *kp;
  583 
  584         noise_remote_handshake_clear(r);
  585 
  586         NET_EPOCH_ENTER(et);
  587         kp = atomic_load_ptr(&r->r_next);
  588         if (kp != NULL)
  589                 atomic_store_bool(&kp->kp_can_send, false);
  590         kp = atomic_load_ptr(&r->r_current);
  591         if (kp != NULL)
  592                 atomic_store_bool(&kp->kp_can_send, false);
  593         NET_EPOCH_EXIT(et);
  594 }
  595 
  596 /* Keypair functions */
  597 static void
  598 noise_add_new_keypair(struct noise_local *l, struct noise_remote *r,
  599     struct noise_keypair *kp)
  600 {
  601         struct noise_keypair *next, *current, *previous;
  602         struct noise_index *r_i = &r->r_index;
  603 
  604         /* Insert into the keypair table */
  605         mtx_lock(&r->r_keypair_mtx);
  606         next = atomic_load_ptr(&r->r_next);
  607         current = atomic_load_ptr(&r->r_current);
  608         previous = atomic_load_ptr(&r->r_previous);
  609 
  610         if (kp->kp_is_initiator) {
  611                 if (next != NULL) {
  612                         atomic_store_ptr(&r->r_next, NULL);
  613                         atomic_store_ptr(&r->r_previous, next);
  614                         noise_keypair_drop(current);
  615                 } else {
  616                         atomic_store_ptr(&r->r_previous, current);
  617                 }
  618                 noise_keypair_drop(previous);
  619                 atomic_store_ptr(&r->r_current, kp);
  620         } else {
  621                 atomic_store_ptr(&r->r_next, kp);
  622                 noise_keypair_drop(next);
  623                 atomic_store_ptr(&r->r_previous, NULL);
  624                 noise_keypair_drop(previous);
  625 
  626         }
  627         mtx_unlock(&r->r_keypair_mtx);
  628 
  629         /* Insert into index table */
  630         rw_assert(&r->r_handshake_lock, RA_WLOCKED);
  631 
  632         kp->kp_index.i_is_keypair = true;
  633         kp->kp_index.i_local_index = r_i->i_local_index;
  634         kp->kp_index.i_remote_index = r_i->i_remote_index;
  635 
  636         mtx_lock(&l->l_index_mtx);
  637         CK_LIST_INSERT_BEFORE(r_i, &kp->kp_index, i_entry);
  638         r->r_handshake_state = HANDSHAKE_DEAD;
  639         CK_LIST_REMOVE(r_i, i_entry);
  640         mtx_unlock(&l->l_index_mtx);
  641 
  642         explicit_bzero(&r->r_handshake, sizeof(r->r_handshake));
  643 }
  644 
  645 static int
  646 noise_begin_session(struct noise_remote *r)
  647 {
  648         struct noise_keypair *kp;
  649 
  650         rw_assert(&r->r_handshake_lock, RA_WLOCKED);
  651 
  652         if ((kp = malloc(sizeof(*kp), M_NOISE, M_NOWAIT | M_ZERO)) == NULL)
  653                 return (ENOSPC);
  654 
  655         refcount_init(&kp->kp_refcnt, 1);
  656         kp->kp_can_send = true;
  657         kp->kp_is_initiator = r->r_handshake_state == HANDSHAKE_INITIATOR;
  658         kp->kp_birthdate = getsbinuptime();
  659         kp->kp_remote = noise_remote_ref(r);
  660 
  661         if (kp->kp_is_initiator)
  662                 noise_kdf(kp->kp_send, kp->kp_recv, NULL, NULL,
  663                     NOISE_SYMMETRIC_KEY_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, 0,
  664                     r->r_handshake.hs_ck);
  665         else
  666                 noise_kdf(kp->kp_recv, kp->kp_send, NULL, NULL,
  667                     NOISE_SYMMETRIC_KEY_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, 0,
  668                     r->r_handshake.hs_ck);
  669 
  670         rw_init(&kp->kp_nonce_lock, "noise_nonce");
  671 
  672         noise_add_new_keypair(r->r_local, r, kp);
  673         return (0);
  674 }
  675 
  676 struct noise_keypair *
  677 noise_keypair_lookup(struct noise_local *l, uint32_t idx0)
  678 {
  679         struct epoch_tracker et;
  680         struct noise_index *i;
  681         struct noise_keypair *kp, *ret = NULL;
  682         uint32_t idx = idx0 & HT_INDEX_MASK;
  683 
  684         NET_EPOCH_ENTER(et);
  685         CK_LIST_FOREACH(i, &l->l_index_hash[idx], i_entry) {
  686                 if (i->i_local_index == idx0 && i->i_is_keypair) {
  687                         kp = (struct noise_keypair *) i;
  688                         if (refcount_acquire_if_not_zero(&kp->kp_refcnt))
  689                                 ret = kp;
  690                         break;
  691                 }
  692         }
  693         NET_EPOCH_EXIT(et);
  694         return (ret);
  695 }
  696 
  697 struct noise_keypair *
  698 noise_keypair_current(struct noise_remote *r)
  699 {
  700         struct epoch_tracker et;
  701         struct noise_keypair *kp, *ret = NULL;
  702 
  703         NET_EPOCH_ENTER(et);
  704         kp = atomic_load_ptr(&r->r_current);
  705         if (kp != NULL && atomic_load_bool(&kp->kp_can_send)) {
  706                 if (noise_timer_expired(kp->kp_birthdate, REJECT_AFTER_TIME, 0))
  707                         atomic_store_bool(&kp->kp_can_send, false);
  708                 else if (refcount_acquire_if_not_zero(&kp->kp_refcnt))
  709                         ret = kp;
  710         }
  711         NET_EPOCH_EXIT(et);
  712         return (ret);
  713 }
  714 
  715 struct noise_keypair *
  716 noise_keypair_ref(struct noise_keypair *kp)
  717 {
  718         refcount_acquire(&kp->kp_refcnt);
  719         return (kp);
  720 }
  721 
  722 int
  723 noise_keypair_received_with(struct noise_keypair *kp)
  724 {
  725         struct noise_keypair *old;
  726         struct noise_remote *r = kp->kp_remote;
  727 
  728         if (kp != atomic_load_ptr(&r->r_next))
  729                 return (0);
  730 
  731         mtx_lock(&r->r_keypair_mtx);
  732         if (kp != atomic_load_ptr(&r->r_next)) {
  733                 mtx_unlock(&r->r_keypair_mtx);
  734                 return (0);
  735         }
  736 
  737         old = atomic_load_ptr(&r->r_previous);
  738         atomic_store_ptr(&r->r_previous, atomic_load_ptr(&r->r_current));
  739         noise_keypair_drop(old);
  740         atomic_store_ptr(&r->r_current, kp);
  741         atomic_store_ptr(&r->r_next, NULL);
  742         mtx_unlock(&r->r_keypair_mtx);
  743 
  744         return (ECONNRESET);
  745 }
  746 
  747 static void
  748 noise_keypair_smr_free(struct epoch_context *smr)
  749 {
  750         struct noise_keypair *kp;
  751         kp = __containerof(smr, struct noise_keypair, kp_smr);
  752         noise_remote_put(kp->kp_remote);
  753         rw_destroy(&kp->kp_nonce_lock);
  754         zfree(kp, M_NOISE);
  755 }
  756 
  757 void
  758 noise_keypair_put(struct noise_keypair *kp)
  759 {
  760         if (refcount_release(&kp->kp_refcnt))
  761                 NET_EPOCH_CALL(noise_keypair_smr_free, &kp->kp_smr);
  762 }
  763 
  764 static void
  765 noise_keypair_drop(struct noise_keypair *kp)
  766 {
  767         struct noise_remote *r;
  768         struct noise_local *l;
  769 
  770         if (kp == NULL)
  771                 return;
  772 
  773         r = kp->kp_remote;
  774         l = r->r_local;
  775 
  776         mtx_lock(&l->l_index_mtx);
  777         CK_LIST_REMOVE(&kp->kp_index, i_entry);
  778         mtx_unlock(&l->l_index_mtx);
  779 
  780         noise_keypair_put(kp);
  781 }
  782 
  783 struct noise_remote *
  784 noise_keypair_remote(struct noise_keypair *kp)
  785 {
  786         return (noise_remote_ref(kp->kp_remote));
  787 }
  788 
  789 int
  790 noise_keypair_nonce_next(struct noise_keypair *kp, uint64_t *send)
  791 {
  792         if (!atomic_load_bool(&kp->kp_can_send))
  793                 return (EINVAL);
  794 
  795 #ifdef __LP64__
  796         *send = atomic_fetchadd_64(&kp->kp_nonce_send, 1);
  797 #else
  798         rw_wlock(&kp->kp_nonce_lock);
  799         *send = kp->kp_nonce_send++;
  800         rw_wunlock(&kp->kp_nonce_lock);
  801 #endif
  802         if (*send < REJECT_AFTER_MESSAGES)
  803                 return (0);
  804         atomic_store_bool(&kp->kp_can_send, false);
  805         return (EINVAL);
  806 }
  807 
  808 int
  809 noise_keypair_nonce_check(struct noise_keypair *kp, uint64_t recv)
  810 {
  811         unsigned long index, index_current, top, i, bit;
  812         int ret = EEXIST;
  813 
  814         rw_wlock(&kp->kp_nonce_lock);
  815 
  816         if (__predict_false(kp->kp_nonce_recv >= REJECT_AFTER_MESSAGES + 1 ||
  817                             recv >= REJECT_AFTER_MESSAGES))
  818                 goto error;
  819 
  820         ++recv;
  821 
  822         if (__predict_false(recv + COUNTER_WINDOW_SIZE < kp->kp_nonce_recv))
  823                 goto error;
  824 
  825         index = recv >> COUNTER_ORDER;
  826 
  827         if (__predict_true(recv > kp->kp_nonce_recv)) {
  828                 index_current = kp->kp_nonce_recv >> COUNTER_ORDER;
  829                 top = MIN(index - index_current, COUNTER_BITS_TOTAL / COUNTER_BITS);
  830                 for (i = 1; i <= top; i++)
  831                         kp->kp_backtrack[
  832                             (i + index_current) &
  833                                 ((COUNTER_BITS_TOTAL / COUNTER_BITS) - 1)] = 0;
  834 #ifdef __LP64__
  835                 atomic_store_64(&kp->kp_nonce_recv, recv);
  836 #else
  837                 kp->kp_nonce_recv = recv;
  838 #endif
  839         }
  840 
  841         index &= (COUNTER_BITS_TOTAL / COUNTER_BITS) - 1;
  842         bit = 1ul << (recv & (COUNTER_BITS - 1));
  843         if (kp->kp_backtrack[index] & bit)
  844                 goto error;
  845 
  846         kp->kp_backtrack[index] |= bit;
  847         ret = 0;
  848 error:
  849         rw_wunlock(&kp->kp_nonce_lock);
  850         return (ret);
  851 }
  852 
  853 int
  854 noise_keep_key_fresh_send(struct noise_remote *r)
  855 {
  856         struct epoch_tracker et;
  857         struct noise_keypair *current;
  858         int keep_key_fresh;
  859         uint64_t nonce;
  860 
  861         NET_EPOCH_ENTER(et);
  862         current = atomic_load_ptr(&r->r_current);
  863         keep_key_fresh = current != NULL && atomic_load_bool(&current->kp_can_send);
  864         if (!keep_key_fresh)
  865                 goto out;
  866 #ifdef __LP64__
  867         nonce = atomic_load_64(&current->kp_nonce_send);
  868 #else
  869         rw_rlock(&current->kp_nonce_lock);
  870         nonce = current->kp_nonce_send;
  871         rw_runlock(&current->kp_nonce_lock);
  872 #endif
  873         keep_key_fresh = nonce > REKEY_AFTER_MESSAGES;
  874         if (keep_key_fresh)
  875                 goto out;
  876         keep_key_fresh = current->kp_is_initiator && noise_timer_expired(current->kp_birthdate, REKEY_AFTER_TIME, 0);
  877 
  878 out:
  879         NET_EPOCH_EXIT(et);
  880         return (keep_key_fresh ? ESTALE : 0);
  881 }
  882 
  883 int
  884 noise_keep_key_fresh_recv(struct noise_remote *r)
  885 {
  886         struct epoch_tracker et;
  887         struct noise_keypair *current;
  888         int keep_key_fresh;
  889 
  890         NET_EPOCH_ENTER(et);
  891         current = atomic_load_ptr(&r->r_current);
  892         keep_key_fresh = current != NULL && atomic_load_bool(&current->kp_can_send) &&
  893             current->kp_is_initiator && noise_timer_expired(current->kp_birthdate,
  894             REJECT_AFTER_TIME - KEEPALIVE_TIMEOUT - REKEY_TIMEOUT, 0);
  895         NET_EPOCH_EXIT(et);
  896 
  897         return (keep_key_fresh ? ESTALE : 0);
  898 }
  899 
  900 int
  901 noise_keypair_encrypt(struct noise_keypair *kp, uint32_t *r_idx, uint64_t nonce, struct mbuf *m)
  902 {
  903         int ret;
  904 
  905         ret = chacha20poly1305_encrypt_mbuf(m, nonce, kp->kp_send);
  906         if (ret)
  907                 return (ret);
  908 
  909         *r_idx = kp->kp_index.i_remote_index;
  910         return (0);
  911 }
  912 
  913 int
  914 noise_keypair_decrypt(struct noise_keypair *kp, uint64_t nonce, struct mbuf *m)
  915 {
  916         uint64_t cur_nonce;
  917         int ret;
  918 
  919 #ifdef __LP64__
  920         cur_nonce = atomic_load_64(&kp->kp_nonce_recv);
  921 #else
  922         rw_rlock(&kp->kp_nonce_lock);
  923         cur_nonce = kp->kp_nonce_recv;
  924         rw_runlock(&kp->kp_nonce_lock);
  925 #endif
  926 
  927         if (cur_nonce >= REJECT_AFTER_MESSAGES ||
  928             noise_timer_expired(kp->kp_birthdate, REJECT_AFTER_TIME, 0))
  929                 return (EINVAL);
  930 
  931         ret = chacha20poly1305_decrypt_mbuf(m, nonce, kp->kp_recv);
  932         if (ret)
  933                 return (ret);
  934 
  935         return (0);
  936 }
  937 
  938 /* Handshake functions */
  939 int
  940 noise_create_initiation(struct noise_remote *r,
  941     uint32_t *s_idx,
  942     uint8_t ue[NOISE_PUBLIC_KEY_LEN],
  943     uint8_t es[NOISE_PUBLIC_KEY_LEN + NOISE_AUTHTAG_LEN],
  944     uint8_t ets[NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN])
  945 {
  946         struct noise_handshake *hs = &r->r_handshake;
  947         struct noise_local *l = r->r_local;
  948         uint8_t key[NOISE_SYMMETRIC_KEY_LEN];
  949         int ret = EINVAL;
  950 
  951         rw_rlock(&l->l_identity_lock);
  952         rw_wlock(&r->r_handshake_lock);
  953         if (!l->l_has_identity)
  954                 goto error;
  955         if (!noise_timer_expired(r->r_last_sent, REKEY_TIMEOUT, 0))
  956                 goto error;
  957         noise_param_init(hs->hs_ck, hs->hs_hash, r->r_public);
  958 
  959         /* e */
  960         curve25519_generate_secret(hs->hs_e);
  961         if (curve25519_generate_public(ue, hs->hs_e) == 0)
  962                 goto error;
  963         noise_msg_ephemeral(hs->hs_ck, hs->hs_hash, ue);
  964 
  965         /* es */
  966         if (noise_mix_dh(hs->hs_ck, key, hs->hs_e, r->r_public) != 0)
  967                 goto error;
  968 
  969         /* s */
  970         noise_msg_encrypt(es, l->l_public,
  971             NOISE_PUBLIC_KEY_LEN, key, hs->hs_hash);
  972 
  973         /* ss */
  974         if (noise_mix_ss(hs->hs_ck, key, r->r_ss) != 0)
  975                 goto error;
  976 
  977         /* {t} */
  978         noise_tai64n_now(ets);
  979         noise_msg_encrypt(ets, ets,
  980             NOISE_TIMESTAMP_LEN, key, hs->hs_hash);
  981 
  982         noise_remote_index_insert(l, r);
  983         r->r_handshake_state = HANDSHAKE_INITIATOR;
  984         r->r_last_sent = getsbinuptime();
  985         *s_idx = r->r_index.i_local_index;
  986         ret = 0;
  987 error:
  988         rw_wunlock(&r->r_handshake_lock);
  989         rw_runlock(&l->l_identity_lock);
  990         explicit_bzero(key, NOISE_SYMMETRIC_KEY_LEN);
  991         return (ret);
  992 }
  993 
  994 int
  995 noise_consume_initiation(struct noise_local *l, struct noise_remote **rp,
  996     uint32_t s_idx,
  997     uint8_t ue[NOISE_PUBLIC_KEY_LEN],
  998     uint8_t es[NOISE_PUBLIC_KEY_LEN + NOISE_AUTHTAG_LEN],
  999     uint8_t ets[NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN])
 1000 {
 1001         struct noise_remote *r;
 1002         struct noise_handshake hs;
 1003         uint8_t key[NOISE_SYMMETRIC_KEY_LEN];
 1004         uint8_t r_public[NOISE_PUBLIC_KEY_LEN];
 1005         uint8_t timestamp[NOISE_TIMESTAMP_LEN];
 1006         int ret = EINVAL;
 1007 
 1008         rw_rlock(&l->l_identity_lock);
 1009         if (!l->l_has_identity)
 1010                 goto error;
 1011         noise_param_init(hs.hs_ck, hs.hs_hash, l->l_public);
 1012 
 1013         /* e */
 1014         noise_msg_ephemeral(hs.hs_ck, hs.hs_hash, ue);
 1015 
 1016         /* es */
 1017         if (noise_mix_dh(hs.hs_ck, key, l->l_private, ue) != 0)
 1018                 goto error;
 1019 
 1020         /* s */
 1021         if (noise_msg_decrypt(r_public, es,
 1022             NOISE_PUBLIC_KEY_LEN + NOISE_AUTHTAG_LEN, key, hs.hs_hash) != 0)
 1023                 goto error;
 1024 
 1025         /* Lookup the remote we received from */
 1026         if ((r = noise_remote_lookup(l, r_public)) == NULL)
 1027                 goto error;
 1028 
 1029         /* ss */
 1030         if (noise_mix_ss(hs.hs_ck, key, r->r_ss) != 0)
 1031                 goto error_put;
 1032 
 1033         /* {t} */
 1034         if (noise_msg_decrypt(timestamp, ets,
 1035             NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN, key, hs.hs_hash) != 0)
 1036                 goto error_put;
 1037 
 1038         memcpy(hs.hs_e, ue, NOISE_PUBLIC_KEY_LEN);
 1039 
 1040         /* We have successfully computed the same results, now we ensure that
 1041          * this is not an initiation replay, or a flood attack */
 1042         rw_wlock(&r->r_handshake_lock);
 1043 
 1044         /* Replay */
 1045         if (memcmp(timestamp, r->r_timestamp, NOISE_TIMESTAMP_LEN) > 0)
 1046                 memcpy(r->r_timestamp, timestamp, NOISE_TIMESTAMP_LEN);
 1047         else
 1048                 goto error_set;
 1049         /* Flood attack */
 1050         if (noise_timer_expired(r->r_last_init_recv, 0, REJECT_INTERVAL))
 1051                 r->r_last_init_recv = getsbinuptime();
 1052         else
 1053                 goto error_set;
 1054 
 1055         /* Ok, we're happy to accept this initiation now */
 1056         noise_remote_index_insert(l, r);
 1057         r->r_index.i_remote_index = s_idx;
 1058         r->r_handshake_state = HANDSHAKE_RESPONDER;
 1059         r->r_handshake = hs;
 1060         *rp = noise_remote_ref(r);
 1061         ret = 0;
 1062 error_set:
 1063         rw_wunlock(&r->r_handshake_lock);
 1064 error_put:
 1065         noise_remote_put(r);
 1066 error:
 1067         rw_runlock(&l->l_identity_lock);
 1068         explicit_bzero(key, NOISE_SYMMETRIC_KEY_LEN);
 1069         explicit_bzero(&hs, sizeof(hs));
 1070         return (ret);
 1071 }
 1072 
 1073 int
 1074 noise_create_response(struct noise_remote *r,
 1075     uint32_t *s_idx, uint32_t *r_idx,
 1076     uint8_t ue[NOISE_PUBLIC_KEY_LEN],
 1077     uint8_t en[0 + NOISE_AUTHTAG_LEN])
 1078 {
 1079         struct noise_handshake *hs = &r->r_handshake;
 1080         struct noise_local *l = r->r_local;
 1081         uint8_t key[NOISE_SYMMETRIC_KEY_LEN];
 1082         uint8_t e[NOISE_PUBLIC_KEY_LEN];
 1083         int ret = EINVAL;
 1084 
 1085         rw_rlock(&l->l_identity_lock);
 1086         rw_wlock(&r->r_handshake_lock);
 1087 
 1088         if (r->r_handshake_state != HANDSHAKE_RESPONDER)
 1089                 goto error;
 1090 
 1091         /* e */
 1092         curve25519_generate_secret(e);
 1093         if (curve25519_generate_public(ue, e) == 0)
 1094                 goto error;
 1095         noise_msg_ephemeral(hs->hs_ck, hs->hs_hash, ue);
 1096 
 1097         /* ee */
 1098         if (noise_mix_dh(hs->hs_ck, NULL, e, hs->hs_e) != 0)
 1099                 goto error;
 1100 
 1101         /* se */
 1102         if (noise_mix_dh(hs->hs_ck, NULL, e, r->r_public) != 0)
 1103                 goto error;
 1104 
 1105         /* psk */
 1106         noise_mix_psk(hs->hs_ck, hs->hs_hash, key, r->r_psk);
 1107 
 1108         /* {} */
 1109         noise_msg_encrypt(en, NULL, 0, key, hs->hs_hash);
 1110 
 1111         if ((ret = noise_begin_session(r)) == 0) {
 1112                 r->r_last_sent = getsbinuptime();
 1113                 *s_idx = r->r_index.i_local_index;
 1114                 *r_idx = r->r_index.i_remote_index;
 1115         }
 1116 error:
 1117         rw_wunlock(&r->r_handshake_lock);
 1118         rw_runlock(&l->l_identity_lock);
 1119         explicit_bzero(key, NOISE_SYMMETRIC_KEY_LEN);
 1120         explicit_bzero(e, NOISE_PUBLIC_KEY_LEN);
 1121         return (ret);
 1122 }
 1123 
 1124 int
 1125 noise_consume_response(struct noise_local *l, struct noise_remote **rp,
 1126     uint32_t s_idx, uint32_t r_idx,
 1127     uint8_t ue[NOISE_PUBLIC_KEY_LEN],
 1128     uint8_t en[0 + NOISE_AUTHTAG_LEN])
 1129 {
 1130         uint8_t preshared_key[NOISE_SYMMETRIC_KEY_LEN];
 1131         uint8_t key[NOISE_SYMMETRIC_KEY_LEN];
 1132         struct noise_handshake hs;
 1133         struct noise_remote *r = NULL;
 1134         int ret = EINVAL;
 1135 
 1136         if ((r = noise_remote_index_lookup(l, r_idx, false)) == NULL)
 1137                 return (ret);
 1138 
 1139         rw_rlock(&l->l_identity_lock);
 1140         if (!l->l_has_identity)
 1141                 goto error;
 1142 
 1143         rw_rlock(&r->r_handshake_lock);
 1144         if (r->r_handshake_state != HANDSHAKE_INITIATOR) {
 1145                 rw_runlock(&r->r_handshake_lock);
 1146                 goto error;
 1147         }
 1148         memcpy(preshared_key, r->r_psk, NOISE_SYMMETRIC_KEY_LEN);
 1149         hs = r->r_handshake;
 1150         rw_runlock(&r->r_handshake_lock);
 1151 
 1152         /* e */
 1153         noise_msg_ephemeral(hs.hs_ck, hs.hs_hash, ue);
 1154 
 1155         /* ee */
 1156         if (noise_mix_dh(hs.hs_ck, NULL, hs.hs_e, ue) != 0)
 1157                 goto error_zero;
 1158 
 1159         /* se */
 1160         if (noise_mix_dh(hs.hs_ck, NULL, l->l_private, ue) != 0)
 1161                 goto error_zero;
 1162 
 1163         /* psk */
 1164         noise_mix_psk(hs.hs_ck, hs.hs_hash, key, preshared_key);
 1165 
 1166         /* {} */
 1167         if (noise_msg_decrypt(NULL, en,
 1168             0 + NOISE_AUTHTAG_LEN, key, hs.hs_hash) != 0)
 1169                 goto error_zero;
 1170 
 1171         rw_wlock(&r->r_handshake_lock);
 1172         if (r->r_handshake_state == HANDSHAKE_INITIATOR &&
 1173             r->r_index.i_local_index == r_idx) {
 1174                 r->r_handshake = hs;
 1175                 r->r_index.i_remote_index = s_idx;
 1176                 if ((ret = noise_begin_session(r)) == 0)
 1177                         *rp = noise_remote_ref(r);
 1178         }
 1179         rw_wunlock(&r->r_handshake_lock);
 1180 error_zero:
 1181         explicit_bzero(preshared_key, NOISE_SYMMETRIC_KEY_LEN);
 1182         explicit_bzero(key, NOISE_SYMMETRIC_KEY_LEN);
 1183         explicit_bzero(&hs, sizeof(hs));
 1184 error:
 1185         rw_runlock(&l->l_identity_lock);
 1186         noise_remote_put(r);
 1187         return (ret);
 1188 }
 1189 
 1190 static void
 1191 hmac(uint8_t *out, const uint8_t *in, const uint8_t *key, const size_t outlen,
 1192      const size_t inlen, const size_t keylen)
 1193 {
 1194         struct blake2s_state state;
 1195         uint8_t x_key[BLAKE2S_BLOCK_SIZE] __aligned(sizeof(uint32_t)) = { 0 };
 1196         uint8_t i_hash[BLAKE2S_HASH_SIZE] __aligned(sizeof(uint32_t));
 1197         int i;
 1198 
 1199         if (keylen > BLAKE2S_BLOCK_SIZE) {
 1200                 blake2s_init(&state, BLAKE2S_HASH_SIZE);
 1201                 blake2s_update(&state, key, keylen);
 1202                 blake2s_final(&state, x_key);
 1203         } else
 1204                 memcpy(x_key, key, keylen);
 1205 
 1206         for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i)
 1207                 x_key[i] ^= 0x36;
 1208 
 1209         blake2s_init(&state, BLAKE2S_HASH_SIZE);
 1210         blake2s_update(&state, x_key, BLAKE2S_BLOCK_SIZE);
 1211         blake2s_update(&state, in, inlen);
 1212         blake2s_final(&state, i_hash);
 1213 
 1214         for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i)
 1215                 x_key[i] ^= 0x5c ^ 0x36;
 1216 
 1217         blake2s_init(&state, BLAKE2S_HASH_SIZE);
 1218         blake2s_update(&state, x_key, BLAKE2S_BLOCK_SIZE);
 1219         blake2s_update(&state, i_hash, BLAKE2S_HASH_SIZE);
 1220         blake2s_final(&state, i_hash);
 1221 
 1222         memcpy(out, i_hash, outlen);
 1223         explicit_bzero(x_key, BLAKE2S_BLOCK_SIZE);
 1224         explicit_bzero(i_hash, BLAKE2S_HASH_SIZE);
 1225 }
 1226 
 1227 /* Handshake helper functions */
 1228 static void
 1229 noise_kdf(uint8_t *a, uint8_t *b, uint8_t *c, const uint8_t *x,
 1230     size_t a_len, size_t b_len, size_t c_len, size_t x_len,
 1231     const uint8_t ck[NOISE_HASH_LEN])
 1232 {
 1233         uint8_t out[BLAKE2S_HASH_SIZE + 1];
 1234         uint8_t sec[BLAKE2S_HASH_SIZE];
 1235 
 1236         /* Extract entropy from "x" into sec */
 1237         hmac(sec, x, ck, BLAKE2S_HASH_SIZE, x_len, NOISE_HASH_LEN);
 1238 
 1239         if (a == NULL || a_len == 0)
 1240                 goto out;
 1241 
 1242         /* Expand first key: key = sec, data = 0x1 */
 1243         out[0] = 1;
 1244         hmac(out, out, sec, BLAKE2S_HASH_SIZE, 1, BLAKE2S_HASH_SIZE);
 1245         memcpy(a, out, a_len);
 1246 
 1247         if (b == NULL || b_len == 0)
 1248                 goto out;
 1249 
 1250         /* Expand second key: key = sec, data = "a" || 0x2 */
 1251         out[BLAKE2S_HASH_SIZE] = 2;
 1252         hmac(out, out, sec, BLAKE2S_HASH_SIZE, BLAKE2S_HASH_SIZE + 1, BLAKE2S_HASH_SIZE);
 1253         memcpy(b, out, b_len);
 1254 
 1255         if (c == NULL || c_len == 0)
 1256                 goto out;
 1257 
 1258         /* Expand third key: key = sec, data = "b" || 0x3 */
 1259         out[BLAKE2S_HASH_SIZE] = 3;
 1260         hmac(out, out, sec, BLAKE2S_HASH_SIZE, BLAKE2S_HASH_SIZE + 1, BLAKE2S_HASH_SIZE);
 1261         memcpy(c, out, c_len);
 1262 
 1263 out:
 1264         /* Clear sensitive data from stack */
 1265         explicit_bzero(sec, BLAKE2S_HASH_SIZE);
 1266         explicit_bzero(out, BLAKE2S_HASH_SIZE + 1);
 1267 }
 1268 
 1269 static int
 1270 noise_mix_dh(uint8_t ck[NOISE_HASH_LEN], uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
 1271     const uint8_t private[NOISE_PUBLIC_KEY_LEN],
 1272     const uint8_t public[NOISE_PUBLIC_KEY_LEN])
 1273 {
 1274         uint8_t dh[NOISE_PUBLIC_KEY_LEN];
 1275 
 1276         if (!curve25519(dh, private, public))
 1277                 return (EINVAL);
 1278         noise_kdf(ck, key, NULL, dh,
 1279             NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN, ck);
 1280         explicit_bzero(dh, NOISE_PUBLIC_KEY_LEN);
 1281         return (0);
 1282 }
 1283 
 1284 static int
 1285 noise_mix_ss(uint8_t ck[NOISE_HASH_LEN], uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
 1286     const uint8_t ss[NOISE_PUBLIC_KEY_LEN])
 1287 {
 1288         static uint8_t null_point[NOISE_PUBLIC_KEY_LEN];
 1289         if (timingsafe_bcmp(ss, null_point, NOISE_PUBLIC_KEY_LEN) == 0)
 1290                 return (ENOENT);
 1291         noise_kdf(ck, key, NULL, ss,
 1292             NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN, ck);
 1293         return (0);
 1294 }
 1295 
 1296 static void
 1297 noise_mix_hash(uint8_t hash[NOISE_HASH_LEN], const uint8_t *src,
 1298     size_t src_len)
 1299 {
 1300         struct blake2s_state blake;
 1301 
 1302         blake2s_init(&blake, NOISE_HASH_LEN);
 1303         blake2s_update(&blake, hash, NOISE_HASH_LEN);
 1304         blake2s_update(&blake, src, src_len);
 1305         blake2s_final(&blake, hash);
 1306 }
 1307 
 1308 static void
 1309 noise_mix_psk(uint8_t ck[NOISE_HASH_LEN], uint8_t hash[NOISE_HASH_LEN],
 1310     uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
 1311     const uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])
 1312 {
 1313         uint8_t tmp[NOISE_HASH_LEN];
 1314 
 1315         noise_kdf(ck, tmp, key, psk,
 1316             NOISE_HASH_LEN, NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN,
 1317             NOISE_SYMMETRIC_KEY_LEN, ck);
 1318         noise_mix_hash(hash, tmp, NOISE_HASH_LEN);
 1319         explicit_bzero(tmp, NOISE_HASH_LEN);
 1320 }
 1321 
 1322 static void
 1323 noise_param_init(uint8_t ck[NOISE_HASH_LEN], uint8_t hash[NOISE_HASH_LEN],
 1324     const uint8_t s[NOISE_PUBLIC_KEY_LEN])
 1325 {
 1326         struct blake2s_state blake;
 1327 
 1328         blake2s(ck, (uint8_t *)NOISE_HANDSHAKE_NAME, NULL,
 1329             NOISE_HASH_LEN, strlen(NOISE_HANDSHAKE_NAME), 0);
 1330         blake2s_init(&blake, NOISE_HASH_LEN);
 1331         blake2s_update(&blake, ck, NOISE_HASH_LEN);
 1332         blake2s_update(&blake, (uint8_t *)NOISE_IDENTIFIER_NAME,
 1333             strlen(NOISE_IDENTIFIER_NAME));
 1334         blake2s_final(&blake, hash);
 1335 
 1336         noise_mix_hash(hash, s, NOISE_PUBLIC_KEY_LEN);
 1337 }
 1338 
 1339 static void
 1340 noise_msg_encrypt(uint8_t *dst, const uint8_t *src, size_t src_len,
 1341     uint8_t key[NOISE_SYMMETRIC_KEY_LEN], uint8_t hash[NOISE_HASH_LEN])
 1342 {
 1343         /* Nonce always zero for Noise_IK */
 1344         chacha20poly1305_encrypt(dst, src, src_len,
 1345             hash, NOISE_HASH_LEN, 0, key);
 1346         noise_mix_hash(hash, dst, src_len + NOISE_AUTHTAG_LEN);
 1347 }
 1348 
 1349 static int
 1350 noise_msg_decrypt(uint8_t *dst, const uint8_t *src, size_t src_len,
 1351     uint8_t key[NOISE_SYMMETRIC_KEY_LEN], uint8_t hash[NOISE_HASH_LEN])
 1352 {
 1353         /* Nonce always zero for Noise_IK */
 1354         if (!chacha20poly1305_decrypt(dst, src, src_len,
 1355             hash, NOISE_HASH_LEN, 0, key))
 1356                 return (EINVAL);
 1357         noise_mix_hash(hash, src, src_len);
 1358         return (0);
 1359 }
 1360 
 1361 static void
 1362 noise_msg_ephemeral(uint8_t ck[NOISE_HASH_LEN], uint8_t hash[NOISE_HASH_LEN],
 1363     const uint8_t src[NOISE_PUBLIC_KEY_LEN])
 1364 {
 1365         noise_mix_hash(hash, src, NOISE_PUBLIC_KEY_LEN);
 1366         noise_kdf(ck, NULL, NULL, src, NOISE_HASH_LEN, 0, 0,
 1367                   NOISE_PUBLIC_KEY_LEN, ck);
 1368 }
 1369 
 1370 static void
 1371 noise_tai64n_now(uint8_t output[NOISE_TIMESTAMP_LEN])
 1372 {
 1373         struct timespec time;
 1374         uint64_t sec;
 1375         uint32_t nsec;
 1376 
 1377         getnanotime(&time);
 1378 
 1379         /* Round down the nsec counter to limit precise timing leak. */
 1380         time.tv_nsec &= REJECT_INTERVAL_MASK;
 1381 
 1382         /* https://cr.yp.to/libtai/tai64.html */
 1383         sec = htobe64(0x400000000000000aULL + time.tv_sec);
 1384         nsec = htobe32(time.tv_nsec);
 1385 
 1386         /* memcpy to output buffer, assuming output could be unaligned. */
 1387         memcpy(output, &sec, sizeof(sec));
 1388         memcpy(output + sizeof(sec), &nsec, sizeof(nsec));
 1389 }
 1390 
 1391 static inline int
 1392 noise_timer_expired(sbintime_t timer, uint32_t sec, uint32_t nsec)
 1393 {
 1394         sbintime_t now = getsbinuptime();
 1395         return (now > (timer + sec * SBT_1S + nstosbt(nsec))) ? ETIMEDOUT : 0;
 1396 }
 1397 
 1398 static uint64_t siphash24(const uint8_t key[SIPHASH_KEY_LENGTH], const void *src, size_t len)
 1399 {
 1400         SIPHASH_CTX ctx;
 1401         return (SipHashX(&ctx, 2, 4, key, src, len));
 1402 }
 1403 
 1404 #ifdef SELFTESTS
 1405 #include "selftest/counter.c"
 1406 #endif /* SELFTESTS */

Cache object: 1e24ad53c142a9bbb613887a5b8b03a5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.