RSA-2.4.1: Implementation of RSA, using the padding schemes of PKCS#1 v2.1.

Safe Haskell | None
Language | Haskell98

Codec.Crypto.RSA.Exceptions

Contents

- Keys and key generation
- High-level encryption and signature functions
- Core routines for OAEP
- Core PSS routines
- Hashing algorithm declarations for use in RSA functions
- Other mathematical functions that are handy for implementing

Synopsis

- data RSAError
  - = RSAError String
  - | RSAKeySizeTooSmall
  - | RSAIntegerTooLargeToPack
  - | RSAMessageRepOutOfRange
  - | RSACipherRepOutOfRange
  - | RSAMessageTooShort
  - | RSAMessageTooLong
  - | RSAMaskTooLong
  - | RSAIncorrectSigSize
  - | RSAIncorrectMsgSize
  - | RSADecryptionError
  - | RSAGenError GenError
- data HashInfo = HashInfo {
  - algorithmIdent :: ByteString
  - hashFunction :: ByteString -> ByteString
  }
- data PrivateKey = PrivateKey {
  - private_pub :: PublicKey
  - private_d :: Integer
  - private_p :: Integer
  - private_q :: Integer
  - private_dP :: Integer
  - private_dQ :: Integer
  - private_qinv :: Integer
  }
- data PublicKey = PublicKey {
  - public_size :: Int
  - public_n :: Integer
  - public_e :: Integer
  }
- generateKeyPair :: CryptoRandomGen g => g -> Int -> (PublicKey, PrivateKey, g)
- encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g)
- encryptOAEP :: CryptoRandomGen g => g -> (ByteString -> ByteString) -> MGF -> ByteString -> PublicKey -> ByteString -> (ByteString, g)
- encryptPKCS :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g)
- decrypt :: PrivateKey -> ByteString -> ByteString
- decryptOAEP :: (ByteString -> ByteString) -> MGF -> ByteString -> PrivateKey -> ByteString -> ByteString
- decryptPKCS :: PrivateKey -> ByteString -> ByteString
- sign :: PrivateKey -> ByteString -> ByteString
- verify :: PublicKey -> ByteString -> ByteString -> Bool
- type MGF = ByteString -> Int64 -> Either RSAError ByteString
- generateMGF1 :: (ByteString -> ByteString) -> MGF
- rsaes_oaep_encrypt :: CryptoRandomGen g => g -> (ByteString -> ByteString) -> MGF -> PublicKey -> ByteString -> ByteString -> (ByteString, g)
- rsaes_oaep_decrypt :: (ByteString -> ByteString) -> MGF -> PrivateKey -> ByteString -> ByteString -> ByteString
- rsaes_pkcs1_v1_5_encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g)
- rsaes_pkcs1_v1_5_decrypt :: PrivateKey -> ByteString -> ByteString
- rsassa_pkcs1_v1_5_sign :: HashInfo -> PrivateKey -> ByteString -> ByteString
- rsassa_pkcs1_v1_5_verify :: HashInfo -> PublicKey -> ByteString -> ByteString -> Bool
- hashSHA1 :: HashInfo
- hashSHA224 :: HashInfo
- hashSHA256 :: HashInfo
- hashSHA384 :: HashInfo
- hashSHA512 :: HashInfo
- largeRandomPrime :: CryptoRandomGen g => g -> Int -> (Integer, g)
- generatePQ :: CryptoRandomGen g => g -> Int -> (Integer, Integer, g)
- chunkify :: ByteString -> Int64 -> [ByteString]
- os2ip :: ByteString -> Integer
- i2osp :: Integral a => a -> Int -> ByteString
- rsa_dp :: Integer -> Integer -> Integer -> Integer
- rsa_ep :: Integer -> Integer -> Integer -> Integer
- rsa_vp1 :: Integer -> Integer -> Integer -> Integer
- rsa_sp1 :: Integer -> Integer -> Integer -> Integer
- modular_inverse :: Integer -> Integer -> Integer
- modular_exponentiation :: Integer -> Integer -> Integer -> Integer
- randomBS :: CryptoRandomGen g => g -> Int -> (ByteString, g)
- randomNZBS :: CryptoRandomGen g => g -> Int -> (ByteString, g)

