oaep.cpp

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

Generated on Sat Dec 23 02:07:08 2006 for Crypto++ by  doxygen 1.5.1-p1