[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [<UNIKRAFT/LIBHOGWEED> 4/4] Add test directory
Signed-off-by: ARGINT DRAGOS IULIAN <dragosargint21@xxxxxxxxx> --- test/Config.uk | 5 + test/Makefile | 9 + test/Makefile.uk | 2 + test/testutils.h | 305 ++++++++++++++++++ test/testutils_glue.c | 696 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1017 insertions(+) create mode 100644 test/Config.uk create mode 100644 test/Makefile create mode 100644 test/Makefile.uk create mode 100644 test/testutils.h create mode 100644 test/testutils_glue.c diff --git a/test/Config.uk b/test/Config.uk new file mode 100644 index 0000000..14fcc3c --- /dev/null +++ b/test/Config.uk @@ -0,0 +1,5 @@ +### Invisible option for dependencies +config TEST_DEPENDENCIES + bool + default y + diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..a6dd029 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,9 @@ +UK_ROOT ?= $(PWD)/../../../unikraft +UK_LIBS ?= $(PWD)/../../../libs +LIBS := $(UK_LIBS)/newlib:$(UK_LIBS)/libhogweed + +all: + @$(MAKE) -C $(UK_ROOT) A=$(PWD) L=$(LIBS) + +$(MAKECMDGOALS): + @$(MAKE) -C $(UK_ROOT) A=$(PWD) L=$(LIBS) $(MAKECMDGOALS) diff --git a/test/Makefile.uk b/test/Makefile.uk new file mode 100644 index 0000000..a96d0d3 --- /dev/null +++ b/test/Makefile.uk @@ -0,0 +1,2 @@ +$(eval $(call addlib,test)) +TEST_SRCS-y += $(TEST_BASE)/testutils_glue.c diff --git a/test/testutils.h b/test/testutils.h new file mode 100644 index 0000000..c7f5365 --- /dev/null +++ b/test/testutils.h @@ -0,0 +1,305 @@ +#ifndef NETTLE_TESTUTILS_H_INCLUDED +#define NETTLE_TESTUTILS_H_INCLUDED + +/* config.h should usually be first in each .c file. This is an + exception, include it here to reduce clutter in the test cases. */ +//#if HAVE_CONFIG_H +# include "config.h" +//#endif + +#include <stdarg.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "nettle-types.h" +#include "version.h" + +#if WITH_HOGWEED +# include "rsa.h" +# include "dsa-compat.h" +# include "ecc-curve.h" +# include "ecc.h" +# include "ecc-internal.h" +# include "ecdsa.h" +# include "gmp-glue.h" +# if NETTLE_USE_MINI_GMP +# include "knuth-lfib.h" +# endif + +/* Undo dsa-compat name mangling */ +#undef dsa_generate_keypair +#define dsa_generate_keypair nettle_dsa_generate_keypair +#endif /* WITH_HOGWEED */ + +#include "nettle-meta.h" + +/* Forward declare */ +struct nettle_aead; + +#ifdef __cplusplus +extern "C" { +#endif + +void +die(const char *format, ...) PRINTF_STYLE (1, 2) NORETURN; + +void * +xalloc(size_t size); + +struct tstring { + struct tstring *next; + size_t length; + uint8_t data[1]; +}; + +struct tstring * +tstring_alloc (size_t length); + +void +tstring_clear(void); + +struct tstring * +tstring_data(size_t length, const uint8_t *data); + +struct tstring * +tstring_hex(const char *hex); + +void +tstring_print_hex(const struct tstring *s); + +/* Decodes a NUL-terminated hex string. */ + +void +print_hex(size_t length, const uint8_t *data); + +/* The main program */ +void +test_main(void); + +extern int verbose; + +/* Test functions deallocate their inputs when finished.*/ +void +test_cipher(const struct nettle_cipher *cipher, + const struct tstring *key, + const struct tstring *cleartext, + const struct tstring *ciphertext); + +void +test_cipher_cbc(const struct nettle_cipher *cipher, + const struct tstring *key, + const struct tstring *cleartext, + const struct tstring *ciphertext, + const struct tstring *iv); + +void +test_cipher_cfb(const struct nettle_cipher *cipher, + const struct tstring *key, + const struct tstring *cleartext, + const struct tstring *ciphertext, + const struct tstring *iv); + +void +test_cipher_cfb8(const struct nettle_cipher *cipher, + const struct tstring *key, + const struct tstring *cleartext, + const struct tstring *ciphertext, + const struct tstring *iv); + +void +test_cipher_ctr(const struct nettle_cipher *cipher, + const struct tstring *key, + const struct tstring *cleartext, + const struct tstring *ciphertext, + const struct tstring *iv); + +void +test_cipher_stream(const struct nettle_cipher *cipher, + const struct tstring *key, + const struct tstring *cleartext, + const struct tstring *ciphertext); + +void +test_aead(const struct nettle_aead *aead, + nettle_hash_update_func *set_nonce, + const struct tstring *key, + const struct tstring *authtext, + const struct tstring *cleartext, + const struct tstring *ciphertext, + const struct tstring *nonce, + const struct tstring *digest); + +void +test_hash(const struct nettle_hash *hash, + const struct tstring *msg, + const struct tstring *digest); + +void +test_hash_large(const struct nettle_hash *hash, + size_t count, size_t length, + uint8_t c, + const struct tstring *digest); + +void +test_mac(const struct nettle_mac *mac, + const struct tstring *key, + const struct tstring *msg, + const struct tstring *digest); + +void +test_armor(const struct nettle_armor *armor, + size_t data_length, + const uint8_t *data, + const char *ascii); + +#if WITH_HOGWEED + +#if NETTLE_USE_MINI_GMP +typedef struct knuth_lfib_ctx gmp_randstate_t[1]; + +void gmp_randinit_default (struct knuth_lfib_ctx *ctx); +#define gmp_randclear(state) +void mpz_urandomb (mpz_t r, struct knuth_lfib_ctx *ctx, mp_bitcnt_t bits); +/* This is cheating */ +#define mpz_rrandomb mpz_urandomb + +#endif /* NETTLE_USE_MINI_GMP */ + +void +mpn_out_str (FILE *f, int base, const mp_limb_t *xp, mp_size_t xn); + +mp_limb_t * +xalloc_limbs (mp_size_t n); + +void +write_mpn (FILE *f, int base, const mp_limb_t *xp, mp_size_t n); + +void +test_rsa_set_key_1(struct rsa_public_key *pub, + struct rsa_private_key *key); + +void +test_rsa_md5(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected); + +void +test_rsa_sha1(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected); + +void +test_rsa_sha256(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected); + +void +test_rsa_sha512(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected); + +void +test_rsa_key(struct rsa_public_key *pub, + struct rsa_private_key *key); + +void +test_dsa160(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + const struct dsa_signature *expected); + +void +test_dsa256(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + const struct dsa_signature *expected); + +#if 0 +void +test_dsa_sign(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + const struct nettle_hash *hash, + const struct dsa_signature *expected); +#endif + +void +test_dsa_verify(const struct dsa_params *params, + const mpz_t pub, + const struct nettle_hash *hash, + struct tstring *msg, + const struct dsa_signature *ref); + +void +test_dsa_key(const struct dsa_params *params, + const mpz_t pub, + const mpz_t key, + unsigned q_size); + +extern const struct ecc_curve * const ecc_curves[]; + +struct ecc_ref_point +{ + const char *x; + const char *y; +}; + +void +test_ecc_point (const struct ecc_curve *ecc, + const struct ecc_ref_point *ref, + const mp_limb_t *p); + +void +test_ecc_mul_a (unsigned curve, unsigned n, const mp_limb_t *p); + +void +test_ecc_mul_h (unsigned curve, unsigned n, const mp_limb_t *p); + +/* Checks that p == g (affine coordinates) */ +void +test_ecc_ga (unsigned curve, const mp_limb_t *p); + +/* Gets the curve generator, with coordinates in redc form, if + appropriate, and with an appended z = 1 coordinate. */ +void +test_ecc_get_g (unsigned curve, mp_limb_t *rp); + +/* Variant with only two coordinates, and no redc. */ +void +test_ecc_get_ga (unsigned curve, mp_limb_t *rp); + +#endif /* WITH_HOGWEED */ + +/* String literal of type unsigned char. The GNUC version is safer. */ +#if __GNUC__ +#define US(s) ({ static const unsigned char us_s[] = s; us_s; }) +#else +#define US(s) ((const uint8_t *) (s)) +#endif + +/* LDATA needs to handle NUL characters. */ +#define LLENGTH(x) (sizeof(x) - 1) +#define LDATA(x) LLENGTH(x), US(x) +#define LDUP(x) strlen(x), strdup(x) + +#define SHEX(x) (tstring_hex(x)) +#define SDATA(x) ((const struct tstring *)tstring_data(LLENGTH(x), US(x))) +#define H(x) (SHEX(x)->data) + +#define MEMEQ(length, a, b) (!memcmp((a), (b), (length))) + +#define FAIL() abort() +#define SKIP() exit(77) + +#define ASSERT(x) do { \ + if (!(x)) \ + { \ + fprintf(stderr, "Assert failed: %s:%d: %s\n", \ + __FILE__, __LINE__, #x); \ + FAIL(); \ + } \ + } while(0) + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_TESTUTILS_H_INCLUDED */ diff --git a/test/testutils_glue.c b/test/testutils_glue.c new file mode 100644 index 0000000..531bb80 --- /dev/null +++ b/test/testutils_glue.c @@ -0,0 +1,696 @@ +/* testutils.c */ + +#include "testutils.h" + +#include "base16.h" +#include "cbc.h" +#include "cfb.h" +#include "ctr.h" +#include "knuth-lfib.h" +#include "macros.h" +#include "nettle-internal.h" + +#include <assert.h> +#include <ctype.h> + +void +die(const char *format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + abort (); +} + +void * +xalloc(size_t size) +{ + void *p = malloc(size); + if (size && !p) + { + fprintf(stderr, "Virtual memory exhausted.\n"); + abort(); + } + + return p; +} + +static struct tstring *tstring_first = NULL; + +struct tstring * +tstring_alloc (size_t length) +{ + struct tstring *s = xalloc(sizeof(struct tstring) + length); + s->length = length; + s->next = tstring_first; + /* NUL-terminate, for convenience. */ + s->data[length] = '\0'; + tstring_first = s; + return s; +} + +void +tstring_clear(void) +{ + while (tstring_first) + { + struct tstring *s = tstring_first; + tstring_first = s->next; + free(s); + } +} + +struct tstring * +tstring_data(size_t length, const uint8_t *data) +{ + struct tstring *s = tstring_alloc (length); + memcpy (s->data, data, length); + return s; +} + +struct tstring * +tstring_hex(const char *hex) +{ + struct base16_decode_ctx ctx; + struct tstring *s; + size_t length = strlen(hex); + + s = tstring_alloc(BASE16_DECODE_LENGTH (length)); + base16_decode_init (&ctx); + ASSERT (base16_decode_update (&ctx, &s->length, s->data, + length, hex)); + ASSERT (base16_decode_final (&ctx)); + + return s; +} + +void +tstring_print_hex(const struct tstring *s) +{ + print_hex (s->length, s->data); +} + +void +print_hex(size_t length, const uint8_t *data) +{ + size_t i; + + for (i = 0; i < length; i++) + { + switch (i % 16) + { + default: + break; + case 0: + printf("\n"); + break; + case 8: + printf(" "); + break; + } + printf("%02x", data[i]); + } + printf("\n"); +} + +int verbose = 0; + +int +main(int argc, char **argv) +{ + if (argc > 1) + { + if (argc == 2 && !strcmp(argv[1], "-v")) + verbose = 1; + else + { + fprintf(stderr, "Invalid argument `%s', only accepted option is `-v'.\n", + argv[1]); + return 1; + } + } + + test_main(); + + tstring_clear(); + puts("SUCCESS"); + return EXIT_SUCCESS; +} + + +void +mpn_out_str (FILE *f, int base, const mp_limb_t *xp, mp_size_t xn) +{ + mpz_t x; + mpz_out_str (f, base, mpz_roinit_n (x, xp, xn)); +} + +#if NETTLE_USE_MINI_GMP +void +gmp_randinit_default (struct knuth_lfib_ctx *ctx) +{ + knuth_lfib_init (ctx, 17); +} +void +mpz_urandomb (mpz_t r, struct knuth_lfib_ctx *ctx, mp_bitcnt_t bits) +{ + size_t bytes = (bits+7)/8; + uint8_t *buf = xalloc (bytes); + + knuth_lfib_random (ctx, bytes, buf); + buf[0] &= 0xff >> (8*bytes - bits); + nettle_mpz_set_str_256_u (r, bytes, buf); + free (buf); +} +#endif /* NETTLE_USE_MINI_GMP */ + +mp_limb_t * +xalloc_limbs (mp_size_t n) +{ + return xalloc (n * sizeof (mp_limb_t)); +} + +/* Expects local variables pub, key, rstate, digest, signature */ +#define SIGN(hash, msg, expected) do { \ + hash##_update(&hash, LDATA(msg)); \ + ASSERT(rsa_##hash##_sign(key, &hash, signature)); \ + if (verbose) \ + { \ + fprintf(stderr, "rsa-%s signature: ", #hash); \ + mpz_out_str(stderr, 16, signature); \ + fprintf(stderr, "\n"); \ + } \ + ASSERT(mpz_cmp (signature, expected) == 0); \ + \ + hash##_update(&hash, LDATA(msg)); \ + ASSERT(rsa_##hash##_sign_tr(pub, key, &rstate, \ + (nettle_random_func *) knuth_lfib_random, \ + &hash, signature)); \ + ASSERT(mpz_cmp (signature, expected) == 0); \ + \ + hash##_update(&hash, LDATA(msg)); \ + hash##_digest(&hash, sizeof(digest), digest); \ + ASSERT(rsa_##hash##_sign_digest(key, digest, signature)); \ + ASSERT(mpz_cmp (signature, expected) == 0); \ + \ + ASSERT(rsa_##hash##_sign_digest_tr(pub, key, &rstate, \ + (nettle_random_func *)knuth_lfib_random, \ + digest, signature)); \ + ASSERT(mpz_cmp (signature, expected) == 0); \ +} while(0) + +#define VERIFY(key, hash, msg, signature) ( \ + hash##_update(&hash, LDATA(msg)), \ + rsa_##hash##_verify(key, &hash, signature) \ +) + +void +test_rsa_set_key_1(struct rsa_public_key *pub, + struct rsa_private_key *key) +{ + /* Initialize key pair for test programs */ + /* 1000-bit key, generated by + * + * lsh-keygen -a rsa -l 1000 -f advanced-hex + * + * (private-key (rsa-pkcs1 + * (n #69abd505285af665 36ddc7c8f027e6f0 ed435d6748b16088 + * 4fd60842b3a8d7fb bd8a3c98f0cc50ae 4f6a9f7dd73122cc + * ec8afa3f77134406 f53721973115fc2d 8cfbba23b145f28d + * 84f81d3b6ae8ce1e 2850580c026e809b cfbb52566ea3a3b3 + * df7edf52971872a7 e35c1451b8636d22 279a8fb299368238 + * e545fbb4cf#) + * (e #0db2ad57#) + * (d #3240a56f4cd0dcc2 4a413eb4ea545259 5c83d771a1c2ba7b + * ec47c5b43eb4b374 09bd2aa1e236dd86 481eb1768811412f + * f8d91be3545912af b55c014cb55ceac6 54216af3b85d5c4f + * 4a32894e3b5dfcde 5b2875aa4dc8d9a8 6afd0ca92ef50d35 + * bd09f1c47efb4c8d c631e07698d362aa 4a83fd304e66d6c5 + * 468863c307#) + * (p #0a66399919be4b4d e5a78c5ea5c85bf9 aba8c013cb4a8732 + * 14557a12bd67711e bb4073fd39ad9a86 f4e80253ad809e5b + * f2fad3bc37f6f013 273c9552c9f489#) + * (q #0a294f069f118625 f5eae2538db9338c 776a298eae953329 + * 9fd1eed4eba04e82 b2593bc98ba8db27 de034da7daaea795 + * 2d55b07b5f9a5875 d1ca5f6dcab897#) + * (a #011b6c48eb592eee e85d1bb35cfb6e07 344ea0b5e5f03a28 + * 5b405396cbc78c5c 868e961db160ba8d 4b984250930cf79a + * 1bf8a9f28963de53 128aa7d690eb87#) + * (b #0409ecf3d2557c88 214f1af5e1f17853 d8b2d63782fa5628 + * 60cf579b0833b7ff 5c0529f2a97c6452 2fa1a8878a9635ab + * ce56debf431bdec2 70b308fa5bf387#) + * (c #04e103ee925cb5e6 6653949fa5e1a462 c9e65e1adcd60058 + * e2df9607cee95fa8 daec7a389a7d9afc 8dd21fef9d83805a + * 40d46f49676a2f6b 2926f70c572c00#))) + */ + + mpz_set_str(pub->n, + "69abd505285af665" "36ddc7c8f027e6f0" "ed435d6748b16088" + "4fd60842b3a8d7fb" "bd8a3c98f0cc50ae" "4f6a9f7dd73122cc" + "ec8afa3f77134406" "f53721973115fc2d" "8cfbba23b145f28d" + "84f81d3b6ae8ce1e" "2850580c026e809b" "cfbb52566ea3a3b3" + "df7edf52971872a7" "e35c1451b8636d22" "279a8fb299368238" + "e545fbb4cf", 16); + mpz_set_str(pub->e, "0db2ad57", 16); + + ASSERT (rsa_public_key_prepare(pub)); + + /* d is not used */ +#if 0 + mpz_set_str(key->d, + "3240a56f4cd0dcc2" "4a413eb4ea545259" "5c83d771a1c2ba7b" + "ec47c5b43eb4b374" "09bd2aa1e236dd86" "481eb1768811412f" + "f8d91be3545912af" "b55c014cb55ceac6" "54216af3b85d5c4f" + "4a32894e3b5dfcde" "5b2875aa4dc8d9a8" "6afd0ca92ef50d35" + "bd09f1c47efb4c8d" "c631e07698d362aa" "4a83fd304e66d6c5" + "468863c307", 16); +#endif + + mpz_set_str(key->p, + "0a66399919be4b4d" "e5a78c5ea5c85bf9" "aba8c013cb4a8732" + "14557a12bd67711e" "bb4073fd39ad9a86" "f4e80253ad809e5b" + "f2fad3bc37f6f013" "273c9552c9f489", 16); + + mpz_set_str(key->q, + "0a294f069f118625" "f5eae2538db9338c" "776a298eae953329" + "9fd1eed4eba04e82" "b2593bc98ba8db27" "de034da7daaea795" + "2d55b07b5f9a5875" "d1ca5f6dcab897", 16); + + mpz_set_str(key->a, + "011b6c48eb592eee" "e85d1bb35cfb6e07" "344ea0b5e5f03a28" + "5b405396cbc78c5c" "868e961db160ba8d" "4b984250930cf79a" + "1bf8a9f28963de53" "128aa7d690eb87", 16); + + mpz_set_str(key->b, + "0409ecf3d2557c88" "214f1af5e1f17853" "d8b2d63782fa5628" + "60cf579b0833b7ff" "5c0529f2a97c6452" "2fa1a8878a9635ab" + "ce56debf431bdec2" "70b308fa5bf387", 16); + + mpz_set_str(key->c, + "04e103ee925cb5e6" "6653949fa5e1a462" "c9e65e1adcd60058" + "e2df9607cee95fa8" "daec7a389a7d9afc" "8dd21fef9d83805a" + "40d46f49676a2f6b" "2926f70c572c00", 16); + + ASSERT (rsa_private_key_prepare(key)); + ASSERT (pub->size == key->size); +} + +void +test_rsa_md5(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected) +{ + struct md5_ctx md5; + struct knuth_lfib_ctx rstate; + uint8_t digest[MD5_DIGEST_SIZE]; + mpz_t signature; + + md5_init(&md5); + mpz_init(signature); + knuth_lfib_init (&rstate, 15); + + SIGN(md5, "The magic words are squeamish ossifrage", expected); + + /* Try bad data */ + ASSERT (!VERIFY(pub, md5, + "The magick words are squeamish ossifrage", signature)); + + /* Try correct data */ + ASSERT (VERIFY(pub, md5, + "The magic words are squeamish ossifrage", signature)); + + /* Try bad signature */ + mpz_combit(signature, 17); + ASSERT (!VERIFY(pub, md5, + "The magic words are squeamish ossifrage", signature)); + + mpz_clear(signature); +} + +void +test_rsa_sha1(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected) +{ + struct sha1_ctx sha1; + struct knuth_lfib_ctx rstate; + uint8_t digest[SHA1_DIGEST_SIZE]; + mpz_t signature; + + sha1_init(&sha1); + mpz_init(signature); + knuth_lfib_init (&rstate, 16); + + SIGN(sha1, "The magic words are squeamish ossifrage", expected); + + /* Try bad data */ + ASSERT (!VERIFY(pub, sha1, + "The magick words are squeamish ossifrage", signature)); + + /* Try correct data */ + ASSERT (VERIFY(pub, sha1, + "The magic words are squeamish ossifrage", signature)); + + /* Try bad signature */ + mpz_combit(signature, 17); + ASSERT (!VERIFY(pub, sha1, + "The magic words are squeamish ossifrage", signature)); + + mpz_clear(signature); +} + +void +test_rsa_sha256(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected) +{ + struct sha256_ctx sha256; + struct knuth_lfib_ctx rstate; + uint8_t digest[SHA256_DIGEST_SIZE]; + mpz_t signature; + + sha256_init(&sha256); + mpz_init(signature); + knuth_lfib_init (&rstate, 17); + + SIGN(sha256, "The magic words are squeamish ossifrage", expected); + + /* Try bad data */ + ASSERT (!VERIFY(pub, sha256, + "The magick words are squeamish ossifrage", signature)); + + /* Try correct data */ + ASSERT (VERIFY(pub, sha256, + "The magic words are squeamish ossifrage", signature)); + + /* Try bad signature */ + mpz_combit(signature, 17); + ASSERT (!VERIFY(pub, sha256, + "The magic words are squeamish ossifrage", signature)); + + mpz_clear(signature); +} + +void +test_rsa_sha512(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected) +{ + struct sha512_ctx sha512; + struct knuth_lfib_ctx rstate; + uint8_t digest[SHA512_DIGEST_SIZE]; + mpz_t signature; + + sha512_init(&sha512); + mpz_init(signature); + knuth_lfib_init (&rstate, 18); + + SIGN(sha512, "The magic words are squeamish ossifrage", expected); + + /* Try bad data */ + ASSERT (!VERIFY(pub, sha512, + "The magick words are squeamish ossifrage", signature)); + + /* Try correct data */ + ASSERT (VERIFY(pub, sha512, + "The magic words are squeamish ossifrage", signature)); + + /* Try bad signature */ + mpz_combit(signature, 17); + ASSERT (!VERIFY(pub, sha512, + "The magic words are squeamish ossifrage", signature)); + + mpz_clear(signature); +} + +#undef SIGN +#undef VERIFY + +void +test_rsa_key(struct rsa_public_key *pub, + struct rsa_private_key *key) +{ + mpz_t tmp; + mpz_t phi; + + mpz_init(tmp); mpz_init(phi); + + if (verbose) + { + /* FIXME: Use gmp_printf */ + fprintf(stderr, "Public key: n="); + mpz_out_str(stderr, 16, pub->n); + fprintf(stderr, "\n e="); + mpz_out_str(stderr, 16, pub->e); + + fprintf(stderr, "\n\nPrivate key: d="); + mpz_out_str(stderr, 16, key->d); + fprintf(stderr, "\n p="); + mpz_out_str(stderr, 16, key->p); + fprintf(stderr, "\n q="); + mpz_out_str(stderr, 16, key->q); + fprintf(stderr, "\n a="); + mpz_out_str(stderr, 16, key->a); + fprintf(stderr, "\n b="); + mpz_out_str(stderr, 16, key->b); + fprintf(stderr, "\n c="); + mpz_out_str(stderr, 16, key->c); + fprintf(stderr, "\n\n"); + } + + /* Check n = p q */ + mpz_mul(tmp, key->p, key->q); + ASSERT (mpz_cmp(tmp, pub->n)== 0); + + /* Check c q = 1 mod p */ + mpz_mul(tmp, key->c, key->q); + mpz_fdiv_r(tmp, tmp, key->p); + ASSERT (mpz_cmp_ui(tmp, 1) == 0); + + /* Check ed = 1 (mod phi) */ + mpz_sub_ui(phi, key->p, 1); + mpz_sub_ui(tmp, key->q, 1); + + mpz_mul(phi, phi, tmp); + + mpz_mul(tmp, pub->e, key->d); + mpz_fdiv_r(tmp, tmp, phi); + ASSERT (mpz_cmp_ui(tmp, 1) == 0); + + /* Check a e = 1 (mod (p-1) ) */ + mpz_sub_ui(phi, key->p, 1); + mpz_mul(tmp, pub->e, key->a); + mpz_fdiv_r(tmp, tmp, phi); + ASSERT (mpz_cmp_ui(tmp, 1) == 0); + + /* Check b e = 1 (mod (q-1) ) */ + mpz_sub_ui(phi, key->q, 1); + mpz_mul(tmp, pub->e, key->b); + mpz_fdiv_r(tmp, tmp, phi); + ASSERT (mpz_cmp_ui(tmp, 1) == 0); + + mpz_clear(tmp); mpz_clear(phi); +} + +/* Requires that the context is named like the hash algorithm. */ +#define DSA_VERIFY(key, hash, msg, signature) \ + (hash##_update(&hash, LDATA(msg)), \ + dsa_##hash##_verify(key, &hash, signature)) + +void +test_dsa160(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + const struct dsa_signature *expected) +{ + struct sha1_ctx sha1; + struct dsa_signature signature; + struct knuth_lfib_ctx lfib; + + sha1_init(&sha1); + dsa_signature_init(&signature); + knuth_lfib_init(&lfib, 1111); + + sha1_update(&sha1, LDATA("The magic words are squeamish ossifrage")); + ASSERT (dsa_sha1_sign(pub, key, + &lfib, (nettle_random_func *) knuth_lfib_random, + &sha1, &signature)); + + if (verbose) + { + fprintf(stderr, "dsa160 signature: "); + mpz_out_str(stderr, 16, signature.r); + fprintf(stderr, ", "); + mpz_out_str(stderr, 16, signature.s); + fprintf(stderr, "\n"); + } + + if (expected) + ASSERT (mpz_cmp (signature.r, expected->r) == 0 + && mpz_cmp (signature.s, expected->s) == 0); + + /* Try bad data */ + ASSERT (!DSA_VERIFY(pub, sha1, + "The magick words are squeamish ossifrage", + &signature)); + + /* Try correct data */ + ASSERT (DSA_VERIFY(pub, sha1, + "The magic words are squeamish ossifrage", + &signature)); + + /* Try bad signature */ + mpz_combit(signature.r, 17); + ASSERT (!DSA_VERIFY(pub, sha1, + "The magic words are squeamish ossifrage", + &signature)); + + dsa_signature_clear(&signature); +} + +void +test_dsa256(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + const struct dsa_signature *expected) +{ + struct sha256_ctx sha256; + struct dsa_signature signature; + struct knuth_lfib_ctx lfib; + + sha256_init(&sha256); + dsa_signature_init(&signature); + knuth_lfib_init(&lfib, 1111); + + sha256_update(&sha256, LDATA("The magic words are squeamish ossifrage")); + ASSERT (dsa_sha256_sign(pub, key, + &lfib, (nettle_random_func *) knuth_lfib_random, + &sha256, &signature)); + + if (verbose) + { + fprintf(stderr, "dsa256 signature: "); + mpz_out_str(stderr, 16, signature.r); + fprintf(stderr, ", "); + mpz_out_str(stderr, 16, signature.s); + fprintf(stderr, "\n"); + } + + if (expected) + ASSERT (mpz_cmp (signature.r, expected->r) == 0 + && mpz_cmp (signature.s, expected->s) == 0); + + /* Try bad data */ + ASSERT (!DSA_VERIFY(pub, sha256, + "The magick words are squeamish ossifrage", + &signature)); + + /* Try correct data */ + ASSERT (DSA_VERIFY(pub, sha256, + "The magic words are squeamish ossifrage", + &signature)); + + /* Try bad signature */ + mpz_combit(signature.r, 17); + ASSERT (!DSA_VERIFY(pub, sha256, + "The magic words are squeamish ossifrage", + &signature)); + + dsa_signature_clear(&signature); +} + + +void +test_dsa_verify(const struct dsa_params *params, + const mpz_t pub, + const struct nettle_hash *hash, + struct tstring *msg, + const struct dsa_signature *ref) +{ + void *ctx = xalloc (hash->context_size); + uint8_t *digest = xalloc (hash->digest_size); + struct dsa_signature signature; + + dsa_signature_init (&signature); + + hash->init(ctx); + + hash->update (ctx, msg->length, msg->data); + hash->digest (ctx, hash->digest_size, digest); + + mpz_set (signature.r, ref->r); + mpz_set (signature.s, ref->s); + + ASSERT (dsa_verify (params, pub, + hash->digest_size, digest, + &signature)); + + /* Try bad signature */ + mpz_combit(signature.r, 17); + ASSERT (!dsa_verify (params, pub, + hash->digest_size, digest, + &signature)); + + /* Try bad data */ + digest[hash->digest_size / 2-1] ^= 8; + ASSERT (!dsa_verify (params, pub, + hash->digest_size, digest, + ref)); + + free (ctx); + free (digest); + dsa_signature_clear(&signature); +} + +void +test_dsa_key(const struct dsa_params *params, + const mpz_t pub, + const mpz_t key, + unsigned q_size) +{ + mpz_t t; + + mpz_init(t); + + ASSERT(mpz_sizeinbase(params->q, 2) == q_size); + ASSERT(mpz_sizeinbase(params->p, 2) >= DSA_SHA1_MIN_P_BITS); + + ASSERT(mpz_probab_prime_p(params->p, 10)); + + ASSERT(mpz_probab_prime_p(params->q, 10)); + + mpz_fdiv_r(t, params->p, params->q); + + ASSERT(0 == mpz_cmp_ui(t, 1)); + + ASSERT(mpz_cmp_ui(params->g, 1) > 0); + + mpz_powm(t, params->g, params->q, params->p); + ASSERT(0 == mpz_cmp_ui(t, 1)); + + mpz_powm(t, params->g, key, params->p); + ASSERT(0 == mpz_cmp(t, pub)); + + mpz_clear(t); +} + +const struct ecc_curve * const ecc_curves[] = { + &_nettle_secp_192r1, + &_nettle_secp_224r1, + &_nettle_secp_256r1, + &_nettle_secp_384r1, + &_nettle_secp_521r1, + &_nettle_curve25519, + &_nettle_curve448, + &_nettle_gost_gc256b, + &_nettle_gost_gc512a, + NULL +}; + + +void +write_mpn (FILE *f, int base, const mp_limb_t *xp, mp_size_t n) +{ + mpz_t t; + mpz_out_str (f, base, mpz_roinit_n (t,xp, n)); +} -- 2.17.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |