diff options
author | 2013-06-05 05:45:54 +0000 | |
---|---|---|
committer | 2013-06-05 05:45:54 +0000 | |
commit | 20d6f9768ead03670bb879fb5dddd438b6acf621 (patch) | |
tree | 6af4a51de83c4d61bc64436151568ad18562f930 /sys | |
parent | Add tests for ICMP and ICMP6 divert-to. (diff) | |
download | wireguard-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.c | 52 | ||||
-rw-r--r-- | sys/crypto/idgen.h | 12 |
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 *); |