From da129a5124b4493fc3c50ce1dc3bed0aa84ed97e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 24 Mar 2000 10:19:50 +0000 Subject: [PATCH] See ChangeLog: Fri Mar 24 11:25:45 CET 2000 Werner Koch --- cipher/ChangeLog | 10 ++++++ cipher/md.c | 87 ++++++++++++++++++++++++++++++++++++++++++++---- g10/ChangeLog | 8 +++++ g10/OPTIONS | 2 ++ g10/gpg.c | 45 +++++++++++++++++++++---- g10/kbxblob.c | 60 ++++++++++++++++++++++++++++++++- g10/kbxfile.c | 2 +- mpi/ChangeLog | 4 +++ mpi/config.links | 4 +-- 9 files changed, 205 insertions(+), 17 deletions(-) diff --git a/cipher/ChangeLog b/cipher/ChangeLog index a81189702..49595a93c 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,13 @@ +Fri Mar 24 11:25:45 CET 2000 Werner Koch + + * md.c (md_open): Add hmac arg and allocate space for the pads. + (md_finalize): Add HMAC support. + (md_copy): Ditto. + (md_close): Ditto. + (gcry_md_reset): Ditto. + (gcry_md_ctl): Ditto. + (prepare_macpdas): New. + Mon Mar 13 19:22:46 CET 2000 Werner Koch * md.c (gcry_md_hash_buffer): Add support for the other algorithms. diff --git a/cipher/md.c b/cipher/md.c index 680558db2..98795206c 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -41,13 +41,14 @@ struct gcry_md_context { FILE *debug; int finalized; struct md_digest_list_s *list; + byte *macpads; }; #define CTX_MAGIC_NORMAL 0x11071961 #define CTX_MAGIC_SECURE 0x16917011 static const char * digest_algo_to_string( int algo ); static int check_digest_algo( int algo ); -static GCRY_MD_HD md_open( int algo, int secure ); +static GCRY_MD_HD md_open( int algo, int secure, int hmac ); static int md_enable( GCRY_MD_HD hd, int algo ); static GCRY_MD_HD md_copy( GCRY_MD_HD a ); static void md_close(GCRY_MD_HD a); @@ -239,7 +240,7 @@ check_digest_algo( int algo ) * may be 0. */ static GCRY_MD_HD -md_open( int algo, int secure ) +md_open( int algo, int secure, int hmac ) { GCRY_MD_HD hd; struct gcry_md_context *ctx; @@ -280,6 +281,14 @@ md_open( int algo, int secure ) memset( hd->ctx, 0, sizeof *hd->ctx ); ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL; ctx->secure = secure; + if( hmac ) { + ctx->macpads = g10_malloc_secure( 128 ); + if( !ctx->macpads ) { + md_close( hd ); + set_lasterr( GCRYERR_NO_MEM ); + return NULL; + } + } fast_random_poll(); /* FIXME: should we really do that? */ if( algo && md_enable( hd, algo ) ) { md_close( hd ); @@ -295,7 +304,8 @@ gcry_md_open( int algo, unsigned int flags ) GCRY_MD_HD hd; /* fixme: check that algo is available and that only valid * flag values are used */ - hd = md_open( algo, (flags & GCRY_MD_FLAG_SECURE) ); + hd = md_open( algo, (flags & GCRY_MD_FLAG_SECURE), + (flags & GCRY_MD_FLAG_HMAC) ); return hd; } @@ -371,6 +381,10 @@ md_copy( GCRY_MD_HD ahd ) memcpy( b, a, sizeof *a ); b->list = NULL; b->debug = NULL; + if( a->macpads ) { + b->macpads = g10_malloc_secure( 128 ); + memcpy( b->macpads, a->macpads, 128 ); + } /* and now copy the complete list of algorithms */ /* I know that the copied list is reversed, but that doesn't matter */ for( ar=a->list; ar; ar = ar->next ) { @@ -409,6 +423,9 @@ gcry_md_reset( GCRY_MD_HD a ) memset( r->context.c, 0, r->contextsize ); (*r->init)( &r->context.c ); } + if( a->ctx->macpads ) { + md_write( a, a->ctx->macpads, 64 ); /* inner pad */ + } } @@ -425,6 +442,7 @@ md_close(GCRY_MD_HD a) r2 = r->next; g10_free(r); } + g10_free(a->ctx->macpads); g10_free(a); } @@ -479,17 +497,74 @@ md_final(GCRY_MD_HD a) (*r->final)( &r->context.c ); } a->ctx->finalized = 1; + if( a->ctx->macpads ) { /* finish the hmac */ + int algo = md_get_algo( a ); + byte *p = md_read( a, algo ); + size_t dlen = md_digest_length(algo); + + GCRY_MD_HD om = md_open( algo, a->ctx->secure, 0 ); + if( !om ) + g10_fatal_error( gcry_errno(), NULL ); + md_write( om, a->ctx->macpads+64, 64 ); + md_write( om, p, dlen ); + md_final( om ); + /* replace our digest with the mac (they have the same size) */ + memcpy( p, md_read( om, algo ), dlen ); + md_close( om ); + } } + +static int +prepare_macpads( GCRY_MD_HD hd, byte *key, size_t keylen) +{ + int i; + int algo = md_get_algo( hd ); + byte *helpkey = NULL; + byte *ipad, *opad; + + if( !algo ) + return GCRYERR_INV_MD_ALGO; /* i.e. no algo enabled */ + + if( keylen > 64 ) { + helpkey = g10_malloc_secure( md_digest_length( algo ) ); + if( !helpkey ) + return GCRYERR_NO_MEM; + gcry_md_hash_buffer( algo, helpkey, key, keylen ); + key = helpkey; + keylen = md_digest_length( algo ); + assert( keylen <= 64 ); + } + + memset( hd->ctx->macpads, 0, 128 ); + ipad = hd->ctx->macpads; + opad = hd->ctx->macpads+64; + memcpy( ipad, key, keylen ); + memcpy( opad, key, keylen ); + for(i=0; i < 64; i++ ) { + ipad[i] ^= 0x36; + opad[i] ^= 0x5c; + } + g10_free( helpkey ); + return 0; +} + int gcry_md_ctl( GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen) { + int rc = 0; if( cmd == GCRYCTL_FINALIZE ) md_final( hd ); + else if( cmd == GCRYCTL_SET_KEY ) { + if( !(hd->ctx->macpads ) ) + rc = GCRYERR_CONFLICT; + else if ( !(rc = prepare_macpads( hd, buffer, buflen )) ) + gcry_md_reset( hd ); + } else - return GCRYERR_INV_OP; - return 0; + rc = GCRYERR_INV_OP; + return set_lasterr( rc ); } @@ -605,7 +680,7 @@ gcry_md_hash_buffer( int algo, char *digest, const char *buffer, size_t length) rmd160_hash_buffer( digest, buffer, length ); else { /* for the others we do not have a fast function, so * we use the normal functions to do it */ - GCRY_MD_HD h = md_open( algo, 0 ); + GCRY_MD_HD h = md_open( algo, 0, 0 ); if( !h ) BUG(); /* algo not available */ md_write( h, (byte*)buffer, length ); diff --git a/g10/ChangeLog b/g10/ChangeLog index 6cd97d675..d20c26aec 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,11 @@ +Fri Mar 24 11:25:45 CET 2000 Werner Koch + + * gpg.c (print_mds): Add arg keys as a kludge to print hmacs + (main): New option --print-hmac. + + * trustdb.c (verify_own_keys): Do not print warning about unprotected + key when in quiet mode. + Mon Mar 13 19:22:46 CET 2000 Werner Koch * build-paket.c (do_user_id): Save offset where name has been stored. diff --git a/g10/OPTIONS b/g10/OPTIONS index 96290f6cf..e8cdb9e39 100644 --- a/g10/OPTIONS +++ b/g10/OPTIONS @@ -1,5 +1,7 @@ # Some notes used by the maintainers +print-hmac +# test function to print a HMAC store # simply packs the input data into a rfc1991 packet format diff --git a/g10/gpg.c b/g10/gpg.c index 5a7042603..0c0b625bc 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -89,6 +89,7 @@ enum cmd_and_opt_values { aNull = 0, aGenRevoke, aPrimegen, aPrintMD, + aPrintHMAC, aPrintMDs, aCheckTrustDB, aUpdateTrustDB, @@ -226,6 +227,7 @@ static ARGPARSE_OPTS opts[] = { { aEnArmor, "enarmor", 256, N_("En-Armor a file or stdin") }, { aEnArmor, "enarmour", 256, "@" }, { aPrintMD, "print-md" , 256, N_("|algo [files]|print message digests")}, + { aPrintHMAC, "print-hmac" , 256, "@"}, { aPrimegen, "gen-prime" , 256, "@" }, { aGenRandom, "gen-random" , 256, "@" }, @@ -354,7 +356,7 @@ static char *build_list( const char *text, const char * (*mapf)(int), static void set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd ); static void print_hex( byte *p, size_t n ); -static void print_mds( const char *fname, int algo ); +static void print_mds( const char *fname, int algo, const char *key ); static void add_notation_data( const char *string ); static int check_policy_url( const char *s ); @@ -739,6 +741,7 @@ main( int argc, char **argv ) case aPrimegen: set_cmd( &cmd, aPrimegen); break; case aGenRandom: set_cmd( &cmd, aGenRandom); break; case aPrintMD: set_cmd( &cmd, aPrintMD); break; + case aPrintHMAC: set_cmd( &cmd, aPrintHMAC); break; case aPrintMDs: set_cmd( &cmd, aPrintMDs); break; case aListTrustDB: set_cmd( &cmd, aListTrustDB); break; case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break; @@ -1074,6 +1077,7 @@ main( int argc, char **argv ) switch( cmd ) { case aPrimegen: case aPrintMD: + case aPrintHMAC: case aPrintMDs: case aGenRandom: case aDeArmor: @@ -1387,10 +1391,34 @@ main( int argc, char **argv ) else { argc--; argv++; if( !argc ) - print_mds(NULL, algo); + print_mds(NULL, algo, NULL); else { for(; argc; argc--, argv++ ) - print_mds(*argv, algo); + print_mds(*argv, algo, NULL); + } + } + } + break; + + case aPrintHMAC: + if( argc < 2 ) + wrong_args("--print-hmac hash-algo key [files]"); + { + int all_algos = (**argv=='*' && !(*argv)[1]); + int algo = all_algos? 0 : gcry_md_map_name(*argv); + + if( !algo && !all_algos ) + log_error(_("invalid hash algorithm `%s'\n"), *argv ); + else { + const char *key; + argc--; argv++; + key = *argv; + argc--; argv++; + if( !argc ) + print_mds(NULL, algo, key ); + else { + for(; argc; argc--, argv++ ) + print_mds(*argv, algo, key ); } } } @@ -1398,10 +1426,10 @@ main( int argc, char **argv ) case aPrintMDs: /* old option */ if( !argc ) - print_mds(NULL,0); + print_mds(NULL,0,NULL); else { for(; argc; argc--, argv++ ) - print_mds(*argv,0); + print_mds(*argv,0,NULL); } break; @@ -1554,7 +1582,7 @@ print_hex( byte *p, size_t n ) } static void -print_mds( const char *fname, int algo ) +print_mds( const char *fname, int algo, const char *key ) { FILE *fp; char buf[1024]; @@ -1578,15 +1606,18 @@ print_mds( const char *fname, int algo ) return; } - md = gcry_md_open( 0, 0 ); + md = gcry_md_open( 0, key? GCRY_MD_FLAG_HMAC : 0 ); if( algo ) gcry_md_enable( md, algo ); else { + /* Fixme: this does not work with hmac */ gcry_md_enable( md, GCRY_MD_MD5 ); gcry_md_enable( md, GCRY_MD_SHA1 ); gcry_md_enable( md, GCRY_MD_RMD160 ); have_tiger = !gcry_md_enable( md, GCRY_MD_TIGER ); } + if( key ) + gcry_md_setkey( md, key, strlen(key) ); while( (n=fread( buf, 1, DIM(buf), fp )) ) gcry_md_write( md, buf, n ); diff --git a/g10/kbxblob.c b/g10/kbxblob.c index c7804870c..301671fbe 100644 --- a/g10/kbxblob.c +++ b/g10/kbxblob.c @@ -90,7 +90,7 @@ The standard KBX Blob looks like this: maybe we put a sigture here later. - b16 MD5 checksum (useful for KS syncronsiation) + b16 MD5 checksum (useful for KS syncronisation) * */ @@ -540,3 +540,61 @@ kbx_release_blob ( KBXBLOB blob ) gcry_free( blob ); } +static ulong +get32( const byte *buffer ) +{ + ulong a; + a = *buffer << 24; + a |= buffer[1] << 16; + a |= buffer[2] << 8; + a |= buffer[3]; + return a; +} + +static ulong +get16( const byte *buffer ) +{ + ulong a; + a = *buffer << 8; + a |= buffer[0]; + return a; +} + + +int +kbx_dump_blob ( FILE *fp, const byte* buffer, size_t length ) +{ + #if 0 + ulong n; + ulong keyblock_off, keyblock_len; + + if( length < 40 ) { + fprintf( fp, "blob too short\n"); + return -1; + } + n = get32( buffer ); + if( n > length ) { + fprintf( fp, "blob larger than length - output truncated\n"); + } + else + length = n; /* ignore the rest */ + fprintf( fp, "Length: %lu\n", n ); + fprintf( fp, "Type: %d\n", buffer[4] ), + fprintf( fp, "Version: %d\n", buffer[5] ), + if( buffer[4] != 2 ) { + fprintf( fp, "can't dump this blob type\n" ); + return 0; + } + + n = get16( buffer + 6 ); + fprintf( fp, "Blob-Flags: %04lX\n", n ); + keyblock_off = get32( buffer + 8 ); + keyblock_len = get32( buffer + 12 ); + fprintf( fp, "Keyblock-Offset: %lu\n", keyblock_off ); + fprintf( fp, "Keyblock-Length: %lu\n", keyblock_len ); + + #endif + +} + + diff --git a/g10/kbxfile.c b/g10/kbxfile.c index 215259ee4..33bac3a44 100644 --- a/g10/kbxfile.c +++ b/g10/kbxfile.c @@ -20,7 +20,7 @@ /**************** * We will change the whole system to use only KBX. This file here - * will implements the methods needed to operate on plain KBXfiles. + * will implement the methods needed to operate on plain KBXfiles. * Most stuff from getkey and ringedit will be replaced by stuff here. * To make things even mor easier we will only allow one updateable kbxfile * and optionally some read-only files. diff --git a/mpi/ChangeLog b/mpi/ChangeLog index 9465aa513..d9e7faa30 100644 --- a/mpi/ChangeLog +++ b/mpi/ChangeLog @@ -1,3 +1,7 @@ +2000-03-21 16:17:30 Werner Koch (wk@habibti.openit.de) + + * config.links: Add support for FreeBSD 5. + Mon Jan 24 22:24:38 CET 2000 Werner Koch * mpicoder.c (gcry_mpi_aprint): Now really returns the length. diff --git a/mpi/config.links b/mpi/config.links index da44a9122..40125e47b 100644 --- a/mpi/config.links +++ b/mpi/config.links @@ -12,12 +12,12 @@ echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h if test "$try_asm_modules" = "yes" ; then case "${target}" in - i[34]86*-*-freebsd*-elf | i[34]86*-*-freebsd[34]* | i[34]86*-*-freebsdelf*) + i[34]86*-*-freebsd*-elf | i[34]86*-*-freebsd[3-9]* | i[34]86*-*-freebsdelf*) echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h path="i386" ;; - i[56]86*-*-freebsd*-elf | i[56]86*-*-freebsd[34]* | i[56]86*-*-freebsdelf*) + i[56]86*-*-freebsd*-elf | i[56]86*-*-freebsd[3-9]* | i[56]86*-*-freebsdelf*) echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h path="i586 i386"