add missing modules

This commit is contained in:
Vincent Hanquez 2015-03-30 14:09:18 +01:00
parent b1e222cf3d
commit b556bdb649
7 changed files with 132 additions and 123 deletions

View File

@ -5,7 +5,6 @@
-- Stability : experimental -- Stability : experimental
-- Portability : Good -- Portability : Good
-- --
{-# LANGUAGE DeriveDataTypeable #-}
module Crypto.PubKey.RSA module Crypto.PubKey.RSA
( Error(..) ( Error(..)
, PublicKey(..) , PublicKey(..)
@ -18,7 +17,6 @@ module Crypto.PubKey.RSA
) where ) where
import Data.Bits import Data.Bits
import Data.Data
import Data.Word import Data.Word
import Control.Applicative import Control.Applicative
import Crypto.Random.Types import Crypto.Random.Types
@ -27,56 +25,6 @@ import Crypto.Number.Generate (generateMax)
import Crypto.Number.Prime (generatePrime) import Crypto.Number.Prime (generatePrime)
import Crypto.PubKey.RSA.Types import Crypto.PubKey.RSA.Types
-- | Represent a RSA public key
data PublicKey = PublicKey
{ public_size :: Int -- ^ size of key in bytes
, public_n :: Integer -- ^ public p*q
, public_e :: Integer -- ^ public exponant e
} deriving (Show,Read,Eq,Data,Typeable)
-- | Represent a RSA private key.
--
-- Only the pub, d fields are mandatory to fill.
--
-- p, q, dP, dQ, qinv are by-product during RSA generation,
-- but are useful to record here to speed up massively
-- the decrypt and sign operation.
--
-- implementations can leave optional fields to 0.
--
data PrivateKey = PrivateKey
{ private_pub :: PublicKey -- ^ public part of a private key (size, n and e)
, private_d :: Integer -- ^ private exponant d
, private_p :: Integer -- ^ p prime number
, private_q :: Integer -- ^ q prime number
, private_dP :: Integer -- ^ d mod (p-1)
, private_dQ :: Integer -- ^ d mod (q-1)
, private_qinv :: Integer -- ^ q^(-1) mod p
} deriving (Show,Read,Eq,Data,Typeable)
-- | get the size in bytes from a private key
private_size = public_size . private_pub
-- | get n from a private key
private_n = public_n . private_pub
-- | get e from a private key
private_e = public_e . private_pub
-- | Represent RSA KeyPair
--
-- note the RSA private key contains already an instance of public key for efficiency
newtype KeyPair = KeyPair PrivateKey
deriving (Show,Read,Eq,Data,Typeable)
-- | Public key of a RSA KeyPair
toPublicKey :: KeyPair -> PublicKey
toPublicKey (KeyPair priv) = private_pub priv
-- | Private key of a RSA KeyPair
toPrivateKey :: KeyPair -> PrivateKey
toPrivateKey (KeyPair priv) = priv
-- some bad implementation will not serialize ASN.1 integer properly, leading -- some bad implementation will not serialize ASN.1 integer properly, leading
-- to negative modulus. -- to negative modulus.
-- TODO : Find a better place for this -- TODO : Find a better place for this

View File

@ -21,12 +21,11 @@ module Crypto.PubKey.RSA.OAEP
, decryptSafer , decryptSafer
) where ) where
import Crypto.Random import Crypto.Random.Types
import Crypto.Types.PubKey.RSA import Crypto.PubKey.RSA.Types
import Crypto.PubKey.HashDescr import Crypto.PubKey.HashDescr
import Crypto.PubKey.MaskGenFunction import Crypto.PubKey.MaskGenFunction
import Crypto.PubKey.RSA.Prim import Crypto.PubKey.RSA.Prim
import Crypto.PubKey.RSA.Types
import Crypto.PubKey.RSA (generateBlinder) import Crypto.PubKey.RSA (generateBlinder)
import Crypto.PubKey.Internal (and') import Crypto.PubKey.Internal (and')
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
@ -77,16 +76,17 @@ encryptWithSeed seed oaep pk msg
em = B.concat [B.singleton 0x0,maskedSeed,maskedDB] em = B.concat [B.singleton 0x0,maskedSeed,maskedDB]
-- | Encrypt a message using OAEP -- | Encrypt a message using OAEP
encrypt :: CPRG g encrypt :: MonadRandom m
=> g -- ^ random number generator. => OAEPParams -- ^ OAEP params to use for encryption.
-> OAEPParams -- ^ OAEP params to use for encryption.
-> PublicKey -- ^ Public key. -> PublicKey -- ^ Public key.
-> ByteString -- ^ Message to encrypt -> ByteString -- ^ Message to encrypt
-> (Either Error ByteString, g) -> m (Either Error ByteString)
encrypt g oaep pk msg = (encryptWithSeed seed oaep pk msg, g') encrypt oaep pk msg = do
where hashF = oaepHash oaep seed <- getRandomBytes hashLen
hashLen = B.length (hashF B.empty) return (encryptWithSeed seed oaep pk msg)
(seed, g') = cprgGenerate hashLen g where
hashF = oaepHash oaep
hashLen = B.length (hashF B.empty)
-- | un-pad a OAEP encoded message. -- | un-pad a OAEP encoded message.
-- --
@ -141,11 +141,11 @@ decrypt blinder oaep pk cipher
hashLen = B.length (hashF B.empty) hashLen = B.length (hashF B.empty)
-- | Decrypt a ciphertext using OAEP and by automatically generating a blinder. -- | Decrypt a ciphertext using OAEP and by automatically generating a blinder.
decryptSafer :: CPRG g decryptSafer :: MonadRandom m
=> g -- ^ random number generator => OAEPParams -- ^ OAEP params to use for decryption
-> OAEPParams -- ^ OAEP params to use for decryption
-> PrivateKey -- ^ Private key -> PrivateKey -- ^ Private key
-> ByteString -- ^ Cipher text -> ByteString -- ^ Cipher text
-> (Either Error ByteString, g) -> m (Either Error ByteString)
decryptSafer rng oaep pk cipher = (decrypt (Just blinder) oaep pk cipher, rng') decryptSafer oaep pk cipher = do
where (blinder, rng') = generateBlinder rng (private_n pk) blinder <- generateBlinder (private_n pk)
return (decrypt (Just blinder) oaep pk cipher)

View File

@ -22,34 +22,33 @@ module Crypto.PubKey.RSA.PKCS15
, verify , verify
) where ) where
import Crypto.Random import Crypto.Random.Types
import Crypto.PubKey.Internal (and') import Crypto.PubKey.Internal (and')
import Crypto.Types.PubKey.RSA import Crypto.PubKey.RSA.Types
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import qualified Data.ByteString as B import qualified Data.ByteString as B
import Crypto.PubKey.RSA.Prim import Crypto.PubKey.RSA.Prim
import Crypto.PubKey.RSA.Types
import Crypto.PubKey.RSA (generateBlinder) import Crypto.PubKey.RSA (generateBlinder)
import Crypto.PubKey.HashDescr import Crypto.PubKey.HashDescr
-- | This produce a standard PKCS1.5 padding for encryption -- | This produce a standard PKCS1.5 padding for encryption
pad :: CPRG g => g -> Int -> ByteString -> Either Error (ByteString, g) pad :: MonadRandom m => Int -> ByteString -> m (Either Error ByteString)
pad rng len m pad len m
| B.length m > len - 11 = Left MessageTooLong | B.length m > len - 11 = return (Left MessageTooLong)
| otherwise = | otherwise = do
let (padding, rng') = getNonNullRandom rng (len - B.length m - 3) padding <- getNonNullRandom (len - B.length m - 3)
in Right (B.concat [ B.singleton 0, B.singleton 2, padding, B.singleton 0, m ], rng') return $ Right $ B.concat [ B.singleton 0, B.singleton 2, padding, B.singleton 0, m ]
where {- get random non-null bytes -} where {- get random non-null bytes -}
getNonNullRandom :: CPRG g => g -> Int -> (ByteString, g) getNonNullRandom :: MonadRandom m => Int -> m ByteString
getNonNullRandom g n = getNonNullRandom n = do
let (bs0,g') = cprgGenerate n g bs0 <- getRandomBytes n
bytes = B.pack $ filter (/= 0) $ B.unpack $ bs0 let bytes = B.pack $ filter (/= 0) $ B.unpack $ bs0
left = (n - B.length bytes) left = n - B.length bytes
in if left == 0 if left == 0
then (bytes, g') then return bytes
else let (bend, g'') = getNonNullRandom g' left else do bend <- getNonNullRandom left
in (bytes `B.append` bend, g'') return (bytes `B.append` bend)
-- | Produce a standard PKCS1.5 padding for signature -- | Produce a standard PKCS1.5 padding for signature
padSignature :: Int -> ByteString -> Either Error ByteString padSignature :: Int -> ByteString -> Either Error ByteString
@ -89,23 +88,23 @@ decrypt blinder pk c
| otherwise = unpad $ dp blinder pk c | otherwise = unpad $ dp blinder pk c
-- | decrypt message using the private key and by automatically generating a blinder. -- | decrypt message using the private key and by automatically generating a blinder.
decryptSafer :: CPRG g decryptSafer :: MonadRandom m
=> g -- ^ random generator => PrivateKey -- ^ RSA private key
-> PrivateKey -- ^ RSA private key
-> ByteString -- ^ cipher text -> ByteString -- ^ cipher text
-> (Either Error ByteString, g) -> m (Either Error ByteString)
decryptSafer rng pk b = decryptSafer pk b = do
let (blinder, rng') = generateBlinder rng (private_n pk) blinder <- generateBlinder (private_n pk)
in (decrypt (Just blinder) pk b, rng') return (decrypt (Just blinder) pk b)
-- | encrypt a bytestring using the public key and a CPRG random generator. -- | encrypt a bytestring using the public key and a CPRG random generator.
-- --
-- the message need to be smaller than the key size - 11 -- the message need to be smaller than the key size - 11
encrypt :: CPRG g => g -> PublicKey -> ByteString -> (Either Error ByteString, g) encrypt :: MonadRandom m => PublicKey -> ByteString -> m (Either Error ByteString)
encrypt rng pk m = do encrypt pk m = do
case pad rng (public_size pk) m of r <- pad (public_size pk) m
Left err -> (Left err, rng) case r of
Right (em, rng') -> (Right (ep pk em), rng') Left err -> return $ Left err
Right em -> return $ Right (ep pk em)
-- | sign message using private key, a hash and its ASN1 description -- | sign message using private key, a hash and its ASN1 description
-- --
@ -121,15 +120,14 @@ sign :: Maybe Blinder -- ^ optional blinder
sign blinder hashDescr pk m = dp blinder pk `fmap` makeSignature hashDescr (private_size pk) m sign blinder hashDescr pk m = dp blinder pk `fmap` makeSignature hashDescr (private_size pk) m
-- | sign message using the private key and by automatically generating a blinder. -- | sign message using the private key and by automatically generating a blinder.
signSafer :: CPRG g signSafer :: MonadRandom m
=> g -- ^ random generator => HashDescr -- ^ Hash descriptor
-> HashDescr -- ^ Hash descriptor
-> PrivateKey -- ^ private key -> PrivateKey -- ^ private key
-> ByteString -- ^ message to sign -> ByteString -- ^ message to sign
-> (Either Error ByteString, g) -> m (Either Error ByteString)
signSafer rng hashDescr pk m = signSafer hashDescr pk m = do
let (blinder, rng') = generateBlinder rng (private_n pk) blinder <- generateBlinder (private_n pk)
in (sign (Just blinder) hashDescr pk m, rng') return (sign (Just blinder) hashDescr pk m)
-- | verify message with the signed message -- | verify message with the signed message
verify :: HashDescr -> PublicKey -> ByteString -> ByteString -> Bool verify :: HashDescr -> PublicKey -> ByteString -> ByteString -> Bool

View File

@ -16,8 +16,8 @@ module Crypto.PubKey.RSA.PSS
, verify , verify
) where ) where
import Crypto.Random import Crypto.Random.Types
import Crypto.Types.PubKey.RSA import Crypto.PubKey.RSA.Types
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import Data.Byteable import Data.Byteable
import qualified Data.ByteString as B import qualified Data.ByteString as B
@ -78,25 +78,25 @@ signWithSalt salt blinder params pk m
em = B.concat [maskedDB, h, B.singleton (pssTrailerField params)] em = B.concat [maskedDB, h, B.singleton (pssTrailerField params)]
-- | Sign using the PSS Parameters -- | Sign using the PSS Parameters
sign :: CPRG g sign :: MonadRandom m
=> g -- ^ random generator to use to generate the salt => Maybe Blinder -- ^ optional blinder to use
-> Maybe Blinder -- ^ optional blinder to use
-> PSSParams -- ^ PSS Parameters to use -> PSSParams -- ^ PSS Parameters to use
-> PrivateKey -- ^ RSA Private Key -> PrivateKey -- ^ RSA Private Key
-> ByteString -- ^ Message to sign -> ByteString -- ^ Message to sign
-> (Either Error ByteString, g) -> m (Either Error ByteString)
sign rng blinder params pk m = (signWithSalt salt blinder params pk m, rng') sign blinder params pk m = do
where (salt,rng') = cprgGenerate (pssSaltLength params) rng salt <- getRandomBytes (pssSaltLength params)
return (signWithSalt salt blinder params pk m)
-- | Sign using the PSS Parameters and an automatically generated blinder. -- | Sign using the PSS Parameters and an automatically generated blinder.
signSafer :: CPRG g signSafer :: MonadRandom m
=> g -- ^ random generator => PSSParams -- ^ PSS Parameters to use
-> PSSParams -- ^ PSS Parameters to use
-> PrivateKey -- ^ private key -> PrivateKey -- ^ private key
-> ByteString -- ^ message to sign -> ByteString -- ^ message to sign
-> (Either Error ByteString, g) -> m (Either Error ByteString)
signSafer rng params pk m = sign rng' (Just blinder) params pk m signSafer params pk m = do
where (blinder, rng') = generateBlinder rng (private_n pk) blinder <- generateBlinder (private_n pk)
sign (Just blinder) params pk m
-- | Verify a signature using the PSS Parameters -- | Verify a signature using the PSS Parameters
verify :: PSSParams -- ^ PSS Parameters to use to verify, verify :: PSSParams -- ^ PSS Parameters to use to verify,

View File

@ -14,8 +14,7 @@ module Crypto.PubKey.RSA.Prim
) where ) where
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import Crypto.PubKey.RSA.Types (Blinder(..)) import Crypto.PubKey.RSA.Types
import Crypto.Types.PubKey.RSA
import Crypto.Number.ModArithmetic (expFast, expSafe) import Crypto.Number.ModArithmetic (expFast, expSafe)
import Crypto.Number.Serialize (os2ip, i2ospOf_) import Crypto.Number.Serialize (os2ip, i2ospOf_)

View File

@ -5,11 +5,21 @@
-- Stability : experimental -- Stability : experimental
-- Portability : Good -- Portability : Good
-- --
{-# LANGUAGE DeriveDataTypeable #-}
module Crypto.PubKey.RSA.Types module Crypto.PubKey.RSA.Types
( Error(..) ( Error(..)
, Blinder(..) , Blinder(..)
, PublicKey(..)
, PrivateKey(..)
, KeyPair(..)
, private_size
, private_n
, private_e
) where ) where
import Data.Data
import Data.Typeable
-- | Blinder which is used to obfuscate the timing -- | Blinder which is used to obfuscate the timing
-- of the decryption primitive (used by decryption and signing). -- of the decryption primitive (used by decryption and signing).
data Blinder = Blinder !Integer !Integer data Blinder = Blinder !Integer !Integer
@ -24,3 +34,53 @@ data Error =
| InvalidParameters -- ^ some parameters lead to breaking assumptions. | InvalidParameters -- ^ some parameters lead to breaking assumptions.
deriving (Show,Eq) deriving (Show,Eq)
-- | Represent a RSA public key
data PublicKey = PublicKey
{ public_size :: Int -- ^ size of key in bytes
, public_n :: Integer -- ^ public p*q
, public_e :: Integer -- ^ public exponant e
} deriving (Show,Read,Eq,Data,Typeable)
-- | Represent a RSA private key.
--
-- Only the pub, d fields are mandatory to fill.
--
-- p, q, dP, dQ, qinv are by-product during RSA generation,
-- but are useful to record here to speed up massively
-- the decrypt and sign operation.
--
-- implementations can leave optional fields to 0.
--
data PrivateKey = PrivateKey
{ private_pub :: PublicKey -- ^ public part of a private key (size, n and e)
, private_d :: Integer -- ^ private exponant d
, private_p :: Integer -- ^ p prime number
, private_q :: Integer -- ^ q prime number
, private_dP :: Integer -- ^ d mod (p-1)
, private_dQ :: Integer -- ^ d mod (q-1)
, private_qinv :: Integer -- ^ q^(-1) mod p
} deriving (Show,Read,Eq,Data,Typeable)
-- | get the size in bytes from a private key
private_size = public_size . private_pub
-- | get n from a private key
private_n = public_n . private_pub
-- | get e from a private key
private_e = public_e . private_pub
-- | Represent RSA KeyPair
--
-- note the RSA private key contains already an instance of public key for efficiency
newtype KeyPair = KeyPair PrivateKey
deriving (Show,Read,Eq,Data,Typeable)
-- | Public key of a RSA KeyPair
toPublicKey :: KeyPair -> PublicKey
toPublicKey (KeyPair priv) = private_pub priv
-- | Private key of a RSA KeyPair
toPrivateKey :: KeyPair -> PrivateKey
toPrivateKey (KeyPair priv) = priv

View File

@ -69,6 +69,10 @@ Library
Crypto.PubKey.ECC.ECDSA Crypto.PubKey.ECC.ECDSA
Crypto.PubKey.ECC.Types Crypto.PubKey.ECC.Types
Crypto.PubKey.RSA Crypto.PubKey.RSA
Crypto.PubKey.RSA.PKCS15
Crypto.PubKey.RSA.Prim
Crypto.PubKey.RSA.PSS
Crypto.PubKey.RSA.OAEP
Crypto.PubKey.RSA.Types Crypto.PubKey.RSA.Types
Crypto.Random Crypto.Random
Crypto.Random.Types Crypto.Random.Types