aboutsummaryrefslogtreecommitdiffstats
path: root/src/wg_noise.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wg_noise.c')
-rw-r--r--src/wg_noise.c67
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: