1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

More ECDH code cleanups

This commit is contained in:
Werner Koch 2011-01-25 17:48:51 +01:00
parent 638dca5dbc
commit 302c5a826c
4 changed files with 74 additions and 103 deletions

View File

@ -1,5 +1,9 @@
2011-01-25 Werner Koch <wk@g10code.com> 2011-01-25 Werner Koch <wk@g10code.com>
* ecdh.c (pk_ecdh_default_params_to_mpi): Remove.
(pk_ecdh_default_params): Rewrite. Factor KEK table out to ..
(kek_params_table): .. here.
* pubkey-enc.c (get_it): Fix assertion. * pubkey-enc.c (get_it): Fix assertion.
Use GPG_ERR_WRONG_SECKEY instead of log_fatal. Add safety checks Use GPG_ERR_WRONG_SECKEY instead of log_fatal. Add safety checks
for NFRAME. for NFRAME.
@ -14,6 +18,8 @@
(pk_ecc_keypair_gen): Fold it into .. (pk_ecc_keypair_gen): Fold it into ..
(gen_ecc): .. this. (gen_ecc): .. this.
(ask_keysize): Use proper rounding for ECC. (ask_keysize): Use proper rounding for ECC.
(pk_ecc_build_key_params): Remove NBITSSTR.
* verify-stubs.c: Remove. * verify-stubs.c: Remove.
2011-01-20 Werner Koch <wk@g10code.com> 2011-01-20 Werner Koch <wk@g10code.com>

View File

@ -30,26 +30,15 @@
#include "main.h" #include "main.h"
#include "options.h" #include "options.h"
gcry_mpi_t /* A table with the default KEK parameters used by GnuPG. */
pk_ecdh_default_params_to_mpi (int qbits) static const struct
{ {
gpg_error_t err; unsigned int qbits;
gcry_mpi_t result; int openpgp_hash_id; /* KEK digest algorithm. */
/* Defaults are the strongest possible choices. Performance is not int openpgp_cipher_id; /* KEK cipher algorithm. */
an issue here, only interoperability. */ } kek_params_table[] =
byte kek_params[4] = { /* Note: Must be sorted by ascending values for QBITS. */
3 /*size of following field*/, {
1 /*fixed version for KDF+AESWRAP*/,
DIGEST_ALGO_SHA512 /* KEK MD */,
CIPHER_ALGO_AES256 /*KEK AESWRAP alg*/
};
int i;
static const struct {
int qbits;
int openpgp_hash_id;
int openpgp_cipher_id;
} kek_params_table[] = {
{ 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES }, { 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES },
{ 384, DIGEST_ALGO_SHA384, CIPHER_ALGO_AES256 }, { 384, DIGEST_ALGO_SHA384, CIPHER_ALGO_AES256 },
@ -57,77 +46,44 @@ pk_ecdh_default_params_to_mpi (int qbits)
{ 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 } { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 }
}; };
for (i=0; i<sizeof(kek_params_table)/sizeof(kek_params_table[0]); i++)
{
if (kek_params_table[i].qbits >= qbits)
{
kek_params[2] = kek_params_table[i].openpgp_hash_id;
kek_params[3] = kek_params_table[i].openpgp_cipher_id;
break;
}
}
if (DBG_CIPHER)
log_printhex ("ecdh kek params are", kek_params, sizeof(kek_params) );
err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG,
kek_params, sizeof(kek_params), NULL);
if (err)
log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err));
return result;
}
/* Returns allocated (binary) KEK parameters; the size is returned in /* Returns allocated (binary) KEK parameters; the size is returned in
* sizeout. The caller must free the returned value with xfree. sizeout. The caller must free the returned value. Returns NULL
* Returns NULL on error. and sets ERRNO on error. */
*/
byte * byte *
pk_ecdh_default_params (int qbits, size_t *sizeout) pk_ecdh_default_params (unsigned int qbits, size_t *sizeout)
{ {
/* Defaults are the strongest possible choices. Performance is not byte kek_params[4];
an issue here, only interoperability. */
byte kek_params[4] = {
3 /*size of following field*/,
1 /*fixed version for KDF+AESWRAP*/,
DIGEST_ALGO_SHA512 /* KEK MD */,
CIPHER_ALGO_AES256 /* KEK AESWRAP alg */
};
int i; int i;
byte *buffer;
static const struct { kek_params[0] = 3; /* Number of bytes to follow. */
int qbits; kek_params[1] = 1; /* Version for KDF+AESWRAP. */
int openpgp_hash_id;
int openpgp_cipher_id;
} kek_params_table[] = {
{ 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES },
{ 384, DIGEST_ALGO_SHA384, CIPHER_ALGO_AES256 },
/* Note: 528 is 521 rounded to the 8 bit boundary */
{ 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 }
};
byte *p; /* Search for matching KEK parameter. Defaults to the strongest
possible choices. Performance is not an issue here, only
*sizeout = 0; interoperability. */
for (i=0; i < DIM (kek_params_table); i++)
for (i=0; i<sizeof(kek_params_table)/sizeof(kek_params_table[0]); i++)
{ {
if (kek_params_table[i].qbits >= qbits) if (kek_params_table[i].qbits >= qbits
|| i+1 == DIM (kek_params_table))
{ {
kek_params[2] = kek_params_table[i].openpgp_hash_id; kek_params[2] = kek_params_table[i].openpgp_hash_id;
kek_params[3] = kek_params_table[i].openpgp_cipher_id; kek_params[3] = kek_params_table[i].openpgp_cipher_id;
break; break;
} }
} }
if (DBG_CIPHER ) assert (i < DIM (kek_params_table));
log_printhex ("ecdh kek params are", kek_params, sizeof(kek_params)); if (DBG_CIPHER)
log_printhex ("ECDH KEK params are", kek_params, sizeof(kek_params) );
p = xtrymalloc (sizeof(kek_params)); buffer = xtrymalloc (sizeof(kek_params));
if (!p) if (!buffer)
return NULL; return NULL;
memcpy (p, kek_params, sizeof(kek_params)); memcpy (buffer, kek_params, sizeof (kek_params));
*sizeout = sizeof(kek_params); *sizeout = sizeof (kek_params);
return p; return buffer;
} }