# Documentation

data RSAError Source #

Constructors

RSAError String |
RSAKeySizeTooSmall |
RSAIntegerTooLargeToPack |
RSAMessageRepOutOfRange |
RSACipherRepOutOfRange |
RSAMessageTooShort |
RSAMessageTooLong |
RSAMaskTooLong |
RSAIncorrectSigSize |
RSAIncorrectMsgSize |
RSADecryptionError |
RSAGenError GenError |

#### Instances

Instances details

Exception RSAError Source # |
Instance details Defined in Codec.Crypto.RSA.Pure Methods toException :: RSAError -> SomeException Source # fromException :: SomeException -> Maybe RSAError Source # displayException :: RSAError -> String Source # backtraceDesired :: RSAError -> Bool Source #
Show RSAError Source # |
Instance details Defined in Codec.Crypto.RSA.Pure Methods showsPrec :: Int -> RSAError -> ShowS Source # show :: RSAError -> String Source # showList :: [RSAError] -> ShowS Source #
Eq RSAError Source # |
Instance details Defined in Codec.Crypto.RSA.Pure Methods (==) :: RSAError -> RSAError -> Bool Source # (/=) :: RSAError -> RSAError -> Bool Source #

data HashInfo Source #

Constructors

HashInfo |

Fields

- algorithmIdent :: ByteString

  The ASN.1 DER encoding of the hash function identifier.

- hashFunction :: ByteString -> ByteString

  The hash function

# Keys and key generation

data PrivateKey Source #

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.

Constructors

PrivateKey |

Fields

- 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

#### Instances

Instances details

ASN1Object PrivateKey |
Instance details Defined in Crypto.Types.PubKey.RSA Methods toASN1 :: PrivateKey -> ASN1S fromASN1 :: [ASN1] -> Either String (PrivateKey, [ASN1])
Binary PrivateKey Source # |
Instance details Defined in Codec.Crypto.RSA.Pure Methods put :: PrivateKey -> Put Source # get :: Get PrivateKey Source # putList :: [PrivateKey] -> Put Source #
Data PrivateKey |

Instance details

Defined in Crypto.Types.PubKey.RSA

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> PrivateKey -> c PrivateKey Source #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c PrivateKey Source #

toConstr :: PrivateKey -> Constr Source #

dataTypeOf :: PrivateKey -> DataType Source #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c PrivateKey) Source #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PrivateKey) Source #

gmapT :: (forall b. Data b => b -> b) -> PrivateKey -> PrivateKey Source #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> PrivateKey -> r Source #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> PrivateKey -> r Source #

gmapQ :: (forall d. Data d => d -> u) -> PrivateKey -> [u] Source #

gmapQi :: Int -> (forall d. Data d => d -> u) -> PrivateKey -> u Source #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> PrivateKey -> m PrivateKey Source #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> PrivateKey -> m PrivateKey Source #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> PrivateKey -> m PrivateKey Source #

Read PrivateKey |
Instance details Defined in Crypto.Types.PubKey.RSA Methods readsPrec :: Int -> ReadS PrivateKey Source # readList :: ReadS [PrivateKey] Source # readPrec :: ReadPrec PrivateKey Source # readListPrec :: ReadPrec [PrivateKey] Source #
Show PrivateKey |
Instance details Defined in Crypto.Types.PubKey.RSA Methods showsPrec :: Int -> PrivateKey -> ShowS Source # show :: PrivateKey -> String Source # showList :: [PrivateKey] -> ShowS Source #
Eq PrivateKey |
Instance details Defined in Crypto.Types.PubKey.RSA Methods (==) :: PrivateKey -> PrivateKey -> Bool Source # (/=) :: PrivateKey -> PrivateKey -> Bool Source #

data PublicKey Source #

Represent a RSA public key

Constructors

PublicKey |

Fields

- public_size :: Int

  size of key in bytes

