diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 0.15.1
+
+* Add error check on salt length in bcrypt
+* Fix buffer length in scrypt (Luke Taylor)
+* build fixes for i686 and arm related to rdrand
+* Fix basepoint for Ed448
+
 ## 0.15
 
 * Fix serialization of DH and ECDH
diff --git a/Crypto/Cipher/Blowfish/Primitive.hs b/Crypto/Cipher/Blowfish/Primitive.hs
--- a/Crypto/Cipher/Blowfish/Primitive.hs
+++ b/Crypto/Cipher/Blowfish/Primitive.hs
@@ -79,7 +79,9 @@
 -- Cost must be between 4 and 31 inclusive
 -- See <https://www.usenix.org/conference/1999-usenix-annual-technical-conference/future-adaptable-password-scheme>
 eksBlowfish :: (ByteArrayAccess salt, ByteArrayAccess password) => Int -> salt -> password -> Context
-eksBlowfish cost salt key = makeKeySchedule key (Just (salt, cost))
+eksBlowfish cost salt key
+    | B.length salt /= 16 = error "bcrypt salt must be 16 bytes"
+    | otherwise           = makeKeySchedule key (Just (salt, cost))
 
 coreCrypto :: Context -> Word64 -> Word64
 coreCrypto (BF p s0 s1 s2 s3) input = doRound input 0
diff --git a/Crypto/KDF/Scrypt.hs b/Crypto/KDF/Scrypt.hs
--- a/Crypto/KDF/Scrypt.hs
+++ b/Crypto/KDF/Scrypt.hs
@@ -53,7 +53,7 @@
         let b = PBKDF2.generate prf (PBKDF2.Parameters 1 intLen) password salt :: B.Bytes
         newSalt <- B.copy b $ \bPtr ->
             allocaBytesAligned (128*(fromIntegral $ n params)*(r params)) 8 $ \v ->
-            allocaBytesAligned (256*r params) 8 $ \xy -> do
+            allocaBytesAligned (256*r params + 64) 8 $ \xy -> do
                 forM_ [0..(p params-1)] $ \i ->
                     ccryptonite_scrypt_smix (bPtr `plusPtr` (i * 128 * (r params)))
                                             (fromIntegral $ r params) (n params) v xy
diff --git a/Crypto/PubKey/Ed448.hs b/Crypto/PubKey/Ed448.hs
--- a/Crypto/PubKey/Ed448.hs
+++ b/Crypto/PubKey/Ed448.hs
@@ -89,7 +89,7 @@
     withByteArray sec               $ \psec   ->
         ccryptonite_ed448 result psec basePoint
   where
