changeset 6415:8fdeec35e290

* gc-gnulib.c: Support ARCTWO in CBC mode.
author Simon Josefsson <simon@josefsson.org>
date Fri, 21 Oct 2005 13:39:43 +0000
parents 46d47c8fe734
children 3249ff532a18
files lib/ChangeLog lib/gc-gnulib.c
diffstat 2 files changed, 60 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,7 @@
+2005-10-21  Simon Josefsson  <jas@extundo.com>
+
+	* gc-gnulib.c: Support ARCTWO in CBC mode.
+
 2005-10-21  Simon Josefsson  <jas@extundo.com>
 
 	* hmac-md5.c (hmac_md5): Add comments, suggested by Bruno Haible
--- a/lib/gc-gnulib.c
+++ b/lib/gc-gnulib.c
@@ -166,6 +166,7 @@
   Gc_cipher_mode mode;
 #ifdef GC_USE_ARCTWO
   arctwo_context arctwoContext;
+  char arctwoIV[ARCTWO_BLOCK_SIZE];
 #endif
 #ifdef GC_USE_ARCFOUR
   arcfour_context arcfourContext;
@@ -199,6 +200,7 @@
       switch (mode)
 	{
 	case GC_ECB:
+	case GC_CBC:
 	  break;
 
 	default:
@@ -333,6 +335,14 @@
 
   switch (ctx->alg)
     {
+#ifdef GC_USE_ARCTWO
+    case GC_ARCTWO40:
+      if (ivlen != ARCTWO_BLOCK_SIZE)
+	return GC_INVALID_CIPHER;
+      memcpy (ctx->arctwoIV, iv, ivlen);
+      break;
+#endif
+
 #ifdef GC_USE_RIJNDAEL
     case GC_AES128:
     case GC_AES192:
@@ -381,7 +391,28 @@
     {
 #ifdef GC_USE_ARCTWO
     case GC_ARCTWO40:
-      arctwo_encrypt (&ctx->arctwoContext, data, data, len);
+      switch (ctx->mode)
+	{
+	case GC_ECB:
+	  arctwo_encrypt (&ctx->arctwoContext, data, data, len);
+	  break;
+
+	case GC_CBC:
+	  for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
+		 data += ARCTWO_BLOCK_SIZE)
+	    {
+	      size_t i;
+	      for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
+		data[i] ^= ctx->arctwoIV[i];
+	      arctwo_encrypt (&ctx->arctwoContext, data, data,
+			      ARCTWO_BLOCK_SIZE);
+	      memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE);
+	    }
+	    break;
+
+	default:
+	  return GC_INVALID_CIPHER;
+	}
       break;
 #endif
 
@@ -430,7 +461,30 @@
     {
 #ifdef GC_USE_ARCTWO
     case GC_ARCTWO40:
-      arctwo_decrypt (&ctx->arctwoContext, data, data, len);
+      switch (ctx->mode)
+	{
+	case GC_ECB:
+	  arctwo_decrypt (&ctx->arctwoContext, data, data, len);
+	  break;
+
+	case GC_CBC:
+	  for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
+		 data += ARCTWO_BLOCK_SIZE)
+	    {
+	      char tmpIV[ARCTWO_BLOCK_SIZE];
+	      size_t i;
+	      memcpy (tmpIV, data, ARCTWO_BLOCK_SIZE);
+	      arctwo_decrypt (&ctx->arctwoContext, data, data,
+			      ARCTWO_BLOCK_SIZE);
+	      for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
+		data[i] ^= ctx->arctwoIV[i];
+	      memcpy (ctx->arctwoIV, tmpIV, ARCTWO_BLOCK_SIZE);
+	    }
+	  break;
+
+	default:
+	  return GC_INVALID_CIPHER;
+	}
       break;
 #endif