hashes 0.2.2.1 → 0.2.3
raw patch · 8 files changed
+143/−29 lines, 8 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Data.Hash.Internal.OpenSSL: newCtx :: IO (Ctx a)
+ Data.Hash.Class.Mutable: class IncrementalHash a => ResetableHash a
+ Data.Hash.Class.Mutable: reset :: ResetableHash a => Context a -> IO ()
+ Data.Hash.Class.Mutable.Internal: class IncrementalHash a => ResetableHash a
+ Data.Hash.Class.Mutable.Internal: reset :: ResetableHash a => Context a -> IO ()
+ Data.Hash.Internal.OpenSSL: finalizeKeccak256Ptr :: Ctx Keccak256 -> Ptr Word8 -> IO ()
+ Data.Hash.Internal.OpenSSL: finalizeKeccak512Ptr :: Ctx Keccak512 -> Ptr Word8 -> IO ()
+ Data.Hash.Internal.OpenSSL: instance Data.Hash.Class.Mutable.Internal.ResetableHash Data.Hash.Internal.OpenSSL.Keccak256
+ Data.Hash.Internal.OpenSSL: instance Data.Hash.Class.Mutable.Internal.ResetableHash Data.Hash.Internal.OpenSSL.Keccak512
+ Data.Hash.Internal.OpenSSL: instance Data.Hash.Internal.OpenSSL.OpenSslDigest a => Data.Hash.Class.Mutable.Internal.ResetableHash (Data.Hash.Internal.OpenSSL.Digest a)
+ Data.Hash.Internal.OpenSSL: resetCtx :: Ctx a -> IO ()
+ Data.Hash.Keccak: finalizeKeccak256Ptr :: Ctx Keccak256 -> Ptr Word8 -> IO ()
+ Data.Hash.Keccak: finalizeKeccak512Ptr :: Ctx Keccak512 -> Ptr Word8 -> IO ()
Files
- CHANGELOG.md +6/−0
- cbits/keccak.c +22/−6
- cbits/keccak.h +2/−0
- hashes.cabal +1/−1
- src/Data/Hash/Class/Mutable.hs +4/−1
- src/Data/Hash/Class/Mutable/Internal.hs +13/−2
- src/Data/Hash/Internal/OpenSSL.hs +90/−19
- src/Data/Hash/Keccak.hs +5/−0
CHANGELOG.md view
@@ -1,5 +1,11 @@ # Revision history for the hashes package +## 0.2.3 -- 2022-11-22++* Support reset and reuse of context for OpenSSL digests.+* Avoid the use of deprecated OpenSSL methods.+* Add methods to write digests directly to a pointer for Keccak digests.+ ## 0.2.2.1 -- 2022-09-28 * Support for Apple Silicon (`aarch64_HOST_ARCH`)
cbits/keccak.c view
@@ -34,7 +34,7 @@ /* *************************************************************************** */ /* OpenSSL 1.1 and OpenSSL 3.0 */ -/* The computation of the magic offset is base on the keccak_st structure in+/* The computation of the magic offset is based on the keccak_st structure in * OpenSSL-1.1 and OpenSSL-3.0 * * Assuming conventional alignment, the bytes offset is@@ -79,7 +79,7 @@ /* OPENSSL 3.1 */ #if OPENSSL_VERSION_NUMBER >= 0x31000000L-#define SET_PAD_BYTE +#define SET_PAD_BYTE /* OPENSSL 3.0 */ #elif OPENSSL_VERSION_NUMBER >= 0x30000000L@@ -111,7 +111,7 @@ int ok = 1; const EVP_MD *md = NULL; CHECKED(md = EVP_get_digestbyname("SHA3-256"));- CHECKED(EVP_DigestInit(ctx, md));+ CHECKED(EVP_DigestInit_ex(ctx, md, NULL)); SET_PAD_BYTE; finally: return ok;@@ -121,12 +121,28 @@ int ok = 1; const EVP_MD *md = NULL; CHECKED(md = EVP_get_digestbyname("SHA3-512"));- CHECKED(EVP_DigestInit(ctx, md));+ CHECKED(EVP_DigestInit_ex(ctx, md, NULL)); SET_PAD_BYTE; finally: return ok; } +int keccak256_reset(KECCAK512_CTX *ctx) {+ int ok = 1;+ CHECKED(EVP_DigestInit_ex(ctx, NULL, NULL));+ SET_PAD_BYTE;+finally:+ return ok;+}++int keccak512_reset(KECCAK512_CTX *ctx) {+ int ok = 1;+ CHECKED(EVP_DigestInit_ex(ctx, NULL, NULL));+ SET_PAD_BYTE;+finally:+ return ok;+}+ int keccak256_update(KECCAK256_CTX *ctx, const void *p, size_t l) { return EVP_DigestUpdate(ctx, p, l);@@ -140,13 +156,13 @@ int keccak256_final(KECCAK256_CTX *ctx, unsigned char *md) { unsigned int l;- return EVP_DigestFinal(ctx, md, &l);+ return EVP_DigestFinal_ex(ctx, md, &l); } int keccak512_final(KECCAK512_CTX *ctx, unsigned char *md) { unsigned int l;- return EVP_DigestFinal(ctx, md, &l);+ return EVP_DigestFinal_ex(ctx, md, &l); } void keccak256_freectx(KECCAK256_CTX *ctx)
cbits/keccak.h view
@@ -17,6 +17,7 @@ // KECCAK-256 KECCAK256_CTX *keccak256_newctx(); int keccak256_init(KECCAK256_CTX *ctx);+int keccak256_reset(KECCAK256_CTX *ctx); int keccak256_update(KECCAK256_CTX *ctx, const void *p, size_t l); int keccak256_final(KECCAK256_CTX *ctx, unsigned char *md); void keccak256_freectx(KECCAK256_CTX *ctx);@@ -24,6 +25,7 @@ // KECCAK-512 KECCAK512_CTX *keccak512_newctx(); int keccak512_init(KECCAK512_CTX *ctx);+int keccak512_reset(KECCAK512_CTX *ctx); int keccak512_update(KECCAK512_CTX *ctx, const void *p, size_t l); int keccak512_final(KECCAK512_CTX *ctx, unsigned char *md); void keccak512_freectx(KECCAK512_CTX *ctx);
hashes.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: hashes-version: 0.2.2.1+version: 0.2.3 synopsis: Hash functions Description: Efficient implementations of hash functions homepage: https://github.com/larskuhtz/hs-hashes
src/Data/Hash/Class/Mutable.hs view
@@ -29,6 +29,9 @@ , updateShortByteString , updateStorable , updateByteArray++-- * Resetable Hashes+, ResetableHash(..) ) where import qualified Data.ByteString as B@@ -47,7 +50,7 @@ import Data.Hash.Class.Mutable.Internal -- -------------------------------------------------------------------------- ----- Class of Salted Pure Hashes+-- Class of Mutable Hashes class IncrementalHash a => Hash a where initialize :: IO (Context a)
src/Data/Hash/Class/Mutable/Internal.hs view
@@ -12,15 +12,20 @@ -- Maintainer: Lars Kuhtz <lakuhtz@gmail.com> -- Stability: experimental ----- Incremental Mutable Hashes+-- Incremental and Resetable Mutable Hashes -- module Data.Hash.Class.Mutable.Internal-( IncrementalHash(..)+(+-- * Incremental Hashes+ IncrementalHash(..) , updateByteString , updateByteStringLazy , updateShortByteString , updateStorable , updateByteArray++-- * Resetable Hashes+, ResetableHash(..) ) where import qualified Data.ByteString as B@@ -103,4 +108,10 @@ where size# = sizeofByteArray# a# {-# INLINE updateByteArray #-}++-- -------------------------------------------------------------------------- --+-- Class of Resetable Hashes++class IncrementalHash a => ResetableHash a where+ reset :: Context a -> IO ()
src/Data/Hash/Internal/OpenSSL.hs view
@@ -28,7 +28,7 @@ Algorithm(..) , Ctx(..) , Digest(..)-, newCtx+, resetCtx , initCtx , updateCtx , finalCtx@@ -67,6 +67,10 @@ , Keccak256(..) , Keccak512(..) +-- *** Unsafe finalize functions+, finalizeKeccak256Ptr+, finalizeKeccak512Ptr+ -- ** Blake2 -- -- $blake2@@ -126,16 +130,17 @@ #endif c_evp_ctx_free_ptr :: FunPtr (Ptr a -> IO ()) --- obsolete, superseeded by EVP_DigestInit_ex instead, but not deprecated--- (beware in case this becomes a macro in future versions)----foreign import ccall unsafe "opnessl/evp.h EVP_DigestInit"- c_evp_digest_init :: Ptr ctx -> Ptr alg -> IO Bool+#if OPENSSL_VERSION_NUMBER >= 0x30000000L+foreign import ccall unsafe "openssl/evp.h EVP_DigestInit_ex2"+#else+foreign import ccall unsafe "openssl/evp.h EVP_DigestInit_ex"+#endif+ c_evp_digest_init :: Ptr ctx -> Ptr alg -> Ptr Void {- nullPtr -} -> IO Bool -foreign import ccall unsafe "opnessl/evp.h EVP_DigestUpdate"+foreign import ccall unsafe "openssl/evp.h EVP_DigestUpdate" c_evp_digest_update :: Ptr ctx -> Ptr d -> Int -> IO Bool -foreign import ccall unsafe "opnessl/evp.h EVP_DigestFinal"+foreign import ccall unsafe "openssl/evp.h EVP_DigestFinal_ex" c_evp_digest_final :: Ptr ctx -> Ptr d -> Int -> IO Bool #if OPENSSL_VERSION_NUMBER >= 0x30000000L@@ -152,28 +157,40 @@ #endif c_evp_get_size :: Algorithm -> IO Int -newCtx :: IO (Ctx a)-newCtx = fmap Ctx $ mask_ $ do- ptr <- c_evp_ctx_new- when (ptr == nullPtr) $ throw $ OpenSslException "failed to initialize context"- newForeignPtr c_evp_ctx_free_ptr ptr-{-# INLINE newCtx #-}-+-- | Allocates and initializes a new context. The context may be reused by+-- calling 'resetCtx' on it.+-- initCtx :: Algorithm -> IO (Ctx a) initCtx (Algorithm alg) = do- Ctx ctx <- newCtx+ ctx <- mask_ $ do+ ptr <- c_evp_ctx_new+ when (ptr == nullPtr) $ throw $ OpenSslException "failed to create new context"+ newForeignPtr c_evp_ctx_free_ptr ptr r <- withForeignPtr ctx $ \ptr ->- c_evp_digest_init ptr alg+ c_evp_digest_init ptr alg nullPtr unless r $ throw $ OpenSslException "digest initialization failed" return $ Ctx ctx {-# INLINE initCtx #-} +-- | Resets a context an initialize context.+--+resetCtx :: Ctx a -> IO ()+resetCtx (Ctx ctx) = do+ r <- withForeignPtr ctx $ \ptr ->+ c_evp_digest_init ptr nullPtr nullPtr+ unless r $ throw $ OpenSslException "digest re-initialization failed"+{-# INLINE resetCtx #-}++-- | Feed more data into an context.+-- updateCtx :: Ctx a -> Ptr Word8 -> Int -> IO () updateCtx (Ctx ctx) d c = withForeignPtr ctx $ \ptr -> do r <- c_evp_digest_update ptr d c unless r $ throw $ OpenSslException "digest update failed" {-# INLINE updateCtx #-} +-- | Finalize a hash and return the digest.+-- finalCtx :: Ctx a -> IO (Digest a) finalCtx (Ctx ctx) = withForeignPtr ctx $ \ptr -> do s <- c_evp_ctx_get0_md ptr >>= c_evp_get_size@@ -200,6 +217,10 @@ initialize = initCtx (algorithm @a) {-# INLINE initialize #-} +instance OpenSslDigest a => ResetableHash (Digest a) where+ reset = resetCtx+ {-# INLINE reset #-}+ -- -------------------------------------------------------------------------- -- -- Digests -- -------------------------------------------------------------------------- --@@ -378,6 +399,9 @@ foreign import ccall unsafe "keccak.h keccak256_init" c_keccak256_init :: Ptr ctx -> IO Bool +foreign import ccall unsafe "keccak.h keccak256_reset"+ c_keccak256_reset :: Ptr ctx -> IO Bool+ foreign import ccall unsafe "keccak.h keccak256_update" c_keccak256_update :: Ptr ctx -> Ptr Word8 -> Int -> IO Bool @@ -400,7 +424,6 @@ {-# INLINE update #-} {-# INLINE finalize #-} - newKeccak256Ctx :: IO (Ctx Keccak256) newKeccak256Ctx = fmap Ctx $ mask_ $ do ptr <- c_keccak256_newctx@@ -408,6 +431,25 @@ newForeignPtr c_keccak256_freectx_ptr ptr {-# INLINE newKeccak256Ctx #-} +resetKeccak256Ctx :: Ctx Keccak256 -> IO ()+resetKeccak256Ctx (Ctx ctx) = do+ r <- withForeignPtr ctx $ \ptr ->+ c_keccak256_reset ptr+ unless r $ throw $ OpenSslException "digest re-initialization failed"+{-# INLINE resetKeccak256Ctx #-}++-- | Low-Level function that writes the final digest directly into the provided+-- pointer. The pointer must point to at least 64 bytes of allocated memory.+-- This is not checked and a violation of this condition may result in a+-- segmentation fault.+--+finalizeKeccak256Ptr :: Ctx Keccak256 -> Ptr Word8 -> IO ()+finalizeKeccak256Ptr (Ctx ctx) dptr =+ withForeignPtr ctx $ \cptr -> do+ r <- c_keccak256_final cptr dptr+ unless r $ throw $ OpenSslException "digest finalization failed"+{-# INLINE finalizeKeccak256Ptr #-}+ instance Hash Keccak256 where initialize = do Ctx ctx <- newKeccak256Ctx@@ -417,6 +459,10 @@ return $ Ctx ctx {-# INLINE initialize #-} +instance ResetableHash Keccak256 where+ reset = resetKeccak256Ctx+ {-# INLINE reset #-}+ -- KECCAK-512 newtype Keccak512 = Keccak512 BS.ShortByteString@@ -429,6 +475,9 @@ foreign import ccall unsafe "keccak.h keccak512_init" c_keccak512_init :: Ptr ctx -> IO Bool +foreign import ccall unsafe "keccak.h keccak512_reset"+ c_keccak512_reset :: Ptr ctx -> IO Bool+ foreign import ccall unsafe "keccak.h keccak512_update" c_keccak512_update :: Ptr ctx -> Ptr Word8 -> Int -> IO Bool @@ -451,7 +500,6 @@ {-# INLINE update #-} {-# INLINE finalize #-} - newKeccak512Ctx :: IO (Ctx Keccak512) newKeccak512Ctx = fmap Ctx $ mask_ $ do ptr <- c_keccak512_newctx@@ -459,6 +507,25 @@ newForeignPtr c_keccak512_freectx_ptr ptr {-# INLINE newKeccak512Ctx #-} +resetKeccak512Ctx :: Ctx Keccak512 -> IO ()+resetKeccak512Ctx (Ctx ctx) = do+ r <- withForeignPtr ctx $ \ptr ->+ c_keccak512_reset ptr+ unless r $ throw $ OpenSslException "digest re-initialization failed"+{-# INLINE resetKeccak512Ctx #-}++-- | Low-Level function that writes the final digest directly into the provided+-- pointer. The pointer must point to at least 64 bytes of allocated memory.+-- This is not checked and a violation of this condition may result in a+-- segmentation fault.+--+finalizeKeccak512Ptr :: Ctx Keccak512 -> Ptr Word8 -> IO ()+finalizeKeccak512Ptr (Ctx ctx) dptr = do+ withForeignPtr ctx $ \cptr -> do+ r <- c_keccak512_final cptr dptr+ unless r $ throw $ OpenSslException "digest finalization failed"+{-# INLINE finalizeKeccak512Ptr #-}+ instance Hash Keccak512 where initialize = do Ctx ctx <- newKeccak512Ctx@@ -467,6 +534,10 @@ unless r $ throw $ OpenSslException "digest initialization failed" return $ Ctx ctx {-# INLINE initialize #-}++instance ResetableHash Keccak512 where+ reset = resetKeccak512Ctx+ {-# INLINE reset #-} -- -------------------------------------------------------------------------- -- -- Blake
src/Data/Hash/Keccak.hs view
@@ -33,6 +33,11 @@ Keccak256(..) , Keccak512(..) , module Data.Hash.Class.Mutable++-- *** Unsafe finalize functions+, finalizeKeccak256Ptr+, finalizeKeccak512Ptr+ ) where import Data.Hash.Class.Mutable