- public_n :: Integer

  public p*q

- public_e :: Integer

  public exponant e

#### Instances

Instances details

ASN1Object PublicKey |
Instance details Defined in Crypto.Types.PubKey.RSA Methods toASN1 :: PublicKey -> ASN1S fromASN1 :: [ASN1] -> Either String (PublicKey, [ASN1])
Binary PublicKey Source # |
Instance details Defined in Codec.Crypto.RSA.Pure Methods put :: PublicKey -> Put Source # get :: Get PublicKey Source # putList :: [PublicKey] -> Put Source #
Data PublicKey |

Instance details

Defined in Crypto.Types.PubKey.RSA

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> PublicKey -> c PublicKey Source #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c PublicKey Source #

toConstr :: PublicKey -> Constr Source #

dataTypeOf :: PublicKey -> DataType Source #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c PublicKey) Source #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PublicKey) Source #

gmapT :: (forall b. Data b => b -> b) -> PublicKey -> PublicKey Source #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> PublicKey -> r Source #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> PublicKey -> r Source #

gmapQ :: (forall d. Data d => d -> u) -> PublicKey -> [u] Source #

gmapQi :: Int -> (forall d. Data d => d -> u) -> PublicKey -> u Source #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey Source #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey Source #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey Source #

Read PublicKey |
Instance details Defined in Crypto.Types.PubKey.RSA Methods readsPrec :: Int -> ReadS PublicKey Source # readList :: ReadS [PublicKey] Source # readPrec :: ReadPrec PublicKey Source # readListPrec :: ReadPrec [PublicKey] Source #
Show PublicKey |
Instance details Defined in Crypto.Types.PubKey.RSA Methods showsPrec :: Int -> PublicKey -> ShowS Source # show :: PublicKey -> String Source # showList :: [PublicKey] -> ShowS Source #
Eq PublicKey |
Instance details Defined in Crypto.Types.PubKey.RSA Methods (==) :: PublicKey -> PublicKey -> Bool Source # (/=) :: PublicKey -> PublicKey -> Bool Source #

generateKeyPair :: CryptoRandomGen g => g -> Int -> (PublicKey, PrivateKey, g) Source #

Randomly generate a key pair of the given modules length (in bits) to use in any of the following functions. Use of a good random number generator is of considerable importance when using this function. The input CryptoRandomGen should never be used again for any other purpose; either use the output'd generator or throw it all away.

# High-level encryption and signature functions

encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g) Source #

Encrypt an arbitrarily-sized message given the public key and reasonable options. This is equivalent to calling encryptOAEP with SHA-256 as the hash function, MGF1(SHA-256) as the mask generation function, and no label. NOTE: This hash choice means that your key size must be 1024 bits or larger.

encryptOAEP Source #

Arguments

:: CryptoRandomGen g |
=> g |
-> (ByteString -> ByteString) | The hash function to use
-> MGF | The mask generation function to use
-> ByteString | An optional label to include
-> PublicKey | The public key to encrypt with
-> ByteString | The message to encrypt
-> (ByteString, g) |

Encrypt an arbitrarily-sized message using OAEP encoding. This is the encouraged encoding for doing RSA encryption. Note that your key size must be greater than (2 * hash length + 2) * 8. (For example, the `encrypt` convenience function uses a 256 bit / 32 byte hash function. Thus, its key must be greater than (2 * 32 + 2) * 8 = 528 bits long, and we suggest 1024 as a lower bound.)

encryptPKCS :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g) Source #

Encrypt an arbitrarily-sized message using PKCS1 v1.5 encoding. This encoding is deprecated, and should only be used when interacting with legacy software that cannot be modified.

decrypt :: PrivateKey -> ByteString -> ByteString Source #

Decrypt an arbitrarily-sized message given the public key and reasonable options. This is equivalent to calling encryptOAEP with SHA-256 as the hash function, MGF1(SHA-256) as the mask generation function, and no label.

decryptOAEP Source #

Arguments

