summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordjm <djm@openbsd.org>2013-06-05 05:45:54 +0000
committerdjm <djm@openbsd.org>2013-06-05 05:45:54 +0000
commit20d6f9768ead03670bb879fb5dddd438b6acf621 (patch)
tree6af4a51de83c4d61bc64436151568ad18562f930 /sys
parentAdd tests for ICMP and ICMP6 divert-to. (diff)
downloadwireguard-openbsd-20d6f9768ead03670bb879fb5dddd438b6acf621.tar.xz
wireguard-openbsd-20d6f9768ead03670bb879fb5dddd438b6acf621.zip
fix a bug that caused time-based rekeys to happen too frequently.
rename the structure internals to id32_* in anticipation of an idgen16() that might come in the future.
Diffstat (limited to 'sys')
-rw-r--r--sys/crypto/idgen.c52
-rw-r--r--sys/crypto/idgen.h12
2 files changed, 32 insertions, 32 deletions
diff --git a/sys/crypto/idgen.c b/sys/crypto/idgen.c
index bbcde5da3bf..7b639637f63 100644
--- a/sys/crypto/idgen.c
+++ b/sys/crypto/idgen.c
@@ -15,9 +15,10 @@
*/
/*
- * IDGEN32: non-repeating ID generation covering an almost maximal
- * 32 bit range.
- * Based on public domain SKIP32 by Greg Rose.
+ * IDGEN32: non-repeating ID generation covering an almost maximal 32-bit
+ * range.
+ *
+ * IDGEN32 is based on public domain SKIP32 by Greg Rose.
*/
#include <sys/types.h>
@@ -28,7 +29,7 @@
#include <crypto/idgen.h>
-static const u_int8_t ftable[256] = {
+static const u_int8_t idgen32_ftable[256] = {
0xa3, 0xd7, 0x09, 0x83, 0xf8, 0x48, 0xf6, 0xf4,
0xb3, 0x21, 0x15, 0x78, 0x99, 0xb1, 0xaf, 0xf9,
0xe7, 0x2d, 0x4d, 0x8a, 0xce, 0x4c, 0xca, 0x2e,
@@ -72,16 +73,16 @@ idgen32_g(u_int8_t *key, int k, u_int16_t w)
g1 = (w >> 8) & 0xff;
g2 = w & 0xff;
- g3 = ftable[g2 ^ key[o++ & (IDGEN32_KEYLEN - 1)]] ^ g1;
- g4 = ftable[g3 ^ key[o++ & (IDGEN32_KEYLEN - 1)]] ^ g2;
- g5 = ftable[g4 ^ key[o++ & (IDGEN32_KEYLEN - 1)]] ^ g3;
- g6 = ftable[g5 ^ key[o++ & (IDGEN32_KEYLEN - 1)]] ^ g4;
+ g3 = idgen32_ftable[g2 ^ key[o++ & (IDGEN32_KEYLEN - 1)]] ^ g1;
+ g4 = idgen32_ftable[g3 ^ key[o++ & (IDGEN32_KEYLEN - 1)]] ^ g2;
+ g5 = idgen32_ftable[g4 ^ key[o++ & (IDGEN32_KEYLEN - 1)]] ^ g3;
+ g6 = idgen32_ftable[g5 ^ key[o++ & (IDGEN32_KEYLEN - 1)]] ^ g4;
return (g5 << 8) | g6;
}
static u_int32_t
-idgen32_permute(u_int8_t key[IDGEN32_KEYLEN], u_int32_t in)
+idgen32_permute(struct idgen32_ctx *ctx, u_int32_t in)
{
u_int i, r;
u_int16_t wl, wr;
@@ -91,12 +92,12 @@ idgen32_permute(u_int8_t key[IDGEN32_KEYLEN], u_int32_t in)
/* Doubled up rounds, with an odd round at the end to swap */
for (i = r = 0; i < IDGEN32_ROUNDS / 2; ++i) {
- wr ^= (idgen32_g(key, r, wl) ^ r);
+ wr ^= (idgen32_g(ctx->id32_key, r, wl) ^ r);
r++;
- wl ^= (idgen32_g(key, r, wr) ^ r) & 0x7fff;
+ wl ^= (idgen32_g(ctx->id32_key, r, wr) ^ r) & 0x7fff;
r++;
}
- wr ^= (idgen32_g(key, r, wl) ^ r);
+ wr ^= (idgen32_g(ctx->id32_key, r, wl) ^ r);
return (wl << 16) | wr;
}
@@ -104,18 +105,18 @@ idgen32_permute(u_int8_t key[IDGEN32_KEYLEN], u_int32_t in)
static void
idgen32_rekey(struct idgen32_ctx *ctx)
{
- ctx->id_counter = 0;
- ctx->id_hibit ^= 0x80000000;
- ctx->id_offset = arc4random();
- arc4random_buf(ctx->id_key, sizeof(ctx->id_key));
- ctx->id_rekey_time = time_second + IDGEN32_REKEY_TIME;
+ ctx->id32_counter = 0;
+ ctx->id32_hibit ^= 0x80000000;
+ ctx->id32_offset = arc4random();
+ arc4random_buf(ctx->id32_key, sizeof(ctx->id32_key));
+ ctx->id32_rekey_time = time_second + IDGEN32_REKEY_TIME;
}
void
idgen32_init(struct idgen32_ctx *ctx)
{
bzero(ctx, sizeof(*ctx));
- ctx->id_hibit = arc4random() & 0x80000000;
+ ctx->id32_hibit = arc4random() & 0x80000000;
idgen32_rekey(ctx);
}
@@ -124,16 +125,15 @@ idgen32(struct idgen32_ctx *ctx)
{
u_int32_t ret;
- /* Avoid emitting a zero ID as they often have special meaning */
do {
- ret = idgen32_permute(ctx->id_key,
- ctx->id_offset + ctx->id_counter++);
-
/* Rekey a little early to avoid "card counting" attack */
- if (ctx->id_counter > IDGEN32_REKEY_LIMIT ||
- ctx->id_rekey_time > time_second)
+ if (ctx->id32_counter > IDGEN32_REKEY_LIMIT ||
+ ctx->id32_rekey_time < time_second)
idgen32_rekey(ctx);
- } while (ret == 0);
+ ret = ctx->id32_hibit | idgen32_permute(ctx,
+ (ctx->id32_offset + ctx->id32_counter++) & 0x7fffffff);
+ } while (ret == 0); /* Zero IDs are often special, so avoid */
- return ret | ctx->id_hibit;
+ return ret;
}
+
diff --git a/sys/crypto/idgen.h b/sys/crypto/idgen.h
index 02d5110c767..2c96627db9e 100644
--- a/sys/crypto/idgen.h
+++ b/sys/crypto/idgen.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: idgen.h,v 1.2 2008/06/25 00:55:53 djm Exp $ */
+/* $OpenBSD: idgen.h,v 1.3 2013/06/05 05:45:54 djm Exp $ */
/*
* Copyright (c) 2008 Damien Miller <djm@mindrot.org>
*
@@ -21,11 +21,11 @@
#define IDGEN32_REKEY_TIME 600
struct idgen32_ctx {
- u_int32_t id_counter;
- u_int32_t id_offset;
- u_int32_t id_hibit;
- u_int8_t id_key[IDGEN32_KEYLEN];
- time_t id_rekey_time;
+ u_int32_t id32_counter;
+ u_int32_t id32_offset;
+ u_int32_t id32_hibit;
+ u_int8_t id32_key[IDGEN32_KEYLEN];
+ time_t id32_rekey_time;
};
void idgen32_init(struct idgen32_ctx *);