From 45a29b37173ab724d8b90af7e0b1a9fda3acbeb2 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Sat, 27 Jan 2018 17:05:58 -0500 Subject: Data.Digest: Switch back to EVP Use the finalizer techniques demonstrated in 4e56c79b907da4a4654e5278bdcf94b08480a426 to safely allocate `EVP_MD_CTX` on the Haskell heap. This allows us to return to the high-level EVP API, eliminating much boilerplate code. --- src/Cleanse.hsc | 62 --------------------------------------------------------- 1 file changed, 62 deletions(-) delete mode 100644 src/Cleanse.hsc (limited to 'src/Cleanse.hsc') diff --git a/src/Cleanse.hsc b/src/Cleanse.hsc deleted file mode 100644 index bb60945..0000000 --- a/src/Cleanse.hsc +++ /dev/null @@ -1,62 +0,0 @@ -{-# LANGUAGE ScopedTypeVariables #-} - --- | This module wraps BoringSSL's @OPENSSL_cleanse@, which securely overwrites --- memory. ("Securely" here means that BoringSSL uses some assembly magic to --- prevent the compiler from optimizing out the write.) However, the module --- doesn't actually expose @OPENSSL_cleanse@ directly; instead, it lets you --- allocate 'ForeignPtr's with cleansing registered as a finalizer. GHC runs all --- 'ForeignPtr' finalizers prior to program termination, which gives the --- 'ForeignPtr's allocated this way the approximately same security guarantees --- as memory allocated through BoringSSL's allocator interface. In particular, --- unless you exit your program through GHC's foreign function interface, all --- memory allocated through 'mallocCleansablePtr' will be forcibly cleared prior --- to program exit. -module Cleanse - ( mallocCleansablePtr - ) where - -import Foreign - (FinalizerPtr, ForeignPtr, Storable(poke, sizeOf), - addForeignPtrFinalizer, mallocForeignPtrBytes, withForeignPtr) -import Foreign.C.Types -import Foreign.ForeignPtr.Compat (plusForeignPtr) - -#include - -#include - --- We implement 'mallocCleansablePtr' using the standard allocator technique of --- saving the allocated region size immediately before the allocated region. - -#def struct __attribute__((__packed__)) Buffer { - size_t size; - char data[]; -}; - -bufferSize :: Int -bufferSize = #size struct Buffer - -dataOffset :: Int -dataOffset = #offset struct Buffer, data - -mallocCleansablePtr :: forall a. Storable a => IO (ForeignPtr a) -mallocCleansablePtr = do - -- Allocate the buffer. - let dataSize = sizeOf (undefined :: a) - fp <- mallocForeignPtrBytes (bufferSize + dataSize) - -- Save the data size. - withForeignPtr fp $ \p -> poke p (fromIntegral dataSize :: CSize) - -- Now that the size is saved, we can register the cleansing finalizer. This - -- will look at the size and wipe the buffer. - addForeignPtrFinalizer btlsCleansePtr fp - -- Return a pointer to the data region. - return (fp `plusForeignPtr` dataOffset :: ForeignPtr a) - --- The cleansing finalizer itself is totally straightforward. - -#def void btlsCleanse(struct Buffer* const p) { - OPENSSL_cleanse(p->data, p->size); -} - -foreign import ccall "&btlsCleanse" - btlsCleansePtr :: FinalizerPtr a -- cgit v1.2.3