diff --git a/AES.cabal b/AES.cabal
--- a/AES.cabal
+++ b/AES.cabal
@@ -1,7 +1,7 @@
 Name: AES
 Synopsis: Fast AES encryption/decryption for bytestrings
 Description: A zero-copy binding to Brian Gladman's AES implementation, including a copy of that implementation
-Version: 0.2.3
+Version: 0.2.4
 License: BSD3
 License-file: COPYING
 Copyright: Copyright (c) 2009 University of Tromsø
diff --git a/Codec/Crypto/AES/IO.hsc b/Codec/Crypto/AES/IO.hsc
--- a/Codec/Crypto/AES/IO.hsc
+++ b/Codec/Crypto/AES/IO.hsc
@@ -10,7 +10,7 @@
 import Foreign
 import Control.Applicative
 import Control.Monad
-import Data.IORef
+import Numeric
 
 #include "aesopt.h"
 #include "aes.h"
@@ -29,11 +29,6 @@
 
 newtype IV = IV (ForeignPtr Word8)
 
-{-# NOINLINE toIV #-}
-toIV :: B.ByteString -> IV
-toIV bs | B.length bs == 16 = let (bsPtr,0,16) = BI.toForeignPtr (B.copy bs) in IV bsPtr
-        | otherwise = error $ "toIV: IV has wrong length: " ++ show (B.length bs)
-
 data Direction = Encrypt | Decrypt
 
 -- | Modes ECB and CBC can only handle full 16-byte frames. This means
@@ -69,7 +64,12 @@
          -> B.ByteString -- ^ A 16-byte IV
          -> Direction 
          -> IO AESCtx
-newCtx mode (toKey -> key) (toIV -> iv) dir = newCtx' key iv mode dir
+newCtx mode (toKey -> key) (BI.toForeignPtr -> (iv,offset,size)) dir = do
+  unless (size == 16) $ error $ "newCtx: IV has wrong length: " ++ show size
+  iv' <- mallocForeignPtrBytes 16
+  withForeignPtr iv $ \ivp ->
+    withForeignPtr iv' $ \iv'p -> copyBytes iv'p (ivp `plusPtr` offset) size
+  newCtx' key (IV iv') mode dir
 
 newCtx' :: AESKey -> IV -> Mode -> Direction -> IO AESCtx
 newCtx' key _ ECB dir      = newECBCtx' key dir
