Compare commits

...

5 Commits

Author SHA1 Message Date
Luke Taylor
b15401b39d bump version to 0.15.1 2016-08-22 13:49:43 +02:00
Luke Taylor
a8c80e9531 Add a check for salt length in bcrypt function
Raises an error (as the original doc claimed) if the salt is not the
required length of 16 bytes.

validatePasswordEither doesn't require separate checking since the hash
length as a whole is checked, implicitly ensuring the salt is the right
length. Therefore it shouldn't be possible to trigger the error by
calling this function.

Fixes #93.
2016-08-22 13:41:42 +02:00
Luke Taylor
d04756d51c Fix buffer length in scrypt
The temporary XY buffer passed to the scrypt_smix C function should be
256r+64 bytes in length, but the Haskell code was only allocating 256r
bytes, causing the additional 64 to be written past the end of the
buffer.

See #91.
2016-08-22 13:41:22 +02:00
John Galt
7d83ff16f8 rdrand-related code and build flag changes
Combined commits between 0.15 and 0.19:

- Decoupled -DARCH_X86_64 and support_rdrand
- add an untested workaround for i686 machine
- limit to i686 and x86_64
- add possible workaround for fPIC building
- re-use standard instruction
2016-08-22 13:34:38 +02:00
John Galt
ab3ca7b5df [Ed448] Fixed incorrect base point 2016-08-22 13:05:44 +02:00
8 changed files with 67 additions and 27 deletions

View File

@ -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 ## 0.15
* Fix serialization of DH and ECDH * Fix serialization of DH and ECDH

View File

@ -79,7 +79,9 @@ initBlowfish key
-- Cost must be between 4 and 31 inclusive -- Cost must be between 4 and 31 inclusive
-- See <https://www.usenix.org/conference/1999-usenix-annual-technical-conference/future-adaptable-password-scheme> -- 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 :: (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 :: Context -> Word64 -> Word64
coreCrypto (BF p s0 s1 s2 s3) input = doRound input 0 coreCrypto (BF p s0 s1 s2 s3) input = doRound input 0

View File

@ -53,7 +53,7 @@ generate params password salt
let b = PBKDF2.generate prf (PBKDF2.Parameters 1 intLen) password salt :: B.Bytes let b = PBKDF2.generate prf (PBKDF2.Parameters 1 intLen) password salt :: B.Bytes
newSalt <- B.copy b $ \bPtr -> newSalt <- B.copy b $ \bPtr ->
allocaBytesAligned (128*(fromIntegral $ n params)*(r params)) 8 $ \v -> 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 -> forM_ [0..(p params-1)] $ \i ->
ccryptonite_scrypt_smix (bPtr `plusPtr` (i * 128 * (r params))) ccryptonite_scrypt_smix (bPtr `plusPtr` (i * 128 * (r params)))
(fromIntegral $ r params) (n params) v xy (fromIntegral $ r params) (n params) v xy

View File

@ -89,7 +89,7 @@ toPublic (SecretKey sec) = PublicKey <$>
withByteArray sec $ \psec -> withByteArray sec $ \psec ->
ccryptonite_ed448 result psec basePoint ccryptonite_ed448 result psec basePoint
where 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 #-} {-# NOINLINE toPublic #-}
x448_bytes :: Int x448_bytes :: Int

View File

