Changed keyring handling - saving still does not work.
authorWerner Koch <wk@gnupg.org>
Tue, 10 Oct 2000 12:58:42 +0000 (12:58 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 10 Oct 2000 12:58:42 +0000 (12:58 +0000)
Added new cipher mode and updated cipher test program.

cipher/ChangeLog
cipher/Makefile.am
cipher/blowfish.h
cipher/cipher.c
src/ChangeLog
src/gcrypt.h
src/global.c

index 1d793ec..38045bb 100644 (file)
@@ -1,3 +1,10 @@
+2000-10-09  Werner Koch  <wk@gnupg.org>
+
+       * arcfour.c, arcfour.h: New.
+       * cipher.c (cipher_encrypt, cipher_decrypt): Add stream mode.
+       (setup_cipher_table): Add Arcfour.
+       (gcry_cipher_open): Kludge to allow stream mode.
+
 Wed Oct  4 13:16:18 CEST 2000  Werner Koch  <wk@openit.de>
 
         * sha1.c (transform): Use rol() macro.  Actually this is not needed
index 6feea15..0a9b10b 100644 (file)
@@ -42,6 +42,7 @@ libcipher_la_SOURCES = cipher.c  \
                 blowfish.h     \
                 cast5.c        \
                 cast5.h        \
+                arcfour.c arcfour.h \
                 elgamal.c      \
                 elgamal.h      \
                 primegen.c     \
index 7c34bab..bed034c 100644 (file)
@@ -41,4 +41,14 @@ twofish_get_info( int algo, size_t *keylen,
                   void (**decryptf)( void *c, byte *outbuf, byte *inbuf )
                 );
 
+/* this is just a kludge for the time we have not yet chnaged the cipher
+ * stuff to the scheme we use for random and digests */
+const char *
+rijndael_get_info( int algo, size_t *keylen,
+                  size_t *blocksize, size_t *contextsize,
+                  int  (**setkeyf)( void *c, byte *key, unsigned keylen ),
+                  void (**encryptf)( void *c, byte *outbuf, byte *inbuf ),
+                  void (**decryptf)( void *c, byte *outbuf, byte *inbuf )
+                );
+
 #endif /*G10_BLOWFISH_H*/
index d36db66..ad36bfb 100644 (file)
 #include "des.h"
 #include "blowfish.h"
 #include "cast5.h"
+#include "arcfour.h"
 #include "dynload.h"
 
 #define MAX_BLOCKSIZE 16
-#define TABLE_SIZE 12
+#define TABLE_SIZE 14
 #define CTX_MAGIC_NORMAL 0x24091964
 #define CTX_MAGIC_SECURE 0x46919042
 
@@ -46,6 +47,8 @@ struct cipher_table_s {
     int  (*setkey)( void *c, byte *key, unsigned keylen );
     void (*encrypt)( void *c, byte *outbuf, byte *inbuf );
     void (*decrypt)( void *c, byte *outbuf, byte *inbuf );
+    void (*stencrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n );
+    void (*stdecrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n );
 };
 
 static struct cipher_table_s cipher_table[TABLE_SIZE];
@@ -63,6 +66,8 @@ struct gcry_cipher_handle {
     int  (*setkey)( void *c, byte *key, unsigned keylen );
     void (*encrypt)( void *c, byte *outbuf, byte *inbuf );
     void (*decrypt)( void *c, byte *outbuf, byte *inbuf );
+    void (*stencrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n );
+    void (*stdecrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n );
     PROPERLY_ALIGNED_TYPE context;
 };
 
@@ -73,6 +78,12 @@ static void
 dummy_encrypt_block( void *c, byte *outbuf, byte *inbuf ) { BUG(); }
 static void
 dummy_decrypt_block( void *c, byte *outbuf, byte *inbuf ) { BUG(); }
+static void
+dummy_encrypt_stream( void *c, byte *outbuf, byte *inbuf, unsigned int n )
+{ BUG(); }
+static void
+dummy_decrypt_stream( void *c, byte *outbuf, byte *inbuf, unsigned int n )
+{ BUG(); }
 
 
 
@@ -84,6 +95,13 @@ setup_cipher_table(void)
 {
     int i;
 
+    for (i=0; i < TABLE_SIZE; i++ ) {
+        cipher_table[i].encrypt = dummy_encrypt_block;
+        cipher_table[i].decrypt = dummy_decrypt_block;
+        cipher_table[i].stencrypt = dummy_encrypt_stream;
+        cipher_table[i].stdecrypt = dummy_decrypt_stream;
+    }
+    
     i = 0;
     cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL;
     cipher_table[i].name = rijndael_get_info( cipher_table[i].algo,
@@ -162,14 +180,23 @@ setup_cipher_table(void)
     if( !cipher_table[i].name )
        BUG();
     i++;
+    cipher_table[i].algo = GCRY_CIPHER_ARCFOUR;
+    cipher_table[i].name = arcfour_get_info( cipher_table[i].algo,
+                                        &cipher_table[i].keylen,
+                                        &cipher_table[i].blocksize,
+                                        &cipher_table[i].contextsize,
+                                        &cipher_table[i].setkey,
+                                        &cipher_table[i].stencrypt,
+                                        &cipher_table[i].stdecrypt   );
+    if( !cipher_table[i].name )
+       BUG();
+    i++;
     cipher_table[i].algo = CIPHER_ALGO_DUMMY;
     cipher_table[i].name = "DUMMY";
     cipher_table[i].blocksize = 8;
     cipher_table[i].keylen = 128;
     cipher_table[i].contextsize = 0;
     cipher_table[i].setkey = dummy_setkey;
-    cipher_table[i].encrypt = dummy_encrypt_block;
-    cipher_table[i].decrypt = dummy_decrypt_block;
     i++;
 
     for( ; i < TABLE_SIZE; i++ )
@@ -411,12 +438,24 @@ gcry_cipher_open( int algo, int mode, unsigned int flags )
       case GCRY_CIPHER_MODE_ECB:
       case GCRY_CIPHER_MODE_CBC:
       case GCRY_CIPHER_MODE_CFB:
+        if ( cipher_table[idx].encrypt == dummy_encrypt_block
+             || cipher_table[idx].decrypt == dummy_decrypt_block ) {
+            set_lasterr( GCRYERR_INV_CIPHER_MODE );
+            return NULL;
+        }
+        break;
+      case GCRY_CIPHER_MODE_STREAM:
+        if ( cipher_table[idx].stencrypt == dummy_encrypt_stream
+             || cipher_table[idx].stdecrypt == dummy_decrypt_stream ) {
+            set_lasterr( GCRYERR_INV_CIPHER_MODE );
+            return NULL;
+        }
        break;
       case GCRY_CIPHER_MODE_NONE:
        /* FIXME: issue a warning when this mode is used */
        break;
       default:
-       set_lasterr( GCRYERR_INV_CIPHER_ALGO );
+       set_lasterr( GCRYERR_INV_CIPHER_MODE );
        return NULL;
     }
 
@@ -426,7 +465,7 @@ gcry_cipher_open( int algo, int mode, unsigned int flags )
                                       + cipher_table[idx].contextsize
                                       - sizeof(PROPERLY_ALIGNED_TYPE) )
               : g10_calloc( 1, sizeof *h + cipher_table[idx].contextsize
-                                          - sizeof(PROPERLY_ALIGNED_TYPE)  );
+                                       - sizeof(PROPERLY_ALIGNED_TYPE)  );
     if( !h ) {
        set_lasterr( GCRYERR_NO_MEM );
        return NULL;
@@ -439,6 +478,8 @@ gcry_cipher_open( int algo, int mode, unsigned int flags )
     h->setkey  = cipher_table[idx].setkey;
     h->encrypt = cipher_table[idx].encrypt;
     h->decrypt = cipher_table[idx].decrypt;
+    h->stencrypt = cipher_table[idx].stencrypt;
+    h->stdecrypt = cipher_table[idx].stdecrypt;
 
     return h;
 }
