See ChangeLog: Fri Mar 24 11:25:45 CET 2000 Werner Koch
authorWerner Koch <wk@gnupg.org>
Fri, 24 Mar 2000 10:19:50 +0000 (10:19 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 24 Mar 2000 10:19:50 +0000 (10:19 +0000)
cipher/ChangeLog
cipher/md.c
g10/ChangeLog
g10/OPTIONS
g10/gpg.c
g10/kbxblob.c
g10/kbxfile.c
mpi/ChangeLog
mpi/config.links

index a811897..49595a9 100644 (file)
@@ -1,3 +1,13 @@
+Fri Mar 24 11:25:45 CET 2000  Werner Koch  <wk@openit.de>
+
+       * 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  <wk@openit.de>
 
        * md.c (gcry_md_hash_buffer): Add support for the other algorithms.
index 680558d..9879520 100644 (file)
@@ -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 );
index 6cd97d6..d20c26a 100644 (file)
@@ -1,3 +1,11 @@
+Fri Mar 24 11:25:45 CET 2000  Werner Koch  <wk@openit.de>
+
+       * 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  <wk@openit.de>
 
        * build-paket.c (do_user_id): Save offset where name has been stored.
index 96290f6..e8cdb9e 100644 (file)
@@ -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
index 5a70426..0c0b625 100644 (file)
--- 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 );
index c780487..301671f 100644 (file)
@@ -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
+
+}
+
+
index 215259e..33bac3a 100644 (file)
@@ -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.
index 9465aa5..d9e7faa 100644 (file)
@@ -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  <wk@gnupg.de>
 
        * mpicoder.c (gcry_mpi_aprint): Now really returns the length.
index da44a91..40125e4 100644 (file)
@@ -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"