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
-- Portability : Good
--
{-# LANGUAGE DeriveDataTypeable #-}
module Crypto.PubKey.RSA
( Error(..)
, PublicKey(..)
@ -18,7 +17,6 @@ module Crypto.PubKey.RSA
) where
import Data.Bits
import Data.Data
import Data.Word
import Control.Applicative
import Crypto.Random.Types
@ -27,56 +25,6 @@ import Crypto.Number.Generate (generateMax)
import Crypto.Number.Prime (generatePrime)
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
-- to negative modulus.
-- TODO : Find a better place for this

View File

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

View File

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

View File

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

View File

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

View File

@ -5,11 +5,21 @@
-- Stability : experimental
-- Portability : Good
--
{-# LANGUAGE DeriveDataTypeable #-}
module Crypto.PubKey.RSA.Types
( Error(..)
, Blinder(..)
, PublicKey(..)
, PrivateKey(..)
, KeyPair(..)
, private_size
, private_n
, private_e
) where
import Data.Data
import Data.Typeable
-- | Blinder which is used to obfuscate the timing
-- of the decryption primitive (used by decryption and signing).
data Blinder = Blinder !Integer !Integer
@ -24,3 +34,53 @@ data Error =
| InvalidParameters -- ^ some parameters lead to breaking assumptions.
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.Types
Crypto.PubKey.RSA
Crypto.PubKey.RSA.PKCS15
Crypto.PubKey.RSA.Prim
Crypto.PubKey.RSA.PSS
Crypto.PubKey.RSA.OAEP
Crypto.PubKey.RSA.Types
Crypto.Random
Crypto.Random.Types