01e1152003-03-12Niels Möller /* nettle.cmod -*- c -*- */ #include "global.h"
49acab2003-11-09Niels Möller RCSID("$Id: nettle.cmod,v 1.18 2003/11/09 22:02:19 nisse 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 {
49acab2003-11-09Niels Möller  CVAR struct yarrow256_ctx ctx;
25f5432003-08-06Martin Nilsson  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; 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");
49acab2003-11-09Niels Möller  free (THIS->sources);
25f5432003-08-06Martin Nilsson  THIS->sources = xalloc(sizeof(struct yarrow_source)*num); }
49acab2003-11-09Niels Möller  else { free (THIS->sources); THIS->sources = NULL; } 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);
49acab2003-11-09Niels Möller  yarrow256_seed(&THIS->ctx, data->len, data->str);
d745992003-08-05Martin Nilsson  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() {
49acab2003-11-09Niels Möller  RETURN make_shared_binary_string(THIS->ctx.seed_file, YARROW256_SEED_FILE_SIZE);
d745992003-08-05Martin Nilsson  } /*! @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() {
49acab2003-11-09Niels Möller  RETURN yarrow256_is_seeded(&THIS->ctx);
d745992003-08-05Martin Nilsson  }
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() {
49acab2003-11-09Niels Möller  yarrow256_force_reseed(&THIS->ctx);
d745992003-08-05Martin Nilsson  }
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) {
49acab2003-11-09Niels Möller  /* FIXME: Wide strings could actually be supported here */
f1d8912003-08-06Martin Nilsson  NO_WIDE_STRING(data);
49acab2003-11-09Niels Möller  if( !THIS->sources )
f1d8912003-08-06Martin Nilsson  Pike_error("This random generator has no sources.\n");
49acab2003-11-09Niels Möller  if( source<0 || source>=THIS->ctx.nsources )
f1d8912003-08-06Martin Nilsson  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");
49acab2003-11-09Niels Möller  RETURN yarrow256_update(&THIS->ctx, source, entropy, data->len, data->str);
f1d8912003-08-06Martin Nilsson  }
d745992003-08-05Martin Nilsson  PIKEFUN int(0..) needed_sources() {
49acab2003-11-09Niels Möller  RETURN yarrow256_needed_sources(&THIS->ctx);
d745992003-08-05Martin Nilsson  } /*! @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");
49acab2003-11-09Niels Möller  if( !yarrow256_is_seeded(&THIS->ctx) )
d745992003-08-05Martin Nilsson  Pike_error("Random generator not seeded.\n"); rnd = begin_shared_string(length);
49acab2003-11-09Niels Möller  yarrow256_random(&THIS->ctx, length, rnd->str);
d745992003-08-05Martin Nilsson  RETURN end_shared_string(rnd); } INIT {
49acab2003-11-09Niels Möller  THIS->sources = NULL; yarrow256_init(&THIS->ctx, 0, NULL);
d745992003-08-05Martin Nilsson  } EXIT {
49acab2003-11-09Niels Möller  /* It's ok to call free(NULL); */ free(THIS->sources);
d745992003-08-05Martin Nilsson  } } /*! @endclass
01e1152003-03-12Niels Möller  */
3955a92003-08-24Martin Nilsson char *crypt_md5(int pl, const char *pw, int sl, const char *salt);
9d4fc82003-08-25Martin Nilsson /*! @decl string crypt_md5(string password, string salt) *! Does the crypt_md5 abrakadabra (MD5 + snakeoil).
3955a92003-08-24Martin Nilsson  *! It is assumed that @[salt] does not contain "$". */ PIKEFUN string crypt_md5(string pw, string salt) { NO_WIDE_STRING(pw); NO_WIDE_STRING(salt); RETURN make_shared_string(crypt_md5(pw->len, pw->str, salt->len, salt->str)); }
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; }