:: (ByteString -> ByteString) | The hash function to use
-> MGF | The mask generation function to use
-> ByteString | An optional label to include
-> PrivateKey | The public key to encrypt with
-> ByteString | The message to decrypt
-> ByteString |

Decrypt an arbitrarily-sized message using OAEP encoding. This is the encouraged encoding for doing RSA encryption.

decryptPKCS :: PrivateKey -> ByteString -> ByteString Source #

Decrypt an arbitrarily-sized message using PKCS1 v1.5 encoding. This encoding is deprecated, and should only be used when interacting with legacy software that cannot be modified.

sign :: PrivateKey -> ByteString -> ByteString Source #

Compute a signature for the given ByteString, using the SHA256 algorithm in the computation. This is currently defined as rsassa_pkcs1_v1_5_sign hashSHA256. If you want to use a different function, simply use the PKCS function, below; it will accept arbitrarily-length messages.

verify Source #

Arguments

:: PublicKey | The key of the signer
-> ByteString | The message
-> ByteString | The purported signature
-> Bool |

Verify a signature for the given ByteString, using the SHA25 algorithm in the computation. Again, if you'd like to use a different algorithm, use the rsassa_pkcs1_v1_5_verify function.

# Core routines for OAEP

type MGF = ByteString -> Int64 -> Either RSAError ByteString Source #

A 'mask generation function'. The input is a bytestring, and the output is a hash of the given length. Unless you know what you're doing, you should probably use a MGF1 formulation created with generate_MGF1.

generateMGF1 :: (ByteString -> ByteString) -> MGF Source #

Generate a mask generation function for the rsaes_oaep_*. As suggested by the name, the generated function is an instance of the MGF1 function. The arguments are the underlying hash function to use and the size of a hash in bytes.

The bytestring passed to the generated function cannot be longer than 2^32 * hLen, where hLen is the passed length of the hash.

rsaes_oaep_encrypt Source #

Arguments

:: CryptoRandomGen g |
=> g |
-> (ByteString -> ByteString) | The hash function to use
-> MGF | An appropriate mask genereation function
-> PublicKey | The recipient's public key
-> ByteString | A label to associate with the message (feel free to use BS.empty)
-> ByteString | The message to encrypt
-> (ByteString, g) |

The generalized implementation of RSAES-OAEP-ENCRYPT. Using the default instantiontion of this, provided by the `encrypt` function, is a pretty good plan if this makes no sense to you, as it is instantiated with reasonable defaults.

The message to be encrypted may not be longer then (k - 2*hLen - 2), where k is the length of the RSA modulus in bytes and hLen is the length of a hash in bytes. Passing in a larger message will generate an error, represented by the Left constructor. Note that this means that OAEP encryption cannot be used with keys smaller than 512 bits.

I have not put in a check for the length of the label, because I don't expect you to use more than 2^32 bytes. So don't make me regret that, eh?

rsaes_oaep_decrypt Source #

Arguments

:: (ByteString -> ByteString) | The hash function to use
-> MGF | A mask generation function
-> PrivateKey | The private key to use
-> ByteString | An optional label whose association with the message should be verified.
-> ByteString | The ciphertext to decrypt
-> ByteString |

The generalized implementation of RSAES-OAEP-DECRYPT. Again, `decrypt` initializes this with a pretty good set of defaults if you don't understand what all of the arguments involve.

The ciphertext message passed to this function must be k bytes long, where k is the size of the modulus in bytes. If it is not, this function will generate an error, represented by the Left constructor.

Futher, k (the length of the ciphertext in bytes) must be greater than or equal to (2 * hLen + 2), where hLen is the length of the output of the hash function in bytes. If this equation does not hold, a (different) error will be generated.

Finally, there are any number of internal situations that may generate an error indicating that decryption failed.

# Core PSS routines

|RSASSA-PSS-Sign, RSASSA-PSS-Verify, and the related functions are not included because they are covered by U.S. Patent 7036014, and it's not clear what the restrictions on implementation are. Sorry.

rsaes_pkcs1_v1_5_encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g) Source #

