01e1152003-03-12Niels Möller /* nettle.cmod -*- c -*- */ #include "global.h"
9109472003-08-07Martin Nilsson RCSID("$Id: nettle.cmod,v 1.15 2003/08/07 20:32:37 nilsson Exp $");
01e1152003-03-12Niels Möller #include "interpret.h" #include "svalue.h" /* For this_object() */ #include "object.h" #include "module_support.h"
4e1f622003-03-13Niels Möller #include "nettle_config.h"
770fee2003-03-12Henrik Grubbström (Grubba) #ifdef HAVE_LIBNETTLE
efb89c2003-08-06Henrik Grubbström (Grubba) #include "nettle.h"
01e1152003-03-12Niels Möller 
3184172003-08-06Henrik Grubbström (Grubba) #include <nettle/yarrow.h>
01e1152003-03-12Niels Möller #include <assert.h> #include <stdio.h> #include <stdarg.h> DECLARATIONS /*! @module Nettle
d745992003-08-05Martin Nilsson  *! Low level crypto functions used by the @[Crypto] module. Unless *! you are doing something very special, you would want to use the *! Crypto module instead. */ /*! @class Yarrow *! *! Yarrow is a family of pseudo-randomness generators, designed for *! cryptographic use, by John Kelsey, Bruce Schneier and Niels Ferguson. *! Yarrow-160 is described in a paper at *! @url{http://www.counterpane.com/yarrow.html@}, and it uses SHA1 and *! triple-DES, and has a 160-bit internal state. Nettle implements *! Yarrow-256, which is similar, but uses SHA256 and AES to get an *! internal state of 256 bits. */ PIKECLASS Yarrow {
25f5432003-08-06Martin Nilsson  CVAR struct yarrow256_ctx *ctx; CVAR struct yarrow_source *sources;
9109472003-08-07Martin Nilsson  /*! @decl void create(void|int sources) *! The number of entropy sources that will feed entropy to the *! random number generator is given as an argument to Yarrow *! during instantiation. *! @seealso *! @[update] */
25f5432003-08-06Martin Nilsson  PIKEFUN void create(void|int arg) { INT32 num = 0; THIS->sources = NULL; if(arg) { if (arg->type != PIKE_T_INT) Pike_error("Bad argument type.\n"); num = arg->u.integer; if(num < 0) Pike_error("Invalid number of sources.\n"); THIS->sources = xalloc(sizeof(struct yarrow_source)*num); } yarrow256_init(THIS->ctx, num, THIS->sources);
d745992003-08-05Martin Nilsson  } /*! @decl Yarrow seed(string data) *! The random generator needs to be seeded before *! it can be used. The seed must be at least 32 *! characters long. The seed could be stored from *! a previous run by inserting the value returned *! from @[get_seed]. *! @returns *! Returns the called object.
9109472003-08-07Martin Nilsson  *! @seealso *! @[min_seed_size], @[get_seed], @[is_seeded]
d745992003-08-05Martin Nilsson  */ PIKEFUN object seed(string data) { if(data->len < YARROW256_SEED_FILE_SIZE) Pike_error( "Seed must be at least 32 characters.\n" ); NO_WIDE_STRING(data); yarrow256_seed(THIS->ctx, data->len, data->str); RETURN this_object(); }
9109472003-08-07Martin Nilsson  /*! @decl int(0..) min_seed_size() *! Returns the minimal number of characters that the @[seed] *! needs to properly seed the random number generator. *! @seealso *! @[seed] */ PIKEFUN int(0..) min_seed_size() { RETURN YARROW256_SEED_FILE_SIZE; }
d745992003-08-05Martin Nilsson  /*! @decl string get_seed() *! Returns part of the internal state so that it can *! be saved for later seeding.
9109472003-08-07Martin Nilsson  *! @seealso *! @[seed]
d745992003-08-05Martin Nilsson  */ PIKEFUN string get_seed() { RETURN make_shared_string(THIS->ctx->seed_file); } /*! @decl int(0..1) is_seeded() *! Returns 1 if the random generator is seeded and ready *! to generator output. 0 otherwise.
9109472003-08-07Martin Nilsson  *! @seealso *! @[seed]
d745992003-08-05Martin Nilsson  */ PIKEFUN int(0..1) is_seeded() { RETURN yarrow256_is_seeded(THIS->ctx); }
9109472003-08-07Martin Nilsson  /*! @decl void force_reseed() *! By calling this function entropy is moved from the slow *! pool to the fast pool. Read more about Yarrow before using *! this. */
d745992003-08-05Martin Nilsson  PIKEFUN void force_reseed() { yarrow256_force_reseed(THIS->ctx); }
9109472003-08-07Martin Nilsson  /*! @decl int(0..1) update(string data, int source, int entropy) *! Inject additional entropy into the random number generator. *! *! @seealso *! @[create] */
f1d8912003-08-06Martin Nilsson  PIKEFUN int(0..1) update(string data, int source, int entropy) { NO_WIDE_STRING(data); if( !THIS->ctx->nsources ) Pike_error("This random generator has no sources.\n"); if( source<0 || source>=THIS->ctx->nsources ) Pike_error("Invalid random source.\n"); if( entropy<0 ) Pike_error("Entropy must be positive.\n");
9109472003-08-07Martin Nilsson  if( entropy>(data->len*8) ) Pike_error("Impossibly large entropy value.\n");
f1d8912003-08-06Martin Nilsson  RETURN yarrow256_update(THIS->ctx, source, entropy, data->len, data->str); }
d745992003-08-05Martin Nilsson  PIKEFUN int(0..) needed_sources() { RETURN yarrow256_needed_sources(THIS->ctx); } /*! @decl string random_string(int length) *! Returns a pseudo-random string of the requested @[length]. */ PIKEFUN string random_string(int length) { struct pike_string *rnd; if(length < 0) Pike_error("Invalid length, must be positive.\n"); if( !yarrow256_is_seeded(THIS->ctx) ) Pike_error("Random generator not seeded.\n"); rnd = begin_shared_string(length); yarrow256_random(THIS->ctx, length, rnd->str); RETURN end_shared_string(rnd); } INIT { THIS->ctx = xalloc(sizeof(struct yarrow256_ctx));
25f5432003-08-06Martin Nilsson  THIS->ctx->nsources = 0;
d745992003-08-05Martin Nilsson  } EXIT {
25f5432003-08-06Martin Nilsson  if(THIS->ctx->nsources) free(THIS->sources);
d745992003-08-05Martin Nilsson  free(THIS->ctx); } } /*! @endclass
01e1152003-03-12Niels Möller  */
1ab4b12003-03-18Niels Möller /*! @endmodule */
770fee2003-03-12Henrik Grubbström (Grubba) 
654f152003-03-14Marcus Comstedt #endif /* HAVE_LIBNETTLE */
4e1f622003-03-13Niels Möller PIKE_MODULE_INIT { INIT;
654f152003-03-14Marcus Comstedt #ifdef HAVE_LIBNETTLE
4e1f622003-03-13Niels Möller  hash_init();
636c422003-03-18Niels Möller  cipher_init();
654f152003-03-14Marcus Comstedt #endif /* HAVE_LIBNETTLE */
4e1f622003-03-13Niels Möller } PIKE_MODULE_EXIT {
654f152003-03-14Marcus Comstedt #ifdef HAVE_LIBNETTLE
636c422003-03-18Niels Möller  cipher_exit();
4e1f622003-03-13Niels Möller  hash_exit();
654f152003-03-14Marcus Comstedt #endif /* HAVE_LIBNETTLE */
4e1f622003-03-13Niels Möller  EXIT; }