diff options
Diffstat (limited to 'crypto.c')
-rw-r--r-- | crypto.c | 263 |
1 files changed, 49 insertions, 214 deletions
@@ -34,8 +34,10 @@ struct brandt_ec_pkey { unsigned char q_y[256 / 8]; }; -gcry_mpi_point_t ec_gen; gcry_ctx_t ec_ctx; +gcry_mpi_point_t ec_gen; +gcry_mpi_point_t ec_zero; +gcry_mpi_t ec_n; /** * brandt_crypto_init @@ -49,10 +51,19 @@ brandt_crypto_init () rc = gcry_mpi_ec_new (&ec_ctx, NULL, CURVE); brandt_assert_gpgerr (rc); + ec_gen = gcry_mpi_ec_get_point ("g", ec_ctx, 0); brandt_assert (NULL != ec_gen); + + ec_zero = gcry_mpi_point_new (0); + brandt_assert (NULL != ec_zero); + gcry_mpi_ec_sub (ec_zero, ec_gen, ec_gen, ec_ctx); + + ec_n = gcry_mpi_ec_get_mpi ("n", ec_ctx, 1); + brandt_assert (NULL != ec_n); } + /* --- RANDOM --- */ void @@ -64,6 +75,7 @@ brandt_rand_poll () gcry_fast_random_poll (); } + /* --- HASHING --- */ /** @@ -79,6 +91,7 @@ brandt_hash (const void *block, size_t size, struct brandt_hash_code *ret) gcry_md_hash_buffer (GCRY_MD_SHA512, ret, block, size); } + /* --- MPI --- */ /** @@ -101,6 +114,7 @@ adjust (void *buf, size_t size, size_t target) } } + /** * Output the given MPI value to the given buffer in * network byte order. @@ -141,6 +155,7 @@ brandt_mpi_print_unsigned (void *buf, size_t size, gcry_mpi_t val) } } + /** * Convert data buffer into MPI value. * The buffer is interpreted as network @@ -159,6 +174,7 @@ brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, size_t size) brandt_assert_gpgerr (rc); } + //gcry_mpi_point_t //deserialize_point(const struct brandt_point* data, const int len) //{ @@ -185,73 +201,18 @@ brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, size_t size) /* --- EC --- */ /** - * Extract values from an S-expression. - * - * @param array where to store the result(s) - * @param sexp S-expression to parse - * @param topname top-level name in the S-expression that is of interest - * @param elems names of the elements to extract - * @return 0 on success - */ -static int -key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname, - const char *elems) -{ - gcry_sexp_t list; - gcry_sexp_t l2; - const char *s; - unsigned int i; - unsigned int idx; - - list = gcry_sexp_find_token (sexp, topname, 0); - if (!list) - return 1; - l2 = gcry_sexp_cadr (list); - gcry_sexp_release (list); - list = l2; - if (!list) - return 2; - idx = 0; - for (s = elems; *s; s++, idx++) - { - l2 = gcry_sexp_find_token (list, s, 1); - if (!l2) - { - for (i = 0; i < idx; i++) - { - gcry_free (array[i]); - array[i] = NULL; - } - gcry_sexp_release (list); - return 3; /* required parameter not found */ - } - array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); - gcry_sexp_release (l2); - if (!array[idx]) - { - for (i = 0; i < idx; i++) - { - gcry_free (array[i]); - array[i] = NULL; - } - gcry_sexp_release (list); - return 4; /* required parameter is invalid */ - } - } - gcry_sexp_release (list); - return 0; -} - -/** * brandt_ec_skey_create * * @param[out] skey where to store the generated secret key */ void -brandt_ec_skey_create (gcry_mpi_t *skey) +brandt_ec_skey_create (gcry_mpi_t skey) { + gcry_mpi_t ret; gcry_sexp_t s_keyparam; gcry_sexp_t priv_sexp; + gcry_sexp_t priv_key; + gcry_sexp_t priv_key2; gcry_error_t rc; rc = gcry_sexp_build (&s_keyparam, NULL, "(genkey(ecc(curve \"" CURVE "\")" @@ -262,24 +223,22 @@ brandt_ec_skey_create (gcry_mpi_t *skey) brandt_assert_gpgerr (rc); gcry_sexp_release (s_keyparam); - rc = key_from_sexp (skey, priv_sexp, "private-key", "d"); - brandt_assert_gpgerr (rc); - + priv_key = gcry_sexp_find_token (priv_sexp, "private-key", 11); + brandt_assert (NULL != priv_key); gcry_sexp_release (priv_sexp); -} -/** - * brandt_ec_pkey_compute - * - * @param pkey TODO - * @param skey TODO - */ -void -brandt_ec_pkey_compute (gcry_mpi_point_t *pkey, const gcry_mpi_t skey) -{ + priv_key2 = gcry_sexp_find_token (priv_key, "d", 1); + brandt_assert (NULL != priv_key2); + gcry_sexp_release (priv_key); + ret = gcry_sexp_nth_mpi (priv_key2, 1, GCRYMPI_FMT_USG); + brandt_assert (NULL != ret); + gcry_sexp_release (priv_key2); + + gcry_mpi_snatch (skey, ret); } + /** * brandt_ec_keypair_create * @@ -287,33 +246,16 @@ brandt_ec_pkey_compute (gcry_mpi_point_t *pkey, const gcry_mpi_t skey) * @param[out] skey where to store the generated secret key */ void -brandt_ec_keypair_create (gcry_mpi_point_t *pkey, gcry_mpi_t *skey) +brandt_ec_keypair_create (gcry_mpi_point_t pkey, gcry_mpi_t skey) { - gcry_ctx_t ctx; - gcry_sexp_t s_keyparam; - gcry_sexp_t priv_sexp; - gcry_error_t rc; - - rc = gcry_sexp_build (&s_keyparam, NULL, "(genkey(ecc(curve \"" CURVE "\")" - "(flags)))"); - brandt_assert_gpgerr (rc); - - rc = gcry_pk_genkey (&priv_sexp, s_keyparam); - brandt_assert_gpgerr (rc); - gcry_sexp_release (s_keyparam); - - rc = key_from_sexp (skey, priv_sexp, "private-key", "d"); - brandt_assert_gpgerr (rc); - - rc = gcry_mpi_ec_new (&ctx, priv_sexp, NULL); - brandt_assert_gpgerr (rc); - gcry_sexp_release (priv_sexp); + brandt_assert (NULL != pkey); + brandt_assert (NULL != skey); - *pkey = gcry_mpi_ec_get_point ("q", ctx, 0); - brandt_assert (NULL != *pkey); - gcry_ctx_release (ctx); + brandt_ec_skey_create (skey); + gcry_mpi_ec_mul (pkey, skey, ec_gen, ec_ctx); } + /** * brandt_ec_keypair_create_base * @@ -322,16 +264,19 @@ brandt_ec_keypair_create (gcry_mpi_point_t *pkey, gcry_mpi_t *skey) * @param[in] base which base point should be used to calculate the public key */ void -brandt_ec_keypair_create_base (gcry_mpi_point_t *pkey, gcry_mpi_t *skey, +brandt_ec_keypair_create_base (gcry_mpi_point_t pkey, + gcry_mpi_t skey, const gcry_mpi_point_t base) { + brandt_assert (NULL != pkey); + brandt_assert (NULL != skey); + brandt_assert (NULL != base); + brandt_ec_skey_create (skey); - brandt_assert (*skey); - *pkey = gcry_mpi_point_new (0); - brandt_assert (*pkey); - gcry_mpi_ec_mul (*pkey, *skey, base, ec_ctx); + gcry_mpi_ec_mul (pkey, skey, base, ec_ctx); } + /** * brandt_ec_point_cmp compares two curve points * @@ -356,8 +301,8 @@ brandt_ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b) return 1; } - if (!gcry_mpi_ec_get_affine (ax, ay, a, ec_ctx) - && !gcry_mpi_ec_get_affine (bx, by, b, ec_ctx)) + if (!gcry_mpi_ec_get_affine (ax, ay, a, ec_ctx) && + !gcry_mpi_ec_get_affine (bx, by, b, ec_ctx)) { ret = gcry_mpi_cmp (ax, bx) || gcry_mpi_cmp (ay, by); } @@ -369,117 +314,6 @@ brandt_ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b) return ret; } -/** - * Convert the given private key from the network format to the - * S-expression that can be used by libgcrypt. - * - * @param priv private key to decode - * @return NULL on error - */ -static gcry_sexp_t -decode_private_ecdhe_key (const struct brandt_ec_skey *priv) -{ - gcry_sexp_t result; - gcry_error_t rc; - - rc = gcry_sexp_build (&result, NULL, - "(private-key(ecc(curve \"" CURVE "\")" - "(d %b)))", - (int)sizeof (priv->d), priv->d); - brandt_assert_gpgerr (rc); - return result; -} - -/** - * Extract the public key for the given private key. - * - * @param priv the private key - * @param pub where to write the public key - */ -void -brandt_ecdhe_key_get_public (const struct brandt_ec_skey *priv, - struct brandt_ec_pkey *pub) -{ - gcry_sexp_t sexp; - gcry_ctx_t ctx; - gcry_mpi_t q; - gcry_error_t rc; - - sexp = decode_private_ecdhe_key (priv); - brandt_assert (NULL != sexp); - rc = gcry_mpi_ec_new (&ctx, sexp, NULL); - brandt_assert_gpgerr (rc); - gcry_sexp_release (sexp); - q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0); - brandt_assert (NULL != q); - brandt_mpi_print_unsigned (pub->q_y, sizeof (pub->q_y), q); - gcry_mpi_release (q); - gcry_ctx_release (ctx); -} - -/** - * Derive key material from a public and a private ECDHE key. - * - * @param priv private key to use for the ECDH (x) - * @param pub public key to use for the ECDH (yG) - * @param key_material where to write the key material (xyG) - * @return 0 on error, 1 on success - */ -int -brandt_ecdhe (const struct brandt_ec_skey *priv, - const struct brandt_ec_pkey *pub, - struct brandt_hash_code *key_material) -{ - gcry_error_t rc; - int rc2; - gcry_mpi_point_t result; - gcry_mpi_point_t q; - gcry_mpi_t d; - gcry_ctx_t ctx; - gcry_sexp_t pub_sexpr; - gcry_mpi_t result_x; - unsigned char xbuf[256 / 8]; - size_t rsize; - - /* first, extract the q = dP value from the public key */ - if (0 != gcry_sexp_build (&pub_sexpr, NULL, - "(public-key(ecc(curve " CURVE ")(q %b)))", - (int)sizeof (pub->q_y), pub->q_y)) - return 0; - rc = gcry_mpi_ec_new (&ctx, pub_sexpr, NULL); - brandt_assert_gpgerr (rc); - gcry_sexp_release (pub_sexpr); - q = gcry_mpi_ec_get_point ("q", ctx, 0); - - /* second, extract the d value from our private key */ - brandt_mpi_scan_unsigned (&d, priv->d, sizeof (priv->d)); - - /* then call the 'multiply' function, to compute the product */ - result = gcry_mpi_point_new (0); - gcry_mpi_ec_mul (result, d, q, ctx); - gcry_mpi_point_release (q); - gcry_mpi_release (d); - - /* finally, convert point to string for hashing */ - result_x = gcry_mpi_new (256); - rc = gcry_mpi_ec_get_affine (result_x, NULL, result, ctx); - brandt_assert (0 == rc); - gcry_mpi_point_release (result); - gcry_ctx_release (ctx); - - rsize = sizeof (xbuf); - rc2 = gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE); - brandt_assert (0 == rc2); - /* result_x can be negative here, so we do not use 'brandt_mpi_print_unsigned' - * as that does not include the sign bit; x should be a 255-bit - * value, so with the sign it should fit snugly into the 256-bit - * xbuf */ - rc = gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize, result_x); - brandt_assert_gpgerr (rc); - brandt_hash (xbuf, rsize, key_material); - gcry_mpi_release (result_x); - return 1; -} /** * Clear memory that was used to store a private key. @@ -492,6 +326,7 @@ brandt_ec_key_clear (struct brandt_ec_skey *skey) memset (skey, 0, sizeof (struct brandt_ec_skey)); } + /** * Generate a random value mod n. * |