@ -37,23 +37,15 @@
int cryptonite_cpu_has_rdrand() int cryptonite_cpu_has_rdrand()
{ {
uint32_t ax,bx,cx,dx,func=1; 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)); __asm__ volatile ("cpuid": "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func));
#endif
return (cx & 0x40000000); 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 /* inline encoding of 'rdrand %rax' to cover old binutils
* - no inputs * - no inputs
* - 'cc' to the clobber list as we modify condition code. * - 'cc' to the clobber list as we modify condition code.
@ -65,17 +57,51 @@ static inline int crypto_random_rdrand64_step(uint64_t *buffer)
: \ : \
: "cc") : "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 */ /* Returns the number of bytes succesfully generated */
int cryptonite_get_rand_bytes(uint8_t *buffer, size_t len) int cryptonite_get_rand_bytes(uint8_t *buffer, size_t len)
{ {
uint64_t tmp; RDRAND_T tmp;
int aligned = (intptr_t) buffer % 8; int aligned = (intptr_t) buffer % RDRAND_SZ;
int orig_len = len; int orig_len = len;
int to_alignment = 8 - aligned; int to_alignment = RDRAND_SZ - aligned;
uint8_t ok; uint8_t ok;
if (aligned != 0) { if (aligned != 0) {
inline_rdrand_rax(tmp, ok); inline_rdrand(tmp, ok);
if (!ok) if (!ok)
return 0; return 0;
memcpy(buffer, (uint8_t *) &tmp, to_alignment); memcpy(buffer, (uint8_t *) &tmp, to_alignment);
@ -83,15 +109,15 @@ int cryptonite_get_rand_bytes(uint8_t *buffer, size_t len)
len -= to_alignment; len -= to_alignment;
} }
for (; len >= 8; buffer += 8, len -= 8) { for (; len >= RDRAND_SZ; buffer += RDRAND_SZ, len -= RDRAND_SZ) {
inline_rdrand_rax(tmp, ok); inline_rdrand(tmp, ok);
if (!ok) if (!ok)
return (orig_len - len); return (orig_len - len);
*((uint64_t *) buffer) = tmp; *((RDRAND_T *) buffer) = tmp;
} }
if (len > 0) { if (len > 0) {
inline_rdrand_rax(tmp, ok); inline_rdrand(tmp, ok);
if (!ok) if (!ok)
return (orig_len - len); return (orig_len - len);
memcpy(buffer, (uint8_t *) &tmp, len); memcpy(buffer, (uint8_t *) &tmp, len);

View File

@ -1,5 +1,5 @@
Name: cryptonite Name: cryptonite
Version: 0.15 Version: 0.15.1
Synopsis: Cryptography Primitives sink Synopsis: Cryptography Primitives sink
Description: Description:
A repository of cryptographic primitives. A repository of cryptographic primitives.
@ -236,8 +236,10 @@ Library
if arch(i386) if arch(i386)
CPP-options: -DARCH_X86 CPP-options: -DARCH_X86
if flag(support_rdrand) && arch(x86_64) if arch(x86_64)
CPP-options: -DARCH_X86_64 CPP-options: -DARCH_X86_64
if flag(support_rdrand) && (arch(i386) || arch(x86_64))
CPP-options: -DSUPPORT_RDRAND CPP-options: -DSUPPORT_RDRAND
Other-modules: Crypto.Random.Entropy.RDRand Other-modules: Crypto.Random.Entropy.RDRand
c-sources: cbits/cryptonite_rdrand.c c-sources: cbits/cryptonite_rdrand.c

View File

@ -74,4 +74,5 @@ makeKATs = concatMap maketest (zip3 is passwords hashes)
tests = testGroup "bcrypt" tests = testGroup "bcrypt"
[ testGroup "KATs" makeKATs [ testGroup "KATs" makeKATs
, testCase "Invalid hash length" (assertEqual "" (Left "Invalid hash format") (validatePasswordEither B.empty ("$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s" :: B.ByteString)))
] ]

View File

@ -16,6 +16,8 @@ katTests :: [TestTree]
katTests = katTests =
[ testCase "0" (aliceMultBob @=? B.convert (Ed448.dh alicePublic bobPrivate)) [ testCase "0" (aliceMultBob @=? B.convert (Ed448.dh alicePublic bobPrivate))
, testCase "1" (aliceMultBob @=? B.convert (Ed448.dh bobPublic alicePrivate)) , testCase "1" (aliceMultBob @=? B.convert (Ed448.dh bobPublic alicePrivate))
, testCase "2" (alicePublic @=? Ed448.toPublic alicePrivate)
, testCase "3" (bobPublic @=? Ed448.toPublic bobPrivate)
] ]
tests = testGroup "Ed448" tests = testGroup "Ed448"