diff options
Diffstat (limited to 'src/wg_noise.c')
-rw-r--r-- | src/wg_noise.c | 67 |
1 files changed, 52 insertions, 15 deletions
diff --git a/src/wg_noise.c b/src/wg_noise.c index f8d823c..d562ed1 100644 --- a/src/wg_noise.c +++ b/src/wg_noise.c @@ -181,9 +181,7 @@ noise_local_alloc(void *arg) struct noise_local *l; size_t i; - l = malloc(sizeof(*l), M_NOISE, M_NOWAIT | M_ZERO); - if (!l) - return (NULL); + l = malloc(sizeof(*l), M_NOISE, M_WAITOK | M_ZERO); rw_init(&l->l_identity_lock, "noise_identity"); l->l_has_identity = false; @@ -297,8 +295,7 @@ noise_remote_alloc(struct noise_local *l, void *arg, { struct noise_remote *r; - if ((r = malloc(sizeof(*r), M_NOISE, M_NOWAIT | M_ZERO)) == NULL) - return (NULL); + r = malloc(sizeof(*r), M_NOISE, M_WAITOK | M_ZERO); memcpy(r->r_public, public, NOISE_PUBLIC_KEY_LEN); rw_init(&r->r_handshake_lock, "noise_handshake"); @@ -905,8 +902,11 @@ noise_keep_key_fresh_recv(struct noise_remote *r) int noise_keypair_encrypt(struct noise_keypair *kp, uint32_t *r_idx, uint64_t nonce, struct mbuf *m) { - if (chacha20poly1305_encrypt_mbuf(m, nonce, kp->kp_send) == 0) - return (ENOMEM); + int ret; + + ret = chacha20poly1305_encrypt_mbuf(m, nonce, kp->kp_send); + if (ret) + return (ret); *r_idx = kp->kp_index.i_remote_index; return (0); @@ -916,6 +916,7 @@ int noise_keypair_decrypt(struct noise_keypair *kp, uint64_t nonce, struct mbuf *m) { uint64_t cur_nonce; + int ret; #ifdef __LP64__ cur_nonce = ck_pr_load_64(&kp->kp_nonce_recv); @@ -929,8 +930,9 @@ noise_keypair_decrypt(struct noise_keypair *kp, uint64_t nonce, struct mbuf *m) noise_timer_expired(kp->kp_birthdate, REJECT_AFTER_TIME, 0)) return (EINVAL); - if (chacha20poly1305_decrypt_mbuf(m, nonce, kp->kp_recv) == 0) - return (EINVAL); + ret = chacha20poly1305_decrypt_mbuf(m, nonce, kp->kp_recv); + if (ret) + return (ret); return (0); } @@ -1187,6 +1189,43 @@ error: return (ret); } +static void +hmac(uint8_t *out, const uint8_t *in, const uint8_t *key, const size_t outlen, + const size_t inlen, const size_t keylen) +{ + struct blake2s_state state; + uint8_t x_key[BLAKE2S_BLOCK_SIZE] __aligned(sizeof(uint32_t)) = { 0 }; + uint8_t i_hash[BLAKE2S_HASH_SIZE] __aligned(sizeof(uint32_t)); + int i; + + if (keylen > BLAKE2S_BLOCK_SIZE) { + blake2s_init(&state, BLAKE2S_HASH_SIZE); + blake2s_update(&state, key, keylen); + blake2s_final(&state, x_key); + } else + memcpy(x_key, key, keylen); + + for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i) + x_key[i] ^= 0x36; + + blake2s_init(&state, BLAKE2S_HASH_SIZE); + blake2s_update(&state, x_key, BLAKE2S_BLOCK_SIZE); + blake2s_update(&state, in, inlen); + blake2s_final(&state, i_hash); + + for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i) + x_key[i] ^= 0x5c ^ 0x36; + + blake2s_init(&state, BLAKE2S_HASH_SIZE); + blake2s_update(&state, x_key, BLAKE2S_BLOCK_SIZE); + blake2s_update(&state, i_hash, BLAKE2S_HASH_SIZE); + blake2s_final(&state, i_hash); + + memcpy(out, i_hash, outlen); + explicit_bzero(x_key, BLAKE2S_BLOCK_SIZE); + explicit_bzero(i_hash, BLAKE2S_HASH_SIZE); +} + /* Handshake helper functions */ static void noise_kdf(uint8_t *a, uint8_t *b, uint8_t *c, const uint8_t *x, @@ -1197,14 +1236,14 @@ noise_kdf(uint8_t *a, uint8_t *b, uint8_t *c, const uint8_t *x, uint8_t sec[BLAKE2S_HASH_SIZE]; /* Extract entropy from "x" into sec */ - blake2s_hmac(sec, x, ck, BLAKE2S_HASH_SIZE, x_len, NOISE_HASH_LEN); + hmac(sec, x, ck, BLAKE2S_HASH_SIZE, x_len, NOISE_HASH_LEN); if (a == NULL || a_len == 0) goto out; /* Expand first key: key = sec, data = 0x1 */ out[0] = 1; - blake2s_hmac(out, out, sec, BLAKE2S_HASH_SIZE, 1, BLAKE2S_HASH_SIZE); + hmac(out, out, sec, BLAKE2S_HASH_SIZE, 1, BLAKE2S_HASH_SIZE); memcpy(a, out, a_len); if (b == NULL || b_len == 0) @@ -1212,8 +1251,7 @@ noise_kdf(uint8_t *a, uint8_t *b, uint8_t *c, const uint8_t *x, /* Expand second key: key = sec, data = "a" || 0x2 */ out[BLAKE2S_HASH_SIZE] = 2; - blake2s_hmac(out, out, sec, BLAKE2S_HASH_SIZE, BLAKE2S_HASH_SIZE + 1, - BLAKE2S_HASH_SIZE); + hmac(out, out, sec, BLAKE2S_HASH_SIZE, BLAKE2S_HASH_SIZE + 1, BLAKE2S_HASH_SIZE); memcpy(b, out, b_len); if (c == NULL || c_len == 0) @@ -1221,8 +1259,7 @@ noise_kdf(uint8_t *a, uint8_t *b, uint8_t *c, const uint8_t *x, /* Expand third key: key = sec, data = "b" || 0x3 */ out[BLAKE2S_HASH_SIZE] = 3; - blake2s_hmac(out, out, sec, BLAKE2S_HASH_SIZE, BLAKE2S_HASH_SIZE + 1, - BLAKE2S_HASH_SIZE); + hmac(out, out, sec, BLAKE2S_HASH_SIZE, BLAKE2S_HASH_SIZE + 1, BLAKE2S_HASH_SIZE); memcpy(c, out, c_len); out: |