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/seskey.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 12 deletions(-) (limited to 'g10/seskey.c') diff --git a/g10/seskey.c b/g10/seskey.c index ee5584c66..4cc9158c9 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -27,6 +27,7 @@ #include "gpg.h" #include "util.h" #include "cipher.h" +#include "options.h" #include "main.h" #include "i18n.h" @@ -73,15 +74,48 @@ make_session_key( DEK *dek ) * returns: A mpi with the session key (caller must free) */ gcry_mpi_t -encode_session_key (DEK *dek, unsigned int nbits) +encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) { size_t nframe = (nbits+7) / 8; byte *p; byte *frame; int i,n; - u16 csum; + u16 csum = 0; gcry_mpi_t a; + if( DBG_CIPHER ) + log_debug("encode_session_key: encoding %d byte DEK", dek->keylen); + + for( p = dek->key, i=0; i < dek->keylen; i++ ) + csum += *p++; + + /* Shortcut for ECDH. It's padding is minimal to simply make the output be a multiple of 8 bytes. */ + if( openpgp_pk_algo == PUBKEY_ALGO_ECDH ) { + /* pad to 8 byte granulatiry; the padding byte is the number of padded bytes. + * A DEK(k bytes) CSUM(2 bytes) 0x 0x 0x 0x ... 0x + * +---- x times ---+ + */ + nframe = ( 1 + dek->keylen + 2 /* the value so far is always odd */ + 7 ) & (~7); + assert( !(nframe%8) && nframe > 1 + dek->keylen + 2 ); /* alg+key+csum fit and the size is congruent to 8 */ + frame = xmalloc_secure( nframe ); + n = 0; + frame[n++] = dek->algo; + memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen; + frame[n++] = csum >>8; + frame[n++] = csum; + i = nframe - n; /* number padded bytes */ + memset( frame+n, i, i );/* use it as the value of each padded byte */ + assert( n+i == nframe ); + + if( DBG_CIPHER ) + log_debug("encode_session_key: [%d] %02x %02x %02x ... %02x %02x %02x", nframe, frame[0],frame[1],frame[2], frame[nframe-3],frame[nframe-2],frame[nframe-1]); + + if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, nframe, &nframe)) + BUG(); + xfree(frame); + return a; + } + /* The current limitation is that we can only use a session key * whose length is a multiple of BITS_PER_MPI_LIMB * I think we can live with that. @@ -103,9 +137,6 @@ encode_session_key (DEK *dek, unsigned int nbits) * cipher algorithm (20 is used with blowfish160). * CSUM is the 16 bit checksum over the DEK */ - csum = 0; - for( p = dek->key, i=0; i < dek->keylen; i++ ) - csum += *p++; frame = xmalloc_secure( nframe ); n = 0; @@ -161,8 +192,8 @@ do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits, gcry_mpi_t a; if( len + asnlen + 4 > nframe ) - log_bug("can't encode a %d bit MD into a %d bits frame\n", - (int)(len*8), (int)nbits); + log_bug("can't encode a %d bit MD into a %d bits frame, algo=%d\n", + (int)(len*8), (int)nbits, algo); /* We encode the MD in this way: * @@ -209,16 +240,23 @@ gcry_mpi_t encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) { gcry_mpi_t frame; + int gcry_pkalgo; assert (hash_algo); assert (pk); - if (pk->pubkey_algo == GCRY_PK_DSA) + gcry_pkalgo = map_pk_openpgp_to_gcry( pk->pubkey_algo ); + + if (gcry_pkalgo == GCRY_PK_DSA || gcry_pkalgo == GCRY_PK_ECDSA ) { /* It's a DSA signature, so find out the size of q. */ size_t qbytes = gcry_mpi_get_nbits (pk->pkey[1]); + /* pkey[1] is Q for ECDSA, which is an uncompressed point, i.e. 04 */ + if( gcry_pkalgo==GCRY_PK_ECDSA ) + qbytes = ecdsa_qbits_from_Q( qbytes ); + /* Make sure it is a multiple of 8 bits. */ if(qbytes%8) @@ -236,7 +274,8 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) DSA. ;) */ if (qbytes < 160) { - log_error (_("DSA key %s uses an unsafe (%zu bit) hash\n"), + log_error (_("%s key %s uses an unsafe (%zu bit) hash\n"), + gcry_pk_algo_name( gcry_pkalgo ), keystr_from_pk (pk), qbytes); return NULL; } @@ -245,10 +284,16 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) /* Check if we're too short. Too long is safe as we'll automatically left-truncate. */ - if (gcry_md_get_algo_dlen (hash_algo) < qbytes) + /* This checks would require the use of SHA512 with ECDSA 512. I think this is overkill to fail in this case. + * Therefore, relax the check, but only for ECDSA keys. We may need to adjust it later for general case. + * ( Note that the check will never pass for ECDSA 521 anyway as the only hash that intended to match it is SHA 512, but 512 < 521 ). + */ + //if (gcry_md_get_algo_dlen (hash_algo) < qbytes ) + if (gcry_md_get_algo_dlen (hash_algo) < ((gcry_pkalgo==GCRY_PK_ECDSA && qbytes>(521)/8) ? 512/8 : qbytes) ) { - log_error (_("DSA key %s requires a %zu bit or larger hash\n"), - keystr_from_pk(pk), qbytes*8); + log_error (_("%s key %s requires a %zu bit or larger hash, used hash-algo=%d\n"), + gcry_pk_algo_name( gcry_pkalgo ), + keystr_from_pk(pk), qbytes*8, hash_algo); return NULL; } -- cgit v1.2.3 From b73d8ed06ffef8d2fd70ab2e48da9ef515472fe9 Mon Sep 17 00:00:00 2001 From: Andrey Jivsov Date: Wed, 12 Jan 2011 21:14:45 -0800 Subject: Fixed key generation with P-521. Confirmed that signature generation and verification work. --- g10/seskey.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'g10/seskey.c') diff --git a/g10/seskey.c b/g10/seskey.c index 4cc9158c9..e50cf5c02 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -288,7 +288,6 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) * Therefore, relax the check, but only for ECDSA keys. We may need to adjust it later for general case. * ( Note that the check will never pass for ECDSA 521 anyway as the only hash that intended to match it is SHA 512, but 512 < 521 ). */ - //if (gcry_md_get_algo_dlen (hash_algo) < qbytes ) if (gcry_md_get_algo_dlen (hash_algo) < ((gcry_pkalgo==GCRY_PK_ECDSA && qbytes>(521)/8) ? 512/8 : qbytes) ) { log_error (_("%s key %s requires a %zu bit or larger hash, used hash-algo=%d\n"), @@ -297,8 +296,9 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) return NULL; } + /* Note that in case of ECDSA 521 hash is always smaller than the key size */ if (gcry_mpi_scan (&frame, GCRYMPI_FMT_USG, - gcry_md_read (md, hash_algo), qbytes, &qbytes)) + gcry_md_read (md, hash_algo), gcry_md_get_algo_dlen (hash_algo), &qbytes)) BUG(); } else -- 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/seskey.c | 279 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 152 insertions(+), 127 deletions(-) (limited to 'g10/seskey.c') diff --git a/g10/seskey.c b/g10/seskey.c index e50cf5c02..fa6765dc6 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -1,6 +1,6 @@ /* seskey.c - make sesssion keys etc. * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, - * 2006, 2009 Free Software Foundation, Inc. + * 2006, 2009, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -76,109 +76,125 @@ make_session_key( DEK *dek ) gcry_mpi_t encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) { - size_t nframe = (nbits+7) / 8; - byte *p; - byte *frame; - int i,n; - u16 csum = 0; - gcry_mpi_t a; - - if( DBG_CIPHER ) - log_debug("encode_session_key: encoding %d byte DEK", dek->keylen); - - for( p = dek->key, i=0; i < dek->keylen; i++ ) - csum += *p++; - - /* Shortcut for ECDH. It's padding is minimal to simply make the output be a multiple of 8 bytes. */ - if( openpgp_pk_algo == PUBKEY_ALGO_ECDH ) { - /* pad to 8 byte granulatiry; the padding byte is the number of padded bytes. - * A DEK(k bytes) CSUM(2 bytes) 0x 0x 0x 0x ... 0x - * +---- x times ---+ - */ - nframe = ( 1 + dek->keylen + 2 /* the value so far is always odd */ + 7 ) & (~7); - assert( !(nframe%8) && nframe > 1 + dek->keylen + 2 ); /* alg+key+csum fit and the size is congruent to 8 */ - frame = xmalloc_secure( nframe ); - n = 0; - frame[n++] = dek->algo; - memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen; - frame[n++] = csum >>8; - frame[n++] = csum; - i = nframe - n; /* number padded bytes */ - memset( frame+n, i, i );/* use it as the value of each padded byte */ - assert( n+i == nframe ); - - if( DBG_CIPHER ) - log_debug("encode_session_key: [%d] %02x %02x %02x ... %02x %02x %02x", nframe, frame[0],frame[1],frame[2], frame[nframe-3],frame[nframe-2],frame[nframe-1]); - - if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, nframe, &nframe)) - BUG(); - xfree(frame); - return a; + size_t nframe = (nbits+7) / 8; + byte *p; + byte *frame; + int i,n; + u16 csum; + gcry_mpi_t a; + + if (DBG_CIPHER) + log_debug ("encode_session_key: encoding %d byte DEK", dek->keylen); + + csum = 0; + for (p = dek->key, i=0; i < dek->keylen; i++) + csum += *p++; + + /* Shortcut for ECDH. It's padding is minimal to simply make the + output be a multiple of 8 bytes. */ + if (openpgp_pk_algo == PUBKEY_ALGO_ECDH) + { + /* Pad to 8 byte granulatiry; the padding byte is the number of + * padded bytes. + * + * A DEK(k bytes) CSUM(2 bytes) 0x 0x 0x 0x ... 0x + * +---- x times ---+ + */ + nframe = (( 1 + dek->keylen + 2 /* The value so far is always odd. */ + + 7 ) & (~7)); + + /* alg+key+csum fit and the size is congruent to 8. */ + assert (!(nframe%8) && nframe > 1 + dek->keylen + 2 ); + + frame = xmalloc_secure (nframe); + n = 0; + frame[n++] = dek->algo; + memcpy (frame+n, dek->key, dek->keylen); + n += dek->keylen; + frame[n++] = csum >> 8; + frame[n++] = csum; + i = nframe - n; /* Number of padded bytes. */ + memset (frame+n, i, i); /* Use it as the value of each padded byte. */ + assert (n+i == nframe); + + if (DBG_CIPHER) + log_debug ("encode_session_key: " + "[%d] %02x %02x %02x ... %02x %02x %02x\n", + nframe, frame[0], frame[1], frame[2], + frame[nframe-3], frame[nframe-2], frame[nframe-1]); + + if (gcry_mpi_scan (&a, GCRYMPI_FMT_USG, frame, nframe, &nframe)) + BUG(); + xfree(frame); + return a; } - - /* The current limitation is that we can only use a session key - * whose length is a multiple of BITS_PER_MPI_LIMB - * I think we can live with that. - */ - if( dek->keylen + 7 > nframe || !nframe ) - log_bug("can't encode a %d bit key in a %d bits frame\n", - dek->keylen*8, nbits ); - - /* We encode the session key in this way: - * - * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) - * - * (But how can we store the leading 0 - the external representaion - * of MPIs doesn't allow leading zeroes =:-) - * - * RND are non-zero random bytes. - * A is the cipher algorithm - * DEK is the encryption key (session key) length k depends on the - * cipher algorithm (20 is used with blowfish160). - * CSUM is the 16 bit checksum over the DEK - */ - - frame = xmalloc_secure( nframe ); - n = 0; - frame[n++] = 0; - frame[n++] = 2; - i = nframe - 6 - dek->keylen; - assert( i > 0 ); - p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM); - /* Replace zero bytes by new values. */ - for(;;) { - int j, k; - byte *pp; - - /* count the zero bytes */ - for(j=k=0; j < i; j++ ) - if( !p[j] ) - k++; - if( !k ) - break; /* okay: no zero bytes */ - k += k/128 + 3; /* better get some more */ - pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM); - for(j=0; j < i && k ;) { - if( !p[j] ) - p[j] = pp[--k]; - if (p[j]) - j++; + + /* The current limitation is that we can only use a session key + * whose length is a multiple of BITS_PER_MPI_LIMB + * I think we can live with that. + */ + if (dek->keylen + 7 > nframe || !nframe) + log_bug ("can't encode a %d bit key in a %d bits frame\n", + dek->keylen*8, nbits ); + + /* We encode the session key in this way: + * + * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) + * + * (But how can we store the leading 0 - the external representaion + * of MPIs doesn't allow leading zeroes =:-) + * + * RND are non-zero random bytes. + * A is the cipher algorithm + * DEK is the encryption key (session key) length k depends on the + * cipher algorithm (20 is used with blowfish160). + * CSUM is the 16 bit checksum over the DEK + */ + + frame = xmalloc_secure( nframe ); + n = 0; + frame[n++] = 0; + frame[n++] = 2; + i = nframe - 6 - dek->keylen; + assert( i > 0 ); + p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM); + /* Replace zero bytes by new values. */ + for (;;) + { + int j, k; + byte *pp; + + /* Count the zero bytes. */ + for (j=k=0; j < i; j++ ) + if (!p[j]) + k++; + if (!k) + break; /* Okay: no zero bytes. */ + k += k/128 + 3; /* Better get some more. */ + pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM); + for (j=0; j < i && k ;) + { + if (!p[j]) + p[j] = pp[--k]; + if (p[j]) + j++; } - xfree(pp); + xfree (pp); } - memcpy( frame+n, p, i ); - xfree(p); - n += i; - frame[n++] = 0; - frame[n++] = dek->algo; - memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen; - frame[n++] = csum >>8; - frame[n++] = csum; - assert( n == nframe ); - if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe)) - BUG(); - xfree(frame); - return a; + memcpy (frame+n, p, i); + xfree (p); + n += i; + frame[n++] = 0; + frame[n++] = dek->algo; + memcpy (frame+n, dek->key, dek->keylen ); + n += dek->keylen; + frame[n++] = csum >>8; + frame[n++] = csum; + assert (n == nframe); + if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe)) + BUG(); + xfree (frame); + return a; } @@ -192,8 +208,8 @@ do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits, gcry_mpi_t a; if( len + asnlen + 4 > nframe ) - log_bug("can't encode a %d bit MD into a %d bits frame, algo=%d\n", - (int)(len*8), (int)nbits, algo); + log_bug ("can't encode a %d bit MD into a %d bits frame, algo=%d\n", + (int)(len*8), (int)nbits, algo); /* We encode the MD in this way: * @@ -240,26 +256,27 @@ gcry_mpi_t encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) { gcry_mpi_t frame; - int gcry_pkalgo; + int pkalgo; assert (hash_algo); assert (pk); - gcry_pkalgo = map_pk_openpgp_to_gcry( pk->pubkey_algo ); + pkalgo = map_pk_openpgp_to_gcry (pk->pubkey_algo); - if (gcry_pkalgo == GCRY_PK_DSA || gcry_pkalgo == GCRY_PK_ECDSA ) + if (pkalgo == GCRY_PK_DSA || pkalgo == GCRY_PK_ECDSA) { - /* It's a DSA signature, so find out the size of q. */ + /* It's a DSA signature, so find out the size of q. */ size_t qbytes = gcry_mpi_get_nbits (pk->pkey[1]); - /* pkey[1] is Q for ECDSA, which is an uncompressed point, i.e. 04 */ - if( gcry_pkalgo==GCRY_PK_ECDSA ) - qbytes = ecdsa_qbits_from_Q( qbytes ); - + /* pkey[1] is Q for ECDSA, which is an uncompressed point, + i.e. 04 */ + if (pkalgo == GCRY_PK_ECDSA) + qbytes = ecdsa_qbits_from_Q (qbytes); + /* Make sure it is a multiple of 8 bits. */ - - if(qbytes%8) + + if (qbytes%8) { log_error(_("DSA requires the hash length to be a" " multiple of 8 bits\n")); @@ -275,30 +292,38 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) if (qbytes < 160) { log_error (_("%s key %s uses an unsafe (%zu bit) hash\n"), - gcry_pk_algo_name( gcry_pkalgo ), - keystr_from_pk (pk), qbytes); + gcry_pk_algo_name (pkalgo), keystr_from_pk (pk), qbytes); return NULL; } - + qbytes /= 8; /* Check if we're too short. Too long is safe as we'll - automatically left-truncate. */ - /* This checks would require the use of SHA512 with ECDSA 512. I think this is overkill to fail in this case. - * Therefore, relax the check, but only for ECDSA keys. We may need to adjust it later for general case. - * ( Note that the check will never pass for ECDSA 521 anyway as the only hash that intended to match it is SHA 512, but 512 < 521 ). - */ - if (gcry_md_get_algo_dlen (hash_algo) < ((gcry_pkalgo==GCRY_PK_ECDSA && qbytes>(521)/8) ? 512/8 : qbytes) ) + automatically left-truncate. + + FIXME: Check against FIPS. + This checks would require the use of SHA512 with ECDSA 512. I + think this is overkill to fail in this case. Therefore, + relax the check, but only for ECDSA keys. We may need to + adjust it later for general case. (Note that the check will + never pass for ECDSA 521 anyway as the only hash that + intended to match it is SHA 512, but 512 < 521). */ + if (gcry_md_get_algo_dlen (hash_algo) + < ((pkalgo == GCRY_PK_ECDSA && qbytes > (521)/8) ? 512/8 : qbytes)) { - log_error (_("%s key %s requires a %zu bit or larger hash, used hash-algo=%d\n"), - gcry_pk_algo_name( gcry_pkalgo ), - keystr_from_pk(pk), qbytes*8, hash_algo); + log_error (_("%s key %s requires a %zu bit or larger hash " + "(hash is %s\n"), + gcry_pk_algo_name (pkalgo), + keystr_from_pk(pk), qbytes*8, + gcry_md_algo_name (hash_algo)); return NULL; } - /* Note that in case of ECDSA 521 hash is always smaller than the key size */ + /* Note that in case of ECDSA 521 hash is always smaller than + the key size. */ if (gcry_mpi_scan (&frame, GCRYMPI_FMT_USG, - gcry_md_read (md, hash_algo), gcry_md_get_algo_dlen (hash_algo), &qbytes)) + gcry_md_read (md, hash_algo), + gcry_md_get_algo_dlen (hash_algo), &qbytes)) BUG(); } else -- cgit v1.2.3 From c3db7705c049e31e678ff87e230b8160aa0027f1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 21 Jan 2011 15:58:07 +0100 Subject: Truncate the DSA hash; fixes regression. Removed left over debug code. --- g10/seskey.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'g10/seskey.c') diff --git a/g10/seskey.c b/g10/seskey.c index fa6765dc6..2d7918d39 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -319,11 +319,13 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) return NULL; } - /* Note that in case of ECDSA 521 hash is always smaller than - the key size. */ + /* By passing QBYTES as length to mpi_scan, we do the truncation + of the hash. + + Note that in case of ECDSA 521 the hash is always smaller + than the key size. */ if (gcry_mpi_scan (&frame, GCRYMPI_FMT_USG, - gcry_md_read (md, hash_algo), - gcry_md_get_algo_dlen (hash_algo), &qbytes)) + gcry_md_read (md, hash_algo), qbytes, &qbytes)) BUG(); } 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/seskey.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'g10/seskey.c') diff --git a/g10/seskey.c b/g10/seskey.c index 2d7918d39..1f3e8ab49 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -49,10 +49,10 @@ make_session_key( DEK *dek ) 0 : GCRY_CIPHER_ENABLE_SYNC))) ) BUG(); gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM ); - for (i=0; i < 16; i++ ) + for (i=0; i < 16; i++ ) { rc = gcry_cipher_setkey (chd, dek->key, dek->keylen); - if (!rc) + if (!rc) { gcry_cipher_close (chd); return; @@ -82,7 +82,7 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) int i,n; u16 csum; gcry_mpi_t a; - + if (DBG_CIPHER) log_debug ("encode_session_key: encoding %d byte DEK", dek->keylen); @@ -102,10 +102,10 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) */ nframe = (( 1 + dek->keylen + 2 /* The value so far is always odd. */ + 7 ) & (~7)); - + /* alg+key+csum fit and the size is congruent to 8. */ assert (!(nframe%8) && nframe > 1 + dek->keylen + 2 ); - + frame = xmalloc_secure (nframe); n = 0; frame[n++] = dek->algo; @@ -122,13 +122,13 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) "[%d] %02x %02x %02x ... %02x %02x %02x\n", nframe, frame[0], frame[1], frame[2], frame[nframe-3], frame[nframe-2], frame[nframe-1]); - + if (gcry_mpi_scan (&a, GCRYMPI_FMT_USG, frame, nframe, &nframe)) BUG(); xfree(frame); return a; } - + /* The current limitation is that we can only use a session key * whose length is a multiple of BITS_PER_MPI_LIMB * I think we can live with that. @@ -136,7 +136,7 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) if (dek->keylen + 7 > nframe || !nframe) log_bug ("can't encode a %d bit key in a %d bits frame\n", dek->keylen*8, nbits ); - + /* We encode the session key in this way: * * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) @@ -163,7 +163,7 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) { int j, k; byte *pp; - + /* Count the zero bytes. */ for (j=k=0; j < i; j++ ) if (!p[j]) @@ -273,9 +273,9 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) i.e. 04 */ if (pkalgo == GCRY_PK_ECDSA) qbytes = ecdsa_qbits_from_Q (qbytes); - + /* Make sure it is a multiple of 8 bits. */ - + if (qbytes%8) { log_error(_("DSA requires the hash length to be a" @@ -295,11 +295,11 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) gcry_pk_algo_name (pkalgo), keystr_from_pk (pk), qbytes); return NULL; } - + qbytes /= 8; /* Check if we're too short. Too long is safe as we'll - automatically left-truncate. + automatically left-truncate. FIXME: Check against FIPS. This checks would require the use of SHA512 with ECDSA 512. I @@ -308,7 +308,7 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) adjust it later for general case. (Note that the check will never pass for ECDSA 521 anyway as the only hash that intended to match it is SHA 512, but 512 < 521). */ - if (gcry_md_get_algo_dlen (hash_algo) + if (gcry_md_get_algo_dlen (hash_algo) < ((pkalgo == GCRY_PK_ECDSA && qbytes > (521)/8) ? 512/8 : qbytes)) { log_error (_("%s key %s requires a %zu bit or larger hash " -- cgit v1.2.3