@@ -550,7 +591,8 @@ do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblo
 
 
 static void
-do_cfb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbytes )
+do_cfb_encrypt( GCRY_CIPHER_HD c,
+                byte *outbuf, const byte *inbuf, unsigned nbytes )
 {
     byte *ivp;
     size_t blocksize = c->blocksize;
@@ -594,7 +636,8 @@ do_cfb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbyt
 }
 
 static void
-do_cfb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbytes )
+do_cfb_decrypt( GCRY_CIPHER_HD c,
+                byte *outbuf, const byte *inbuf, unsigned nbytes )
 {
     byte *ivp;
     ulong temp;
@@ -651,14 +694,16 @@ do_cfb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbyt
 }
 
 
+
+
 /****************
  * Encrypt INBUF to OUTBUF with the mode selected at open.
  * inbuf and outbuf may overlap or be the same.
- * Depending on the mode some some contraints apply to NBYTES.
+ * Depending on the mode some contraints apply to NBYTES.
  */
 static void
 cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf,
-                                 const byte *inbuf, unsigned nbytes )
+                                 const byte *inbuf, unsigned int nbytes )
 {
     switch( c->mode ) {
       case GCRY_CIPHER_MODE_ECB:
@@ -672,6 +717,10 @@ cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf,
       case GCRY_CIPHER_MODE_CFB:
        do_cfb_encrypt(c, outbuf, inbuf, nbytes );
        break;
+      case GCRY_CIPHER_MODE_STREAM:
+        (*c->stencrypt)( &c->context.c,
+                         outbuf, (byte*)/*arggg*/inbuf, nbytes );
+        break;
       case GCRY_CIPHER_MODE_NONE:
        if( inbuf != outbuf )
            memmove( outbuf, inbuf, nbytes );
@@ -729,6 +778,10 @@ cipher_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf,
       case GCRY_CIPHER_MODE_CFB:
        do_cfb_decrypt(c, outbuf, inbuf, nbytes );
        break;
+      case GCRY_CIPHER_MODE_STREAM:
+        (*c->stdecrypt)( &c->context.c,
+                         outbuf, (byte*)/*arggg*/inbuf, nbytes );
+        break;
       case GCRY_CIPHER_MODE_NONE:
        if( inbuf != outbuf )
            memmove( outbuf, inbuf, nbytes );
index fd38464..6d94721 100644 (file)
@@ -1,3 +1,9 @@
+2000-10-09  Werner Koch  <wk@gnupg.org>
+
+       * gcrypt.h: New cipher mode, new algo Arcfour and new error code
+       GCRYERR_INV_CIPHER_MODE.
+       * global.c (gcry_strerror): New errorcode.
+
 Wed Oct  4 13:16:18 CEST 2000  Werner Koch  <wk@openit.de>
 
         * gcrypt.h (gcry_md_setkey): Replaced macro by function prototype.
index 5593b59..cf7eb7c 100644 (file)
@@ -90,6 +90,7 @@ enum {
     GCRYERR_NO_OBJ = 68,     /* Missing item in an object */
     GCRYERR_NOT_IMPL = 69,   /* Not implemented */
     GCRYERR_CONFLICT = 70,
+    GCRYERR_INV_CIPHER_MODE = 71, 
 };
 
 const char *gcry_check_version( const char *req_version );
@@ -263,6 +264,8 @@ enum gcry_cipher_algos {
     GCRY_CIPHER_RIJNDAEL192 = 8,
     GCRY_CIPHER_RIJNDAEL256 = 9,
     GCRY_CIPHER_TWOFISH     = 10,
+    /* other cipher numbers are above 300 for OpenPGP reasons. */
+    GCRY_CIPHER_ARCFOUR     = 301
 };
 
 enum gcry_cipher_modes {
@@ -270,6 +273,7 @@ enum gcry_cipher_modes {
     GCRY_CIPHER_MODE_ECB    = 1,
     GCRY_CIPHER_MODE_CFB    = 2,
     GCRY_CIPHER_MODE_CBC    = 3,
+    GCRY_CIPHER_MODE_STREAM = 4 /* native stream mode of some the algorithms */
 };
 
 enum gcry_cipher_flags {
index 63b46a7..5dd69cf 100644 (file)
@@ -226,6 +226,7 @@ gcry_strerror( int ec )
       X(INV_MD_ALGO,   N_("invalid hash algorithm"))
       X(WRONG_PK_ALGO, N_("unusable public key algorithm"))
       X(CONFLICT,      N_("conflict"))
+      X(INV_CIPHER_MODE,N_("invalid cipher mode"))
       default:
        sprintf( buf, "ec=%d", ec );
        s = buf;