diff --git a/include/serpent.h b/include/serpent.h
index 0cf482a1543d2a5f781d65fd2307e41e7e8c13d2..94d98ed5b66a4594803d8f6a5af0202fd810d0f3 100644
--- a/include/serpent.h
+++ b/include/serpent.h
@@ -21,13 +21,18 @@
    to using key lengths less than 256 bits. */
 #define SERPENT_KEYSIZE 32
 
+/* Allow keys of size 128 <= bits <= 256 */
+
+#define SERPENT_MIN_KEYSIZE 16
+#define SERPENT_MAX_KEYSIZE 32
+
 typedef struct {
   UINT32 keys[33][4];		/* key schedule */
 } SERPENT_context;
 
 /* This performs Serpent's key scheduling algorithm. */
 void
-serpent_setup(SERPENT_context *ctx, const UINT8 *key);
+serpent_setup(SERPENT_context *ctx, UINT32 key_size, const UINT8 *key);
 
 /*
  * serpent_encrypt()
diff --git a/serpent.c b/serpent.c
index 20112a928bcf760e9d731a7be24af535ff036273..32161aad73b7a69588efa7b492afac4693bc81bd 100644
--- a/serpent.c
+++ b/serpent.c
@@ -36,16 +36,37 @@
 #include "serpent.h"
 #include "serpentsboxes.h"
 
+#include <assert.h>
+
 /*  The functions  */
 void
-serpent_setup(SERPENT_context *ctx, const UINT8 *key)
+serpent_setup(SERPENT_context *ctx, UINT32 key_size, const UINT8 *key)
 {
   UINT32 i, j;
   UINT32 w[132], k[132];
   UINT32 kd[8];
   const UINT8 *kptr;
 
-  kptr = key;
+  assert(key_size >= SERPENT_MIN_KEYSIZE);
+  assert(key_size <= SERPENT_MAX_KEYSIZE);
+
+  if (key_size == SERPENT_KEYSIZE)
+    kptr = key;
+  else
+    {
+      /* Expand key by appending bits 1000...0. */
+      UINT8 *ekey = alloca(SERPENT_KEYSIZE);
+      unsigned i = key_size;
+      
+      memcpy(ekey, key, i);
+      ekey[i++] = 0x01;
+
+      while (i < SERPENT_KEYSIZE)
+	ekey[i++] = 0;
+
+      kptr = ekey;
+    }
+      
   for (i=0; i<8; i++) {
     kd[i] = 0;
     for (j=0; j<4; j++)
@@ -55,8 +76,11 @@ serpent_setup(SERPENT_context *ctx, const UINT8 *key)
   for(i=0; i<8; i++)
     w[i]=kd[i];
 
+#if 0
   for(i++; i<8; i++)
     w[i]=0;
+#endif
+
   for(i=8; i<16; i++)
     w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^(i-8),11);
   for(i=0; i<8; i++)