d5f689 | 2013-11-24 | Martin 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 "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>
|
2b1c92 | 2013-12-24 | Henrik Grubbström (Grubba) | | #include "bignum.h"
|
d5f689 | 2013-11-24 | Martin Nilsson | | 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();
}
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | /*! @decl array(object(Gmp.mpz)) @
*! dsa_generate_keypair(int p_bits, int q_bits, @
*! function(int:string(0..255)) rnd)
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *!
*! Generates a DSA key pair with @[p_bits] number of bits (sometimes
|
d5f689 | 2013-11-24 | Martin 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
|
230ae0 | 2013-11-25 | Martin Nilsson | | *! 2048 224 (rejected by some versions of Hogweed)
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! 2048 256
*! 3072 256
*! @}
*!
*! @returns
*! @array
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 0
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value p, the modulo.
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 1
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value q, the group order.
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 2
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value g, the generator.
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 3
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value y, the public value.
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 4
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value x, the private value.
*! @endarray
*/
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | PIKEFUN array(object(Gmp.mpz))
dsa_generate_keypair(int p_bits, int q_bits, function(int:string(0..255)) rnd)
|
d5f689 | 2013-11-24 | Martin Nilsson | | {
struct dsa_public_key pub;
struct dsa_private_key key;
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | | dsa_public_key_init(&pub);
dsa_private_key_init(&key);
|
d5f689 | 2013-11-24 | Martin Nilsson | |
if( !nettle_dsa_generate_keypair(&pub, &key, rnd, random_func_wrapper,
NULL, NULL, p_bits, q_bits) )
{
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | | dsa_private_key_clear(&key);
dsa_public_key_clear(&pub);
|
28aa06 | 2013-12-02 | Martin Nilsson | | Pike_error("Illegal parameter value.\n");
|
d5f689 | 2013-11-24 | Martin Nilsson | | }
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | | push_bignum((MP_INT *)&pub.p);
push_bignum((MP_INT *)&pub.q);
push_bignum((MP_INT *)&pub.g);
push_bignum((MP_INT *)&pub.y);
push_bignum((MP_INT *)&key.x);
dsa_private_key_clear(&key);
dsa_public_key_clear(&pub);
|
d5f689 | 2013-11-24 | Martin Nilsson | |
f_aggregate(5);
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | | stack_pop_n_elems_keep_top(args); /* Remove p_bits, q_bits and rnd. */
|
d5f689 | 2013-11-24 | Martin Nilsson | | }
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | /*! @decl array(object(Gmp.mpz)) @
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | *! rsa_generate_keypair(int bits, int e, function(int:string(0..255)) rnd)
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *!
*! Generates an RSA key pair with a @[bits] sized modulus (n), using
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! the provided value for @[e] and random function @[rnd].
*!
*! @returns
*! @array
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 0
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value n, the modulo.
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 1
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value d, the private exponent.
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 2
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value p, a prime.
|
6668dd | 2013-12-06 | Henrik Grubbström (Grubba) | | *! @elem Gmp.mpz 3
|
d5f689 | 2013-11-24 | Martin Nilsson | | *! The value q, a prime.
*! @endarray
*/
PIKEFUN array(object(Gmp.mpz))
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | rsa_generate_keypair(int bits, int e, function(int:string(0..255)) rnd)
|
d5f689 | 2013-11-24 | Martin Nilsson | | {
struct rsa_public_key pub;
struct rsa_private_key key;
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | |
rsa_public_key_init(&pub);
rsa_private_key_init(&key);
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | mpz_set_ui((MP_INT *)&pub.e, e);
|
d5f689 | 2013-11-24 | Martin Nilsson | |
if( !nettle_rsa_generate_keypair(&pub, &key, rnd, random_func_wrapper,
NULL, NULL, bits, 0) )
{
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | | rsa_private_key_clear(&key);
rsa_public_key_clear(&pub);
|
28aa06 | 2013-12-02 | Martin Nilsson | | Pike_error("Illegal parameter value.\n");
|
d5f689 | 2013-11-24 | Martin Nilsson | | }
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | | push_bignum((MP_INT *)&pub.n);
push_bignum((MP_INT *)&key.d);
push_bignum((MP_INT *)&key.p);
push_bignum((MP_INT *)&key.q);
rsa_private_key_clear(&key);
rsa_public_key_clear(&pub);
|
d5f689 | 2013-11-24 | Martin Nilsson | |
f_aggregate(4);
|
b6a409 | 2013-12-25 | Henrik Grubbström (Grubba) | | stack_pop_n_elems_keep_top(args); /* Remove bits, e and rnd. */
|
d5f689 | 2013-11-24 | Martin Nilsson | | }
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | #ifdef HAVE_NETTLE_ECDSA_H
#include <nettle/ecc-curve.h>
#include <nettle/ecc.h>
/*! @class ECC_Curve
*!
*! Elliptic Curve Definition
*/
PIKECLASS ECC_Curve
{
CVAR const struct ecc_curve *curve;
/*! @decl int size()
*!
*! @returns
*! Returns the size in bits for a single coordinate on the curve.
*/
PIKEFUN int size()
{
if (THIS->curve) {
push_int64(ecc_size(THIS->curve) * sizeof(mp_limb_t) * 8);
} else {
push_undefined();
}
}
/*! @decl Gmp.mpz new_scalar(function(int:string(8bit)) rnd)
*!
*! @param rnd
*! Randomness function to use as source.
*!
*! @returns
*! Returns a random scalar suitable to use as an @[ECDSA] private key
*! or as an ECDH exponent.
*/
PIKEFUN object(Gmp.mpz) new_scalar(function(int:string(8bit)) rnd)
{
struct ecc_scalar s;
struct object *ret;
ecc_scalar_init(&s, THIS->curve);
ecc_scalar_random(&s, rnd, random_func_wrapper);
push_object(ret = fast_clone_object(get_auto_bignum_program()));
ecc_scalar_get(&s, (mpz_ptr)ret->storage);
ecc_scalar_clear(&s);
}
/*! @decl array(Gmp.mpz) `*(Gmp.moz|int scalar)
*!
*! Multiply the curve by a scalar.
*!
*! @returns
*! Returns a new point (x, y) on the curve.
*/
PIKEFUN array(object(Gmp.mpz)) `*(object(Gmp.mpz)|int scalar)
{
struct ecc_scalar s;
struct ecc_point r;
struct object *x;
struct object *y;
convert_svalue_to_bignum(scalar);
ecc_scalar_init(&s, THIS->curve);
ecc_point_init(&r, THIS->curve);
if (!ecc_scalar_set(&s, (mpz_srcptr)scalar->u.object->storage)) {
ecc_scalar_clear(&s);
ecc_point_clear(&r);
SIMPLE_ARG_ERROR("`*", 1, "Invalid scalar for curve.");
}
ecc_point_mul_g(&r, &s);
push_object(x = fast_clone_object(get_auto_bignum_program()));
push_object(y = fast_clone_object(get_auto_bignum_program()));
ecc_point_get(&r, (mpz_ptr)x->storage, (mpz_ptr)y->storage);
ecc_scalar_clear(&s);
ecc_point_clear(&r);
f_aggregate(2);
}
}
/*! @endclass ECC_Curve
*/
#endif /* HAVE_NETTLE_ECDSA_H */
|
d5f689 | 2013-11-24 | Martin Nilsson | | void
hogweed_init(void)
{
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | | #ifdef HAVE_NETTLE_ECDSA_H
struct svalue c;
#endif
|
d5f689 | 2013-11-24 | Martin Nilsson | | INIT;
|
4bf09f | 2013-12-27 | Henrik Grubbström (Grubba) | |
#ifdef HAVE_NETTLE_ECDSA_H
SET_SVAL(c, PIKE_T_OBJECT, 0, object, fast_clone_object(ECC_Curve_program));
OBJ2_ECC_CURVE(c.u.object)->curve = &nettle_secp_192r1;
simple_add_constant("SECP_192R1", &c, 0);
free_svalue(&c);
SET_SVAL(c, PIKE_T_OBJECT, 0, object, fast_clone_object(ECC_Curve_program));
OBJ2_ECC_CURVE(c.u.object)->curve = &nettle_secp_224r1;
simple_add_constant("SECP_224R1", &c, 0);
free_svalue(&c);
SET_SVAL(c, PIKE_T_OBJECT, 0, object, fast_clone_object(ECC_Curve_program));
OBJ2_ECC_CURVE(c.u.object)->curve = &nettle_secp_256r1;
simple_add_constant("SECP_256R1", &c, 0);
free_svalue(&c);
SET_SVAL(c, PIKE_T_OBJECT, 0, object, fast_clone_object(ECC_Curve_program));
OBJ2_ECC_CURVE(c.u.object)->curve = &nettle_secp_384r1;
simple_add_constant("SECP_384R1", &c, 0);
free_svalue(&c);
SET_SVAL(c, PIKE_T_OBJECT, 0, object, fast_clone_object(ECC_Curve_program));
OBJ2_ECC_CURVE(c.u.object)->curve = &nettle_secp_521r1;
simple_add_constant("SECP_521R1", &c, 0);
free_svalue(&c);
#endif
|
d5f689 | 2013-11-24 | Martin Nilsson | | }
void
hogweed_exit(void)
{
EXIT;
}
#endif
|