pike.git / src / post_modules / Nettle / nettle.cmod

version» Context lines:

pike.git/src/post_modules/Nettle/nettle.cmod:1:   /* nettle.cmod -*- c -*- */      #include "global.h" - RCSID("$Id: nettle.cmod,v 1.31 2004/02/04 21:36:29 nilsson Exp $"); + RCSID("$Id: nettle.cmod,v 1.32 2004/02/13 23:27:29 nilsson Exp $");   #include "interpret.h"   #include "svalue.h"   /* For this_object() */   #include "object.h"   #include "operators.h"   #include "module_support.h" -  + #include "threads.h"      #include "nettle_config.h"      #ifdef HAVE_LIBNETTLE      #include "nettle.h"      #include <nettle/yarrow.h>      #include <assert.h>
pike.git/src/post_modules/Nettle/nettle.cmod:44:    CVAR struct yarrow256_ctx ctx;    CVAR struct yarrow_source *sources;       /*! @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]    */ -  PIKEFUN void create(void|int arg) { +  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");    free (THIS->sources);    THIS->sources = xalloc(sizeof(struct yarrow_source)*num);
pike.git/src/post_modules/Nettle/nettle.cmod:76:    *! 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.    *! @seealso    *! @[min_seed_size], @[get_seed], @[is_seeded]    */    PIKEFUN object seed(string data) +  optflags OPT_SIDE_EFFECT;    {    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();    }       /*! @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() -  +  optflags OPT_TRY_OPTIMIZE;    {    RETURN YARROW256_SEED_FILE_SIZE;    }       /*! @decl string get_seed()    *! Returns part of the internal state so that it can    *! be saved for later seeding.    *! @seealso    *! @[seed]    */    PIKEFUN string get_seed() -  +  optflags OPT_EXTERNAL_DEPEND;    {    if( !yarrow256_is_seeded(&THIS->ctx) )    Pike_error("Random generator not seeded.\n"); -  RETURN make_shared_binary_string(THIS->ctx.seed_file, YARROW256_SEED_FILE_SIZE); +  RETURN make_shared_binary_string(THIS->ctx.seed_file, +  YARROW256_SEED_FILE_SIZE);    }       /*! @decl int(0..1) is_seeded()    *! Returns 1 if the random generator is seeded and ready    *! to generator output. 0 otherwise.    *! @seealso    *! @[seed]    */    PIKEFUN int(0..1) is_seeded() -  +  optflags OPT_EXTERNAL_DEPEND;    {    RETURN yarrow256_is_seeded(&THIS->ctx);    }       /*! @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.    */    PIKEFUN void force_reseed() -  +  optflags OPT_SIDE_EFFECT;    {    yarrow256_force_reseed(&THIS->ctx);    }       /*! @decl int(0..1) update(string data, int source, int entropy)    *! Inject additional entropy into the random number generator.    *!    *! @seealso    *! @[create]    */    PIKEFUN int(0..1) update(string data, int source, int entropy) -  +  optflags OPT_SIDE_EFFECT;    {    /* FIXME: Wide strings could actually be supported here */    NO_WIDE_STRING(data);    if( !THIS->sources )    Pike_error("This random generator has no sources.\n");    if( source<0 || (unsigned)source>=THIS->ctx.nsources )    Pike_error("Invalid random source.\n");    if( entropy<0 )    Pike_error("Entropy must be positive.\n");    if( entropy>(data->len*8) )    Pike_error("Impossibly large entropy value.\n");    RETURN yarrow256_update(&THIS->ctx, source, entropy, data->len, data->str);    }       /*! @decl int(0..) needed_sources()    *! The number of sources that must reach the threshold before a    *! slow reseed will happen.    */    PIKEFUN int(0..) needed_sources() -  +  optflags OPT_EXTERNAL_DEPEND;    {    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) -  +  optflags OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT; +  /* We could however set this to not have side effect to allow +  unused values from not getting generated. */    {    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);    }
pike.git/src/post_modules/Nettle/nettle.cmod:197:   /*! @endclass    */      char *crypt_md5(int pl, const char *pw, int sl, const char *salt);      /*! @decl string crypt_md5(string password, string salt)    *! Does the crypt_md5 abrakadabra (MD5 + snakeoil).    *! It is assumed that @[salt] does not contain "$".    */   PIKEFUN string crypt_md5(string pw, string salt) +  optflags OPT_TRY_OPTIMIZE;   {    NO_WIDE_STRING(pw);    NO_WIDE_STRING(salt); -  RETURN make_shared_string(crypt_md5(pw->len, pw->str, -  salt->len, salt->str)); +  THREADS_ALLOW(); +  push_text(crypt_md5(pw->len, pw->str,salt->len, salt->str)); +  THREADS_DISALLOW();   }         static const char *crypto_functions[] = {    "block_size",    "key_size",    "set_encrypt_key",    "set_decrypt_key",    "crypt",    0
pike.git/src/post_modules/Nettle/nettle.cmod:362:    MEMCPY(THIS->iv, source, block_size);    }       /*! @decl void create(program|object|function cipher, mixed ... args)    *! Initialize the CBC wrapper with a cipher algorithm. If it is a    *! program, an object will be instantiated with @[args] as arguments.    *! If it is an object that doesn't conform to the cipher API, but has    *! an @[LFUN::`()], that LFUN will be called. If it is a function,    *! that function will be called with @[args] as arguments.    */ -  PIKEFUN void create(program|object|function cipher, mixed ... more) { +  PIKEFUN void create(program|object|function cipher, mixed ... more) +  flags ID_STATIC; +  {    int old_block_size = THIS->block_size;    THIS->object = make_cipher_object(args);       safe_apply(THIS->object, "block_size", 0);       if(Pike_sp[-1].type != T_INT)    Pike_error("block_size() didn't return an int.\n");       THIS->block_size = Pike_sp[-1].u.integer;   
pike.git/src/post_modules/Nettle/nettle.cmod:391:    free(THIS->iv);    }    THIS->iv = (unsigned INT8 *)xalloc(THIS->block_size);    MEMSET(THIS->iv, 0, THIS->block_size);    }       /*! @decl string name()    *! Returns the string @expr{"CBC(x)"@} where x is the    *! encapsulated algorithm.    */ -  PIKEFUN string name() { +  PIKEFUN string name() +  optflags OPT_TRY_OPTIMIZE; +  {    push_constant_text("CBC(");    safe_apply(THIS->object, "name", 0);    push_constant_text(")");    f_add(3);    }       /*! @decl int block_size()    *! Reurns the block size of the encapsulated cipher.    */ -  PIKEFUN int block_size() { +  PIKEFUN int block_size() +  optflags OPT_TRY_OPTIMIZE; +  {    RETURN THIS->block_size;    }       /*! @decl int key_size()    *! Returns the key size of the encapsulated cipher.    */ -  PIKEFUN int key_size() { +  PIKEFUN int key_size() +  optflags OPT_EXTERNAL_DEPEND; +  {    safe_apply(THIS->object, "key_size", args);    }       /*! @decl this_program set_encrypt_key(string key)    *! Prepare the cipher and the wrapper for encrypting    *! with the given @[key].    */ -  PIKEFUN object set_encrypt_key(string key) { +  PIKEFUN object set_encrypt_key(string key) +  optflags OPT_SIDE_EFFECT; +  {    assert(THIS->block_size);    THIS->mode = 0;    safe_apply(THIS->object, "set_encrypt_key", args);    pop_stack();    RETURN this_object();    }       /*! @decl this_program set_decrypt_key(string key)    *! Prepare the cipher and the wrapper for decrypting    *! with the given @[key].    */ -  PIKEFUN object set_decrypt_key(string key) { +  PIKEFUN object set_decrypt_key(string key) +  optflags OPT_SIDE_EFFECT; +  {    assert(THIS->block_size);    THIS->mode = 1;    safe_apply(THIS->object, "set_decrypt_key", args);    pop_stack();    RETURN this_object();    }       /*! @decl this_program set_iv(string iv)    *! Set the initialization vector to @[iv].    */ -  PIKEFUN object set_iv(string iv) { +  PIKEFUN object set_iv(string iv) +  optflags OPT_SIDE_EFFECT; +  {    assert(THIS->iv);    NO_WIDE_STRING(iv);    if(iv->len != THIS->block_size)    Pike_error("Argument incompatible with cipher block size.\n");    MEMCPY(THIS->iv, iv->str, THIS->block_size);    RETURN this_object();    }       /*! @decl string crypt(string data)    *! Encrypt/decrypt @[data] and return the result. @[data] must
pike.git/src/post_modules/Nettle/nettle.cmod:520:    free_object(THIS->object);    }       /*! @decl void create(program|object|function cipher, mixed ... args)    *! Initialize the Proxy wrapper with a cipher algorithm. If it is a    *! program, an object will be instantiated with @[args] as arguments.    *! If it is an object that doesn't conform to the cipher API, but has    *! an @[LFUN::`()], that LFUN will be called. If it is a function,    *! that function will be called with @[args] as arguments.    */ -  PIKEFUN void create(program|object|function cipher, mixed ... more) { +  PIKEFUN void create(program|object|function cipher, mixed ... more) +  flags ID_STATIC; +  {    THIS->object = make_cipher_object(args);       safe_apply(THIS->object, "block_size", 0);    if (Pike_sp[-1].type != T_INT)    Pike_error("block_size() didn't return an int\n");    THIS->block_size = Pike_sp[-1].u.integer;       pop_stack();       if ((!THIS->block_size) ||
pike.git/src/post_modules/Nettle/nettle.cmod:543:       THIS->backlog = (unsigned char *)xalloc(THIS->block_size);    THIS->backlog_len = 0;    MEMSET(THIS->backlog, 0, THIS->block_size);    }       /*! @decl string name()    *! Returns the string @expr{"CBC(x)"@} where x is the    *! encapsulated algorithm.    */ -  PIKEFUN string name() { +  PIKEFUN string name() +  optflags OPT_TRY_OPTIMIZE; +  {    push_constant_text("Proxy(");    safe_apply(THIS->object, "name", 0);    push_constant_text(")");    f_add(3);    }       /*! @decl int block_size()    *!    *! Get the block size of the contained block crypto.    */ -  PIKEFUN int block_size() { +  PIKEFUN int block_size() +  optflags OPT_TRY_OPTIMIZE; +  {    RETURN THIS->block_size;    }       /*! @decl int key_size()    *!    *! Get the key size of the contained block crypto.    */ -  PIKEFUN int key_size() { +  PIKEFUN int key_size() +  optflags OPT_EXTERNAL_DEPEND; +  {    safe_apply(THIS->object, "key_size", args);    }       /*! @decl this_program set_encrypt_key(string key)    *!    *! Set the encryption key.    *!    *! @note    *! As a side-effect any buffered data will be cleared.    */ -  PIKEFUN object set_encrypt_key(string key) { +  PIKEFUN object set_encrypt_key(string key) +  optflags OPT_SIDE_EFFECT; +  {    MEMSET(THIS->backlog, 0, THIS->block_size);    THIS->backlog_len = 0;    safe_apply(THIS->object, "set_encrypt_key", args);    pop_stack();    RETURN this_object();    }       /*! @decl this_program set_decrypt_key(string key)    *!    *! Set the decryption key.    *!    *! @note    *! As a side-effect any buffered data will be cleared.    */ -  PIKEFUN object set_decrypt_key(string key) { +  PIKEFUN object set_decrypt_key(string key) +  optflags OPT_SIDE_EFFECT; +  {    MEMSET(THIS->backlog, 0, THIS->block_size);    THIS->backlog_len = 0;    safe_apply(THIS->object, "set_decrypt_key", args);    pop_stack();    RETURN this_object();    }       /*! @decl string crypt(string data)    *!    *! Encrypt some data.