/* -*- 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) |
|
/*! @decl array(object(Gmp.mpz)) @ |
*! dsa_generate_keypair(int p_bits, int q_bits, @ |
*! function(int:string(0..255)) rnd) |
*! |
*! Generates a DSA key pair with @[p_bits] number of bits (sometimes |
*! 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 |
*! 2048 224 (rejected by some versions of Hogweed) |
*! 2048 256 |
*! 3072 256 |
*! @} |
*! |
*! @returns |
*! @array |
*! @elem Gmp.mpz 0 |
*! The value p, the modulo. |
*! @elem Gmp.mpz 1 |
*! The value q, the group order. |
*! @elem Gmp.mpz 2 |
*! The value g, the generator. |
*! @elem Gmp.mpz 3 |
*! The value y, the public value. |
*! @elem Gmp.mpz 4 |
*! The value x, the private value. |
*! @endarray |
*/ |
PIKEFUN array(object(Gmp.mpz)) |
dsa_generate_keypair(int p_bits, int q_bits, function(int:string(0..255)) rnd) |
{ |
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) ) |
{ |
Pike_error("Illegal parameter value.\n"); |
} |
|
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. */ |
} |
|
/*! @decl array(object(Gmp.mpz)) @ |
*! rsa_generate_keypair(int bits, int e, function(int:string(0..255)) rnd) |
*! |
*! Generates an RSA key pair with a @[bits] sized modulus (n), using |
*! the provided value for @[e] and random function @[rnd]. |
*! |
*! @returns |
*! @array |
*! @elem Gmp.mpz 0 |
*! The value n, the modulo. |
*! @elem Gmp.mpz 1 |
*! The value d, the private exponent. |
*! @elem Gmp.mpz 2 |
*! The value p, a prime. |
*! @elem Gmp.mpz 3 |
*! The value q, a prime. |
*! @endarray |
*/ |
PIKEFUN array(object(Gmp.mpz)) |
rsa_generate_keypair(int bits, int e, function(int:string(0..255)) rnd) |
{ |
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) ) |
{ |
Pike_error("Illegal parameter value.\n"); |
} |
|
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 |
|