diff --git a/des-compat.c b/des-compat.c
index f210361067db39bf2f460f54ab9c9e35c49cbd98..e930b1af8d313eaac13a2dbc46d5c5927a3f46f2 100644
--- a/des-compat.c
+++ b/des-compat.c
@@ -25,27 +25,41 @@
 
 #include "des-compat.h"
 
+#undef des_set_key
+
 #include "cbc.h"
 
-void des_ecb3_encrypt(const uint8_t *src, uint8_t *dst,
-		      struct des_ctx *k1, struct des_ctx *k2,
-		      struct des_ctx *k3, int enc)
+struct des_compat_des3 { struct des_ctx *keys[3]; }; 
+
+typedef void (*cbc_crypt_func)(void *, uint32_t, uint8_t *, const uint8_t *);
+
+static void
+des_compat_des3_encrypt(struct des_compat_des3 *ctx,
+			uint32_t length, uint8_t *dst, const uint8_t *src)
+{
+  des_encrypt(ctx->keys[0], length, dst, src);
+  des_decrypt(ctx->keys[1], length, dst, dst);
+  des_encrypt(ctx->keys[2], length, dst, dst);
+}
+
+static void
+des_compat_des3_decrypt(struct des_compat_des3 *ctx,
+			uint32_t length, uint8_t *dst, const uint8_t *src)
 {
-  switch(enc)
-    {
-    case DES_ENCRYPT:
-      des_encrypt(k1, dst, src, DES_BLOCK_SIZE);
-      des_decrypt(k2, dst, dst, DES_BLOCK_SIZE);
-      des_encrypt(k3, dst, dst, DES_BLOCK_SIZE);
-      break;
-    case DES_DECRYPT:
-      des_decrypt(k3, dst, src, DES_BLOCK_SIZE);
-      des_encrypt(k2, dst, dst, DES_BLOCK_SIZE);
-      des_decrypt(k1, dst, dst, DES_BLOCK_SIZE);
-      break;
-    default:
-      abort();
-    }
+  des_decrypt(ctx->keys[0], length, dst, src);
+  des_encrypt(ctx->keys[1], length, dst, dst);
+  des_decrypt(ctx->keys[2], length, dst, dst);
+}
+
+void
+des_ecb3_encrypt(const uint8_t *src, uint8_t *dst,
+		 struct des_ctx *k1, struct des_ctx *k2,
+		 struct des_ctx *k3, int enc)
+{
+  struct des_compat_des3 keys = { { k1, k2, k3 } };
+
+  ((enc == DES_ENCRYPT) ? des_compat_des3_encrypt : des_compat_des3_decrypt)
+    (&keys, DES_BLOCK_SIZE, dst, src);
 }
 
 uint32_t
@@ -58,39 +72,64 @@ des_cbc_encrypt(const uint8_t *src, uint8_t *dst, long length,
 		struct des_ctx *ctx, uint8_t *iv,
 		int enc)
 {
-  cbc_encrypt(ctx, (enc == DES_ENCRYPT) ? des_encrypt : des_decrypt,
+  cbc_encrypt(ctx,
+	      (cbc_crypt_func) ((enc == DES_ENCRYPT) ? des_encrypt : des_decrypt),
               DES_BLOCK_SIZE, iv,
               length, dst, src);
 }
 
 void
 des_3cbc_encrypt(const uint8_t *src, uint8_t *dst, long length,
-		 struct des_ctx * k1,struct des_ctx *k2, struct des_ctx *k3,
+		 struct des_ctx * k1,struct des_ctx *k2,
 		 /* What mode is this, two iv:s? */
 		 uint8_t *iv1, uint8_t *iv2,
 		 int enc);
 
 void
 des_ecb_encrypt(const uint8_t *src, uint8_t *dst, long length,
-		struct des_ctx *ctx, uint8_t *iv,
+		struct des_ctx *ctx,
 		int enc)
 {
-  )(enc == DES_ENCRYPT) ? des_encrypt : des_decrypt)(
+  ((enc == DES_ENCRYPT) ? des_encrypt : des_decrypt)(ctx, length, dst, src);
 }
+
 void
 des_ede3_cbc_encrypt(const uint8_t *src, uint8_t *dst, long length,
-		     struct des_ctx * k1,struct des_ctx *k2, struct des_ctx *k3,
+		     struct des_ctx * k1, struct des_ctx *k2, struct des_ctx *k3,
 		     uint8_t *iv,
-		     int enc);
+		     int enc)
+{
+  struct des_compat_des3 keys = { { k1, k2, k3 } };
+
+  if (enc == DES_ENCRYPT)
+    cbc_encrypt(&keys, (cbc_crypt_func) des_compat_des3_encrypt,
+		DES_BLOCK_SIZE, iv,
+		length, dst, src);
+  else
+    cbc_decrypt(&keys, (cbc_crypt_func) des_compat_des3_decrypt,
+		DES_BLOCK_SIZE, iv,
+		length, dst, src);
+}
 
 int
-des_set_odd_parity(uint8_t *key);
+des_set_odd_parity(uint8_t *key)
+{
+  des_fix_parity(DES_KEY_SIZE, key, key);
+}
 
 int
-des_set_key(const uint8_t *key, struct des_ctx *ctx);
+des_compat_set_key(const uint8_t *key, struct des_ctx *ctx)
+{
+  des_set_key(ctx, key);
+}
 
 int
 des_key_sched(const uint8_t *key, struct des_ctx *ctx);
 
 int
-des_is_weak_key(const uint8_t key);
+des_is_weak_key(const uint8_t *key)
+{
+  struct des_ctx ctx;
+
+  return !des_set_key(&ctx, key);
+}