| b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From 5fb6a3ba3af6aff7cdc53d319fc4cc6f79555ca1 Mon Sep 17 00:00:00 2001 |
| 2 | From: "Jason A. Donenfeld" <Jason@zx2c4.com> |
| 3 | Date: Tue, 11 Jan 2022 14:37:41 +0100 |
| 4 | Subject: lib/crypto: blake2s: move hmac construction into wireguard |
| 5 | |
| 6 | commit d8d83d8ab0a453e17e68b3a3bed1f940c34b8646 upstream. |
| 7 | |
| 8 | Basically nobody should use blake2s in an HMAC construction; it already |
| 9 | has a keyed variant. But unfortunately for historical reasons, Noise, |
| 10 | used by WireGuard, uses HKDF quite strictly, which means we have to use |
| 11 | this. Because this really shouldn't be used by others, this commit moves |
| 12 | it into wireguard's noise.c locally, so that kernels that aren't using |
| 13 | WireGuard don't get this superfluous code baked in. On m68k systems, |
| 14 | this shaves off ~314 bytes. |
| 15 | |
| 16 | Cc: Herbert Xu <herbert@gondor.apana.org.au> |
| 17 | Tested-by: Geert Uytterhoeven <geert@linux-m68k.org> |
| 18 | Acked-by: Ard Biesheuvel <ardb@kernel.org> |
| 19 | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> |
| 20 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| 21 | --- |
| 22 | drivers/net/wireguard/noise.c | 45 ++++++++++++++++++++++++++++++----- |
| 23 | include/crypto/blake2s.h | 3 --- |
| 24 | lib/crypto/blake2s-selftest.c | 31 ------------------------ |
| 25 | lib/crypto/blake2s.c | 37 ---------------------------- |
| 26 | 4 files changed, 39 insertions(+), 77 deletions(-) |
| 27 | |
| 28 | --- a/drivers/net/wireguard/noise.c |
| 29 | +++ b/drivers/net/wireguard/noise.c |
| 30 | @@ -302,6 +302,41 @@ void wg_noise_set_static_identity_privat |
| 31 | static_identity->static_public, private_key); |
| 32 | } |
| 33 | |
| 34 | +static void hmac(u8 *out, const u8 *in, const u8 *key, const size_t inlen, const size_t keylen) |
| 35 | +{ |
| 36 | + struct blake2s_state state; |
| 37 | + u8 x_key[BLAKE2S_BLOCK_SIZE] __aligned(__alignof__(u32)) = { 0 }; |
| 38 | + u8 i_hash[BLAKE2S_HASH_SIZE] __aligned(__alignof__(u32)); |
| 39 | + int i; |
| 40 | + |
| 41 | + if (keylen > BLAKE2S_BLOCK_SIZE) { |
| 42 | + blake2s_init(&state, BLAKE2S_HASH_SIZE); |
| 43 | + blake2s_update(&state, key, keylen); |
| 44 | + blake2s_final(&state, x_key); |
| 45 | + } else |
| 46 | + memcpy(x_key, key, keylen); |
| 47 | + |
| 48 | + for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i) |
| 49 | + x_key[i] ^= 0x36; |
| 50 | + |
| 51 | + blake2s_init(&state, BLAKE2S_HASH_SIZE); |
| 52 | + blake2s_update(&state, x_key, BLAKE2S_BLOCK_SIZE); |
| 53 | + blake2s_update(&state, in, inlen); |
| 54 | + blake2s_final(&state, i_hash); |
| 55 | + |
| 56 | + for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i) |
| 57 | + x_key[i] ^= 0x5c ^ 0x36; |
| 58 | + |
| 59 | + blake2s_init(&state, BLAKE2S_HASH_SIZE); |
| 60 | + blake2s_update(&state, x_key, BLAKE2S_BLOCK_SIZE); |
| 61 | + blake2s_update(&state, i_hash, BLAKE2S_HASH_SIZE); |
| 62 | + blake2s_final(&state, i_hash); |
| 63 | + |
| 64 | + memcpy(out, i_hash, BLAKE2S_HASH_SIZE); |
| 65 | + memzero_explicit(x_key, BLAKE2S_BLOCK_SIZE); |
| 66 | + memzero_explicit(i_hash, BLAKE2S_HASH_SIZE); |
| 67 | +} |
| 68 | + |
| 69 | /* This is Hugo Krawczyk's HKDF: |
| 70 | * - https://eprint.iacr.org/2010/264.pdf |
| 71 | * - https://tools.ietf.org/html/rfc5869 |
| 72 | @@ -322,14 +357,14 @@ static void kdf(u8 *first_dst, u8 *secon |
| 73 | ((third_len || third_dst) && (!second_len || !second_dst)))); |
| 74 | |
| 75 | /* Extract entropy from data into secret */ |
| 76 | - blake2s256_hmac(secret, data, chaining_key, data_len, NOISE_HASH_LEN); |
| 77 | + hmac(secret, data, chaining_key, data_len, NOISE_HASH_LEN); |
| 78 | |
| 79 | if (!first_dst || !first_len) |
| 80 | goto out; |
| 81 | |
| 82 | /* Expand first key: key = secret, data = 0x1 */ |
| 83 | output[0] = 1; |
| 84 | - blake2s256_hmac(output, output, secret, 1, BLAKE2S_HASH_SIZE); |
| 85 | + hmac(output, output, secret, 1, BLAKE2S_HASH_SIZE); |
| 86 | memcpy(first_dst, output, first_len); |
| 87 | |
| 88 | if (!second_dst || !second_len) |
| 89 | @@ -337,8 +372,7 @@ static void kdf(u8 *first_dst, u8 *secon |
| 90 | |
| 91 | /* Expand second key: key = secret, data = first-key || 0x2 */ |
| 92 | output[BLAKE2S_HASH_SIZE] = 2; |
| 93 | - blake2s256_hmac(output, output, secret, BLAKE2S_HASH_SIZE + 1, |
| 94 | - BLAKE2S_HASH_SIZE); |
| 95 | + hmac(output, output, secret, BLAKE2S_HASH_SIZE + 1, BLAKE2S_HASH_SIZE); |
| 96 | memcpy(second_dst, output, second_len); |
| 97 | |
| 98 | if (!third_dst || !third_len) |
| 99 | @@ -346,8 +380,7 @@ static void kdf(u8 *first_dst, u8 *secon |
| 100 | |
| 101 | /* Expand third key: key = secret, data = second-key || 0x3 */ |
| 102 | output[BLAKE2S_HASH_SIZE] = 3; |
| 103 | - blake2s256_hmac(output, output, secret, BLAKE2S_HASH_SIZE + 1, |
| 104 | - BLAKE2S_HASH_SIZE); |
| 105 | + hmac(output, output, secret, BLAKE2S_HASH_SIZE + 1, BLAKE2S_HASH_SIZE); |
| 106 | memcpy(third_dst, output, third_len); |
| 107 | |
| 108 | out: |