From b21162cf8e06f40baa1f58be6a8c17435cebc34d Mon Sep 17 00:00:00 2001 From: weidai Date: Fri, 4 Oct 2002 17:31:41 +0000 Subject: Initial revision git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@2 57ff6487-cd31-0410-9ec3-f628ee90f5f0 --- oaep.cpp | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 oaep.cpp (limited to 'oaep.cpp') diff --git a/oaep.cpp b/oaep.cpp new file mode 100644 index 0000000..9391f5b --- /dev/null +++ b/oaep.cpp @@ -0,0 +1,103 @@ +// oaep.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "oaep.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +// ******************************************************** + +ANONYMOUS_NAMESPACE_BEGIN + template + struct PHashComputation + { + PHashComputation() {H().CalculateDigest(pHash, P, PLen);} + byte pHash[H::DIGESTSIZE]; + }; + + template + const byte *PHash() + { + static PHashComputation pHash; + return pHash.pHash; + } +NAMESPACE_END + +template +unsigned int OAEP::MaxUnpaddedLength(unsigned int paddedLength) const +{ + return paddedLength/8 > 1+2*H::DIGESTSIZE ? paddedLength/8-1-2*H::DIGESTSIZE : 0; +} + +template +void OAEP::Pad(RandomNumberGenerator &rng, const byte *input, unsigned int inputLength, byte *oaepBlock, unsigned int oaepBlockLen) const +{ + assert (inputLength <= MaxUnpaddedLength(oaepBlockLen)); + + // convert from bit length to byte length + if (oaepBlockLen % 8 != 0) + { + oaepBlock[0] = 0; + oaepBlock++; + } + oaepBlockLen /= 8; + + const unsigned int hLen = H::DIGESTSIZE; + const unsigned int seedLen = hLen, dbLen = oaepBlockLen-seedLen; + byte *const maskedSeed = oaepBlock; + byte *const maskedDB = oaepBlock+seedLen; + + // DB = pHash || 00 ... || 01 || M + memcpy(maskedDB, PHash(), hLen); + memset(maskedDB+hLen, 0, dbLen-hLen-inputLength-1); + maskedDB[dbLen-inputLength-1] = 0x01; + memcpy(maskedDB+dbLen-inputLength, input, inputLength); + + rng.GenerateBlock(maskedSeed, seedLen); + MGF::GenerateAndMask(maskedDB, dbLen, maskedSeed, seedLen); + MGF::GenerateAndMask(maskedSeed, seedLen, maskedDB, dbLen); +} + +template +DecodingResult OAEP::Unpad(const byte *oaepBlock, unsigned int oaepBlockLen, byte *output) const +{ + bool invalid = false; + + // convert from bit length to byte length + if (oaepBlockLen % 8 != 0) + { + invalid = (oaepBlock[0] != 0) || invalid; + oaepBlock++; + } + oaepBlockLen /= 8; + + const unsigned int hLen = H::DIGESTSIZE; + const unsigned int seedLen = hLen, dbLen = oaepBlockLen-seedLen; + + invalid = (oaepBlockLen < 2*hLen+1) || invalid; + + SecByteBlock t(oaepBlock, oaepBlockLen); + byte *const maskedSeed = t; + byte *const maskedDB = t+seedLen; + + MGF::GenerateAndMask(maskedSeed, seedLen, maskedDB, dbLen); + MGF::GenerateAndMask(maskedDB, dbLen, maskedSeed, seedLen); + + // DB = pHash' || 00 ... || 01 || M + + byte *M = std::find(maskedDB+hLen, maskedDB+dbLen, 0x01); + invalid = (M == maskedDB+dbLen) || invalid; + invalid = (std::find_if(maskedDB+hLen, M, std::bind2nd(std::not_equal_to(), 0)) != M) || invalid; + invalid = (memcmp(maskedDB, PHash(), hLen) != 0) || invalid; + + if (invalid) + return DecodingResult(); + + M++; + memcpy(output, M, maskedDB+dbLen-M); + return DecodingResult(maskedDB+dbLen-M); +} + +NAMESPACE_END -- cgit v1.2.1