⬢ DragonFlyBSD Kernel Audit
DF-3562 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/crypto/serpent/serpent.c b/sys/crypto/serpent/serpent.c
index fef80f8..bdfddb0 100644
--- a/sys/crypto/serpent/serpent.c
+++ b/sys/crypto/serpent/serpent.c
@@ -448,12 +448,21 @@
 
 // initialise the key schedule from the user supplied key
 
+/*
+ * NOTE: key_len is in bits.  Valid inputs are 0..256 in multiples of 8
+ * bits.  Values outside that range must be rejected: negative values
+ * wrap through the unsigned i/lk arithmetic below into wildly
+ * out-of-bounds stores (i = (u_int32_t)(key_len / 32) == 0xFFFFFFFF, or
+ * a runaway load loop when (u_int32_t)((key_len + 31) / 32) is huge),
+ * and lengths that are not a multiple of 8 bits read up to 3 bytes
+ * past the caller's key buffer.
+ */
 void serpent_set_key(serpent_ctx *ctx, const u_int8_t in_key[], int key_len)
 {
     u_int32_t  i,lk,a,b,c,d,e,f,g,h;
     u_int32_t  t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;
 
-    if(key_len > 256)
+    if(key_len < 0 || key_len > 256 || (key_len & 7))
         return;
 
     i = 0; lk = (key_len + 31) / 32;