X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccrypt%2Fsilcrng.h;h=a5da3c348ad2f514be44cd6f1f18ef8ed9c05273;hb=a818c5b5411bbc4436d1c5f011236985c96bb787;hp=630f76ee903b05c86a1e6ca18a06475414ee06e1;hpb=01fcf2fb84532f681880a766a707334648b4feb8;p=silc.git diff --git a/lib/silccrypt/silcrng.h b/lib/silccrypt/silcrng.h index 630f76ee..a5da3c34 100644 --- a/lib/silccrypt/silcrng.h +++ b/lib/silccrypt/silcrng.h @@ -1,24 +1,23 @@ -/****h* silccrypt/silcrng.h - * - * NAME - * - * silcSilcRng.h - * - * COPYRIGHT - * - * Author: Pekka Riikonen - * - * Copyright (C) 1997 - 2001 Pekka Riikonen - * - * 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. - * - * 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. +/* + + silcrng.h + + Author: Pekka Riikonen + + Copyright (C) 1997 - 2002 Pekka Riikonen + + 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; version 2 of the License. + + 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. + +*/ + +/****h* silccrypt/SilcRNGAPI * * DESCRIPTION * @@ -27,165 +26,309 @@ * in the SILC sessions. All key material and other sources needing random * numbers use this generator. * - * The RNG has a random pool of 1024 bytes of size that provides the actual - * random numbers for the application. The pool is initialized when the - * RNG is allocated and initialized with silc_rng_alloc and silc_rng_init - * functions, respectively. - * - * - * Random Pool Initialization - * - * The RNG's random pool is the source of all random output data. The pool is - * initialized with silc_rng_init and application can reseed it at any time - * by calling the silc_rng_add_noise function. - * - * The initializing phase attempts to set the random pool in a state that it - * is impossible to learn the input data to the RNG or any random output - * data. This is achieved by acquiring noise from various system sources. The - * first source is called to provide "soft noise". This noise is various - * data from system's processes. The second source is called to provide - * "medium noise". This noise is various output data from executed commands. - * Usually the commands are Unix `ps' and `ls' commands with various options. - * The last source is called to provide "hard noise" and is noise from - * system's /dev/random, if it exists. - * - * - * Stirring the Random Pool - * - * Every time data is acquired from any source, the pool is stirred. The - * stirring process performs an CFB (cipher feedback) encryption with SHA1 - * algorithm to the entire random pool. First it acquires an IV (Initial - * Vector) from the constant location of the pool and performs the first CFB - * pass. Then it acquires a new encryption key from variable location of the - * pool and performs the second CFB pass. The encryption key thus is always - * acquired from unguessable data. - * - * The encryption process to the entire random pool assures that it is - * impossible to learn the input data to the random pool without breaking the - * encryption process. This would effectively mean breaking the SHA1 hash - * function. The encryption process also assures that each random output from - * the random pool is secured with cryptographically strong function, the - * SHA1 in this case. - * - * The random pool can be restirred by the application at any point by - * calling the silc_rng_add_noise function. This function adds new noise to - * the pool and then stirs the entire pool. - * - * - * Stirring Threshholds - * - * The random pool has two threshholds that controls when the random pool - * needs more new noise and requires restirring. As previously mentioned, the - * application may do this by calling the silc_rng_add_noise. However, the - * RNG performs this also automatically. - * - * The first threshhold gets soft noise from system and stirs the random pool. - * The threshhold is reached after 64 bits of random data has been fetched - * from the RNG. After the 64 bits, the soft noise acquiring and restirring - * process is performed every 8 bits of random output data until the second - * threshhold is reached. - * - * The second threshhold gets hard noise from system and stirs the random - * pool. The threshhold is reached after 160 bits of random output. After the - * noise is acquired (from /dev/random) the random pool is stirred and the - * threshholds are set to zero. The process is repeated again after 64 bits of - * output for first threshhold and after 160 bits of output for the second - * threshhold. - * - * - * Internal State of the Random Pool - * - * The random pool has also internal state that provides several variable - * distinct points to the random pool where the data is fetched. The state - * changes every 8 bits of output data and it is guaranteed that the fetched - * 8 bits of data is from distinct location compared to the previous 8 bits. - * It is also guaranteed that the internal state never wraps before - * restirring the entire random pool. The internal state means that the data - * is not fetched linearly from the pool, eg. starting from zero and wrapping - * at the end of the pool. The internal state is not dependent of any random - * data in the pool. The internal states are initialized (by default the pool - * is splitted to four different sections (states)) at the RNG - * initialization phase. The state's current position is added linearly and - * wraps at the the start of the next state. The states provides the distinct - * locations. - * - * - * Security Considerations - * - * The security of this random number generator, like of any other RNG's, - * depends of the initial state of the RNG. The initial state of the random - * number generators must be unknown to an adversary. This means that after - * the RNG is initialized it is required that the input data to the RNG and - * the output data to the application has no correlation of any kind that - * could be used to compromise the acquired random numbers or any future - * random numbers. - * - * It is, however, clear that the correlation exists but it needs to be - * hard to solve for an adversary. To accomplish this the input data to the - * random number generator needs to be secret. Usually this is impossible to - * achieve. That is why SILC's RNG acquires the noise from three different - * sources and provides for the application an interface to add more noise at - * any time. The first source ("soft noise") is known to the adversary but - * requires exact timing to get all of the input data. However, getting only - * partial data is easy. The second source ("medium noise") depends on the - * place of execution of the application. Getting at least partial data is - * easy but securing for example the user's home directory from outside access - * makes it harder. The last source ("hard noise") is considered to be the - * most secure source of data. An adversary is not considered to have any - * access on this data. This of course greatly depends on the operating system. - * - * These three sources are considered to be adequate since the random pool is - * relatively large and the output of each bit of the random pool is secured - * by cryptographically secure function, the SHA1 in CFB mode encryption. - * Furthermore the application may provide other random data, such as random - * key strokes or mouse movement to the RNG. However, it is recommended that - * the application would not be the single point of source for the RNG, in - * either intializing or reseeding phases later in the session. Good solution - * is probably to use both, the application's seeds and the RNG's own - * sources, equally. - * - * The RNG must also assure that any old or future random numbers are not - * compromised if an adversary would learn the initial input data (or any - * input data for that matter). The SILC's RNG provides good protection for - * this even if the some of the output bits would be compromised in old or - * future random numbers. The RNG reinitalizes (reseeds) itself using the - * threshholds after every 64 and 160 bits of output. This is considered to be - * adequate even if some of the bits would get compromised. Also, the - * applications that use the RNG usually fetches at least 256 bits from the - * RNG. This means that everytime RNG is accessed both of the threshholds are - * reached. This should mean that the RNG is never too long in an compromised - * state and recovers as fast as possible. - * - * Currently the SILC's RNG does not use random seed files to store some - * random data for future initializing. This is important and must be - * implemented in the future. + * The interface provides functions for retrieving different size of + * random number and arbitrary length of random data buffers. The interface + * also defines Global RNG API which makes it possible to call any + * RNG API function without specific RNG context. * ***/ #ifndef SILCRNG_H #define SILCRNG_H -/* Forward declaration. Actual object is in source file. */ -typedef struct SilcRngObjectStruct *SilcRng; +/****s* silccrypt/SilcRNGAPI/SilcRng + * + * NAME + * + * typedef struct SilcRngStruct *SilcRng; + * + * DESCRIPTION + * + * This context is the actual Random Number Generator and is allocated + * by silc_rng_alloc and given as argument usually to all silc_rng_* + * functions. It is freed by the silc_rng_free function. The RNG is + * initialized by calling the silc_rng_init function. + * + ***/ +typedef struct SilcRngStruct *SilcRng; /* Prototypes */ -SilcRng silc_rng_alloc(); + +/****f* silccrypt/SilcRNGAPI/silc_rng_alloc + * + * SYNOPSIS + * + * SilcRng silc_rng_alloc(void); + * + * DESCRIPTION + * + * Allocates new SILC random number generator and returns context to + * it. After the RNG is allocated it must be initialized by calling + * silc_rng_init before it actually can be used to produce any random + * number. This function returns NULL if RNG could not allocated. + * + ***/ +SilcRng silc_rng_alloc(void); + +/****f* silccrypt/SilcRNGAPI/silc_rng_free + * + * SYNOPSIS + * + * void silc_rng_free(SilcRng rng); + * + * DESCRIPTION + * + * Frees the random number generator and destroys the random number + * pool. + * + ***/ void silc_rng_free(SilcRng rng); + +/****f* silccrypt/SilcRNGAPI/silc_rng_init + * + * SYNOPSIS + * + * void silc_rng_init(SilcRng rng); + * + * DESCRIPTION + * + * This function is used to initialize the random number generator. + * This is the function that must be called after the RNG is allocated + * by calling silc_rng_alloc. RNG cannot be used before this function + * is called. + * + * NOTES + * + * This function may be slow since it will acquire secret noise from + * the environment in an attempt to set the RNG in unguessable state. + * + ***/ void silc_rng_init(SilcRng rng); -unsigned char silc_rng_get_byte(SilcRng rng); -uint16 silc_rng_get_rn16(SilcRng rng); -uint32 silc_rng_get_rn32(SilcRng rng); -unsigned char *silc_rng_get_rn_string(SilcRng rng, uint32 len); -unsigned char *silc_rng_get_rn_data(SilcRng rng, uint32 len); -void silc_rng_add_noise(SilcRng rng, unsigned char *buffer, uint32 len); - -int silc_rng_global_init(SilcRng rng); -int silc_rng_global_uninit(); -unsigned char silc_rng_global_get_byte(); -uint16 silc_rng_global_get_rn16(); -uint32 silc_rng_global_get_rn32(); -unsigned char *silc_rng_global_get_rn_string(uint32 len); -unsigned char *silc_rng_global_get_rn_data(uint32 len); -void silc_rng_global_add_noise(unsigned char *buffer, uint32 len); + +/****f* silccrypt/SilcRNGAPI/silc_rng_get_byte + * + * SYNOPSIS + * + * SilcUInt8 silc_rng_get_byte(SilcRng rng); + * + * DESCRIPTION + * + * Returns one 8-bit random byte from the random number generator. + * + ***/ +SilcUInt8 silc_rng_get_byte(SilcRng rng); + +/****f* silccrypt/SilcRNGAPI/silc_rng_get_rn16 + * + * SYNOPSIS + * + * SilcUInt16 silc_rng_get_rn16(SilcRng rng); + * + * DESCRIPTION + * + * Returns one 16-bit random number from the random number generator. + * + ***/ +SilcUInt16 silc_rng_get_rn16(SilcRng rng); + +/****f* silccrypt/SilcRNGAPI/silc_rng_get_rn32 + * + * SYNOPSIS + * + * SilcUInt32 silc_rng_get_rn32(SilcRng rng); + * + * DESCRIPTION + * + * Returns one 32-bit random number from the random number generator. + * + ***/ +SilcUInt32 silc_rng_get_rn32(SilcRng rng); + +/****f* silccrypt/SilcRNGAPI/silc_rng_get_rn_string + * + * SYNOPSIS + * + * unsigned char *silc_rng_get_rn_string(SilcRng rng, SilcUInt32 len); + * + * DESCRIPTION + * + * Returns random string in HEX form of the length of `len' bytes. + * The caller must free returned data buffer. + * + ***/ +unsigned char *silc_rng_get_rn_string(SilcRng rng, SilcUInt32 len); + +/****f* silccrypt/SilcRNGAPI/silc_rng_get_rn_data + * + * SYNOPSIS + * + * unsigned char *silc_rng_get_rn_data(SilcRng rng, SilcUInt32 len); + * + * DESCRIPTION + * + * Returns random binary data of the length of `len' bytes. The + * caller must free returned data buffer. + * + ***/ +unsigned char *silc_rng_get_rn_data(SilcRng rng, SilcUInt32 len); + +/****f* silccrypt/SilcRNGAPI/silc_rng_add_noise + * + * SYNOPSIS + * + * void silc_rng_add_noise(SilcRng rng, unsigned char *buffer, SilcUInt32 len); + * + * DESCRIPTION + * + * Add the data buffer indicated by `buffer' of length of `len' bytes + * as noise to the random number generator. The random number generator + * is restirred (reseeded) when this function is called. + * + ***/ +void silc_rng_add_noise(SilcRng rng, unsigned char *buffer, SilcUInt32 len); + +/****f* silccrypt/SilcRNGAPI/silc_rng_global_init + * + * SYNOPSIS + * + * bool silc_rng_global_init(SilcRng rng); + * + * DESCRIPTION + * + * This function sets the `rng' if non-NULL as global RNG context. + * When any of the silc_rng_global_* functions is called the `rng' is + * used as RNG. If `rng' is NULL this will allocate new RNG as global + * RNG. The application in this case must free it later by calling + * silc_rng_global_uninit. Returns TRUE after Global RNG is initialized. + * + * NOTES + * + * If `rng' was non-NULL, the silc_rng_init must have been called for + * the `rng' already. + * + * This function can be used to define the `rng' as global RNG and then + * use silc_rng_global_* functions easily without need to provide + * the RNG as argument. + * + ***/ +bool silc_rng_global_init(SilcRng rng); + +/****f* silccrypt/SilcRNGAPI/silc_rng_global_uninit + * + * SYNOPSIS + * + * bool silc_rng_global_uninit(void); + * + * DESCRIPTION + * + * Uninitialized the Global RNG object and frees it. This should not + * be called if silc_rng_global_init was called with non-NULL RNG. + * + ***/ +bool silc_rng_global_uninit(void); + +/****f* silccrypt/SilcRNGAPI/silc_rng_global_get_byte + * + * SYNOPSIS + * + * SilcUInt8 silc_rng_global_get_byte(void); + * + * DESCRIPTION + * + * Returns one 8-bit random byte from the random number generator. + * + ***/ +SilcUInt8 silc_rng_global_get_byte(void); + +/****f* silccrypt/SilcRNGAPI/silc_rng_global_get_byte_fast + * + * SYNOPSIS + * + * SilcUInt8 silc_rng_global_get_byte_fast(void); + * + * DESCRIPTION + * + * Returns one 8-bit random byte from the random number generator as + * fast as possible. + * + * NOTES + * + * This will read the data from /dev/urandom if it is available in the + * operating system, since this may be faster than retrieving a byte + * from the SILC RNG. If /dev/urandom is not available this will take + * the byte from SILC RNG and is effectively same as silc_rng_get_byte. + * + ***/ +SilcUInt8 silc_rng_global_get_byte_fast(void); + +/****f* silccrypt/SilcRNGAPI/silc_rng_global_get_rn16 + * + * SYNOPSIS + * + * SilcUInt16 silc_rng_global_get_rn16(void); + * + * DESCRIPTION + * + * Returns one 16-bit random number from the random number generator. + * + ***/ +SilcUInt16 silc_rng_global_get_rn16(void); + +/****f* silccrypt/SilcRNGAPI/silc_rng_global_get_rn32 + * + * SYNOPSIS + * + * SilcUInt32 silc_rng_global_get_rn32(void); + * + * DESCRIPTION + * + * Returns one 32-bit random number from the random number generator. + * + ***/ +SilcUInt32 silc_rng_global_get_rn32(void); + +/****f* silccrypt/SilcRNGAPI/silc_rng_global_get_rn_string + * + * SYNOPSIS + * + * unsigned char *silc_rng_global_get_rn_string(SilcUInt32 len); + * + * DESCRIPTION + * + * Returns random string in HEX form of the length of `len' bytes. + * The caller must free returned data buffer. + * + ***/ +unsigned char *silc_rng_global_get_rn_string(SilcUInt32 len); + +/****f* silccrypt/SilcRNGAPI/silc_rng_global_get_rn_data + * + * SYNOPSIS + * + * unsigned char *silc_rng_global_get_rn_data(SilcUInt32 len); + * + * DESCRIPTION + * + * Returns random binary data of the length of `len' bytes. The + * caller must free returned data buffer. + * + ***/ +unsigned char *silc_rng_global_get_rn_data(SilcUInt32 len); + +/****f* silccrypt/SilcRNGAPI/silc_rng_global_add_noise + * + * SYNOPSIS + * + * void silc_rng_global_add_noise(unsigned char *buffer, SilcUInt32 len); + * + * DESCRIPTION + * + * Add the data buffer indicated by `buffer' of length of `len' bytes + * as noise to the random number generator. The random number generator + * is restirred (reseeded) when this function is called. + * + ***/ + +void silc_rng_global_add_noise(unsigned char *buffer, SilcUInt32 len); #endif