Implements RSAES-PKCS1-v1.5-Encrypt, for completeness and backward compatibility. Also because I've already written everything else, so why not?

This encryption / padding mechanism has several known attacks, which are described in the literature. So unless you absolutely need to use this for some historical reason, you should avoid it.

The message to be encrypted must be less then or equal to (k - 11) bytes long, where k is the length of the key modulus in bytes.

Because this function uses an unknown amount of randomly-generated data, it takes an instance of RandomGen rather than taking a random number as input, and returns the resultant generator as output. You should take care that you (a) do not reuse the input generator, thus losing important randomness, and (b) choose a decent instance of RandomGen for passing to this function.

rsaes_pkcs1_v1_5_decrypt :: PrivateKey -> ByteString -> ByteString Source #

Implements RSAES-PKCS1-v1.5-Decrypt, for completeness and possible backward compatibility. Please see the notes for rsaes_pkcs_v1_5_encrypt regarding use of this function in new applications without backwards compatibility requirements.

The ciphertext message passed to this function must be of length k, where k is the length of the key modulus in bytes.

rsassa_pkcs1_v1_5_sign Source #

Arguments

:: HashInfo | The hash function to use
-> PrivateKey | The private key to sign with
-> ByteString | The message to sign
-> ByteString | The signature

Generate a signature for the given message using the given private key, using the RSASSA-PKCS1-v1.5-Sign algorithm. Note that in researching the requirements for this project, several independent sources suggested not using the same key across signvalidate and encryptdecrypt contexts. You've been warned.

The output of this function is the signature only, not the message and the signature.

SIZE CONSTRAINT: The size of the public key (in bytes) must be greater than or equal to the length of the hash identifier plus the length of a hash plus 1. Thus, for example, you cannot use a 256 bit RSA key with MD5: 32 (the size of a 256-bit RSA key in bytes) is less than 18 (the size of MD5's identier) + 16 (the size of an MD5 hash in bytes) + 1, or 35.

Thus, * for SHA1 and SHA256, use 512+ bit keys * for SHA384 and SHA512, use 1024+ bit keys

rsassa_pkcs1_v1_5_verify Source #

Arguments

:: HashInfo | The hash function to use
-> PublicKey | The public key to validate against
-> ByteString | The message that was signed
-> ByteString | The purported signature
-> Bool |

Validate a signature for the given message using the given public key. The signature must be exactly k bytes long, where k is the size of the RSA modulus IN BYTES.

# Hashing algorithm declarations for use in RSA functions

hashSHA1 :: HashInfo Source #

hashSHA224 :: HashInfo Source #

hashSHA256 :: HashInfo Source #

hashSHA384 :: HashInfo Source #

hashSHA512 :: HashInfo Source #

# Other mathematical functions that are handy for implementing

largeRandomPrime :: CryptoRandomGen g => g -> Int -> (Integer, g) Source #

Generate a large random prime of a given length in bytes.

generatePQ :: CryptoRandomGen g => g -> Int -> (Integer, Integer, g) Source #

chunkify :: ByteString -> Int64 -> [ByteString] Source #

os2ip :: ByteString -> Integer Source #

i2osp :: Integral a => a -> Int -> ByteString Source #

rsa_dp :: Integer -> Integer -> Integer -> Integer Source #

rsa_ep :: Integer -> Integer -> Integer -> Integer Source #

rsa_vp1 :: Integer -> Integer -> Integer -> Integer Source #

rsa_sp1 :: Integer -> Integer -> Integer -> Integer Source #

modular_inverse Source #

Arguments

:: Integer | e
-> Integer | phi
-> Integer |

Compute the modular inverse (d = e^-1 mod phi) via the extended euclidean algorithm.

modular_exponentiation :: Integer -> Integer -> Integer -> Integer Source #

Computes a^b mod c using a moderately good algorithm.

randomBS :: CryptoRandomGen g => g -> Int -> (ByteString, g) Source #

Generate a random ByteString of the given length

randomNZBS :: CryptoRandomGen g => g -> Int -> (ByteString, g) Source #

Create a random bytestring of non-zero bytes of the given length.