View File

@ -1329,7 +1329,7 @@ gen_dsa (unsigned int nbits, KBNODE pub_root,
/* Create an S-expression string out QBITS, ALGO and the TRANSIENT /* Create an S-expression string out of QBITS, ALGO and the TRANSIENT
flag. On success a malloced string is returned, on failure NULL flag. On success a malloced string is returned, on failure NULL
and ERRNO is set. */ and ERRNO is set. */
static char * static char *
@ -1337,56 +1337,63 @@ pk_ecc_build_key_params (int qbits, int algo, int transient)
{ {
byte *kek_params = NULL; byte *kek_params = NULL;
size_t kek_params_size; size_t kek_params_size;
char nbitsstr[35];
char qbitsstr[35]; char qbitsstr[35];
char *keyparms; char *result;
int n; size_t n;
/* KEK parameters are only needed for long term key generation. */ /* KEK parameters are only needed for long term key generation. */
if (!transient && algo == PUBKEY_ALGO_ECDH) if (!transient && algo == PUBKEY_ALGO_ECDH)
{
kek_params = pk_ecdh_default_params (qbits, &kek_params_size); kek_params = pk_ecdh_default_params (qbits, &kek_params_size);
if (!kek_params)
return NULL;
}
else else
kek_params = NULL; kek_params = NULL;
snprintf (nbitsstr, sizeof nbitsstr, "%u", qbits);
snprintf (qbitsstr, sizeof qbitsstr, "%u", qbits); snprintf (qbitsstr, sizeof qbitsstr, "%u", qbits);
if (algo == PUBKEY_ALGO_ECDSA || !kek_params) if (algo == PUBKEY_ALGO_ECDSA || !kek_params)
{ {
keyparms = xtryasprintf ("(genkey(%s(nbits %zu:%s)" result = xtryasprintf ("(genkey(%s(nbits %zu:%s)"
/**/ "(qbits %zu:%s)" /**/ "(qbits %zu:%s)"
/**/ "(transient-key 1:%d)))", /**/ "(transient-key 1:%d)))",
algo == PUBKEY_ALGO_ECDSA ? "ecdsa" : "ecdh", algo == PUBKEY_ALGO_ECDSA ? "ecdsa" : "ecdh",
strlen (nbitsstr), nbitsstr, strlen (qbitsstr), qbitsstr,
strlen (qbitsstr), qbitsstr, strlen (qbitsstr), qbitsstr,
transient); transient);
} }
else else
{ {
assert (kek_params); char *tmpstr;
keyparms = xtryasprintf ("(genkey(ecdh(nbits %zu:%s)" assert (kek_params);
tmpstr = xtryasprintf ("(genkey(ecdh(nbits %zu:%s)"
/**/ "(qbits %zu:%s)" /**/ "(qbits %zu:%s)"
/**/ "(transient-key 1:%d)" /**/ "(transient-key 1:%d)"
/**/ "(kek-params %zu:", /**/ "(kek-params %zu:",
strlen (nbitsstr), nbitsstr, strlen (qbitsstr), qbitsstr,
strlen (qbitsstr), qbitsstr, strlen (qbitsstr), qbitsstr,
transient, transient,
kek_params_size); kek_params_size);
if (keyparms) if (!tmpstr)
{
n = strlen (keyparms);
keyparms = xtryrealloc (keyparms, n + kek_params_size + 4);
}
if (!keyparms)
{ {
xfree (kek_params); xfree (kek_params);
return NULL; return NULL;
} }
memcpy (keyparms+n, kek_params, kek_params_size); /* Append the binary KEK parmas. */
n = strlen (tmpstr);
result = xtryrealloc (tmpstr, n + kek_params_size + 4);
if (!result)
{
xfree (tmpstr);
xfree (kek_params); xfree (kek_params);
memcpy (keyparms+n+kek_params_size, ")))", 4); return NULL;
} }
return keyparms; memcpy (result + n, kek_params, kek_params_size);
strcpy (result + n + kek_params_size, ")))");
}
xfree (kek_params);
return result;
} }

View File

@ -20,6 +20,7 @@
#ifndef GNUPG_G10_PKGLUE_H #ifndef GNUPG_G10_PKGLUE_H
#define GNUPG_G10_PKGLUE_H #define GNUPG_G10_PKGLUE_H
/*-- pkglue.c --*/
gcry_mpi_t mpi_from_sexp (gcry_sexp_t sexp, const char * item); gcry_mpi_t mpi_from_sexp (gcry_sexp_t sexp, const char * item);
int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data,
@ -29,12 +30,13 @@ int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
gcry_mpi_t *pkey); gcry_mpi_t *pkey);
int pk_check_secret_key (int algo, gcry_mpi_t *skey); int pk_check_secret_key (int algo, gcry_mpi_t *skey);
/*-- ecdh.c --*/
byte *pk_ecdh_default_params (unsigned int qbits, size_t *sizeout);
int pk_ecdh_encrypt (gcry_mpi_t *resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], int pk_ecdh_encrypt (gcry_mpi_t *resarr, const byte pk_fp[MAX_FINGERPRINT_LEN],
gcry_mpi_t data, gcry_mpi_t * pkey); gcry_mpi_t data, gcry_mpi_t * pkey);
int pk_ecdh_decrypt (gcry_mpi_t *result, const byte sk_fp[MAX_FINGERPRINT_LEN], int pk_ecdh_decrypt (gcry_mpi_t *result, const byte sk_fp[MAX_FINGERPRINT_LEN],
gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey); gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey);
gcry_mpi_t pk_ecdh_default_params_to_mpi (int qbits);
byte *pk_ecdh_default_params (int qbits, size_t *sizeout);
#endif /*GNUPG_G10_PKGLUE_H*/ #endif /*GNUPG_G10_PKGLUE_H*/