diff options
Diffstat (limited to '')
-rw-r--r-- | agent/ChangeLog | 3 | ||||
-rw-r--r-- | agent/findkey.c | 4 | ||||
-rw-r--r-- | g10/ChangeLog | 7 | ||||
-rw-r--r-- | g10/build-packet.c | 51 | ||||
-rw-r--r-- | g10/ecdh.c | 191 | ||||
-rw-r--r-- | g10/encrypt.c | 2 | ||||
-rw-r--r-- | g10/packet.h | 2 | ||||
-rw-r--r-- | g10/pkglue.c | 4 | ||||
-rw-r--r-- | g10/pubkey-enc.c | 2 |
9 files changed, 119 insertions, 147 deletions
diff --git a/agent/ChangeLog b/agent/ChangeLog index 432803fa3..6338c56c5 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,7 +1,8 @@ -2011-01-27 Werner Koch <[email protected]> +2011-01-31 Werner Koch <[email protected]> * protect.c (protect_info): Adjust ECDSA and ECDH parameter names. Add "ecc". + * findkey.c (key_parms_from_sexp): Ditto. 2011-01-19 Werner Koch <[email protected]> diff --git a/agent/findkey.c b/agent/findkey.c index 02e938e6e..108146693 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -729,12 +729,12 @@ key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list, else if (n==5 && !memcmp (name, "ecdsa", 5)) { algoname = "ecdsa"; - elems = "cq"; + elems = "pabgnq"; } else if (n==4 && !memcmp (name, "ecdh", 4)) { algoname = "ecdh"; - elems = "cqp"; + elems = "pabgnq"; } else if (n==3 && !memcmp (name, "elg", 3)) { diff --git a/g10/ChangeLog b/g10/ChangeLog index f6c144d7c..587c9f158 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,10 @@ +2011-01-31 Werner Koch <[email protected]> + + * ecdh.c (pk_ecdh_encrypt_with_shared_point): Return an opaque MPI. + + * build-packet.c (mpi_write): Rename to gpg_mpi_write and make global. + (write_size_body_mpi): Remove. + 2011-01-30 Werner Koch <[email protected]> diff --git a/g10/build-packet.c b/g10/build-packet.c index 122ef15e7..1cdf9616c 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -157,8 +157,8 @@ build_packet( IOBUF out, PACKET *pkt ) /* * Write the mpi A to OUT. */ -static int -mpi_write (iobuf_t out, gcry_mpi_t a) +gpg_error_t +gpg_mpi_write (iobuf_t out, gcry_mpi_t a) { int rc; @@ -191,45 +191,6 @@ mpi_write (iobuf_t out, gcry_mpi_t a) } -/* - * Write a special size+body mpi A, to OUT. The format of the content - * of the MPI is one byte LEN, following by LEN bytes. - */ -gpg_error_t -write_size_body_mpi (iobuf_t out, gcry_mpi_t a) -{ - gpg_error_t err; - byte buffer[256]; /* Fixed buffer for a public parameter, max possible */ - size_t nbytes = (mpi_get_nbits (a)+7)/8; - - if (nbytes > sizeof(buffer)) - { - log_error("mpi with size+body is too large (%u bytes)\n", nbytes); - return gpg_error (GPG_ERR_TOO_LARGE); - } - - err = gcry_mpi_print (GCRYMPI_FMT_USG, buffer, sizeof(buffer), &nbytes, a); - if (err) - { - log_error ("failed to exported size+body mpi\n"); - return err; - } - if (nbytes < 2 || buffer[0] != nbytes-1) - { - if (nbytes > 2) - log_error ("internal size mismatch in mpi size+body: " - "%02x != %02x (other bytes: %02x %02x ... %02x %02x)\n", - buffer[0], nbytes-1, buffer[1], buffer[2], buffer[nbytes-2], - buffer[nbytes-1]); - else - log_error ("internal size mismatch in mpi size+body: " - "only %d bytes\n", nbytes); - return gpg_error (GPG_ERR_INV_DATA); - } - return iobuf_write (out, buffer, nbytes); -} - - /* Calculate the length of a packet described by PKT. */ u32 calc_packet_length( PACKET *pkt ) @@ -341,7 +302,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) for (i=0; i < npkey; i++ ) { - err = mpi_write (a, pk->pkey[i]); + err = gpg_mpi_write (a, pk->pkey[i]); if (err) goto leave; } @@ -436,7 +397,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) { /* Non-protected key. */ for ( ; i < nskey; i++ ) - if ( (err = mpi_write (a, pk->pkey[i]))) + if ( (err = gpg_mpi_write (a, pk->pkey[i]))) goto leave; write_16 (a, ski->csum ); } @@ -512,7 +473,7 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) write_fake_data( a, enc->data[0] ); for (i=0; i < n && !rc ; i++ ) - rc = mpi_write (a, enc->data[i]); + rc = gpg_mpi_write (a, enc->data[i]); if (!rc) { @@ -1170,7 +1131,7 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig ) if ( !n ) write_fake_data( a, sig->data[0] ); for (i=0; i < n && !rc ; i++ ) - rc = mpi_write(a, sig->data[i] ); + rc = gpg_mpi_write (a, sig->data[i] ); if (!rc) { diff --git a/g10/ecdh.c b/g10/ecdh.c index cf002b957..09ab3ed16 100644 --- a/g10/ecdh.c +++ b/g10/ecdh.c @@ -1,5 +1,5 @@ /* ecdh.c - ECDH public key operations used in public key glue code - * Copyright (C) 2010 Free Software Foundation, Inc. + * Copyright (C) 2010, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -105,11 +105,13 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, gpg_error_t err; byte *secret_x; int secret_x_size; - byte kdf_params[256]; - int kdf_params_size=0; - int nbits; + unsigned int nbits; + const unsigned char *kdf_params; + size_t kdf_params_size; int kdf_hash_algo; int kdf_encr_algo; + unsigned char message[256]; + size_t message_size; *r_result = NULL; @@ -137,12 +139,11 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, return err; } - /* fixme: explain what we are doing. */ secret_x_size = (nbits+7)/8; assert (nbytes > secret_x_size); memmove (secret_x, secret_x+1, secret_x_size); memset (secret_x+secret_x_size, 0, nbytes-secret_x_size); - + if (DBG_CIPHER) log_printhex ("ECDH shared secret X is:", secret_x, secret_x_size ); } @@ -155,38 +156,34 @@ 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 * a KEK. */ - { - IOBUF obuf = iobuf_temp(); - err = write_size_body_mpi (obuf, pkey[2]); /* KEK params */ - - kdf_params_size = iobuf_temp_to_buffer (obuf, - kdf_params, sizeof(kdf_params)); - - if (DBG_CIPHER) - log_printhex ("ecdh KDF public key params are:", - kdf_params, kdf_params_size ); - - /* Expect 4 bytes 03 01 hash_alg symm_alg. */ - if (kdf_params_size != 4 || kdf_params[0] != 3 || kdf_params[1] != 1) - return GPG_ERR_BAD_PUBKEY; - - kdf_hash_algo = kdf_params[2]; - kdf_encr_algo = kdf_params[3]; - - if (DBG_CIPHER) - log_debug ("ecdh KDF algorithms %s+%s with aeswrap\n", - gcry_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_ERR_BAD_PUBKEY; - if (kdf_encr_algo != GCRY_CIPHER_AES128 - && kdf_encr_algo != GCRY_CIPHER_AES192 - && kdf_encr_algo != GCRY_CIPHER_AES256) - return GPG_ERR_BAD_PUBKEY; - } + if (!gcry_mpi_get_flag (pkey[2], GCRYMPI_FLAG_OPAQUE)) + return GPG_ERR_BUG; + kdf_params = gcry_mpi_get_opaque (pkey[2], &nbits); + kdf_params_size = (nbits+7)/8; + + if (DBG_CIPHER) + log_printhex ("ecdh KDF params:", kdf_params, kdf_params_size); + + /* Expect 4 bytes 03 01 hash_alg symm_alg. */ + if (kdf_params_size != 4 || kdf_params[0] != 3 || kdf_params[1] != 1) + return GPG_ERR_BAD_PUBKEY; + + kdf_hash_algo = kdf_params[2]; + kdf_encr_algo = kdf_params[3]; + + if (DBG_CIPHER) + 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_ERR_BAD_PUBKEY; + if (kdf_encr_algo != GCRY_CIPHER_AES128 + && kdf_encr_algo != GCRY_CIPHER_AES192 + && kdf_encr_algo != GCRY_CIPHER_AES256) + return GPG_ERR_BAD_PUBKEY; /* Build kdf_params. */ { @@ -194,18 +191,17 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, obuf = iobuf_temp(); /* variable-length field 1, curve name OID */ - err = write_size_body_mpi (obuf, pkey[0]); + err = gpg_mpi_write (obuf, pkey[0]); /* fixed-length field 2 */ iobuf_put (obuf, PUBKEY_ALGO_ECDH); /* variable-length field 3, KDF params */ - err = (err ? err : write_size_body_mpi ( obuf, pkey[2] )); + err = (err ? err : gpg_mpi_write (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); - kdf_params_size = iobuf_temp_to_buffer (obuf, - kdf_params, sizeof(kdf_params)); + message_size = iobuf_temp_to_buffer (obuf, message, sizeof message); iobuf_close (obuf); if (err) return err; @@ -223,10 +219,10 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, err = gcry_md_open (&h, kdf_hash_algo, 0); if(err) log_bug ("gcry_md_open failed for algo %d: %s", - kdf_hash_algo, gpg_strerror (gcry_error(err))); - 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, kdf_params, kdf_params_size); /* KDF parameters */ + kdf_hash_algo, gpg_strerror (err)); + 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, kdf_params, kdf_params_size);/* KDF parameters */ gcry_md_final (h); @@ -320,13 +316,13 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, if (DBG_CIPHER) log_printhex ("ecdh encrypted to:", data_buf+1, data_buf[0] ); - err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, - data_buf, 1+data_buf[0], NULL); - /* (byte)size + aeswrap of DEK */ - xfree( data_buf ); - if (err) + result = gcry_mpi_set_opaque (NULL, data_buf, 8 * (1+data_buf[0])); + if (!result) { - log_error ("ecdh failed to create an MPI: %s\n", gpg_strerror (err)); + err = gpg_error_from_syserror (); + xfree (data_buf); + log_error ("ecdh failed to create an MPI: %s\n", + gpg_strerror (err)); return err; } @@ -335,55 +331,62 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, else { byte *in; + const void *p; - err = gcry_mpi_print (GCRYMPI_FMT_USG, data_buf, data_buf_size, - &nbytes, data/*in*/); - if (nbytes != data_buf_size || data_buf[0] != data_buf_size-1) + p = gcry_mpi_get_opaque (data, &nbits); + nbytes = (nbits+7)/8; + if (!p || nbytes > data_buf_size || !nbytes) + { + xfree (data_buf); + return GPG_ERR_BAD_MPI; + } + memcpy (data_buf, p, nbytes); + if (data_buf[0] != nbytes-1) { log_error ("ecdh inconsistent size\n"); xfree (data_buf); return GPG_ERR_BAD_MPI; } - in = data_buf+data_buf_size; - data_buf_size = data_buf[0]; - - if (DBG_CIPHER) - log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size); - - err = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1, - data_buf_size); - gcry_cipher_close (hd); - if (err) - { - log_error ("ecdh failed in gcry_cipher_decrypt: %s\n", - gpg_strerror (err)); - xfree (data_buf); - return err; - } - - data_buf_size -= 8; - - if (DBG_CIPHER) - log_printhex ("ecdh decrypted to :", in, data_buf_size); - - /* Padding is removed later. */ - /* if (in[data_buf_size-1] > 8 ) */ - /* { */ - /* log_error("ecdh failed at decryption: invalid padding. %02x > 8\n", */ - /* in[data_buf_size-1] ); */ - /* return GPG_ERR_BAD_KEY; */ - /* } */ + in = data_buf+data_buf_size; + data_buf_size = data_buf[0]; + + if (DBG_CIPHER) + log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size); + + err = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1, + data_buf_size); + gcry_cipher_close (hd); + if (err) + { + log_error ("ecdh failed in gcry_cipher_decrypt: %s\n", + gpg_strerror (err)); + xfree (data_buf); + return err; + } + + data_buf_size -= 8; + + if (DBG_CIPHER) + log_printhex ("ecdh decrypted to :", in, data_buf_size); + + /* Padding is removed later. */ + /* if (in[data_buf_size-1] > 8 ) */ + /* { */ + /* log_error("ecdh failed at decryption: invalid padding. %02x > 8\n", */ + /* in[data_buf_size-1] ); */ + /* return GPG_ERR_BAD_KEY; */ + /* } */ - err = gcry_mpi_scan ( &result, GCRYMPI_FMT_USG, in, data_buf_size, NULL); - xfree (data_buf); - if (err) - { - log_error ("ecdh failed to create a plain text MPI: %s\n", - gpg_strerror (err)); - return err; - } - - *r_result = result; + err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, in, data_buf_size, NULL); + xfree (data_buf); + if (err) + { + log_error ("ecdh failed to create a plain text MPI: %s\n", + gpg_strerror (err)); + return err; + } + + *r_result = result; } } diff --git a/g10/encrypt.c b/g10/encrypt.c index f52921582..8548a5739 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -921,7 +921,7 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out) { char *ustr = get_user_id_string_native (enc->keyid); log_info (_("%s/%s encrypted for: \"%s\"\n"), - gcry_pk_algo_name (enc->pubkey_algo), + openpgp_pk_algo_name (enc->pubkey_algo), openpgp_cipher_algo_name (dek->algo), ustr ); xfree (ustr); diff --git a/g10/packet.h b/g10/packet.h index d06c4c7e7..5411e524a 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -444,7 +444,7 @@ PACKET *create_gpg_control ( ctrlpkttype_t type, /*-- build-packet.c --*/ int build_packet( iobuf_t inp, PACKET *pkt ); -gpg_error_t write_size_body_mpi (iobuf_t out, gcry_mpi_t a); +gpg_error_t gpg_mpi_write (iobuf_t out, gcry_mpi_t a); u32 calc_packet_length( PACKET *pkt ); void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, const byte *buffer, size_t buflen ); diff --git a/g10/pkglue.c b/g10/pkglue.c index 27ee239a4..66ba48b60 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -220,8 +220,8 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t shared, public, result; /* Get the shared point and the ephemeral public key. */ - shared = mpi_from_sexp (s_ciph, "a"); - public = mpi_from_sexp (s_ciph, "b"); + shared = mpi_from_sexp (s_ciph, "s"); + public = mpi_from_sexp (s_ciph, "e"); gcry_sexp_release (s_ciph); s_ciph = NULL; if (DBG_CIPHER) diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 43f5419db..d45b4a217 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -176,7 +176,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) if (!enc->data[0] || !enc->data[1]) err = gpg_error (GPG_ERR_BAD_MPI); else - err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(a%m)(b%m)))", + err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(s%m)(e%m)))", enc->data[0], enc->data[1]); } else |