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