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/build-packet.c | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) (limited to 'g10/build-packet.c') diff --git a/g10/build-packet.c b/g10/build-packet.c index 83d6c7a73..3a2c206c8 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -178,6 +178,16 @@ mpi_write (iobuf_t out, gcry_mpi_t a) return rc; } +/* + * Write the name OID, encoded as an mpi, to OUT. The format of the content of the MPI is + * one byte LEN, following by LEN bytes that are DER representation of an ASN.1 OID. + * This is true for each of the 3 following functions. + */ +#define iobuf_name_oid_write iobuf_write_size_body_mpi +/* Write the value of KEK fields for ECDH. */ +#define ecdh_kek_params_write iobuf_write_size_body_mpi +/* Write the value of encrypted filed for ECDH. */ +#define ecdh_esk_write iobuf_write_size_body_mpi /**************** @@ -290,10 +300,24 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) } assert (npkey < nskey); - /* Writing the public parameters is easy. */ - for (i=0; i < npkey; i++ ) - if ((err = mpi_write (a, pk->pkey[i]))) - goto leave; + if( pk->pubkey_algo != PUBKEY_ALGO_ECDSA && pk->pubkey_algo != PUBKEY_ALGO_ECDH ) { + /* Writing the public parameters is easy, */ + for (i=0; i < npkey; i++ ) + if ((err = mpi_write (a, pk->pkey[i]))) + goto leave; + } + else { + /* ... except we do an adjustment for ECC OID and possibly KEK params for ECDH */ + if( (err=iobuf_name_oid_write(a, pk->pkey[0])) || /* DER of OID with preceeding length byte */ + (err = mpi_write (a, pk->pkey[1])) ) /* point Q, the public key */ + { + goto leave; + } + if( pk->pubkey_algo == PUBKEY_ALGO_ECDH && (err=ecdh_kek_params_write(a,pk->pkey[2]))) { /* one more public field for ECDH */ + goto leave; + } + /* followed by possibly protected private scalar */ + } if (pk->seckey_info) { @@ -458,8 +482,18 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) n = pubkey_get_nenc( enc->pubkey_algo ); if ( !n ) write_fake_data( a, enc->data[0] ); - for (i=0; i < n && !rc ; i++ ) - rc = mpi_write(a, enc->data[i] ); + + if( enc->pubkey_algo != PUBKEY_ALGO_ECDH ) { + for (i=0; i < n && !rc ; i++ ) + rc = mpi_write(a, enc->data[i] ); + } + else { + /* the second field persists as a LEN+field structure, even though it is + * stored for uniformity as an MPI internally */ + assert( n==2 ); + rc = mpi_write(a, enc->data[0] ); + if( !rc ) rc = ecdh_esk_write(a, enc->data[1] ); + } if (!rc) { -- 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/build-packet.c | 87 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 37 deletions(-) (limited to 'g10/build-packet.c') diff --git a/g10/build-packet.c b/g10/build-packet.c index 3a2c206c8..d138e0614 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -178,21 +178,20 @@ mpi_write (iobuf_t out, gcry_mpi_t a) return rc; } -/* - * Write the name OID, encoded as an mpi, to OUT. The format of the content of the MPI is - * one byte LEN, following by LEN bytes that are DER representation of an ASN.1 OID. - * This is true for each of the 3 following functions. - */ +/* Write the name OID, encoded as an mpi, to OUT. The format of the + * content of the MPI is one byte LEN, following by LEN bytes that are + * DER representation of an ASN.1 OID. This is true for each of the 3 + * following functions. */ #define iobuf_name_oid_write iobuf_write_size_body_mpi + /* Write the value of KEK fields for ECDH. */ #define ecdh_kek_params_write iobuf_write_size_body_mpi -/* Write the value of encrypted filed for ECDH. */ + +/* Write the value of encrypted filed for ECDH. */ #define ecdh_esk_write iobuf_write_size_body_mpi -/**************** - * calculate the length of a packet described by PKT - */ +/* Calculate the length of a packet described by PKT. */ u32 calc_packet_length( PACKET *pkt ) { @@ -300,24 +299,35 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) } assert (npkey < nskey); - if( pk->pubkey_algo != PUBKEY_ALGO_ECDSA && pk->pubkey_algo != PUBKEY_ALGO_ECDH ) { - /* Writing the public parameters is easy, */ - for (i=0; i < npkey; i++ ) - if ((err = mpi_write (a, pk->pkey[i]))) - goto leave; - } - else { - /* ... except we do an adjustment for ECC OID and possibly KEK params for ECDH */ - if( (err=iobuf_name_oid_write(a, pk->pkey[0])) || /* DER of OID with preceeding length byte */ - (err = mpi_write (a, pk->pkey[1])) ) /* point Q, the public key */ + /* Writing the public parameters is easy. Except if we do an + adjustment for ECC OID and possibly KEK params for ECDH. */ + if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA + || pk->pubkey_algo == PUBKEY_ALGO_ECDH) { - goto leave; + /* Write DER of OID with preceeding length byte. */ + err = iobuf_name_oid_write (a, pk->pkey[0]); + if (err) + goto leave; + /* Write point Q, the public key. */ + err = mpi_write (a, pk->pkey[1]); + if (err) + goto leave; + + /* Write one more public field for ECDH. */ + if (pk->pubkey_algo == PUBKEY_ALGO_ECDH) + { + err = ecdh_kek_params_write(a,pk->pkey[2]); + if (err) + goto leave; + } } - if( pk->pubkey_algo == PUBKEY_ALGO_ECDH && (err=ecdh_kek_params_write(a,pk->pkey[2]))) { /* one more public field for ECDH */ - goto leave; + else + { + for (i=0; i < npkey; i++ ) + if ((err = mpi_write (a, pk->pkey[i]))) + goto leave; } - /* followed by possibly protected private scalar */ - } + if (pk->seckey_info) { @@ -483,22 +493,25 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) if ( !n ) write_fake_data( a, enc->data[0] ); - if( enc->pubkey_algo != PUBKEY_ALGO_ECDH ) { - for (i=0; i < n && !rc ; i++ ) - rc = mpi_write(a, enc->data[i] ); - } - else { - /* the second field persists as a LEN+field structure, even though it is - * stored for uniformity as an MPI internally */ - assert( n==2 ); - rc = mpi_write(a, enc->data[0] ); - if( !rc ) rc = ecdh_esk_write(a, enc->data[1] ); - } + if (enc->pubkey_algo == PUBKEY_ALGO_ECDH ) + { + /* The second field persists as a LEN+field structure, even + * though it is stored for uniformity as an MPI internally. */ + assert (n == 2); + rc = mpi_write (a, enc->data[0]); + if (!rc) + rc = ecdh_esk_write (a, enc->data[1]); + } + else + { + for (i=0; i < n && !rc ; i++ ) + rc = mpi_write(a, enc->data[i] ); + } if (!rc) { - write_header(out, ctb, iobuf_get_temp_length(a) ); - rc = iobuf_write_temp( out, a ); + write_header (out, ctb, iobuf_get_temp_length(a) ); + rc = iobuf_write_temp (out, a); } iobuf_close(a); return rc; -- cgit v1.2.3 From 358afc0dc8980d5ae0cb700efbb61499625a4625 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 26 Jan 2011 17:17:43 +0100 Subject: Function name cleanups Also nuked some trailing spaces. --- g10/build-packet.c | 105 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 39 deletions(-) (limited to 'g10/build-packet.c') diff --git a/g10/build-packet.c b/g10/build-packet.c index d138e0614..e2bbdb511 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -178,17 +178,44 @@ mpi_write (iobuf_t out, gcry_mpi_t a) return rc; } -/* Write the name OID, encoded as an mpi, to OUT. The format of the - * content of the MPI is one byte LEN, following by LEN bytes that are - * DER representation of an ASN.1 OID. This is true for each of the 3 - * following functions. */ -#define iobuf_name_oid_write iobuf_write_size_body_mpi -/* Write the value of KEK fields for ECDH. */ -#define ecdh_kek_params_write iobuf_write_size_body_mpi +/* + * 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); + } -/* Write the value of encrypted filed for ECDH. */ -#define ecdh_esk_write iobuf_write_size_body_mpi + 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. */ @@ -228,11 +255,11 @@ calc_packet_length( PACKET *pkt ) static void write_fake_data (IOBUF out, gcry_mpi_t a) { - if (a) + if (a) { unsigned int n; void *p; - + p = gcry_mpi_get_opaque ( a, &n ); iobuf_write (out, p, (n+7)/8 ); } @@ -281,18 +308,18 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) ndays = 0; write_16(a, ndays); } - + iobuf_put (a, pk->pubkey_algo ); - + /* Get number of secret and public parameters. They are held in one array first the public ones, then the secret ones. */ nskey = pubkey_get_nskey (pk->pubkey_algo); npkey = pubkey_get_npkey (pk->pubkey_algo); - + /* If we don't have any public parameters - which is the case if we don't know the algorithm used - the parameters are stored as one blob in a faked (opaque) MPI. */ - if (!npkey) + if (!npkey) { write_fake_data (a, pk->pkey[0]); goto leave; @@ -305,7 +332,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) || pk->pubkey_algo == PUBKEY_ALGO_ECDH) { /* Write DER of OID with preceeding length byte. */ - err = iobuf_name_oid_write (a, pk->pkey[0]); + err = write_size_body_mpi (a, pk->pkey[0]); if (err) goto leave; /* Write point Q, the public key. */ @@ -316,7 +343,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) /* Write one more public field for ECDH. */ if (pk->pubkey_algo == PUBKEY_ALGO_ECDH) { - err = ecdh_kek_params_write(a,pk->pkey[2]); + err = write_size_body_mpi (a, pk->pkey[2]); if (err) goto leave; } @@ -328,14 +355,14 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) goto leave; } - + if (pk->seckey_info) { /* This is a secret key packet. */ struct seckey_info *ski = pk->seckey_info; /* Build the header for protected (encrypted) secret parameters. */ - if (ski->is_protected) + if (ski->is_protected) { if ( is_RSA (pk->pubkey_algo) && pk->version < 4 && !ski->s2k.mode ) { @@ -355,12 +382,12 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) viewed as a private/experimental extension (this is not specified in rfc2440 but the same scheme is used for all other algorithm identifiers). */ - iobuf_put (a, 101); + iobuf_put (a, 101); iobuf_put (a, ski->s2k.hash_algo); iobuf_write (a, "GNU", 3 ); iobuf_put (a, ski->s2k.mode - 1000); } - else + else { iobuf_put (a, ski->s2k.mode); iobuf_put (a, ski->s2k.hash_algo); @@ -370,7 +397,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) iobuf_write (a, ski->s2k.salt, 8); if (ski->s2k.mode == 3) - iobuf_put (a, ski->s2k.count); + iobuf_put (a, ski->s2k.count); /* For our special modes 1001, 1002 we do not need an IV. */ if (ski->s2k.mode != 1001 && ski->s2k.mode != 1002) @@ -381,10 +408,10 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) iobuf_put (a, 0 ); if (ski->s2k.mode == 1001) - ; /* GnuPG extension - don't write a secret key at all. */ + ; /* GnuPG extension - don't write a secret key at all. */ else if (ski->s2k.mode == 1002) - { - /* GnuPG extension - divert to OpenPGP smartcard. */ + { + /* GnuPG extension - divert to OpenPGP smartcard. */ /* Length of the serial number or 0 for no serial number. */ iobuf_put (a, ski->ivlen ); /* The serial number gets stored in the IV field. */ @@ -395,19 +422,19 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) /* The secret key is protected - write it out as it is. */ byte *p; unsigned int ndatabits; - + assert (gcry_mpi_get_flag (pk->pkey[npkey], GCRYMPI_FLAG_OPAQUE)); p = gcry_mpi_get_opaque (pk->pkey[npkey], &ndatabits); iobuf_write (a, p, (ndatabits+7)/8 ); } - else if (ski->is_protected) + else if (ski->is_protected) { /* The secret key is protected the old v4 way. */ - for ( ; i < nskey; i++ ) + for ( ; i < nskey; i++ ) { byte *p; unsigned int ndatabits; - + assert (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE)); p = gcry_mpi_get_opaque (pk->pkey[i], &ndatabits); iobuf_write (a, p, (ndatabits+7)/8); @@ -476,9 +503,9 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) int rc = 0; int n, i; IOBUF a = iobuf_temp(); - + write_version( a, ctb ); - if ( enc->throw_keyid ) + if ( enc->throw_keyid ) { write_32(a, 0 ); /* Don't tell Eve who can decrypt the message. */ write_32(a, 0 ); @@ -500,7 +527,7 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) assert (n == 2); rc = mpi_write (a, enc->data[0]); if (!rc) - rc = ecdh_esk_write (a, enc->data[1]); + rc = write_size_body_mpi (a, enc->data[1]); } else { @@ -545,7 +572,7 @@ do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt ) for(i=0; i < pt->namelen; i++ ) iobuf_put(out, pt->name[i] ); rc = write_32(out, pt->timestamp ); - if (rc) + if (rc) return rc; n = 0; @@ -661,7 +688,7 @@ delete_sig_subpkt (subpktarea_t *area, sigsubpkttype_t reqtype ) } if( buflen < n ) break; - + type = *buffer & 0x7f; if( type == reqtype ) { buffer++; @@ -695,7 +722,7 @@ delete_sig_subpkt (subpktarea_t *area, sigsubpkttype_t reqtype ) * Note: All pointers into sig->[un]hashed (e.g. returned by * parse_sig_subpkt) are not valid after a call to this function. The * data to put into the subpaket should be in a buffer with a length - * of buflen. + * of buflen. */ void build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type, @@ -798,7 +825,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type, case SIGSUBPKT_SIGNATURE: hashed = 0; break; - default: + default: hashed = 1; break; } @@ -849,7 +876,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type, memcpy (p, buffer, buflen); } - if (hashed) + if (hashed) sig->hashed = newarea; else sig->unhashed = newarea; @@ -1135,7 +1162,7 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig ) if ( sig->version < 4 ) iobuf_put (a, 5 ); /* Constant */ iobuf_put (a, sig->sig_class ); - if ( sig->version < 4 ) + if ( sig->version < 4 ) { write_32(a, sig->timestamp ); write_32(a, sig->keyid[0] ); @@ -1143,7 +1170,7 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig ) } iobuf_put(a, sig->pubkey_algo ); iobuf_put(a, sig->digest_algo ); - if ( sig->version >= 4 ) + if ( sig->version >= 4 ) { size_t nn; /* Timestamp and keyid must have been packed into the subpackets -- cgit v1.2.3 From 0fb0bb8d9a960a2473ab70a021d20639a43227e0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 31 Jan 2011 09:27:06 +0100 Subject: Reworked the ECC changes to better fit into the Libgcrypt API. See ChangeLog for details. Key generation, signing and verification works. Encryption does not yet work. Requires latest Libgcrypt changes. --- g10/build-packet.c | 93 +++++++++++++++++++++--------------------------------- 1 file changed, 36 insertions(+), 57 deletions(-) (limited to 'g10/build-packet.c') diff --git a/g10/build-packet.c b/g10/build-packet.c index e2bbdb511..122ef15e7 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -1,6 +1,6 @@ /* build-packet.c - assemble packets and write them * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - * 2006, 2010 Free Software Foundation, Inc. + * 2006, 2010, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -160,19 +160,31 @@ build_packet( IOBUF out, PACKET *pkt ) static int mpi_write (iobuf_t out, gcry_mpi_t a) { - char buffer[(MAX_EXTERN_MPI_BITS+7)/8+2]; /* 2 is for the mpi length. */ - size_t nbytes; int rc; - nbytes = DIM(buffer); - rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a ); - if( !rc ) - rc = iobuf_write( out, buffer, nbytes ); - else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT ) + if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) { - log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a)); - /* The buffer was too small. We better tell the user about the MPI. */ - rc = gpg_error (GPG_ERR_TOO_LARGE); + size_t nbits; + const void *p; + + p = gcry_mpi_get_opaque (a, &nbits); + rc = iobuf_write (out, p, (nbits+7)/8); + } + else + { + char buffer[(MAX_EXTERN_MPI_BITS+7)/8+2]; /* 2 is for the mpi length. */ + size_t nbytes; + + nbytes = DIM(buffer); + rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a ); + if( !rc ) + rc = iobuf_write( out, buffer, nbytes ); + else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT ) + { + log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a)); + /* The buffer was too small. We better tell the user about the MPI. */ + rc = gpg_error (GPG_ERR_TOO_LARGE); + } } return rc; @@ -252,19 +264,20 @@ calc_packet_length( PACKET *pkt ) return n; } -static void + +static gpg_error_t write_fake_data (IOBUF out, gcry_mpi_t a) { - if (a) - { - unsigned int n; - void *p; + unsigned int n; + void *p; - p = gcry_mpi_get_opaque ( a, &n ); - iobuf_write (out, p, (n+7)/8 ); - } + if (!a) + return 0; + p = gcry_mpi_get_opaque ( a, &n); + return iobuf_write (out, p, (n+7)/8 ); } + static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid ) { @@ -326,33 +339,11 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) } assert (npkey < nskey); - /* Writing the public parameters is easy. Except if we do an - adjustment for ECC OID and possibly KEK params for ECDH. */ - if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA - || pk->pubkey_algo == PUBKEY_ALGO_ECDH) + for (i=0; i < npkey; i++ ) { - /* Write DER of OID with preceeding length byte. */ - err = write_size_body_mpi (a, pk->pkey[0]); - if (err) - goto leave; - /* Write point Q, the public key. */ - err = mpi_write (a, pk->pkey[1]); + err = mpi_write (a, pk->pkey[i]); if (err) goto leave; - - /* Write one more public field for ECDH. */ - if (pk->pubkey_algo == PUBKEY_ALGO_ECDH) - { - err = write_size_body_mpi (a, pk->pkey[2]); - if (err) - goto leave; - } - } - else - { - for (i=0; i < npkey; i++ ) - if ((err = mpi_write (a, pk->pkey[i]))) - goto leave; } @@ -520,20 +511,8 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) if ( !n ) write_fake_data( a, enc->data[0] ); - if (enc->pubkey_algo == PUBKEY_ALGO_ECDH ) - { - /* The second field persists as a LEN+field structure, even - * though it is stored for uniformity as an MPI internally. */ - assert (n == 2); - rc = mpi_write (a, enc->data[0]); - if (!rc) - rc = write_size_body_mpi (a, enc->data[1]); - } - else - { - for (i=0; i < n && !rc ; i++ ) - rc = mpi_write(a, enc->data[i] ); - } + for (i=0; i < n && !rc ; i++ ) + rc = mpi_write (a, enc->data[i]); if (!rc) { -- 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/build-packet.c | 51 ++++++--------------------------------------------- 1 file changed, 6 insertions(+), 45 deletions(-) (limited to 'g10/build-packet.c') 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) { -- cgit v1.2.3