2003-03-02 Moritz Schulte <moritz@g10code.com>
authorMoritz Schulte <mo@g10code.com>
Tue, 4 Mar 2003 18:07:42 +0000 (18:07 +0000)
committerMoritz Schulte <mo@g10code.com>
Tue, 4 Mar 2003 18:07:42 +0000 (18:07 +0000)
* cipher.c (struct gcry_cipher_handle): New member: algo_index.
(gcry_cipher_open): Allocate memory for two cipher contexts.
Initialize algo_index.
(cipher_setkey): Duplicate context into reserved memory.
(cipher_reset): New function, which resets the context and clear
the IV.
(gcry_cipher_ctl): Call cipher_reset.

cipher/ChangeLog
cipher/cipher.c

index 95149bb..ad5cfb5 100644 (file)
@@ -1,3 +1,18 @@
+2003-03-03  Moritz Schulte  <moritz@g10code.com>
+
+       * md.c (gcry_md_ctl): Rewritten to use same style like the other
+       functions dispatchers.
+
+2003-03-02  Moritz Schulte  <moritz@g10code.com>
+
+       * cipher.c (struct gcry_cipher_handle): New member: algo_index.
+       (gcry_cipher_open): Allocate memory for two cipher contexts.
+       Initialize algo_index.
+       (cipher_setkey): Duplicate context into reserved memory.
+       (cipher_reset): New function, which resets the context and clear
+       the IV.
+       (gcry_cipher_ctl): Call cipher_reset.
+
 2003-02-23  Moritz Schulte  <moritz@g10code.com>
 
        * cipher.c: Remove (bogus) `digitp' macro definition.
index 4a1b515..586bf30 100644 (file)
@@ -87,6 +87,7 @@ struct gcry_cipher_handle {
     int  algo;
     int  mode;
     unsigned int flags;
+    int algo_index;
     size_t blocksize;
     byte iv[MAX_BLOCKSIZE];    /* (this should be ulong aligned) */
     byte lastiv[MAX_BLOCKSIZE];
@@ -558,11 +559,14 @@ gcry_cipher_open( int algo, int mode, unsigned int flags )
 
     /* ? perform selftest here and mark this with a flag in cipher_table ? */
 
-    h = secure ? gcry_calloc_secure( 1, sizeof *h
-                                      + cipher_table[idx].contextsize
-                                      - sizeof(PROPERLY_ALIGNED_TYPE) )
-              : gcry_calloc( 1, sizeof *h + cipher_table[idx].contextsize
-                                       - sizeof(PROPERLY_ALIGNED_TYPE)  );
+    h = secure ? gcry_calloc_secure( 1,
+                                    sizeof *h
+                                    + 2 * cipher_table[idx].contextsize
+                                    - sizeof (PROPERLY_ALIGNED_TYPE) )
+              : gcry_calloc( 1,
+                             sizeof *h
+                             + 2 * cipher_table[idx].contextsize
+                             - sizeof (PROPERLY_ALIGNED_TYPE) );
     if( !h ) {
        set_lasterr( GCRYERR_NO_MEM );
        return NULL;
@@ -571,6 +575,7 @@ gcry_cipher_open( int algo, int mode, unsigned int flags )
     h->algo = algo;
     h->mode = mode;
     h->flags = flags;
+    h->algo_index = idx;
     h->blocksize = cipher_table[idx].blocksize;
     h->setkey  = cipher_table[idx].setkey;
     h->encrypt = cipher_table[idx].encrypt;
@@ -598,7 +603,15 @@ gcry_cipher_close( GCRY_CIPHER_HD h )
 static int
 cipher_setkey( GCRY_CIPHER_HD c, byte *key, unsigned keylen )
 {
-    return (*c->setkey)( &c->context.c, key, keylen );
+    int ret;
+
+    ret = (*c->setkey)( &c->context.c, key, keylen );
+    if (! ret)
+      memcpy ((void *) ((char *) &c->context.c
+                       + cipher_table[c->algo_index].contextsize),
+             (void *) &c->context.c,
+             cipher_table[c->algo_index].contextsize);
+    return ret;
 }
 
 
@@ -618,6 +631,17 @@ cipher_setiv( GCRY_CIPHER_HD c, const byte *iv, unsigned ivlen )
 }
 
 
+static void
+cipher_reset (GCRY_CIPHER_HD c)
+{
+  memcpy ((void *) &c->context.c,
+         (void *) ((char *) &c->context.c
+                   + cipher_table[c->algo_index].contextsize),
+         cipher_table[c->algo_index].contextsize);
+  memset (c->iv, 0, c->blocksize);
+  memset (c->lastiv, 0, c->blocksize);
+}
+
 
 static void
 do_ecb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblocks )
@@ -1042,6 +1066,9 @@ gcry_cipher_ctl( GCRY_CIPHER_HD h, int cmd, void *buffer, size_t buflen)
     case GCRYCTL_SET_IV:
       cipher_setiv( h, buffer, buflen );
       break;
+    case GCRYCTL_RESET:
+      cipher_reset (h);
+      break;
     case GCRYCTL_CFB_SYNC:
       cipher_sync( h );
       break;