mirror of
git://git.gnupg.org/gnupg.git
synced 2024-05-28 21:50:02 +02:00
gpg: Clean up ECDH code path (2).
* g10/ecdh.c (build_kdf_params): New. (pk_ecdh_encrypt_with_shared_point): Use build_kdf_params, and check things before extract_secret_x. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
960d37644c
commit
a973d91138
151
g10/ecdh.c
151
g10/ecdh.c
|
@ -136,6 +136,45 @@ extract_secret_x (byte **r_secret_x, gcry_mpi_t shared_mpi,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gpg_error_t
|
||||||
|
build_kdf_params (unsigned char kdf_params[256], size_t *r_size,
|
||||||
|
gcry_mpi_t *pkey, const byte pk_fp[MAX_FINGERPRINT_LEN])
|
||||||
|
{
|
||||||
|
IOBUF obuf;
|
||||||
|
gpg_error_t err;
|
||||||
|
|
||||||
|
*r_size = 0;
|
||||||
|
|
||||||
|
obuf = iobuf_temp();
|
||||||
|
if (!obuf)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
|
||||||
|
/* variable-length field 1, curve name OID */
|
||||||
|
err = gpg_mpi_write_nohdr (obuf, pkey[0]);
|
||||||
|
/* fixed-length field 2 */
|
||||||
|
iobuf_put (obuf, PUBKEY_ALGO_ECDH);
|
||||||
|
/* variable-length field 3, KDF params */
|
||||||
|
err = (err ? err : gpg_mpi_write_nohdr (obuf, pkey[2]));
|
||||||
|
/* fixed-length field 4 */
|
||||||
|
iobuf_write (obuf, "Anonymous Sender ", 20);
|
||||||
|
/* fixed-length field 5, recipient fp */
|
||||||
|
iobuf_write (obuf, pk_fp, 20);
|
||||||
|
|
||||||
|
if (!err)
|
||||||
|
*r_size = iobuf_temp_to_buffer (obuf, kdf_params, 256);
|
||||||
|
|
||||||
|
iobuf_close (obuf);
|
||||||
|
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
if (DBG_CRYPTO)
|
||||||
|
log_printhex (kdf_params, *r_size, "ecdh KDF message params are:");
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Encrypts/decrypts DATA using a key derived from the ECC shared
|
/* Encrypts/decrypts DATA using a key derived from the ECC shared
|
||||||
point SHARED_MPI using the FIPS SP 800-56A compliant method
|
point SHARED_MPI using the FIPS SP 800-56A compliant method
|
||||||
key_derivation+key_wrapping. If IS_ENCRYPT is true the function
|
key_derivation+key_wrapping. If IS_ENCRYPT is true the function
|
||||||
|
@ -157,11 +196,47 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
||||||
size_t kek_params_size;
|
size_t kek_params_size;
|
||||||
int kdf_hash_algo;
|
int kdf_hash_algo;
|
||||||
int kdf_encr_algo;
|
int kdf_encr_algo;
|
||||||
unsigned char message[256];
|
unsigned char kdf_params[256];
|
||||||
size_t message_size;
|
size_t kdf_params_size;
|
||||||
|
|
||||||
*r_result = NULL;
|
*r_result = NULL;
|
||||||
|
|
||||||
|
if (!gcry_mpi_get_flag (pkey[2], GCRYMPI_FLAG_OPAQUE))
|
||||||
|
return gpg_error (GPG_ERR_BUG);
|
||||||
|
|
||||||
|
kek_params = gcry_mpi_get_opaque (pkey[2], &nbits);
|
||||||
|
kek_params_size = (nbits+7)/8;
|
||||||
|
|
||||||
|
if (DBG_CRYPTO)
|
||||||
|
log_printhex (kek_params, kek_params_size, "ecdh KDF params:");
|
||||||
|
|
||||||
|
/* Expect 4 bytes 03 01 hash_alg symm_alg. */
|
||||||
|
if (kek_params_size != 4 || kek_params[0] != 3 || kek_params[1] != 1)
|
||||||
|
return gpg_error (GPG_ERR_BAD_PUBKEY);
|
||||||
|
|
||||||
|
kdf_hash_algo = kek_params[2];
|
||||||
|
kdf_encr_algo = kek_params[3];
|
||||||
|
|
||||||
|
if (DBG_CRYPTO)
|
||||||
|
log_debug ("ecdh KDF algorithms %s+%s with aeswrap\n",
|
||||||
|
openpgp_md_algo_name (kdf_hash_algo),
|
||||||
|
openpgp_cipher_algo_name (kdf_encr_algo));
|
||||||
|
|
||||||
|
if (kdf_hash_algo != GCRY_MD_SHA256
|
||||||
|
&& kdf_hash_algo != GCRY_MD_SHA384
|
||||||
|
&& kdf_hash_algo != GCRY_MD_SHA512)
|
||||||
|
return gpg_error (GPG_ERR_BAD_PUBKEY);
|
||||||
|
|
||||||
|
if (kdf_encr_algo != CIPHER_ALGO_AES
|
||||||
|
&& kdf_encr_algo != CIPHER_ALGO_AES192
|
||||||
|
&& kdf_encr_algo != CIPHER_ALGO_AES256)
|
||||||
|
return gpg_error (GPG_ERR_BAD_PUBKEY);
|
||||||
|
|
||||||
|
/* Build kdf_params. */
|
||||||
|
err = build_kdf_params (kdf_params, &kdf_params_size, pkey, pk_fp);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
nbits = pubkey_nbits (PUBKEY_ALGO_ECDH, pkey);
|
nbits = pubkey_nbits (PUBKEY_ALGO_ECDH, pkey);
|
||||||
if (!nbits)
|
if (!nbits)
|
||||||
return gpg_error (GPG_ERR_TOO_SHORT);
|
return gpg_error (GPG_ERR_TOO_SHORT);
|
||||||
|
@ -182,76 +257,8 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
||||||
* current secret_x with a value derived from it. This will become
|
* current secret_x with a value derived from it. This will become
|
||||||
* a KEK.
|
* a KEK.
|
||||||
*/
|
*/
|
||||||
if (!gcry_mpi_get_flag (pkey[2], GCRYMPI_FLAG_OPAQUE))
|
|
||||||
{
|
|
||||||
xfree (secret_x);
|
|
||||||
return gpg_error (GPG_ERR_BUG);
|
|
||||||
}
|
|
||||||
kek_params = gcry_mpi_get_opaque (pkey[2], &nbits);
|
|
||||||
kek_params_size = (nbits+7)/8;
|
|
||||||
|
|
||||||
if (DBG_CRYPTO)
|
/* Derive a KEK (key wrapping key) using KDF_PARAMS and SECRET_X. */
|
||||||
log_printhex (kek_params, kek_params_size, "ecdh KDF params:");
|
|
||||||
|
|
||||||
/* Expect 4 bytes 03 01 hash_alg symm_alg. */
|
|
||||||
if (kek_params_size != 4 || kek_params[0] != 3 || kek_params[1] != 1)
|
|
||||||
{
|
|
||||||
xfree (secret_x);
|
|
||||||
return gpg_error (GPG_ERR_BAD_PUBKEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
kdf_hash_algo = kek_params[2];
|
|
||||||
kdf_encr_algo = kek_params[3];
|
|
||||||
|
|
||||||
if (DBG_CRYPTO)
|
|
||||||
log_debug ("ecdh KDF algorithms %s+%s with aeswrap\n",
|
|
||||||
openpgp_md_algo_name (kdf_hash_algo),
|
|
||||||
openpgp_cipher_algo_name (kdf_encr_algo));
|
|
||||||
|
|
||||||
if (kdf_hash_algo != GCRY_MD_SHA256
|
|
||||||
&& kdf_hash_algo != GCRY_MD_SHA384
|
|
||||||
&& kdf_hash_algo != GCRY_MD_SHA512)
|
|
||||||
{
|
|
||||||
xfree (secret_x);
|
|
||||||
return gpg_error (GPG_ERR_BAD_PUBKEY);
|
|
||||||
}
|
|
||||||
if (kdf_encr_algo != CIPHER_ALGO_AES
|
|
||||||
&& kdf_encr_algo != CIPHER_ALGO_AES192
|
|
||||||
&& kdf_encr_algo != CIPHER_ALGO_AES256)
|
|
||||||
{
|
|
||||||
xfree (secret_x);
|
|
||||||
return gpg_error (GPG_ERR_BAD_PUBKEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build kdf_params. */
|
|
||||||
{
|
|
||||||
IOBUF obuf;
|
|
||||||
|
|
||||||
obuf = iobuf_temp();
|
|
||||||
/* variable-length field 1, curve name OID */
|
|
||||||
err = gpg_mpi_write_nohdr (obuf, pkey[0]);
|
|
||||||
/* fixed-length field 2 */
|
|
||||||
iobuf_put (obuf, PUBKEY_ALGO_ECDH);
|
|
||||||
/* variable-length field 3, KDF params */
|
|
||||||
err = (err ? err : gpg_mpi_write_nohdr (obuf, pkey[2]));
|
|
||||||
/* fixed-length field 4 */
|
|
||||||
iobuf_write (obuf, "Anonymous Sender ", 20);
|
|
||||||
/* fixed-length field 5, recipient fp */
|
|
||||||
iobuf_write (obuf, pk_fp, 20);
|
|
||||||
|
|
||||||
message_size = iobuf_temp_to_buffer (obuf, message, sizeof message);
|
|
||||||
iobuf_close (obuf);
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
xfree (secret_x);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(DBG_CRYPTO)
|
|
||||||
log_printhex (message, message_size, "ecdh KDF message params are:");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive a KEK (key wrapping key) using MESSAGE and SECRET_X. */
|
|
||||||
{
|
{
|
||||||
gcry_md_hd_t h;
|
gcry_md_hd_t h;
|
||||||
int old_size;
|
int old_size;
|
||||||
|
@ -266,7 +273,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
||||||
}
|
}
|
||||||
gcry_md_write(h, "\x00\x00\x00\x01", 4); /* counter = 1 */
|
gcry_md_write(h, "\x00\x00\x00\x01", 4); /* counter = 1 */
|
||||||
gcry_md_write(h, secret_x, secret_x_size); /* x of the point X */
|
gcry_md_write(h, secret_x, secret_x_size); /* x of the point X */
|
||||||
gcry_md_write(h, message, message_size); /* KDF parameters */
|
gcry_md_write(h, kdf_params, kdf_params_size); /* KDF parameters */
|
||||||
|
|
||||||
gcry_md_final (h);
|
gcry_md_final (h);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user