-        basePoint = Ptr "\x05\x00\x00\x00\x00\x00\x00\x00\x00x00\x00\x00\x00\x00\x00\x00\x00x00\x00\x00\x00\x00\x00\x00\x00x00\x00\x00\x00\x00\x00\x00\x00x00\x00\x00\x00\x00\x00\x00\x00x00\x00\x00\x00\x00\x00\x00\x00x00\x00\x00\x00\x00\x00\x00"#
+        basePoint = Ptr "\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
 {-# NOINLINE toPublic #-}
 
 x448_bytes :: Int
diff --git a/cbits/cryptonite_rdrand.c b/cbits/cryptonite_rdrand.c
--- a/cbits/cryptonite_rdrand.c
+++ b/cbits/cryptonite_rdrand.c
@@ -37,23 +37,15 @@
 int cryptonite_cpu_has_rdrand()
 {
 	uint32_t ax,bx,cx,dx,func=1;
+#if defined(__PIC__) && defined(__i386__)
+	__asm__ volatile ("mov %%ebx, %%edi;" "cpuid;" "xchgl %%ebx, %%edi;"
+		: "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) : "a" (func));
+#else
 	__asm__ volatile ("cpuid": "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func));
+#endif
 	return (cx & 0x40000000);
 }
 
-/* sadly many people are still using an old binutils,
- * leading to report that instruction is not recognized.
- */
-#if 0
-/* Returns 1 on success */
-static inline int crypto_random_rdrand64_step(uint64_t *buffer)
-{
-	unsigned char err;
-	asm volatile ("rdrand %0; setc %1" : "=r" (*buffer), "=qm" (err));
-	return (int) err;
-}
-#endif
-
 /* inline encoding of 'rdrand %rax' to cover old binutils
  * - no inputs
  * - 'cc' to the clobber list as we modify condition code.
@@ -65,17 +57,51 @@
 	   : \
 	   : "cc")
 
+/* inline encoding of 'rdrand %eax' to cover old binutils
+ * - no inputs
+ * - 'cc' to the clobber list as we modify condition code.
+ * - output of rdrand in eax and have a 8 bit error condition
+ */
+#define inline_rdrand_eax(val, err) \
+	asm(".byte 0x0f,0xc7,0xf0; setc %1" \
+	   : "=a" (val), "=q" (err) \
+	   : \
+	   : "cc")
+
+#ifdef __x86_64__
+# define RDRAND_SZ 8
+# define RDRAND_T  uint64_t
+#define inline_rdrand(val, err) err = cryptonite_rdrand_step(&val)
+#else
+# define RDRAND_SZ 4
+# define RDRAND_T  uint32_t
+#define inline_rdrand(val, err) err = cryptonite_rdrand_step(&val)
+#endif
+
+/* sadly many people are still using an old binutils,
+ * leading to report that instruction is not recognized.
+ */
+#if 1
+/* Returns 1 on success */
+static inline int cryptonite_rdrand_step(RDRAND_T *buffer)
+{
+	unsigned char err;
+	asm volatile ("rdrand %0; setc %1" : "=r" (*buffer), "=qm" (err));
+	return (int) err;
+}
+#endif
+
 /* Returns the number of bytes succesfully generated */
 int cryptonite_get_rand_bytes(uint8_t *buffer, size_t len)
 {
-	uint64_t tmp;
-	int aligned = (intptr_t) buffer % 8;
+	RDRAND_T tmp;
+	int aligned = (intptr_t) buffer % RDRAND_SZ;
 	int orig_len = len;
-	int to_alignment = 8 - aligned;
+	int to_alignment = RDRAND_SZ - aligned;
 	uint8_t ok;
 
 	if (aligned != 0) {
-		inline_rdrand_rax(tmp, ok);
+		inline_rdrand(tmp, ok);
 		if (!ok)
 			return 0;
 		memcpy(buffer, (uint8_t *) &tmp, to_alignment);
@@ -83,15 +109,15 @@
 		len -= to_alignment;
 	}
 
-	for (; len >= 8; buffer += 8, len -= 8) {
-		inline_rdrand_rax(tmp, ok);
+	for (; len >= RDRAND_SZ; buffer += RDRAND_SZ, len -= RDRAND_SZ) {
+		inline_rdrand(tmp, ok);
 		if (!ok)
 			return (orig_len - len);
-		*((uint64_t *) buffer) = tmp;
+		*((RDRAND_T *) buffer) = tmp;
 	}
 
 	if (len > 0) {
-		inline_rdrand_rax(tmp, ok);
+		inline_rdrand(tmp, ok);
 		if (!ok)
 			return (orig_len - len);
 		memcpy(buffer, (uint8_t *) &tmp, len);
diff --git a/cryptonite.cabal b/cryptonite.cabal
--- a/cryptonite.cabal
+++ b/cryptonite.cabal
@@ -1,5 +1,5 @@
 Name:                cryptonite
-Version:             0.15
+Version:             0.15.1
 Synopsis:            Cryptography Primitives sink
 Description:
     A repository of cryptographic primitives.
@@ -236,8 +236,10 @@
   if arch(i386)
     CPP-options: -DARCH_X86
 
-  if flag(support_rdrand) && arch(x86_64)
-    CPP-options:    -DARCH_X86_64
+  if arch(x86_64)
+    CPP-options: -DARCH_X86_64
+
+  if flag(support_rdrand) && (arch(i386) || arch(x86_64))
     CPP-options:    -DSUPPORT_RDRAND
     Other-modules:  Crypto.Random.Entropy.RDRand
     c-sources:      cbits/cryptonite_rdrand.c
diff --git a/tests/BCrypt.hs b/tests/BCrypt.hs
--- a/tests/BCrypt.hs
+++ b/tests/BCrypt.hs
@@ -74,4 +74,5 @@
 
 tests = testGroup "bcrypt"
     [ testGroup "KATs" makeKATs
+    , testCase "Invalid hash length" (assertEqual "" (Left "Invalid hash format") (validatePasswordEither B.empty ("$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s" :: B.ByteString)))
     ]
diff --git a/tests/KAT_Ed448.hs b/tests/KAT_Ed448.hs
--- a/tests/KAT_Ed448.hs
+++ b/tests/KAT_Ed448.hs
@@ -16,6 +16,8 @@
 katTests =
     [ testCase "0" (aliceMultBob @=? B.convert (Ed448.dh alicePublic bobPrivate))
     , testCase "1" (aliceMultBob @=? B.convert (Ed448.dh bobPublic alicePrivate))
+    , testCase "2" (alicePublic  @=? Ed448.toPublic alicePrivate)
+    , testCase "3" (bobPublic    @=? Ed448.toPublic bobPrivate)
     ]
 
 tests = testGroup "Ed448"
