d5f6892013-11-24Martin Nilsson /* -*- c -*- || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */ #include "global.h" #include "bignum.h" #include "builtin_functions.h" #include "interpret.h" #include "module.h" #include "nettle_config.h" #ifdef HAVE_LIBHOGWEED DECLARATIONS #include "nettle.h" #include <nettle/dsa.h> #include <nettle/rsa.h> #include <gmp.h> void random_func_wrapper(void *f, unsigned int num, uint8_t *out) { push_int(num); apply_svalue((struct svalue *)f, 1); if(TYPEOF(Pike_sp[-1])!=T_STRING) Pike_error("Random function did not return string value.\n"); if(Pike_sp[-1].u.string->len != num) Pike_error("Random function did not return correct number of bytes.\n"); memcpy(out, Pike_sp[-1].u.string->str, num); pop_stack(); } #define MAKE_GMP(X,Y) do { push_int(0); \ apply_svalue(&auto_bignum_program, 1); \ Y = Pike_sp[-1].u.object; \ memcpy(&X.Y, get_storage(Y, auto_bignum_program.u.program), sizeof(mpz_t));\ } while(0)
f6a6ad2013-12-08Henrik Grubbström (Grubba) /*! @decl array(object(Gmp.mpz)) @ *! dsa_generate_keypair(int p_bits, int q_bits, @ *! function(int:string(0..255)) rnd)
6668dd2013-12-06Henrik Grubbström (Grubba)  *! *! Generates a DSA key pair with @[p_bits] number of bits (sometimes
d5f6892013-11-24Martin Nilsson  *! referred to as L) for p, and @[q_bits] number of bits (sometimes *! referred to as N) for q, using the random function @[rnd]. *! *! Valid combinations as per FIPS 186-3 are *! @pre{ *! p_bits q_bits *! 1024 160
230ae02013-11-25Martin Nilsson  *! 2048 224 (rejected by some versions of Hogweed)
d5f6892013-11-24Martin Nilsson  *! 2048 256 *! 3072 256 *! @} *! *! @returns *! @array
6668dd2013-12-06Henrik Grubbström (Grubba)  *! @elem Gmp.mpz 0
d5f6892013-11-24Martin Nilsson  *! The value p, the modulo.
6668dd2013-12-06Henrik Grubbström (Grubba)  *! @elem Gmp.mpz 1
d5f6892013-11-24Martin Nilsson  *! The value q, the group order.
6668dd2013-12-06Henrik Grubbström (Grubba)  *! @elem Gmp.mpz 2
d5f6892013-11-24Martin Nilsson  *! The value g, the generator.
6668dd2013-12-06Henrik Grubbström (Grubba)  *! @elem Gmp.mpz 3
d5f6892013-11-24Martin Nilsson  *! The value y, the public value.
6668dd2013-12-06Henrik Grubbström (Grubba)  *! @elem Gmp.mpz 4
d5f6892013-11-24Martin Nilsson  *! The value x, the private value. *! @endarray */
f6a6ad2013-12-08Henrik Grubbström (Grubba) PIKEFUN array(object(Gmp.mpz)) dsa_generate_keypair(int p_bits, int q_bits, function(int:string(0..255)) rnd)
d5f6892013-11-24Martin Nilsson { struct dsa_public_key pub; struct object *p, *q, *g, *y; struct dsa_private_key key; struct object *x; MAKE_GMP(pub,p); MAKE_GMP(pub,q); MAKE_GMP(pub,g); MAKE_GMP(pub,y); MAKE_GMP(key,x); if( !nettle_dsa_generate_keypair(&pub, &key, rnd, random_func_wrapper, NULL, NULL, p_bits, q_bits) ) {
28aa062013-12-02Martin Nilsson  Pike_error("Illegal parameter value.\n");
d5f6892013-11-24Martin Nilsson  } memcpy(get_storage(p, auto_bignum_program.u.program), &pub.p, sizeof(mpz_t)); memcpy(get_storage(q, auto_bignum_program.u.program), &pub.q, sizeof(mpz_t)); memcpy(get_storage(g, auto_bignum_program.u.program), &pub.g, sizeof(mpz_t)); memcpy(get_storage(y, auto_bignum_program.u.program), &pub.y, sizeof(mpz_t)); memcpy(get_storage(x, auto_bignum_program.u.program), &key.x, sizeof(mpz_t)); f_aggregate(5); stack_pop_n_elems_keep_top(3); /* Remove p_bits, q_bits and rnd. */ }
6668dd2013-12-06Henrik Grubbström (Grubba) /*! @decl array(object(Gmp.mpz)) @
f6a6ad2013-12-08Henrik Grubbström (Grubba)  *! rsa_generate_keypair(int bits, int e, function(int:string(0..255)) rnd)
6668dd2013-12-06Henrik Grubbström (Grubba)  *! *! Generates an RSA key pair with a @[bits] sized modulus (n), using
d5f6892013-11-24Martin Nilsson  *! the provided value for @[e] and random function @[rnd]. *! *! @returns *! @array
6668dd2013-12-06Henrik Grubbström (Grubba)  *! @elem Gmp.mpz 0
d5f6892013-11-24Martin Nilsson  *! The value n, the modulo.
6668dd2013-12-06Henrik Grubbström (Grubba)  *! @elem Gmp.mpz 1
d5f6892013-11-24Martin Nilsson  *! The value d, the private exponent.
6668dd2013-12-06Henrik Grubbström (Grubba)  *! @elem Gmp.mpz 2
d5f6892013-11-24Martin Nilsson  *! The value p, a prime.
6668dd2013-12-06Henrik Grubbström (Grubba)  *! @elem Gmp.mpz 3
d5f6892013-11-24Martin Nilsson  *! The value q, a prime. *! @endarray */ PIKEFUN array(object(Gmp.mpz))
f6a6ad2013-12-08Henrik Grubbström (Grubba)  rsa_generate_keypair(int bits, int e, function(int:string(0..255)) rnd)
d5f6892013-11-24Martin Nilsson { struct rsa_public_key pub; struct object *n, *_e; struct rsa_private_key key; struct object *d, *p, *q, *a, *b, *c; push_int(e); apply_svalue(&auto_bignum_program, 1); _e = Pike_sp[-1].u.object; memcpy(&pub.e, get_storage(_e, auto_bignum_program.u.program), sizeof(mpz_t)); MAKE_GMP(pub,n); MAKE_GMP(key,d); MAKE_GMP(key,p); MAKE_GMP(key,q); MAKE_GMP(key,a); MAKE_GMP(key,b); MAKE_GMP(key,c); if( !nettle_rsa_generate_keypair(&pub, &key, rnd, random_func_wrapper, NULL, NULL, bits, 0) ) {
28aa062013-12-02Martin Nilsson  Pike_error("Illegal parameter value.\n");
d5f6892013-11-24Martin Nilsson  } memcpy(get_storage(n, auto_bignum_program.u.program), &pub.n, sizeof(mpz_t)); memcpy(get_storage(d, auto_bignum_program.u.program), &key.d, sizeof(mpz_t)); memcpy(get_storage(p, auto_bignum_program.u.program), &key.p, sizeof(mpz_t)); memcpy(get_storage(q, auto_bignum_program.u.program), &key.q, sizeof(mpz_t)); memcpy(get_storage(a, auto_bignum_program.u.program), &key.a, sizeof(mpz_t)); memcpy(get_storage(b, auto_bignum_program.u.program), &key.b, sizeof(mpz_t)); memcpy(get_storage(c, auto_bignum_program.u.program), &key.c, sizeof(mpz_t)); pop_n_elems(3); /* We don't need a, b, c. */ f_aggregate(4); stack_pop_n_elems_keep_top(3); /* Remove bits, e and rnd. */ } void hogweed_init(void) { INIT; } void hogweed_exit(void) { EXIT; } #endif