/* randomness machinery * Copyright (C) 1997 Angelos D. Keromytis. * Copyright (C) 1998-2001 D. Hugh Redelmeier. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. See . * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ /* * Use this file if you want use of arc4random(). This is not the default. */ /* Pluto's uses of randomness: * * - Setting up the "secret_of_the_day". This changes every hour! 20 * bytes a shot. It is used in building responder cookies. * * - generating initiator cookies (8 bytes, once per Phase 1 initiation). * * - IKEv1: 32 bytes per DH local secret. Once per Aggr/Main Mode exchange and once * per Quick Mode Exchange with PFS. (Size is our choice, with * tradeoffs.) * - IKEv2: * * - 16 bytes per nonce we generate. Once per Aggr/Main Mode exchange and * once per Quick Mode exchange. (Again, we choose the size.) * * - 4 bytes per SPI number that we generate. We choose the SPIs for all * inbound SPIs, one to three per IPSEC SA (one for AH (rare, probably) * one for ESP (almost always), and one for tunnel (very common)). * I don't actually know how the kernel would generate these numbers -- * currently Pluto generates them; this isn't the way things will be * done in the future. * * - 4 bytes per Message ID we need to generate. One per Quick Mode * exchange. Eventually, one per informational exchange. */ #include #include #include #include #include #include #include #include #include "sha1.h" #include "constants.h" #include "defs.h" #include "rnd.h" #include "log.h" #include "timer.h" #define get_rnd_byte() (arc4random() % 256) void get_rnd_bytes(u_char *buffer, int length) { int i; for (i = 0; i < length; i++) buffer[i] = get_rnd_byte(); } /* * Initialize the random pool. */ void init_rnd_pool(void) { /* start of rand(3) on the right foot */ { unsigned int seed; get_rnd_bytes((void *)&seed, sizeof(seed)); srand(seed); } } u_char secret_of_the_day[SHA1_DIGEST_SIZE]; void init_secret(void) { /* * Generate the secret value for responder cookies, and * schedule an event for refresh. */ get_rnd_bytes(secret_of_the_day, sizeof(secret_of_the_day)); event_schedule(EVENT_REINIT_SECRET, EVENT_REINIT_SECRET_DELAY, NULL); }