patchlevel 2
[gnupg.git] / g10 / seskey.c
index d816972..2698c73 100644 (file)
@@ -1,4 +1,4 @@
-/* seskey.c -  make sesssion keys
+/* seskey.c -  make sesssion keys etc.
  *     Copyright (c) 1997 by Werner Koch (dd9jn)
  *
  * This file is part of G10.
@@ -26,6 +26,7 @@
 #include "util.h"
 #include "cipher.h"
 #include "mpi.h"
+#include "main.h"
 
 
 
@@ -40,6 +41,10 @@ make_session_key( DEK *dek )
        dek->keylen = 20;
        randomize_buffer( dek->key, dek->keylen, 1 );
        break;
+      case CIPHER_ALGO_BLOWFISH128:
+       dek->keylen = 16;
+       randomize_buffer( dek->key, dek->keylen, 1 );
+       break;
 
       default: log_bug("invalid algo %d in make_session_key()\n");
     }
@@ -48,7 +53,7 @@ make_session_key( DEK *dek )
 
 /****************
  * Encode the session key. NBITS is the number of bits which should be used
- * for packing teh session key.
+ * for packing the session key.
  * returns: A mpi with the session key (caller must free)
  */
 MPI
@@ -73,7 +78,7 @@ encode_session_key( DEK *dek, unsigned nbits )
      *    0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
      *
      * RND are non-zero random bytes.
-     * A   is the cipher algorithm ( 42 for Blowfish )
+     * A   is the cipher algorithm
      * DEK is the encryption key (session key) length k depends on the
      *    cipher algorithm (20 is used with blowfish).
      * CSUM is the 16 bit checksum over the DEK
@@ -99,3 +104,138 @@ encode_session_key( DEK *dek, unsigned nbits )
     return frame;
 }
 
+/****************
+ * Encode a ripemd160 message digest of LEN bytes into NBITS.
+ * returns: A mpi with the session key (caller must free)
+ *  RMD160 Object ID is 1.3.36.3.2.1
+ */
+MPI
+encode_rmd160_value( byte *md, unsigned len, unsigned nbits )
+{
+    static byte asn[15] =
+         { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
+           0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
+    int nframe = (nbits+7) / 8;
+    byte *p;
+    MPI frame;
+    int i,n,c;
+
+    if( (nbits % BITS_PER_MPI_LIMB) || nframe < 42 || len != 20 )
+       log_bug("can't encode a %d bit MD into a %d bits frame\n",len*8, nbits);
+
+    /* We encode the MD in this way:
+     *
+     *    0  A PAD(n bytes)   0  ASN(15 bytes)  MD(20 bytes)
+     *
+     * PAD consists of FF bytes.
+     */
+    frame = mpi_alloc_secure( nframe / BYTES_PER_MPI_LIMB );
+    n = 0;
+    for(i=20-1; i >= 0; i--, n++ )
+       mpi_putbyte(frame, n, md[i] );
+    for( i=15-1; i >= 0; i--, n++ )
+       mpi_putbyte(frame, n, asn[i] );
+    mpi_putbyte(frame, n++, 0 );
+    while( n < nframe-2 )
+       mpi_putbyte(frame, n++, 0xff );
+    mpi_putbyte(frame, n++, DIGEST_ALGO_RMD160 );
+    mpi_putbyte(frame, n++, 0 );
+    assert( n == nframe );
+    return frame;
+}
+
+/****************
+ * Encode a sha-1 message digest of LEN bytes into NBITS.
+ * returns: A mpi with the session key (caller must free)
+ *  SHA-1 Objet ID is 1.3.14.3.2.26
+ */
+MPI
+encode_sha1_value( byte *md, unsigned len, unsigned nbits )
+{
+    static byte asn[15] =
+         { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
+           0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
+    int nframe = (nbits+7) / 8;
+    byte *p;
+    MPI frame;
+    int i,n,c;
+
+    if( (nbits % BITS_PER_MPI_LIMB) || nframe < 42 || len != 20 )
+       log_bug("can't encode a %d bit MD into a %d bits frame\n",len*8, nbits);
+
+    /* We encode the MD in this way:
+     *
+     *    0  A PAD(n bytes)   0  ASN(15 bytes)  MD(20 bytes)
+     *
+     * PAD consists of FF bytes.
+     */
+    frame = mpi_alloc_secure( nframe / BYTES_PER_MPI_LIMB );
+    n = 0;
+    for(i=20-1; i >= 0; i--, n++ )
+       mpi_putbyte(frame, n, md[i] );
+    for( i=15-1; i >= 0; i--, n++ )
+       mpi_putbyte(frame, n, asn[i] );
+    mpi_putbyte(frame, n++, 0 );
+    while( n < nframe-2 )
+       mpi_putbyte(frame, n++, 0xff );
+    mpi_putbyte(frame, n++, DIGEST_ALGO_RMD160 );
+    mpi_putbyte(frame, n++, 0 );
+    assert( n == nframe );
+    return frame;
+}
+
+
+/****************
+ * Encode a md5 message digest of LEN bytes into NBITS.
+ * returns: A mpi with the session key (caller must free)
+ *  MD5 Object ID is 1.2.840.113549.2.5
+ */
+MPI
+encode_md5_value( byte *md, unsigned len, unsigned nbits )
+{
+    static byte asn[18] =
+         { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
+           0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
+    int nframe = (nbits+7) / 8;
+    byte *p;
+    MPI frame;
+    int i,n,c;
+
+    if( (nbits % BITS_PER_MPI_LIMB) || nframe < 38 || len != 16 )
+       log_bug("can't encode a %d bit MD into a %d bits frame\n",len*8, nbits);
+
+    /* We encode the MD in this way:
+     *
+     *    0  A PAD(n bytes)   0  ASN(18 bytes)  MD(16 bytes)
+     *
+     * PAD consists of FF bytes.
+     */
+    frame = mpi_alloc_secure( nframe / BYTES_PER_MPI_LIMB );
+    n = 0;
+    for(i=16-1; i >= 0; i--, n++ )
+       mpi_putbyte(frame, n, md[i] );
+    for( i=18-1; i >= 0; i--, n++ )
+       mpi_putbyte(frame, n, asn[i] );
+    mpi_putbyte(frame, n++, 0 );
+    while( n < nframe-2 )
+       mpi_putbyte(frame, n++, 0xff );
+    mpi_putbyte(frame, n++, DIGEST_ALGO_MD5 );
+    mpi_putbyte(frame, n++, 0 );
+    assert( n == nframe );
+    return frame;
+}
+
+MPI
+encode_md_value( MD_HANDLE *md, unsigned nbits )
+{
+    byte *p = md_final( md );
+    if( md->algo == DIGEST_ALGO_MD5 )
+       return encode_md5_value( p, 16, nbits );
+    else if( md->algo == DIGEST_ALGO_RMD160 )
+       return encode_rmd160_value( p, 20, nbits );
+    else if( md->algo == DIGEST_ALGO_SHA1 )
+       return encode_sha1_value( p, 20, nbits );
+    else
+       log_bug(NULL);
+}
+