From e0972d3d962548972872d889b362560e499340d1 Mon Sep 17 00:00:00 2001 From: Andrey Jivsov Date: Wed, 5 Jan 2011 17:33:17 -0800 Subject: Integrating http://code.google.com/p/gnupg-ecc/source/detail?r=15 . The following works: gpg2 --gen-key (ECC) gpg2 --list-keys gpg2 --list-packets ~/.gnupg/pubring.gpg gpg2 --list-packets ECDH doesn't work yet as the code must be re-written to adjust for gpg-agent refactoring. --- g10/pubkey-enc.c | 62 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 22 deletions(-) (limited to 'g10/pubkey-enc.c') diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 312b591e9..a5224e20a 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -145,6 +145,8 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) gcry_sexp_t s_data; char *desc; char *keygrip; + byte fp[MAX_FINGERPRINT_LEN]; + size_t fpn; /* Get the keygrip. */ err = hexkeygrip_from_pk (sk, &keygrip); @@ -174,9 +176,12 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) if (err) goto leave; + fingerprint_from_pk( sk, fp, &fpn ); + assert( fpn == 20 ); + /* Decrypt. */ desc = gpg_format_keydesc (sk, 0, 1); - err = agent_pkdecrypt (NULL, keygrip, desc, s_data, &frame, &nframe); + err = agent_pkdecrypt (NULL, keygrip, desc, s_data, fp, &frame, &nframe); xfree (desc); gcry_sexp_release (s_data); if (err) @@ -202,28 +207,41 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) if (DBG_CIPHER) log_printhex ("DEK frame:", frame, nframe); n = 0; - if (!card) - { - if (n + 7 > nframe) - { - err = gpg_error (G10ERR_WRONG_SECKEY); - goto leave; - } - if (frame[n] == 1 && frame[nframe - 1] == 2) - { - log_info (_("old encoding of the DEK is not supported\n")); - err = gpg_error (G10ERR_CIPHER_ALGO); - goto leave; - } - if (frame[n] != 2) /* Something went wrong. */ - { - err = gpg_error (G10ERR_WRONG_SECKEY); - goto leave; - } - for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes. */ - ; - n++; /* Skip the zero byte. */ + + if( sk->pubkey_algo != PUBKEY_ALGO_ECDH ) { + if (!card) + { + if (n + 7 > nframe) + { + err = gpg_error (G10ERR_WRONG_SECKEY); + goto leave; + } + if (frame[n] == 1 && frame[nframe - 1] == 2) + { + log_info (_("old encoding of the DEK is not supported\n")); + err = gpg_error (G10ERR_CIPHER_ALGO); + goto leave; + } + if (frame[n] != 2) /* Something went wrong. */ + { + err = gpg_error (G10ERR_WRONG_SECKEY); + goto leave; + } + for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes. */ + ; + n++; /* Skip the zero byte. */ + } + } + else { + /* Allow double padding for the benefit of DEK size concealment. + * Higher than this is wasteful. + */ + if( frame[nframe-1] > 8*2 || nframe <= 8 ) { + err = G10ERR_WRONG_SECKEY; goto leave; } + nframe -= frame[nframe-1]; /* remove padding */ + assert( n==0 ); /* used just bellow */ + } if (n + 4 > nframe) { -- cgit v1.2.3 From 5761a9ba74e41f52660e20a1de700fe784c97832 Mon Sep 17 00:00:00 2001 From: Andrey Jivsov Date: Mon, 10 Jan 2011 20:24:14 -0800 Subject: 'g10/gpg2 --encrypt --debug 15 -r ecdsa -a -o _e.asc _' and 'g10/gpg2 --debug 15 _e.asc', as well as decoding of an old message posted on https://sites.google.com/site/brainhub/pgpecckeys work. This is the milestone 2 that brings in ECDH support from http://code.google.com/p/gnupg-ecc/source/detail?r=15 . This corresponds to the commit 899386826c85f1e757e75bcc5d5b2159d05676a0 in libgcrypt --- g10/pubkey-enc.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'g10/pubkey-enc.c') diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index a5224e20a..24411e8a1 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -147,14 +147,16 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) char *keygrip; byte fp[MAX_FINGERPRINT_LEN]; size_t fpn; + const int gcry_pkalgo = map_pk_openpgp_to_gcry( sk->pubkey_algo ); /* Get the keygrip. */ err = hexkeygrip_from_pk (sk, &keygrip); if (err) goto leave; + /* Convert the data to an S-expression. */ - if (sk->pubkey_algo == GCRY_PK_ELG || sk->pubkey_algo == GCRY_PK_ELG_E) + if (gcry_pkalgo == GCRY_PK_ELG ||gcry_pkalgo == GCRY_PK_ELG_E) { if (!enc->data[0] || !enc->data[1]) err = gpg_error (GPG_ERR_BAD_MPI); @@ -162,7 +164,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))", enc->data[0], enc->data[1]); } - else if (sk->pubkey_algo == GCRY_PK_RSA || sk->pubkey_algo == GCRY_PK_RSA_E) + else if (gcry_pkalgo == GCRY_PK_RSA || gcry_pkalgo == GCRY_PK_RSA_E) { if (!enc->data[0]) err = gpg_error (GPG_ERR_BAD_MPI); @@ -170,6 +172,14 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) err = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", enc->data[0]); } + else if (gcry_pkalgo == GCRY_PK_ECDH ) + { + 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)))", + enc->data[0], enc->data[1]); + } else err = gpg_error (GPG_ERR_BUG); @@ -181,7 +191,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) /* Decrypt. */ desc = gpg_format_keydesc (sk, 0, 1); - err = agent_pkdecrypt (NULL, keygrip, desc, s_data, fp, &frame, &nframe); + err = agent_pkdecrypt (NULL, keygrip, desc, s_data, &frame, &nframe); xfree (desc); gcry_sexp_release (s_data); if (err) @@ -233,6 +243,30 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) } } else { + gcry_mpi_t shared_mpi; + gcry_mpi_t decoded; + + /* at the beginning the frame is the bytes of shared point MPI */ + + err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL); + if (err) { + log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err)); + goto leave; + } + + err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/, shared_mpi, sk->pkey); + mpi_release( shared_mpi ); + if( err ) + goto leave; + + /* reuse nframe, which size is sufficient to include the session key */ + err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, decoded); + mpi_release( decoded ); + if( err ) + goto leave; + + /* Now the frame is the bytes decrypted but padded session key */ + /* Allow double padding for the benefit of DEK size concealment. * Higher than this is wasteful. */ -- cgit v1.2.3 From 90b0ff23b7e51332592668e4034967c1aac1c593 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 21 Jan 2011 12:00:57 +0100 Subject: Editorial changes and allow building with old libgcrypts. Changed order of some conditional to make to put the special case into the true branch. Indentation changes. Minor other changes to make the ECC code more similar to the rest of our code. It builds but many sefltests still fail. Need to fix that before using it with an ECDH enabled libgcrypt. [/] 2011-01-21 Werner Koch * configure.ac: Need Libgcrypt 1.4.6 due to AESWRAP. (HAVE_GCRY_PK_ECDH): Add new test. [agent/] 2011-01-21 Werner Koch * cvt-openpgp.c (GCRY_PK_ECDH) [!HAVE_GCRY_PK_ECDH]: New. [include/] 2011-01-21 Werner Koch * cipher.h (GCRY_PK_USAGE_CERT): Remove compatibility macros because we now require libgcrypt 1.4.6. (GCRY_PK_ECDH): Add replacement. --- g10/pubkey-enc.c | 112 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 54 deletions(-) (limited to 'g10/pubkey-enc.c') diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 24411e8a1..ddca41ec4 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -218,68 +218,72 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) log_printhex ("DEK frame:", frame, nframe); n = 0; - if( sk->pubkey_algo != PUBKEY_ALGO_ECDH ) { - if (!card) - { - if (n + 7 > nframe) - { - err = gpg_error (G10ERR_WRONG_SECKEY); - goto leave; - } - if (frame[n] == 1 && frame[nframe - 1] == 2) - { - log_info (_("old encoding of the DEK is not supported\n")); - err = gpg_error (G10ERR_CIPHER_ALGO); - goto leave; - } - if (frame[n] != 2) /* Something went wrong. */ - { - err = gpg_error (G10ERR_WRONG_SECKEY); - goto leave; - } - for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes. */ - ; - n++; /* Skip the zero byte. */ - } - } - else { - gcry_mpi_t shared_mpi; - gcry_mpi_t decoded; - - /* at the beginning the frame is the bytes of shared point MPI */ - - err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL); - if (err) { - log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err)); - goto leave; - } + if (sk->pubkey_algo == PUBKEY_ALGO_ECDH) + { + gcry_mpi_t shared_mpi; + gcry_mpi_t decoded; + + /* At the beginning the frame are the bytes of shared point MPI. */ + err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL); + if (err) + { + log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err)); + goto leave; + } - err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/, shared_mpi, sk->pkey); - mpi_release( shared_mpi ); - if( err ) - goto leave; + err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/, + shared_mpi, sk->pkey); + mpi_release (shared_mpi); + if(err) + goto leave; - /* reuse nframe, which size is sufficient to include the session key */ - err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, decoded); - mpi_release( decoded ); - if( err ) - goto leave; + /* Reuse NFRAME, which size is sufficient to include the session key. */ + err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, decoded); + mpi_release (decoded); + if (err) + goto leave; - /* Now the frame is the bytes decrypted but padded session key */ + /* Now the frame are the bytes decrypted but padded session key. */ - /* Allow double padding for the benefit of DEK size concealment. - * Higher than this is wasteful. - */ - if( frame[nframe-1] > 8*2 || nframe <= 8 ) { - err = G10ERR_WRONG_SECKEY; goto leave; + /* Allow double padding for the benefit of DEK size concealment. + Higher than this is wasteful. */ + if (frame[nframe-1] > 8*2 || nframe <= 8) + { + err = gpg_error (GPG_ERR_WRONG_SECKEY); + goto leave; + } + nframe -= frame[nframe-1]; /* Remove padding. */ + assert (n); /* (used just below) */ + } + else + { + if (!card) + { + if (n + 7 > nframe) + { + err = gpg_error (GPG_ERR_WRONG_SECKEY); + goto leave; + } + if (frame[n] == 1 && frame[nframe - 1] == 2) + { + log_info (_("old encoding of the DEK is not supported\n")); + err = gpg_error (GPG_ERR_CIPHER_ALGO); + goto leave; + } + if (frame[n] != 2) /* Something went wrong. */ + { + err = gpg_error (GPG_ERR_WRONG_SECKEY); + goto leave; + } + for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes. */ + ; + n++; /* Skip the zero byte. */ + } } - nframe -= frame[nframe-1]; /* remove padding */ - assert( n==0 ); /* used just bellow */ - } if (n + 4 > nframe) { - err = gpg_error (G10ERR_WRONG_SECKEY); + err = gpg_error (GPG_ERR_WRONG_SECKEY); goto leave; } -- cgit v1.2.3 From 638dca5dbc7e119ff5a05dbdb109fbc171624605 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 25 Jan 2011 16:54:18 +0100 Subject: Editorial cleanups of keygen.c Also fixed a regression introduced by me in pubkey_enc.c. Added extra checks. Removed unused code. --- g10/pubkey-enc.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'g10/pubkey-enc.c') diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index ddca41ec4..43f5419db 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -145,18 +145,17 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) gcry_sexp_t s_data; char *desc; char *keygrip; - byte fp[MAX_FINGERPRINT_LEN]; + byte fp[MAX_FINGERPRINT_LEN]; size_t fpn; - const int gcry_pkalgo = map_pk_openpgp_to_gcry( sk->pubkey_algo ); + const int pkalgo = map_pk_openpgp_to_gcry (sk->pubkey_algo); /* Get the keygrip. */ err = hexkeygrip_from_pk (sk, &keygrip); if (err) goto leave; - /* Convert the data to an S-expression. */ - if (gcry_pkalgo == GCRY_PK_ELG ||gcry_pkalgo == GCRY_PK_ELG_E) + if (pkalgo == GCRY_PK_ELG || pkalgo == GCRY_PK_ELG_E) { if (!enc->data[0] || !enc->data[1]) err = gpg_error (GPG_ERR_BAD_MPI); @@ -164,7 +163,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))", enc->data[0], enc->data[1]); } - else if (gcry_pkalgo == GCRY_PK_RSA || gcry_pkalgo == GCRY_PK_RSA_E) + else if (pkalgo == GCRY_PK_RSA || pkalgo == GCRY_PK_RSA_E) { if (!enc->data[0]) err = gpg_error (GPG_ERR_BAD_MPI); @@ -172,12 +171,12 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) err = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", enc->data[0]); } - else if (gcry_pkalgo == GCRY_PK_ECDH ) + else if (pkalgo == GCRY_PK_ECDH) { 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(a%m)(b%m)))", enc->data[0], enc->data[1]); } else @@ -186,8 +185,9 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) if (err) goto leave; - fingerprint_from_pk( sk, fp, &fpn ); - assert( fpn == 20 ); + /* fixme: only needed for ECDH. Don't compute always. */ + fingerprint_from_pk (sk, fp, &fpn); + assert (fpn == 20); /* Decrypt. */ desc = gpg_format_keydesc (sk, 0, 1); @@ -222,12 +222,12 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) { gcry_mpi_t shared_mpi; gcry_mpi_t decoded; - + /* At the beginning the frame are the bytes of shared point MPI. */ err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL); if (err) { - log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err)); + err = gpg_error (GPG_ERR_WRONG_SECKEY); goto leave; } @@ -247,13 +247,14 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) /* Allow double padding for the benefit of DEK size concealment. Higher than this is wasteful. */ - if (frame[nframe-1] > 8*2 || nframe <= 8) + if (!nframe || frame[nframe-1] > 8*2 || nframe <= 8 + || frame[nframe-1] > nframe) { err = gpg_error (GPG_ERR_WRONG_SECKEY); - goto leave; + goto leave; } nframe -= frame[nframe-1]; /* Remove padding. */ - assert (n); /* (used just below) */ + assert (!n); /* (used just below) */ } else { -- cgit v1.2.3 From 328a642aa5ed971870a2667b06307f760fa251dc Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 31 Jan 2011 15:44:24 +0100 Subject: Fixed the ECC interface to Libgcrypt to be ABI compatible with the previous version. Quite some changes were needed but in the end we have less code than before. Instead of trying to do everything with MPIs and pass them back and forth between Libgcrypt and GnuPG, we know use the S-expression based interface and make heavy use of our opaque MPI feature. Encryption, decryption, signing and verification work with self-generared keys. Import and export does not yet work; thus it was not possible to check the test keys at https://sites.google.com/site/brainhub/pgpecckeys . --- g10/pubkey-enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'g10/pubkey-enc.c') 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 -- cgit v1.2.3 From 0b5bcb40cf17a0e1032c113af6024c08b47d7a5c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 3 Feb 2011 16:31:42 +0100 Subject: Finished ECC integration. Wrote the ChangeLog 2011-01-13 entry for Andrey's orginal work modulo the cleanups I did in the last week. Adjusted my own ChangeLog entries to be consistent with that entry. Nuked quite some trailing spaces; again sorry for that, I will better take care of not saving them in the future. "git diff -b" is useful to read the actual changes ;-). The ECC-INTEGRATION-2-1 branch can be closed now. --- g10/pubkey-enc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'g10/pubkey-enc.c') diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index d45b4a217..1b94af54f 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -160,7 +160,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(elg(a%m)(b%m)))", + err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))", enc->data[0], enc->data[1]); } else if (pkalgo == GCRY_PK_RSA || pkalgo == GCRY_PK_RSA_E) @@ -185,9 +185,11 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) if (err) goto leave; - /* fixme: only needed for ECDH. Don't compute always. */ - fingerprint_from_pk (sk, fp, &fpn); - assert (fpn == 20); + if (sk->pubkey_algo == PUBKEY_ALGO_ECDH) + { + fingerprint_from_pk (sk, fp, &fpn); + assert (fpn == 20); + } /* Decrypt. */ desc = gpg_format_keydesc (sk, 0, 1); -- cgit v1.2.3