1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
-----------------------------------------------------------------------------
-- |
-- Module : Coded.Encryption.RSA.EMEOAEP
-- Copyright : (c) David J. Sankel 2003, Dominic Steinitz 2003
-- License : GPL (see the file ReadMe.tex)
--
-- Maintainer : dominic.steinitz@blueyonder.co.uk
-- Stability : experimental
-- Portability : non-portable
--
-- A modified version of the EMEOAEP module supplied by David J. Sankel
-- (<http://www.electronconsulting.com/rsa-haskell>).
--
-- As the original code is GPL, this has to be.
-- This code is free software; you can redistribute it and\/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This code is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this code; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111\-1307 USA
-----------------------------------------------------------------------------
module Codec.Encryption.RSA.EMEOAEP(
-- * Function Types
encode,
decode
)where
import Codec.Utils (Octet)
import Data.Bits
xorOctets :: Bits a => [a] -> [a] -> [a]
xorOctets = zipWith xor
-- | Take a mask generating function, a hash function, a label (which may be
-- null), a random seed, the modulus of the key and the message and returns
-- an encoded message. NB you could pass in the length of the modulus
-- but it seems safer to pass in the modulus itself and calculate the
-- length when required. See
-- <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf> for more
-- details.
encode :: (([Octet] -> [Octet]) -> [Octet] -> Int -> [Octet]) ->
([Octet] -> [Octet]) -> [Octet] -> [Octet] -> [Octet] -> [Octet] ->
[Octet]
encode mgf hash p seed n m =
if length m > emLen - 2*hLen - 2
then error "Codec.Encryption.EMEOAEP.encode: message too long"
else em
where
emLen = length n
mLen = length m
ps = take (emLen-mLen-2*hLen-2) $ repeat $ 0x00
pHash = hash p
hLen = length pHash
db = pHash ++ ps ++ [0x01] ++ m
dbMask = mgf hash seed (length db)
maskedDB = db `xorOctets` dbMask
seedMask = mgf hash maskedDB hLen
maskedSeed = seed `xorOctets` seedMask
em = [0x00] ++ maskedSeed ++ maskedDB
-- | Take a mask generating function, a hash function, a label (which may be
-- null) and the message and returns the decoded.
decode :: (([Octet] -> [Octet]) -> [Octet] -> Int -> [Octet]) ->
([Octet] -> [Octet]) -> [Octet] -> [Octet] -> [Octet]
decode mgf hash p em =
if length em < 2*hLen + 1 ||
one /= 0x01 ||
pHash' /= pHash ||
y /= [0x00]
then error "Codec.Encryption.EMEOAEP.decode: decryption error"
else m
where
(y,rest) = splitAt 1 em
pHash = hash p
hLen = length pHash
(maskedSeed,maskedDB) = splitAt hLen rest
seedMask = mgf hash maskedDB hLen
seed = maskedSeed `xorOctets` seedMask
emLen = length em
dbMask = mgf hash seed (emLen - hLen - 1)
db = maskedDB `xorOctets` dbMask
(pHash',rest') = splitAt hLen db
(one:m) = dropWhile (== 0x00) rest'
|