Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

# oaep.cpp

    00001 // oaep.cpp - written and placed in the public domain by Wei Dai
    00002
    00003 #include "pch.h"
    00004 #include "oaep.h"
    00005
    00006 #include <functional>
    00007
    00008 NAMESPACE_BEGIN(CryptoPP)
    00009
    00010 // ********************************************************
    00011
    00012 ANONYMOUS_NAMESPACE_BEGIN
    00013         template <class H, byte *P, unsigned int PLen>
    00014         struct PHashComputation
    00015         {
    00016                 PHashComputation()      {H().CalculateDigest(pHash, P, PLen);}
    00017                 byte pHash[H::DIGESTSIZE];
    00018         };
    00019
    00020         template <class H, byte *P, unsigned int PLen>
    00021         const byte *PHash()
    00022         {
    00023                 static PHashComputation<H,P,PLen> pHash;
    00024                 return pHash.pHash;
    00025         }
    00026 NAMESPACE_END
    00027
    00028 template <class H, class MGF, byte *P, unsigned int PLen>
    00029 unsigned int OAEP<H,MGF,P,PLen>::MaxUnpaddedLength(unsigned int paddedLength) const
    00030 {
    00031         return paddedLength/8 > 1+2*H::DIGESTSIZE ? paddedLength/8-1-2*H::DIGESTSIZE : 0;
    00032 }
    00033
    00034 template <class H, class MGF, byte *P, unsigned int PLen>
    00035 void OAEP<H,MGF,P,PLen>::Pad(RandomNumberGenerator &rng, const byte *input, unsigned int inputLength, byte *oaepBlock, unsigned int oaepBlockLen) const
    00036 {
    00037         assert (inputLength <= MaxUnpaddedLength(oaepBlockLen));
    00038
    00039         // convert from bit length to byte length
    00040         if (oaepBlockLen % 8 != 0)
    00041         {
    00042                 oaepBlock[0] = 0;
    00043                 oaepBlock++;
    00044         }
    00045         oaepBlockLen /= 8;
    00046
    00047         const unsigned int hLen = H::DIGESTSIZE;
    00048         const unsigned int seedLen = hLen, dbLen = oaepBlockLen-seedLen;
    00049         byte *const maskedSeed = oaepBlock;
    00050         byte *const maskedDB = oaepBlock+seedLen;
    00051
    00052         // DB = pHash || 00 ... || 01 || M
    00053         memcpy(maskedDB, PHash<H,P,PLen>(), hLen);
    00054         memset(maskedDB+hLen, 0, dbLen-hLen-inputLength-1);
    00055         maskedDB[dbLen-inputLength-1] = 0x01;
    00056         memcpy(maskedDB+dbLen-inputLength, input, inputLength);
    00057
    00058         rng.GenerateBlock(maskedSeed, seedLen);
    00059         MGF::GenerateAndMask(maskedDB, dbLen, maskedSeed, seedLen);
    00060         MGF::GenerateAndMask(maskedSeed, seedLen, maskedDB, dbLen);
    00061 }
    00062
    00063 template <class H, class MGF, byte *P, unsigned int PLen>
    00064 DecodingResult OAEP<H,MGF,P,PLen>::Unpad(const byte *oaepBlock, unsigned int oaepBlockLen, byte *output) const
    00065 {
    00066         bool invalid = false;
    00067
    00068         // convert from bit length to byte length
    00069         if (oaepBlockLen % 8 != 0)
    00070         {
    00071                 invalid = (oaepBlock[0] != 0) || invalid;
    00072                 oaepBlock++;
    00073         }
    00074         oaepBlockLen /= 8;
    00075
    00076         const unsigned int hLen = H::DIGESTSIZE;
    00077         const unsigned int seedLen = hLen, dbLen = oaepBlockLen-seedLen;
    00078
    00079         invalid = (oaepBlockLen < 2*hLen+1) || invalid;
    00080
    00081         SecByteBlock t(oaepBlock, oaepBlockLen);
    00082         byte *const maskedSeed = t;
    00083         byte *const maskedDB = t+seedLen;
    00084
    00085         MGF::GenerateAndMask(maskedSeed, seedLen, maskedDB, dbLen);
    00086         MGF::GenerateAndMask(maskedDB, dbLen, maskedSeed, seedLen);
    00087
    00088         // DB = pHash' || 00 ... || 01 || M
    00089
    00090         byte *M = std::find(maskedDB+hLen, maskedDB+dbLen, 0x01);
    00091         invalid = (M == maskedDB+dbLen) || invalid;
    00092         invalid = (std::find_if(maskedDB+hLen, M, std::bind2nd(std::not_equal_to<byte>(), 0)) != M) || invalid;
    00093         invalid = (memcmp(maskedDB, PHash<H,P,PLen>(), hLen) != 0) || invalid;
    00094
    00095         if (invalid)
    00096                 return DecodingResult();
    00097
    00098         M++;
    00099         memcpy(output, M, maskedDB+dbLen-M);
    00100         return DecodingResult(maskedDB+dbLen-M);
    00101 }
    00102
    00103 NAMESPACE_END