01e115 | 2003-03-12 | Niels Möller | | /* nettle.cmod -*- c -*- */
#include "global.h"
#include "interpret.h"
#include "svalue.h"
/* For this_object() */
#include "object.h"
|
7d54f4 | 2004-01-23 | Martin Nilsson | | #include "operators.h"
|
01e115 | 2003-03-12 | Niels Möller | | #include "module_support.h"
|
d7f88a | 2004-02-14 | Martin Nilsson | | #include "threads.h"
|
0a146b | 2013-03-12 | Arne Goedeke | | #include "pike_memory.h"
|
01e115 | 2003-03-12 | Niels Möller | |
|
4e1f62 | 2003-03-13 | Niels Möller | | #include "nettle_config.h"
|
770fee | 2003-03-12 | Henrik Grubbström (Grubba) | | #ifdef HAVE_LIBNETTLE
|
efb89c | 2003-08-06 | Henrik Grubbström (Grubba) | | #include "nettle.h"
|
01e115 | 2003-03-12 | Niels Möller | |
|
318417 | 2003-08-06 | Henrik Grubbström (Grubba) | | #include <nettle/yarrow.h>
|
329a6f | 2004-02-21 | Martin Nilsson | | #include <nettle/knuth-lfib.h>
|
318417 | 2003-08-06 | Henrik Grubbström (Grubba) | |
|
01e115 | 2003-03-12 | Niels Möller | | #include <stdio.h>
#include <stdarg.h>
DECLARATIONS
/*! @module Nettle
|
d74599 | 2003-08-05 | Martin 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
|
1e4bd3 | 2013-10-05 | Henrik Grubbström (Grubba) | | *! @url{http://www.schneier.com/paper-yarrow.html@}, and it uses SHA1 and
|
d74599 | 2003-08-05 | Martin Nilsson | | *! 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
{
|
49acab | 2003-11-09 | Niels Möller | | CVAR struct yarrow256_ctx ctx;
|
25f543 | 2003-08-06 | Martin Nilsson | | CVAR struct yarrow_source *sources;
|
d31127 | 2009-07-05 | Henrik Grubbström (Grubba) | |
|
d1cb85 | 2009-07-05 | Henrik Grubbström (Grubba) | | #ifndef HAVE_STRUCT_YARROW256_CTX_SEED_FILE
|
d31127 | 2009-07-05 | Henrik Grubbström (Grubba) | | /* NOTE: Nettle 2.0 does not have the automatic seed_file maintenance
* that Nettle 1.x had. This stuff is needed since it affected
* the state emitted by random_string(). When Nettle 2.0 is the
* default, consider implementing this via overloading of the
* various seeding functions instead, since it does have a bit
* of overhead.
*
* /grubba 2009-07-05
*/
|
d1cb85 | 2009-07-05 | Henrik Grubbström (Grubba) | | PIKEVAR string seed_file flags ID_PRIVATE|ID_STATIC;
|
0ec141 | 2009-07-05 | Henrik Grubbström (Grubba) | | #endif
DECLARE_STORAGE;
|
d31127 | 2009-07-05 | Henrik Grubbström (Grubba) | |
|
0ec141 | 2009-07-05 | Henrik Grubbström (Grubba) | | #ifndef HAVE_STRUCT_YARROW256_CTX_SEED_FILE
|
d31127 | 2009-07-05 | Henrik Grubbström (Grubba) | | static void pike_generate_seed_file(void)
{
struct pike_string *seed_file =
begin_shared_string(YARROW256_SEED_FILE_SIZE);
yarrow256_random(&THIS->ctx, YARROW256_SEED_FILE_SIZE, STR0(seed_file));
if (THIS->seed_file) {
free_string(THIS->seed_file);
}
THIS->seed_file = end_shared_string(seed_file);
}
#else
#define pike_generate_seed_file()
|
d1cb85 | 2009-07-05 | Henrik Grubbström (Grubba) | | #endif
|
25f543 | 2003-08-06 | Martin Nilsson | |
|
910947 | 2003-08-07 | Martin 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]
*/
|
d7f88a | 2004-02-14 | Martin Nilsson | | PIKEFUN void create(void|int arg)
|
ecc938 | 2008-06-29 | Martin Nilsson | | flags ID_PROTECTED;
|
d7f88a | 2004-02-14 | Martin Nilsson | | {
|
25f543 | 2003-08-06 | Martin Nilsson | | INT32 num = 0;
if(arg) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(*arg) != PIKE_T_INT)
|
25f543 | 2003-08-06 | Martin Nilsson | | Pike_error("Bad argument type.\n");
num = arg->u.integer;
if(num < 0)
Pike_error("Invalid number of sources.\n");
|
49acab | 2003-11-09 | Niels Möller | | free (THIS->sources);
|
25f543 | 2003-08-06 | Martin Nilsson | | THIS->sources = xalloc(sizeof(struct yarrow_source)*num);
}
|
49acab | 2003-11-09 | Niels Möller | | else
{
free (THIS->sources);
THIS->sources = NULL;
}
yarrow256_init(&THIS->ctx, num, THIS->sources);
|
d74599 | 2003-08-05 | Martin Nilsson | | }
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | /*! @decl Yarrow seed(string(0..255) data)
|
658003 | 2013-08-15 | Martin Nilsson | | *!
*! 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].
*!
|
d74599 | 2003-08-05 | Martin Nilsson | | *! @returns
*! Returns the called object.
|
910947 | 2003-08-07 | Martin Nilsson | | *! @seealso
*! @[min_seed_size], @[get_seed], @[is_seeded]
|
d74599 | 2003-08-05 | Martin Nilsson | | */
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | PIKEFUN object seed(string(0..255) data)
|
d7f88a | 2004-02-14 | Martin Nilsson | | optflags OPT_SIDE_EFFECT;
|
d74599 | 2003-08-05 | Martin Nilsson | | {
if(data->len < YARROW256_SEED_FILE_SIZE)
|
c9edeb | 2009-07-01 | Henrik Grubbström (Grubba) | | Pike_error("Seed must be at least %d characters.\n",
YARROW256_SEED_FILE_SIZE);
|
d74599 | 2003-08-05 | Martin Nilsson | |
NO_WIDE_STRING(data);
|
c9edeb | 2009-07-01 | Henrik Grubbström (Grubba) | | yarrow256_seed(&THIS->ctx, data->len, STR0(data));
|
d31127 | 2009-07-05 | Henrik Grubbström (Grubba) | | pike_generate_seed_file();
|
d74599 | 2003-08-05 | Martin Nilsson | | RETURN this_object();
}
|
910947 | 2003-08-07 | Martin 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()
|
d7f88a | 2004-02-14 | Martin Nilsson | | optflags OPT_TRY_OPTIMIZE;
|
910947 | 2003-08-07 | Martin Nilsson | | {
RETURN YARROW256_SEED_FILE_SIZE;
}
|
d31127 | 2009-07-05 | Henrik Grubbström (Grubba) | | /*! @decl string(0..255) get_seed()
|
776b50 | 2009-07-02 | Henrik Grubbström (Grubba) | | *! Returns part of the internal state so that it can
*! be saved for later seeding.
|
de0337 | 2009-07-01 | Henrik Grubbström (Grubba) | | *!
|
910947 | 2003-08-07 | Martin Nilsson | | *! @seealso
|
776b50 | 2009-07-02 | Henrik Grubbström (Grubba) | | *! @[seed()], @[random_string()]
|
d74599 | 2003-08-05 | Martin Nilsson | | */
|
5345c9 | 2013-05-19 | Martin Nilsson | | PIKEFUN string(0..255) get_seed()
|
d7f88a | 2004-02-14 | Martin Nilsson | | optflags OPT_EXTERNAL_DEPEND;
|
47ce5e | 2009-07-05 | Henrik Grubbström (Grubba) | | rawtype tDeprecated(tFunc(tNone, tStr8));
|
d74599 | 2003-08-05 | Martin Nilsson | | {
|
324ca8 | 2003-11-10 | Niels Möller | | if( !yarrow256_is_seeded(&THIS->ctx) )
Pike_error("Random generator not seeded.\n");
|
ad6753 | 2009-07-01 | Henrik Grubbström (Grubba) | |
|
d1cb85 | 2009-07-05 | Henrik Grubbström (Grubba) | | #ifdef HAVE_STRUCT_YARROW256_CTX_SEED_FILE
|
658003 | 2013-08-15 | Martin Nilsson | | RETURN make_shared_binary_string(THIS->ctx.seed_file,
|
776b50 | 2009-07-02 | Henrik Grubbström (Grubba) | | YARROW256_SEED_FILE_SIZE);
|
d1cb85 | 2009-07-05 | Henrik Grubbström (Grubba) | | #else
|
d31127 | 2009-07-05 | Henrik Grubbström (Grubba) | | if (THIS->seed_file) {
REF_RETURN THIS->seed_file;
} else {
|
bb6493 | 2013-08-09 | Arne Goedeke | | /*
* It seems somewhat unreasonable to use uninitialized memory here.
* Instead, I think the user should be warned. It really isnt a very
* good source of entropy and may lead to undefined behavior in C.
* Why not simply return 0 in that case?
* /arne
*/
|
d31127 | 2009-07-05 | Henrik Grubbström (Grubba) | | struct pike_string *s = begin_shared_string(YARROW256_SEED_FILE_SIZE);
|
bb6493 | 2013-08-09 | Arne Goedeke | | PIKE_MEM_RW_RANGE(s->str, YARROW256_SEED_FILE_SIZE);
s = end_shared_string(s);
RETURN s;
|
d31127 | 2009-07-05 | Henrik Grubbström (Grubba) | | }
|
776b50 | 2009-07-02 | Henrik Grubbström (Grubba) | | #endif /* HAVE_STRUCT_YARROW256_CTX_SEED_FILE */
|
d1cb85 | 2009-07-05 | Henrik Grubbström (Grubba) | | }
|
d74599 | 2003-08-05 | Martin Nilsson | |
/*! @decl int(0..1) is_seeded()
*! Returns 1 if the random generator is seeded and ready
*! to generator output. 0 otherwise.
|
910947 | 2003-08-07 | Martin Nilsson | | *! @seealso
*! @[seed]
|
d74599 | 2003-08-05 | Martin Nilsson | | */
PIKEFUN int(0..1) is_seeded()
|
d7f88a | 2004-02-14 | Martin Nilsson | | optflags OPT_EXTERNAL_DEPEND;
|
d74599 | 2003-08-05 | Martin Nilsson | | {
|
49acab | 2003-11-09 | Niels Möller | | RETURN yarrow256_is_seeded(&THIS->ctx);
|
d74599 | 2003-08-05 | Martin Nilsson | | }
|
910947 | 2003-08-07 | Martin 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.
*/
|
d74599 | 2003-08-05 | Martin Nilsson | | PIKEFUN void force_reseed()
|
d7f88a | 2004-02-14 | Martin Nilsson | | optflags OPT_SIDE_EFFECT;
|
d74599 | 2003-08-05 | Martin Nilsson | | {
|
c9edeb | 2009-07-01 | Henrik Grubbström (Grubba) | | #ifdef HAVE_NETTLE_YARROW256_SLOW_RESEED
/* From change notes for Nettle 2.0:
*
* * Changes to the yarrow256 interface. The function
* yarrow256_force_reseed has been replaced by the two
* functions yarrow256_fast_reseed and yarrow256_slow_reseed,
* which were previously static.
*/
yarrow256_slow_reseed(&THIS->ctx);
#else
|
49acab | 2003-11-09 | Niels Möller | | yarrow256_force_reseed(&THIS->ctx);
|
c9edeb | 2009-07-01 | Henrik Grubbström (Grubba) | | #endif
|
d31127 | 2009-07-05 | Henrik Grubbström (Grubba) | | pike_generate_seed_file();
|
d74599 | 2003-08-05 | Martin Nilsson | | }
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | /*! @decl int(0..1) update(string(0..255) data, int source, int entropy)
|
910947 | 2003-08-07 | Martin Nilsson | | *! Inject additional entropy into the random number generator.
*!
*! @seealso
*! @[create]
*/
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | PIKEFUN int(0..1) update(string(0..255) data, int source, int entropy)
|
d7f88a | 2004-02-14 | Martin Nilsson | | optflags OPT_SIDE_EFFECT;
|
f1d891 | 2003-08-06 | Martin Nilsson | | {
|
d31127 | 2009-07-05 | Henrik Grubbström (Grubba) | | int ret;
|
49acab | 2003-11-09 | Niels Möller | | /* FIXME: Wide strings could actually be supported here */
|
f1d891 | 2003-08-06 | Martin Nilsson | | NO_WIDE_STRING(data);
|
49acab | 2003-11-09 | Niels Möller | | if( !THIS->sources )
|
f1d891 | 2003-08-06 | Martin Nilsson | | Pike_error("This random generator has no sources.\n");
|
61e14b | 2004-01-23 | Martin Nilsson | | if( source<0 || (unsigned)source>=THIS->ctx.nsources )
|
f1d891 | 2003-08-06 | Martin Nilsson | | Pike_error("Invalid random source.\n");
if( entropy<0 )
Pike_error("Entropy must be positive.\n");
|
910947 | 2003-08-07 | Martin Nilsson | | if( entropy>(data->len*8) )
Pike_error("Impossibly large entropy value.\n");
|
d31127 | 2009-07-05 | Henrik Grubbström (Grubba) | | ret = yarrow256_update(&THIS->ctx, source, entropy, data->len,
(const uint8_t *)data->str);
|
dce9da | 2010-05-26 | Jonas Wallden | | if (ret) {
|
d31127 | 2009-07-05 | Henrik Grubbström (Grubba) | | pike_generate_seed_file();
|
dce9da | 2010-05-26 | Jonas Wallden | | }
|
d31127 | 2009-07-05 | Henrik Grubbström (Grubba) | | RETURN ret;
|
f1d891 | 2003-08-06 | Martin Nilsson | | }
|
01a1ba | 2003-12-14 | Martin Nilsson | | /*! @decl int(0..) needed_sources()
*! The number of sources that must reach the threshold before a
*! slow reseed will happen.
*/
|
d74599 | 2003-08-05 | Martin Nilsson | | PIKEFUN int(0..) needed_sources()
|
d7f88a | 2004-02-14 | Martin Nilsson | | optflags OPT_EXTERNAL_DEPEND;
|
d74599 | 2003-08-05 | Martin Nilsson | | {
|
49acab | 2003-11-09 | Niels Möller | | RETURN yarrow256_needed_sources(&THIS->ctx);
|
d74599 | 2003-08-05 | Martin Nilsson | | }
|
5345c9 | 2013-05-19 | Martin Nilsson | | /*! @decl string(0..255) random_string(int length)
|
d74599 | 2003-08-05 | Martin Nilsson | | *! Returns a pseudo-random string of the requested @[length].
*/
|
5345c9 | 2013-05-19 | Martin Nilsson | | PIKEFUN string(0..255) random_string(int length)
|
d7f88a | 2004-02-14 | Martin Nilsson | | optflags OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT;
|
d74599 | 2003-08-05 | Martin Nilsson | | {
struct pike_string *rnd;
if(length < 0)
Pike_error("Invalid length, must be positive.\n");
|
49acab | 2003-11-09 | Niels Möller | | if( !yarrow256_is_seeded(&THIS->ctx) )
|
d74599 | 2003-08-05 | Martin Nilsson | | Pike_error("Random generator not seeded.\n");
rnd = begin_shared_string(length);
|
baac7d | 2006-01-07 | Martin Nilsson | | yarrow256_random(&THIS->ctx, length, (uint8_t *)rnd->str);
|
658003 | 2013-08-15 | Martin Nilsson | | RETURN end_shared_string(rnd);
|
d74599 | 2003-08-05 | Martin Nilsson | | }
INIT
{
|
49acab | 2003-11-09 | Niels Möller | | THIS->sources = NULL;
yarrow256_init(&THIS->ctx, 0, NULL);
|
d74599 | 2003-08-05 | Martin Nilsson | | }
|
22038d | 2008-05-30 | Martin Nilsson | |
|
d74599 | 2003-08-05 | Martin Nilsson | | EXIT
|
d3df7c | 2008-05-30 | Martin Nilsson | | gc_trivial;
|
d74599 | 2003-08-05 | Martin Nilsson | | {
|
22038d | 2008-05-30 | Martin Nilsson | | if( THIS->sources )
{
free(THIS->sources);
}
|
d74599 | 2003-08-05 | Martin Nilsson | | }
}
/*! @endclass
|
01e115 | 2003-03-12 | Niels Möller | | */
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | /*! @decl string(0..127) crypt_md5(string(0..255) password, @
*! string(0..255) salt,@
*! void|string(0..255) magic)
|
658003 | 2013-08-15 | Martin Nilsson | | *! Does the crypt_md5 abrakadabra (MD5 + snakeoil). It is assumed
*! that @[salt] does not contain "$".
*!
*! The @[password] memory will be cleared before released.
|
3955a9 | 2003-08-24 | Martin Nilsson | | */
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | PIKEFUN string(0..127) crypt_md5(string(0..255) pw, string(0..255) salt,
void|string(0..255) magic)
|
d7f88a | 2004-02-14 | Martin Nilsson | | optflags OPT_TRY_OPTIMIZE;
|
3955a9 | 2003-08-24 | Martin Nilsson | | {
|
329a6f | 2004-02-21 | Martin Nilsson | | char *hash;
|
3955a9 | 2003-08-24 | Martin Nilsson | | NO_WIDE_STRING(pw);
NO_WIDE_STRING(salt);
|
bb6493 | 2013-08-09 | Arne Goedeke | |
pw->flags |= STRING_CLEAR_ON_EXIT;
|
395c4a | 2012-07-25 | Martin Nilsson | | if(!magic)
{
hash = pike_crypt_md5(pw->len, pw->str, salt->len, salt->str,
3, "$1$");
}
else
{
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | NO_WIDE_STRING(magic);
|
395c4a | 2012-07-25 | Martin Nilsson | | hash = pike_crypt_md5(pw->len, pw->str, salt->len, salt->str,
magic->len, magic->str);
}
|
329a6f | 2004-02-21 | Martin Nilsson | | push_text(hash);
|
3955a9 | 2003-08-24 | Martin Nilsson | | }
|
329a6f | 2004-02-21 | Martin Nilsson | | #if 0
/* @class LFib
* The Donald Knuth Lagged Fibonacci pseudo random number generator.
* This is @b{not@} a source for cryptographic randomness. Use
* @[Crypto.Yarrow] instead.
*/
PIKECLASS LFib
{
CVAR struct knuth_lfib_ctx *ctx;
INIT {
THIS->ctx = xalloc(sizeof(struct knuth_lfib_ctx));
}
|
d3df7c | 2008-05-30 | Martin Nilsson | | EXIT
gc_trivial;
{
|
329a6f | 2004-02-21 | Martin Nilsson | | free(THIS->ctx);
}
/* @decl void create(int seed)
* The Lfib generator must be seeded with a number.
*/
|
c72a03 | 2004-10-23 | Martin Nilsson | | PIKEFUN void create(int seed)
|
ecc938 | 2008-06-29 | Martin Nilsson | | flags ID_PROTECTED;
|
c72a03 | 2004-10-23 | Martin Nilsson | | {
|
329a6f | 2004-02-21 | Martin Nilsson | | knuth_lfib_init(THIS->ctx, seed);
}
/* @decl this_program reseed(int s)
* Reseed this object with seed @[s].
* @return
* Returns the current object.
*/
PIKEFUN object reseed(int s) {
knuth_lfib_init(THIS->ctx, s);
RETURN this_object();
}
/* Get one 32bit pseudorandom integer.
*/
PIKEFUN int get() {
RETURN knuth_lfib_get(THIS->ctx);
}
/* Get a pseudorandom string of length @[len].
*/
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | PIKEFUN string(0..255) get_string(int len) {
|
329a6f | 2004-02-21 | Martin Nilsson | | struct pike_string *s = begin_shared_string(len);
knuth_lfib_random(THIS->ctx, len, s->str);
push_string(end_shared_string(s));
}
}
/* @endclass
*/
#endif
|
1ab4b1 | 2003-03-18 | Niels Möller | | /*! @endmodule
*/
|
770fee | 2003-03-12 | Henrik Grubbström (Grubba) | |
|
099d68 | 2004-01-30 | Martin Nilsson | |
|
654f15 | 2003-03-14 | Marcus Comstedt | | #endif /* HAVE_LIBNETTLE */
|
4e1f62 | 2003-03-13 | Niels Möller | | PIKE_MODULE_INIT
{
|
099d68 | 2004-01-30 | Martin Nilsson | | #ifdef __NT__
struct program *nt_program = NULL;
struct object *nt_object = NULL;
#endif /* __NT__ */
|
4e1f62 | 2003-03-13 | Niels Möller | | INIT;
|
654f15 | 2003-03-14 | Marcus Comstedt | | #ifdef HAVE_LIBNETTLE
|
4e1f62 | 2003-03-13 | Niels Möller | | hash_init();
|
636c42 | 2003-03-18 | Niels Möller | | cipher_init();
|
654f15 | 2003-03-14 | Marcus Comstedt | | #endif /* HAVE_LIBNETTLE */
|
099d68 | 2004-01-30 | Martin Nilsson | | #ifdef __NT__
start_new_program();
nt_init();
nt_program = end_program();
add_object_constant("NT", nt_object=clone_object(nt_program,0), 0);
free_object(nt_object);
free_program(nt_program);
#endif /* __NT__ */
|
d5f689 | 2013-11-24 | Martin Nilsson | | #ifdef HAVE_LIBHOGWEED
hogweed_init();
#endif
|
4e1f62 | 2003-03-13 | Niels Möller | | }
PIKE_MODULE_EXIT
{
|
654f15 | 2003-03-14 | Marcus Comstedt | | #ifdef HAVE_LIBNETTLE
|
636c42 | 2003-03-18 | Niels Möller | | cipher_exit();
|
4e1f62 | 2003-03-13 | Niels Möller | | hash_exit();
|
654f15 | 2003-03-14 | Marcus Comstedt | | #endif /* HAVE_LIBNETTLE */
|
099d68 | 2004-01-30 | Martin Nilsson | | #ifdef __NT__
nt_exit();
#endif /* __NT__ */
|
d5f689 | 2013-11-24 | Martin Nilsson | | #ifdef HAVE_LIBHOGWEED
hogweed_exit();
#endif
|
4e1f62 | 2003-03-13 | Niels Möller | | EXIT;
}
|