From 6d21f2838dcfee933f4c430fba68ba8ada3abd50 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 7 Aug 1998 08:53:38 +0000 Subject: [PATCH] chnages done at the train --- TODO | 1 + cipher/ChangeLog | 5 ++++ cipher/dsa.c | 18 +++++++++++-- cipher/elgamal.c | 22 ++++++++++++--- cipher/g10c.c | 6 ----- cipher/primegen.c | 16 ++++++++--- cipher/random.c | 38 ++++---------------------- cipher/random.h | 1 - g10/ChangeLog | 10 +++++++ g10/g10.c | 5 ++-- g10/passphrase.c | 2 +- g10/ringedit.c | 26 ++++++++++++------ g10/seskey.c | 12 ++++----- g10/tdbio.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++- include/mpi.h | 1 - mpi/ChangeLog | 4 +++ mpi/g10m.c | 6 ----- mpi/mpi-bit.c | 50 ---------------------------------- mpi/mpicoder.c | 1 - 19 files changed, 167 insertions(+), 126 deletions(-) diff --git a/TODO b/TODO index 2af0c45fc..f693799f2 100644 --- a/TODO +++ b/TODO @@ -9,6 +9,7 @@ * check whether it is valid to pack the signature stuff (onepass, data, sig) into a compressed packet - or should we only compress the data? what does pgp 5 do, what does OpenPGP say= + ==> I think it is okay, should be tested against pgp5 * invalid packets (Marco) und Markus Gruber diff --git a/cipher/ChangeLog b/cipher/ChangeLog index 528de20cd..cb6082e34 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,8 @@ +Thu Aug 6 17:25:38 1998 Werner Koch,mobil,,, (wk@tobold) + + * random.c (get_random_byte): Removed and changed all callers + to use get_random_bits() + Mon Jul 27 10:30:22 1998 Werner Koch (wk@(none)) * cipher.c : Support for other blocksizes diff --git a/cipher/dsa.c b/cipher/dsa.c index 107ed71c2..accbca9e8 100644 --- a/cipher/dsa.c +++ b/cipher/dsa.c @@ -66,7 +66,17 @@ gen_k( MPI q ) for(;;) { if( DBG_CIPHER ) fputc('.', stderr); - mpi_set_bytes( k, nbits , get_random_byte, 1 ); + { char *p = get_random_bits( nbits, 1, 1 ); + mpi_set_buffer( k, p, (nbits+7)/8, 0 ); + m_free(p); + /* make sure that the number is of the exact lenght */ + if( mpi_test_bit( k, nbits-1 ) ) + mpi_set_highbit( k, nbits-1 ); + else { + mpi_set_highbit( k, nbits-1 ); + mpi_clear_bit( k, nbits-1 ); + } + } if( !(mpi_cmp( k, q ) < 0) ) /* check: k < q */ continue; /* no */ if( !(mpi_cmp_ui( k, 0 ) > 0) ) /* check: k > 0 */ @@ -92,7 +102,11 @@ test_keys( DSA_secret_key *sk, unsigned qbits ) pk.q = sk->q; pk.g = sk->g; pk.y = sk->y; - mpi_set_bytes( test, qbits, get_random_byte, 0 ); + /*mpi_set_bytes( test, qbits, get_random_byte, 0 );*/ + { char *p = get_random_bits( qbits, 0, 0 ); + mpi_set_buffer( test, p, (qbits+7)/8, 0 ); + m_free(p); + } sign( out1_a, out1_b, test, sk ); if( !verify( out1_a, out1_b, test, &pk ) ) diff --git a/cipher/elgamal.c b/cipher/elgamal.c index 9b9981da1..b330ccff0 100644 --- a/cipher/elgamal.c +++ b/cipher/elgamal.c @@ -60,7 +60,7 @@ static void test_keys( ELG_secret_key *sk, unsigned nbits ) { ELG_public_key pk; - MPI test = mpi_alloc( nbits / BITS_PER_MPI_LIMB ); + MPI test = mpi_alloc( 0 ); MPI out1_a = mpi_alloc( nbits / BITS_PER_MPI_LIMB ); MPI out1_b = mpi_alloc( nbits / BITS_PER_MPI_LIMB ); MPI out2 = mpi_alloc( nbits / BITS_PER_MPI_LIMB ); @@ -69,7 +69,11 @@ test_keys( ELG_secret_key *sk, unsigned nbits ) pk.g = sk->g; pk.y = sk->y; - mpi_set_bytes( test, nbits, get_random_byte, 0 ); + /*mpi_set_bytes( test, nbits, get_random_byte, 0 );*/ + { char *p = get_random_bits( nbits, 0, 0 ); + mpi_set_buffer( test, p, (nbits+7)/8, 0 ); + m_free(p); + } encrypt( out1_a, out1_b, test, &pk ); decrypt( out2, out1_a, out1_b, sk ); @@ -94,7 +98,7 @@ test_keys( ELG_secret_key *sk, unsigned nbits ) static MPI gen_k( MPI p ) { - MPI k = mpi_alloc_secure( mpi_get_nlimbs(p) ); + MPI k = mpi_alloc_secure( 0 ); MPI temp = mpi_alloc( mpi_get_nlimbs(p) ); MPI p_1 = mpi_copy(p); unsigned nbits = mpi_get_nbits(p); @@ -105,7 +109,17 @@ gen_k( MPI p ) for(;;) { if( DBG_CIPHER ) fputc('.', stderr); - mpi_set_bytes( k, nbits , get_random_byte, 1 ); + { char *p = get_random_bits( nbits, 1, 1 ); + mpi_set_buffer( k, p, (nbits+7)/8, 0 ); + m_free(p); + /* make sure that the number is of the exact lenght */ + if( mpi_test_bit( k, nbits-1 ) ) + mpi_set_highbit( k, nbits-1 ); + else { + mpi_set_highbit( k, nbits-1 ); + mpi_clear_bit( k, nbits-1 ); + } + } if( !(mpi_cmp( k, p_1 ) < 0) ) /* check: k < (p-1) */ continue; /* no */ if( !(mpi_cmp_ui( k, 0 ) > 0) ) /* check: k > 0 */ diff --git a/cipher/g10c.c b/cipher/g10c.c index 5bf0eb61f..d5f79bda5 100644 --- a/cipher/g10c.c +++ b/cipher/g10c.c @@ -35,10 +35,4 @@ g10c_generate_secret_prime( unsigned nbits ) return generate_secret_prime( nbits ); } -byte -g10c_get_random_byte( int level ) -{ - return get_random_byte( level ); -} - diff --git a/cipher/primegen.c b/cipher/primegen.c index 66d40dbfc..addc51fd5 100644 --- a/cipher/primegen.c +++ b/cipher/primegen.c @@ -293,7 +293,12 @@ gen_prime( unsigned nbits, int secret, int randomlevel ) int dotcount=0; /* generate a random number */ - mpi_set_bytes( prime, nbits, get_random_byte, randomlevel ); + /*mpi_set_bytes( prime, nbits, get_random_byte, randomlevel );*/ + { char *p = get_random_bits( nbits, randomlevel, secret ); + mpi_set_buffer( prime, p, (nbits+7)/8, 0 ); + m_free(p); + } + /* set high order bit to 1, set low order bit to 1 */ mpi_set_highbit( prime, nbits-1 ); mpi_set_bit( prime, 0 ); @@ -423,8 +428,13 @@ is_prime( MPI n, int steps, int *count ) mpi_set_ui( x, 2 ); } else { - mpi_set_bytes( x, nbits-1, get_random_byte, 0 ); - /* work around a bug in mpi_set_bytes */ + /*mpi_set_bytes( x, nbits-1, get_random_byte, 0 );*/ + { char *p = get_random_bits( nbits, 0, 0 ); + mpi_set_buffer( x, p, (nbits+7)/8, 0 ); + m_free(p); + } + /* make sure that the number is smaller than the prime + * and keep the randomness of the high bit */ if( mpi_test_bit( x, nbits-2 ) ) { mpi_set_highbit( x, nbits-2 ); /* clear all higher bits */ } diff --git a/cipher/random.c b/cipher/random.c index 75754cd01..29b82ee7c 100644 --- a/cipher/random.c +++ b/cipher/random.c @@ -47,15 +47,8 @@ #error weird size for an unsigned long #endif -struct cache { - int len; - int size; - byte *buffer; -}; - static int is_initialized; -static struct cache cache[3]; #define MASK_LEVEL(a) do {if( a > 2 ) a = 2; else if( a < 0 ) a = 0; } while(0) static char *rndpool; /* allocated size is POOLSIZE+BLOCKLEN */ static char *keypool; /* allocated size is POOLSIZE+BLOCKLEN */ @@ -113,38 +106,17 @@ quick_random_gen( int onoff ) void randomize_buffer( byte *buffer, size_t length, int level ) { - for( ; length; length-- ) - *buffer++ = get_random_byte(level); -} - - -byte -get_random_byte( int level ) -{ - MASK_LEVEL(level); - if( !cache[level].len ) { - if( !is_initialized ) - initialize(); - if( !cache[level].buffer ) { - cache[level].size = 100; - cache[level].buffer = level && secure_alloc? - m_alloc_secure( cache[level].size ) - : m_alloc( cache[level].size ); - } - read_pool(cache[level].buffer, cache[level].size, level ); - cache[level].len = cache[level].size; - } - - return cache[level].buffer[--cache[level].len]; + char *p = get_random_bits( length*8, level, m_is_secure(buffer) ); + memcpy( buffer, p, length ); + m_free(p); } /**************** * Return a pointer to a randomized buffer of level 0 and LENGTH bits - * caller must free the buffer. This function does not use the - * cache (will be removed in future). Note: The returned value is - * rounded up to bytes. + * caller must free the buffer. + * Note: The returned value is rounded up to bytes. */ byte * get_random_bits( size_t nbits, int level, int secure ) diff --git a/cipher/random.h b/cipher/random.h index d93e5b766..2ac50a7d4 100644 --- a/cipher/random.h +++ b/cipher/random.h @@ -26,7 +26,6 @@ void secure_random_alloc(void); int quick_random_gen( int onoff ); void randomize_buffer( byte *buffer, size_t length, int level ); -byte get_random_byte( int level ); byte *get_random_bits( size_t nbits, int level, int secure ); void add_randomness( const void *buffer, size_t length, int source ); diff --git a/g10/ChangeLog b/g10/ChangeLog index a907239b2..2e9a3587d 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,13 @@ +Thu Aug 6 16:30:41 1998 Werner Koch,mobil,,, (wk@tobold) + + * seskey.c (encode_session_key): Now uses get_random_bits(). + +Thu Aug 6 07:34:56 1998 Werner Koch,mobil,,, (wk@tobold) + + * ringedit.c (keyring_copy): No more backupfiles for + secret keyrings and add additional warning in case of + a failed secret keyring operation. + Wed Aug 5 11:54:37 1998 Werner Koch (wk@(none)) * g10.c (check_opts): Moved to main. Changed def_cipher_algo diff --git a/g10/g10.c b/g10/g10.c index acc5bf691..8a04db161 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -969,13 +969,14 @@ main( int argc, char **argv ) { int level = atoi(*argv); for(;;) { - int c = get_random_byte(level); + byte *p = get_random_bits( 8, level, 0); if( argc == 1 ) { - printf("%02x", c ); + printf("%02x", *p ); fflush(stdout); } else putchar(c&0xff); + m_free(p); } } break; diff --git a/g10/passphrase.c b/g10/passphrase.c index 46d7f8435..920d508cd 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -210,7 +210,7 @@ hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create ) for(;;) { md_write( md, s2k->salt, 8 ); md_write( md, pw, len ); - if( count < len2 ) + if( count <= len2 ) break; count -= len2; } diff --git a/g10/ringedit.c b/g10/ringedit.c index 58eb6d6d9..6f505ef2a 100644 --- a/g10/ringedit.c +++ b/g10/ringedit.c @@ -55,6 +55,7 @@ #include "mpi.h" #include "iobuf.h" #include "keydb.h" +#include "i18n.h" #include /* for truncate */ @@ -865,14 +866,16 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) } } /* rename and make backup file */ - #if __MINGW32__ - remove( bakfname ); - #endif - if( rename( rentry->fname, bakfname ) ) { - log_error("%s: rename to %s failed: %s\n", - rentry->fname, bakfname, strerror(errno) ); - rc = G10ERR_RENAME_FILE; - goto leave; + if( !rentry->secret ) { /* but not for secret keyrings */ + #if __MINGW32__ + remove( bakfname ); + #endif + if( rename( rentry->fname, bakfname ) ) { + log_error("%s: rename to %s failed: %s\n", + rentry->fname, bakfname, strerror(errno) ); + rc = G10ERR_RENAME_FILE; + goto leave; + } } #if __MINGW32__ remove( rentry->fname ); @@ -881,6 +884,13 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) log_error("%s: rename to %s failed: %s\n", tmpfname, rentry->fname,strerror(errno) ); rc = G10ERR_RENAME_FILE; + if( rentry->secret ) { + log_info(_( + "Warning: 2 files with confidential information exists.\n")); + log_info(_("%s is the unchanged one\n"), rentry->fname ); + log_info(_("%s is the new one\n"), tmpfname ); + log_info(_("Please fix this possible security flaw\n")); + } goto leave; } diff --git a/g10/seskey.c b/g10/seskey.c index 6e76d12db..29881d2e9 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -51,7 +51,7 @@ encode_session_key( DEK *dek, unsigned nbits ) int nframe = (nbits+7) / 8; byte *p; byte *frame; - int i,n,c; + int i,n; u16 csum; MPI a; @@ -86,12 +86,10 @@ encode_session_key( DEK *dek, unsigned nbits ) frame[n++] = 2; i = nframe - 6 - dek->keylen; assert( i > 0 ); - /* FIXME: replace the loop by a call to get_random_bits() */ - for( ; i ; i-- ) { - while( !(c = get_random_byte(1)) ) - ; - frame[n++] = c; - } + p = get_random_bits( i*8, 1, 1 ); + memcpy( frame+n, p, i ); + m_free(p); + n += i; frame[n++] = 0; frame[n++] = dek->algo; memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen; diff --git a/g10/tdbio.c b/g10/tdbio.c index 034e092e3..02950b502 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -871,6 +871,33 @@ tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen, return rc; } +static int +del_reclist( ulong recno, int type ) +{ + TRUSTREC rec; + int rc; + + while( recno ) { + rc = tdbio_read_record( recno, &rec, type); + if( rc ) { + log_error_f(db_name, "can't read record %lu: %s\n", + recno, g10_errstr(rc)); + return rc; + } + switch( type ) { + case RECTYPE_PREF: recno = rec.r.pref.next; break; + case RECTYPE_UID: recno = rec.r.uid.next; break; + default: BUG(); + } + rc = tdbio_delete_record( rec.recnum ); + if( rc ) { + log_error_f(db_name, "can't delete record %lu: %s\n", + rec.recnum, g10_errstr(rc)); + return rc; + } + } + return 0; +} /**************** * Delete the Userid UIDLID from DIRLID @@ -878,7 +905,47 @@ tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen, int tdbio_delete_uidrec( ulong dirlid, ulong uidlid ) { - return G10ERR_GENERAL; /* not implemented */ + TRUSTREC dirrec, rec; + ulong recno; + int rc; + + rc = tdbio_read_record( dirlid, &dirrec, RECTYPE_DIR); + if( rc ) { + log_error_f(db_name, "can't read dirrec %lu: %s\n", dirlid, g10_errstr(rc)); + return rc; + } + recno = dirrec.r.dir.uidlist; + for( ; recno; recno = rec.r.uid.next ) { + rc = tdbio_read_record( recno, &rec, RECTYPE_UID); + if( rc ) { + log_error_f(db_name, "can't read uidrec %lu: %s\n", + recno, g10_errstr(rc)); + return rc; + } + if( recno == uidlid ) { + rc = del_reclist( rec.r.uid.prefrec, RECTYPE_PREF ); + if( rc ) + return rc; + rc = del_reclist( rec.r.uid.siglist, RECTYPE_SIG ); + if( rc ) + return rc; + rc = tdbio_delete_record( recno ); + if( rc ) { + log_error_f(db_name, "can't delete uidrec %lu: %s\n", + recno, g10_errstr(rc)); + return rc; + } + dirrec.r.dir.uidlist = 0; + rc = tdbio_write_record( &dirrec ); + if( rc ) { + log_error_f(db_name, "can't update dirrec %lu: %s\n", + dirrec.recnum, g10_errstr(rc)); + return rc; + } + return 0; + } + } + return -1; /* not found */ } diff --git a/include/mpi.h b/include/mpi.h index d4cb56cae..1347a12e1 100644 --- a/include/mpi.h +++ b/include/mpi.h @@ -162,7 +162,6 @@ void mpi_set_bit( MPI a, unsigned n ); void mpi_set_highbit( MPI a, unsigned n ); void mpi_clear_highbit( MPI a, unsigned n ); void mpi_clear_bit( MPI a, unsigned n ); -void mpi_set_bytes( MPI a, unsigned nbits, byte (*fnc)(int), int opaque ); void mpi_rshift( MPI x, MPI a, unsigned n ); /*-- mpi-inv.c --*/ diff --git a/mpi/ChangeLog b/mpi/ChangeLog index 3fc0b3329..aa9406f5a 100644 --- a/mpi/ChangeLog +++ b/mpi/ChangeLog @@ -1,3 +1,7 @@ +Thu Aug 6 16:39:28 1998 Werner Koch,mobil,,, (wk@tobold) + + * mpi-bit.c (mpi_set_bytes): Removed. + Wed Aug 5 15:11:12 1998 Werner Koch (wk@(none)) * mpicoder.c (mpi_read_from_buffer): New. diff --git a/mpi/g10m.c b/mpi/g10m.c index 28feaf08c..5c23f0ae7 100644 --- a/mpi/g10m.c +++ b/mpi/g10m.c @@ -57,12 +57,6 @@ void g10m_swap( MPI a, MPI b) { mpi_swap( a, b ); } void g10m_set( MPI w, MPI u) { mpi_set( w, u ); } void g10m_set_ui( MPI w, ulong u ) { mpi_set_ui( w, u ); } -void -g10m_set_bytes( MPI a, unsigned nbits, byte (*fnc)(int), int opaque ) -{ - mpi_set_bytes( a, nbits, fnc, opaque ); -} - int g10m_cmp( MPI u, MPI v ) { return mpi_cmp( u, v ); } int g10m_cmp_ui( MPI u, ulong v ) { return mpi_cmp_ui( u, v ); } diff --git a/mpi/mpi-bit.c b/mpi/mpi-bit.c index 2e420875b..f60d5e3b9 100644 --- a/mpi/mpi-bit.c +++ b/mpi/mpi-bit.c @@ -177,56 +177,6 @@ mpi_clear_bit( MPI a, unsigned n ) } -void -mpi_set_bytes( MPI a, unsigned nbits, byte (*fnc)(int), int opaque ) -{ - byte *p; - unsigned nlimbs, nlimbs2, xbits, xbytes; - unsigned n; - int i; - - nlimbs = nbits / BITS_PER_MPI_LIMB; - xbits = nbits % BITS_PER_MPI_LIMB; - nlimbs2 = xbits? (nlimbs+1):nlimbs; - xbytes = xbits / 8; - xbits = xbits % 8; - if( a->alloced < nlimbs2 ) - mpi_resize(a, nlimbs2 ); - a->nlimbs = nlimbs2; - for(n=0; n < nlimbs; n++ ) { - p = (byte*)(a->d+n); - #ifdef LITTLE_ENDIAN_HOST - for(i=0; i < BYTES_PER_MPI_LIMB; i++ ) - p[i] = fnc(opaque); - #else - for(i=BYTES_PER_MPI_LIMB-1; i>=0; i-- ) - p[i] = fnc(opaque); - #endif - } - if( xbytes ) { - p = (byte*)(a->d+n); - #ifdef LITTLE_ENDIAN_HOST - for(i=0; i < xbytes; i++ ) - p[i] = fnc(opaque); - #else - for(i=xbytes-1; i>=0; i-- ) - p[i] = fnc(opaque); - #endif - } - #if 0 /* fixme: set complete random byte and clear out the unwanted ones*/ - if( xbits ) { - p = (byte*)(a->d+n); - #ifdef LITTLE_ENDIAN_HOST - for(i=0; i < xbytes; i++ ) - p[i] = fnc(opaque); - #else - for(i=xbytes-1; i>=0; i-- ) - p[i] = fnc(opaque); - #endif - } - #endif -} - /**************** * Shift A by N bits to the right * FIXME: should use alloc_limb if X and A are same. diff --git a/mpi/mpicoder.c b/mpi/mpicoder.c index 2775f5be8..1fab786f5 100644 --- a/mpi/mpicoder.c +++ b/mpi/mpicoder.c @@ -397,7 +397,6 @@ mpi_set_buffer( MPI a, const byte *buffer, unsigned nbytes, int sign ) alimb |= *p-- << 16 ; alimb |= *p-- << 24 ; #elif BYTES_PER_MPI_LIMB == 8 - /* cast due to egc's "left shift count >= width of type" warning*/ alimb = (mpi_limb_t)*p-- ; alimb |= (mpi_limb_t)*p-- << 8 ; alimb |= (mpi_limb_t)*p-- << 16 ;