module Botan.Low.PubKey.KeyEncapsulation (
KEMSharedKey
, KEMEncapsulatedKey
, KEMEncrypt(..)
, withKEMEncrypt
, kemEncryptDestroy
, kemEncryptCreate
, kemEncryptSharedKeyLength
, kemEncryptEncapsulatedKeyLength
, kemEncryptCreateSharedKey
, KEMDecrypt(..)
, withKEMDecrypt
, kemDecryptDestroy
, kemDecryptCreate
, kemDecryptSharedKeyLength
, kemDecryptSharedKey
) where
import Botan.Bindings.ConstPtr (ConstPtr (..))
import Botan.Bindings.PubKey.KeyEncapsulation
import Botan.Low.Error.Internal
import Botan.Low.Internal.ByteString
import Botan.Low.KDF
import Botan.Low.Make
import Botan.Low.PubKey
import Botan.Low.Remake
import Botan.Low.RNG
import Control.DeepSeq
import Data.ByteString (ByteString)
import qualified Data.ByteString as ByteString
import Foreign.C.Types
import Foreign.ForeignPtr
import Foreign.Marshal.Alloc
import Foreign.Ptr
import Foreign.Storable
type KEMSharedKey = ByteString
type KEMEncapsulatedKey = ByteString
newtype KEMEncrypt = MkKEMEncrypt { KEMEncrypt -> ForeignPtr BotanPKOpKEMEncryptStruct
foreignPtr :: ForeignPtr BotanPKOpKEMEncryptStruct }
withKEMEncrypt :: KEMEncrypt -> (BotanPKOpKEMEncrypt -> IO a) -> IO a
kemEncryptDestroy :: KEMEncrypt -> IO ()
createKEMEncrypt :: (Ptr BotanPKOpKEMEncrypt -> IO CInt) -> IO KEMEncrypt
(KEMEncrypt -> (BotanPKOpKEMEncrypt -> IO a) -> IO a
withKEMEncrypt, KEMEncrypt -> IO ()
kemEncryptDestroy, (Ptr BotanPKOpKEMEncrypt -> IO CInt) -> IO KEMEncrypt
createKEMEncrypt)
= (Ptr BotanPKOpKEMEncryptStruct -> BotanPKOpKEMEncrypt)
-> (BotanPKOpKEMEncrypt -> Ptr BotanPKOpKEMEncryptStruct)
-> (ForeignPtr BotanPKOpKEMEncryptStruct -> KEMEncrypt)
-> (KEMEncrypt -> ForeignPtr BotanPKOpKEMEncryptStruct)
-> FinalizerPtr BotanPKOpKEMEncryptStruct
-> (KEMEncrypt -> (BotanPKOpKEMEncrypt -> IO a) -> IO a,
KEMEncrypt -> IO (),
(Ptr BotanPKOpKEMEncrypt -> IO CInt) -> IO KEMEncrypt)
forall botan struct object a.
Storable botan =>
(Ptr struct -> botan)
-> (botan -> Ptr struct)
-> (ForeignPtr struct -> object)
-> (object -> ForeignPtr struct)
-> FinalizerPtr struct
-> (object -> (botan -> IO a) -> IO a, object -> IO (),
(Ptr botan -> IO CInt) -> IO object)
mkBindings
Ptr BotanPKOpKEMEncryptStruct -> BotanPKOpKEMEncrypt
MkBotanPKOpKEMEncrypt (.ptr)
ForeignPtr BotanPKOpKEMEncryptStruct -> KEMEncrypt
MkKEMEncrypt (.foreignPtr)
FinalizerPtr BotanPKOpKEMEncryptStruct
botan_pk_op_kem_encrypt_destroy
kemEncryptCreate
:: PubKey
-> KDFName
-> IO KEMEncrypt
kemEncryptCreate :: PubKey -> KEMSharedKey -> IO KEMEncrypt
kemEncryptCreate PubKey
pk KEMSharedKey
algo = PubKey -> (BotanPubKey -> IO KEMEncrypt) -> IO KEMEncrypt
forall a. PubKey -> (BotanPubKey -> IO a) -> IO a
withPubKey PubKey
pk ((BotanPubKey -> IO KEMEncrypt) -> IO KEMEncrypt)
-> (BotanPubKey -> IO KEMEncrypt) -> IO KEMEncrypt
forall a b. (a -> b) -> a -> b
$ \ BotanPubKey
pkPtr -> do
KEMSharedKey -> (Ptr CChar -> IO KEMEncrypt) -> IO KEMEncrypt
forall a. KEMSharedKey -> (Ptr CChar -> IO a) -> IO a
asCString KEMSharedKey
algo ((Ptr CChar -> IO KEMEncrypt) -> IO KEMEncrypt)
-> (Ptr CChar -> IO KEMEncrypt) -> IO KEMEncrypt
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
algoPtr -> do
(Ptr BotanPKOpKEMEncrypt -> IO CInt) -> IO KEMEncrypt
createKEMEncrypt ((Ptr BotanPKOpKEMEncrypt -> IO CInt) -> IO KEMEncrypt)
-> (Ptr BotanPKOpKEMEncrypt -> IO CInt) -> IO KEMEncrypt
forall a b. (a -> b) -> a -> b
$ \ Ptr BotanPKOpKEMEncrypt
out -> Ptr BotanPKOpKEMEncrypt -> BotanPubKey -> ConstPtr CChar -> IO CInt
botan_pk_op_kem_encrypt_create
Ptr BotanPKOpKEMEncrypt
out
BotanPubKey
pkPtr
(Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
algoPtr)
kemEncryptSharedKeyLength
:: KEMEncrypt
-> Int
-> IO Int
kemEncryptSharedKeyLength :: KEMEncrypt -> Int -> IO Int
kemEncryptSharedKeyLength = WithPtr KEMEncrypt BotanPKOpKEMEncrypt
-> GetSize_csize BotanPKOpKEMEncrypt -> KEMEncrypt -> Int -> IO Int
forall typ ptr.
WithPtr typ ptr -> GetSize_csize ptr -> typ -> Int -> IO Int
mkGetSize_csize KEMEncrypt -> (BotanPKOpKEMEncrypt -> IO a) -> IO a
WithPtr KEMEncrypt BotanPKOpKEMEncrypt
withKEMEncrypt GetSize_csize BotanPKOpKEMEncrypt
botan_pk_op_kem_encrypt_shared_key_length
kemEncryptEncapsulatedKeyLength
:: KEMEncrypt
-> IO Int
kemEncryptEncapsulatedKeyLength :: KEMEncrypt -> IO Int
kemEncryptEncapsulatedKeyLength = WithPtr KEMEncrypt BotanPKOpKEMEncrypt
-> GetSize BotanPKOpKEMEncrypt -> KEMEncrypt -> IO Int
forall typ ptr. WithPtr typ ptr -> GetSize ptr -> typ -> IO Int
mkGetSize KEMEncrypt -> (BotanPKOpKEMEncrypt -> IO a) -> IO a
WithPtr KEMEncrypt BotanPKOpKEMEncrypt
withKEMEncrypt GetSize BotanPKOpKEMEncrypt
botan_pk_op_kem_encrypt_encapsulated_key_length
kemEncryptCreateSharedKey
:: KEMEncrypt
-> RNG
-> ByteString
-> Int
-> IO (KEMSharedKey,KEMEncapsulatedKey)
kemEncryptCreateSharedKey :: KEMEncrypt
-> RNG -> KEMSharedKey -> Int -> IO (KEMSharedKey, KEMSharedKey)
kemEncryptCreateSharedKey KEMEncrypt
ke RNG
rng KEMSharedKey
salt Int
desiredLen = KEMEncrypt
-> (BotanPKOpKEMEncrypt -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey)
WithPtr KEMEncrypt BotanPKOpKEMEncrypt
withKEMEncrypt KEMEncrypt
ke ((BotanPKOpKEMEncrypt -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey))
-> (BotanPKOpKEMEncrypt -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey)
forall a b. (a -> b) -> a -> b
$ \ BotanPKOpKEMEncrypt
kePtr -> do
RNG
-> (BotanRNG -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey)
forall a. RNG -> (BotanRNG -> IO a) -> IO a
withRNG RNG
rng ((BotanRNG -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey))
-> (BotanRNG -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey)
forall a b. (a -> b) -> a -> b
$ \ BotanRNG
botanRNG -> do
KEMSharedKey
-> (Ptr Word8 -> CSize -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey)
forall byte a. KEMSharedKey -> (Ptr byte -> CSize -> IO a) -> IO a
asBytesLen KEMSharedKey
salt ((Ptr Word8 -> CSize -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey))
-> (Ptr Word8 -> CSize -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey)
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
saltPtr CSize
saltLen -> do
(Ptr CSize -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CSize -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey))
-> (Ptr CSize -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey)
forall a b. (a -> b) -> a -> b
$ \ Ptr CSize
sharedSzPtr -> do
(Ptr CSize -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CSize -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey))
-> (Ptr CSize -> IO (KEMSharedKey, KEMSharedKey))
-> IO (KEMSharedKey, KEMSharedKey)
forall a b. (a -> b) -> a -> b
$ \ Ptr CSize
encapSzPtr -> do
Int
sharedSz <- KEMEncrypt -> Int -> IO Int
kemEncryptSharedKeyLength KEMEncrypt
ke Int
desiredLen
Int
encapSz <- KEMEncrypt -> IO Int
kemEncryptEncapsulatedKeyLength KEMEncrypt
ke
Ptr CSize -> CSize -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CSize
sharedSzPtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
sharedSz)
Ptr CSize -> CSize -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CSize
encapSzPtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
encapSz)
Int
-> (Ptr Word8 -> IO KEMSharedKey)
-> IO (KEMSharedKey, KEMSharedKey)
forall byte a. Int -> (Ptr byte -> IO a) -> IO (a, KEMSharedKey)
allocBytesWith Int
encapSz ((Ptr Word8 -> IO KEMSharedKey) -> IO (KEMSharedKey, KEMSharedKey))
-> (Ptr Word8 -> IO KEMSharedKey)
-> IO (KEMSharedKey, KEMSharedKey)
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
encapPtr -> do
Int -> (Ptr Word8 -> IO ()) -> IO KEMSharedKey
forall byte. Int -> (Ptr byte -> IO ()) -> IO KEMSharedKey
allocBytes Int
sharedSz ((Ptr Word8 -> IO ()) -> IO KEMSharedKey)
-> (Ptr Word8 -> IO ()) -> IO KEMSharedKey
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
sharedPtr -> do
HasCallStack => IO CInt -> IO ()
IO CInt -> IO ()
throwBotanIfNegative_ (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ BotanPKOpKEMEncrypt
-> BotanRNG
-> ConstPtr Word8
-> CSize
-> CSize
-> Ptr Word8
-> Ptr CSize
-> Ptr Word8
-> Ptr CSize
-> IO CInt
botan_pk_op_kem_encrypt_create_shared_key
BotanPKOpKEMEncrypt
kePtr
BotanRNG
botanRNG
(Ptr Word8 -> ConstPtr Word8
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr Word8
saltPtr)
CSize
saltLen
(Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
desiredLen)
Ptr Word8
sharedPtr
Ptr CSize
sharedSzPtr
Ptr Word8
encapPtr
Ptr CSize
encapSzPtr
newtype KEMDecrypt = MkKEMDecrypt { KEMDecrypt -> ForeignPtr BotanPKOpKEMDecryptStruct
foreignPtr :: ForeignPtr BotanPKOpKEMDecryptStruct }
withKEMDecrypt :: KEMDecrypt -> (BotanPKOpKEMDecrypt -> IO a) -> IO a
kemDecryptDestroy :: KEMDecrypt -> IO ()
createKEMDecrypt :: (Ptr BotanPKOpKEMDecrypt -> IO CInt) -> IO KEMDecrypt
(KEMDecrypt -> (BotanPKOpKEMDecrypt -> IO a) -> IO a
withKEMDecrypt, KEMDecrypt -> IO ()
kemDecryptDestroy, (Ptr BotanPKOpKEMDecrypt -> IO CInt) -> IO KEMDecrypt
createKEMDecrypt)
= (Ptr BotanPKOpKEMDecryptStruct -> BotanPKOpKEMDecrypt)
-> (BotanPKOpKEMDecrypt -> Ptr BotanPKOpKEMDecryptStruct)
-> (ForeignPtr BotanPKOpKEMDecryptStruct -> KEMDecrypt)
-> (KEMDecrypt -> ForeignPtr BotanPKOpKEMDecryptStruct)
-> FinalizerPtr BotanPKOpKEMDecryptStruct
-> (KEMDecrypt -> (BotanPKOpKEMDecrypt -> IO a) -> IO a,
KEMDecrypt -> IO (),
(Ptr BotanPKOpKEMDecrypt -> IO CInt) -> IO KEMDecrypt)
forall botan struct object a.
Storable botan =>
(Ptr struct -> botan)
-> (botan -> Ptr struct)
-> (ForeignPtr struct -> object)
-> (object -> ForeignPtr struct)
-> FinalizerPtr struct
-> (object -> (botan -> IO a) -> IO a, object -> IO (),
(Ptr botan -> IO CInt) -> IO object)
mkBindings
Ptr BotanPKOpKEMDecryptStruct -> BotanPKOpKEMDecrypt
MkBotanPKOpKEMDecrypt (.ptr)
ForeignPtr BotanPKOpKEMDecryptStruct -> KEMDecrypt
MkKEMDecrypt (.foreignPtr)
FinalizerPtr BotanPKOpKEMDecryptStruct
botan_pk_op_kem_decrypt_destroy
kemDecryptCreate
:: PrivKey
-> KDFName
-> IO KEMDecrypt
kemDecryptCreate :: PrivKey -> KEMSharedKey -> IO KEMDecrypt
kemDecryptCreate PrivKey
sk KEMSharedKey
algo = PrivKey -> (BotanPrivKey -> IO KEMDecrypt) -> IO KEMDecrypt
forall a. PrivKey -> (BotanPrivKey -> IO a) -> IO a
withPrivKey PrivKey
sk ((BotanPrivKey -> IO KEMDecrypt) -> IO KEMDecrypt)
-> (BotanPrivKey -> IO KEMDecrypt) -> IO KEMDecrypt
forall a b. (a -> b) -> a -> b
$ \ BotanPrivKey
skPtr -> do
KEMSharedKey -> (Ptr CChar -> IO KEMDecrypt) -> IO KEMDecrypt
forall a. KEMSharedKey -> (Ptr CChar -> IO a) -> IO a
asCString KEMSharedKey
algo ((Ptr CChar -> IO KEMDecrypt) -> IO KEMDecrypt)
-> (Ptr CChar -> IO KEMDecrypt) -> IO KEMDecrypt
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
algoPtr -> do
(Ptr BotanPKOpKEMDecrypt -> IO CInt) -> IO KEMDecrypt
createKEMDecrypt ((Ptr BotanPKOpKEMDecrypt -> IO CInt) -> IO KEMDecrypt)
-> (Ptr BotanPKOpKEMDecrypt -> IO CInt) -> IO KEMDecrypt
forall a b. (a -> b) -> a -> b
$ \ Ptr BotanPKOpKEMDecrypt
out -> Ptr BotanPKOpKEMDecrypt
-> BotanPrivKey -> ConstPtr CChar -> IO CInt
botan_pk_op_kem_decrypt_create
Ptr BotanPKOpKEMDecrypt
out
BotanPrivKey
skPtr
(Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
algoPtr)
kemDecryptSharedKeyLength
:: KEMDecrypt
-> Int
-> IO Int
kemDecryptSharedKeyLength :: KEMDecrypt -> Int -> IO Int
kemDecryptSharedKeyLength = WithPtr KEMDecrypt BotanPKOpKEMDecrypt
-> GetSize_csize BotanPKOpKEMDecrypt -> KEMDecrypt -> Int -> IO Int
forall typ ptr.
WithPtr typ ptr -> GetSize_csize ptr -> typ -> Int -> IO Int
mkGetSize_csize KEMDecrypt -> (BotanPKOpKEMDecrypt -> IO a) -> IO a
WithPtr KEMDecrypt BotanPKOpKEMDecrypt
withKEMDecrypt GetSize_csize BotanPKOpKEMDecrypt
botan_pk_op_kem_decrypt_shared_key_length
kemDecryptSharedKey
:: KEMDecrypt
-> ByteString
-> KEMEncapsulatedKey
-> Int
-> IO KEMSharedKey
kemDecryptSharedKey :: KEMDecrypt
-> KEMSharedKey -> KEMSharedKey -> Int -> IO KEMSharedKey
kemDecryptSharedKey KEMDecrypt
kd KEMSharedKey
salt KEMSharedKey
encap Int
desiredLen = KEMDecrypt
-> (BotanPKOpKEMDecrypt -> IO KEMSharedKey) -> IO KEMSharedKey
WithPtr KEMDecrypt BotanPKOpKEMDecrypt
withKEMDecrypt KEMDecrypt
kd ((BotanPKOpKEMDecrypt -> IO KEMSharedKey) -> IO KEMSharedKey)
-> (BotanPKOpKEMDecrypt -> IO KEMSharedKey) -> IO KEMSharedKey
forall a b. (a -> b) -> a -> b
$ \ BotanPKOpKEMDecrypt
kdPtr -> do
KEMSharedKey
-> (Ptr Word8 -> CSize -> IO KEMSharedKey) -> IO KEMSharedKey
forall byte a. KEMSharedKey -> (Ptr byte -> CSize -> IO a) -> IO a
asBytesLen KEMSharedKey
salt ((Ptr Word8 -> CSize -> IO KEMSharedKey) -> IO KEMSharedKey)
-> (Ptr Word8 -> CSize -> IO KEMSharedKey) -> IO KEMSharedKey
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
saltPtr CSize
saltLen -> do
KEMSharedKey
-> (Ptr Word8 -> CSize -> IO KEMSharedKey) -> IO KEMSharedKey
forall byte a. KEMSharedKey -> (Ptr byte -> CSize -> IO a) -> IO a
asBytesLen KEMSharedKey
encap ((Ptr Word8 -> CSize -> IO KEMSharedKey) -> IO KEMSharedKey)
-> (Ptr Word8 -> CSize -> IO KEMSharedKey) -> IO KEMSharedKey
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
encapPtr CSize
encapLen -> do
(Ptr CSize -> IO KEMSharedKey) -> IO KEMSharedKey
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CSize -> IO KEMSharedKey) -> IO KEMSharedKey)
-> (Ptr CSize -> IO KEMSharedKey) -> IO KEMSharedKey
forall a b. (a -> b) -> a -> b
$ \ Ptr CSize
sharedSzPtr -> do
Int
sharedSz <- KEMDecrypt -> Int -> IO Int
kemDecryptSharedKeyLength KEMDecrypt
kd Int
desiredLen
Ptr CSize -> CSize -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CSize
sharedSzPtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
sharedSz)
KEMSharedKey
bytes <- Int -> (Ptr Word8 -> IO ()) -> IO KEMSharedKey
forall byte. Int -> (Ptr byte -> IO ()) -> IO KEMSharedKey
allocBytes Int
sharedSz ((Ptr Word8 -> IO ()) -> IO KEMSharedKey)
-> (Ptr Word8 -> IO ()) -> IO KEMSharedKey
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
outPtr -> do
HasCallStack => IO CInt -> IO ()
IO CInt -> IO ()
throwBotanIfNegative_ (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ BotanPKOpKEMDecrypt
-> ConstPtr Word8
-> CSize
-> ConstPtr Word8
-> CSize
-> CSize
-> Ptr Word8
-> Ptr CSize
-> IO CInt
botan_pk_op_kem_decrypt_shared_key
BotanPKOpKEMDecrypt
kdPtr
(Ptr Word8 -> ConstPtr Word8
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr Word8
saltPtr)
CSize
saltLen
(Ptr Word8 -> ConstPtr Word8
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr Word8
encapPtr)
CSize
encapLen
(Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
desiredLen)
Ptr Word8
outPtr
Ptr CSize
sharedSzPtr
CSize
actualSharedSz <- Ptr CSize -> IO CSize
forall a. Storable a => Ptr a -> IO a
peek Ptr CSize
sharedSzPtr
KEMSharedKey -> IO KEMSharedKey
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (KEMSharedKey -> IO KEMSharedKey)
-> KEMSharedKey -> IO KEMSharedKey
forall a b. NFData a => (a -> b) -> a -> b
$!! Int -> KEMSharedKey -> KEMSharedKey
ByteString.take (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
actualSharedSz) KEMSharedKey
bytes