From 002f30002109e9052ba414e0ff92733add6d1ca1 Mon Sep 17 00:00:00 2001 From: Nicolas DI PRIMA Date: Sat, 11 Feb 2017 12:09:24 +0000 Subject: [PATCH] add fastpbkdf2 with sha512 --- Crypto/KDF/PBKDF2.hs | 23 ++++++++++++++ cbits/cryptonite_pbkdf2.c | 63 +++++++++++++++++++++++++++++++++++++++ cbits/cryptonite_pbkdf2.h | 5 ++++ cbits/cryptonite_sha512.h | 4 ++- tests/KAT_PBKDF2.hs | 2 +- 5 files changed, 95 insertions(+), 2 deletions(-) diff --git a/Crypto/KDF/PBKDF2.hs b/Crypto/KDF/PBKDF2.hs index 16d17fd..b18cc1a 100644 --- a/Crypto/KDF/PBKDF2.hs +++ b/Crypto/KDF/PBKDF2.hs @@ -17,6 +17,7 @@ module Crypto.KDF.PBKDF2 , generate , fastPBKDF2_SHA1 , fastPBKDF2_SHA256 + , fastPBKDF2_SHA512 ) where import Data.Word @@ -136,6 +137,21 @@ fastPBKDF2_SHA256 params password salt = (fromIntegral $ iterCounts params) outPtr (fromIntegral $ outputLength params) +fastPBKDF2_SHA512 :: (ByteArrayAccess password, ByteArrayAccess salt, ByteArray out) + => Parameters + -> password + -> salt + -> out +fastPBKDF2_SHA512 params password salt = + B.allocAndFreeze (outputLength params) $ \outPtr -> + B.withByteArray password $ \passPtr -> + B.withByteArray salt $ \saltPtr -> + c_cryptonite_fastpbkdf2_hmac_sha512 + passPtr (fromIntegral $ B.length password) + saltPtr (fromIntegral $ B.length salt) + (fromIntegral $ iterCounts params) + outPtr (fromIntegral $ outputLength params) + foreign import ccall unsafe "cryptonite_pbkdf2.h cryptonite_fastpbkdf2_hmac_sha1" c_cryptonite_fastpbkdf2_hmac_sha1 :: Ptr Word8 -> CSize @@ -150,3 +166,10 @@ foreign import ccall unsafe "cryptonite_pbkdf2.h cryptonite_fastpbkdf2_hmac_sha2 -> CUInt -> Ptr Word8 -> CSize -> IO () + +foreign import ccall unsafe "cryptonite_pbkdf2.h cryptonite_fastpbkdf2_hmac_sha512" + c_cryptonite_fastpbkdf2_hmac_sha512 :: Ptr Word8 -> CSize + -> Ptr Word8 -> CSize + -> CUInt + -> Ptr Word8 -> CSize + -> IO () diff --git a/cbits/cryptonite_pbkdf2.c b/cbits/cryptonite_pbkdf2.c index 895c47a..baaaec0 100644 --- a/cbits/cryptonite_pbkdf2.c +++ b/cbits/cryptonite_pbkdf2.c @@ -20,6 +20,7 @@ #include "cryptonite_bitfn.h" #include "cryptonite_sha1.h" #include "cryptonite_sha256.h" +#include "cryptonite_sha512.h" /* --- MSVC doesn't support C99 --- */ #ifdef _MSC_VER @@ -337,6 +338,59 @@ DECL_PBKDF2(sha256, sha256_extract, sha256_xor); +static inline void sha512_extract(struct sha512_ctx *restrict ctx, uint8_t *restrict out) +{ + write64_be(ctx->h[0], out); + write64_be(ctx->h[1], out + 8); + write64_be(ctx->h[2], out + 16); + write64_be(ctx->h[3], out + 24); + write64_be(ctx->h[4], out + 32); + write64_be(ctx->h[5], out + 40); + write64_be(ctx->h[6], out + 48); + write64_be(ctx->h[7], out + 56); +} + +static inline void sha512_cpy(struct sha512_ctx *restrict out, const struct sha512_ctx *restrict in) +{ + out->h[0] = in->h[0]; + out->h[1] = in->h[1]; + out->h[2] = in->h[2]; + out->h[3] = in->h[3]; + out->h[4] = in->h[4]; + out->h[5] = in->h[5]; + out->h[6] = in->h[6]; + out->h[7] = in->h[7]; +} + +static inline void sha512_xor(struct sha512_ctx *restrict out, const struct sha512_ctx *restrict in) +{ + out->h[0] ^= in->h[0]; + out->h[1] ^= in->h[1]; + out->h[2] ^= in->h[2]; + out->h[3] ^= in->h[3]; + out->h[4] ^= in->h[4]; + out->h[5] ^= in->h[5]; + out->h[6] ^= in->h[6]; + out->h[7] ^= in->h[7]; +} + +void cryptonite_sha512_transform(struct sha512_ctx* ctx, uint8_t block[SHA512_BLOCK_SIZE]) +{ + cryptonite_sha512_update(ctx, block, SHA512_BLOCK_SIZE); +} + +DECL_PBKDF2(sha512, + SHA512_BLOCK_SIZE, + SHA512_DIGEST_SIZE, + struct sha512_ctx, + cryptonite_sha512_init, + cryptonite_sha512_update, + cryptonite_sha512_transform, + cryptonite_sha512_finalize, + sha512_cpy, + sha512_extract, + sha512_xor); + void cryptonite_fastpbkdf2_hmac_sha1( const uint8_t *pw, size_t npw , const uint8_t *salt, size_t nsalt , uint32_t iterations @@ -354,3 +408,12 @@ void cryptonite_fastpbkdf2_hmac_sha256( const uint8_t *pw, size_t npw { PBKDF2(sha256)(pw, npw, salt, nsalt, iterations, out, nout); } + +void cryptonite_fastpbkdf2_hmac_sha512( const uint8_t *pw, size_t npw + , const uint8_t *salt, size_t nsalt + , uint32_t iterations + , uint8_t *out, size_t nout + ) +{ + PBKDF2(sha512)(pw, npw, salt, nsalt, iterations, out, nout); +} diff --git a/cbits/cryptonite_pbkdf2.h b/cbits/cryptonite_pbkdf2.h index 16f7d5a..5cac4d5 100644 --- a/cbits/cryptonite_pbkdf2.h +++ b/cbits/cryptonite_pbkdf2.h @@ -18,6 +18,11 @@ void cryptonite_fastpbkdf2_hmac_sha256( const uint8_t *pw, size_t npw , uint32_t iterations , uint8_t *out, size_t nout ); +void cryptonite_fastpbkdf2_hmac_sha512( const uint8_t *pw, size_t npw + , const uint8_t *salt, size_t nsalt + , uint32_t iterations + , uint8_t *out, size_t nout + ); #ifdef __cplusplus } diff --git a/cbits/cryptonite_sha512.h b/cbits/cryptonite_sha512.h index 0686162..38fc560 100644 --- a/cbits/cryptonite_sha512.h +++ b/cbits/cryptonite_sha512.h @@ -26,10 +26,12 @@ #include +# define SHA512_BLOCK_SIZE 128 + struct sha512_ctx { uint64_t sz[2]; - uint8_t buf[128]; + uint8_t buf[SHA512_BLOCK_SIZE]; uint64_t h[8]; }; diff --git a/tests/KAT_PBKDF2.hs b/tests/KAT_PBKDF2.hs index c72e3e5..bbb9951 100644 --- a/tests/KAT_PBKDF2.hs +++ b/tests/KAT_PBKDF2.hs @@ -3,7 +3,7 @@ -- from module KAT_PBKDF2 (tests) where -import Crypto.Hash (SHA1(..), SHA256(..)) +import Crypto.Hash (SHA1(..), SHA256(..), SHA512(..)) import qualified Crypto.KDF.PBKDF2 as PBKDF2 import Data.ByteString (ByteString)