summaryrefslogtreecommitdiff
path: root/oaep.cpp
diff options
context:
space:
mode:
authorweidai <weidai11@users.noreply.github.com>2002-10-04 17:31:41 +0000
committerweidai <weidai11@users.noreply.github.com>2002-10-04 17:31:41 +0000
commita3b6ece7ab341b5b14135baeccea7d5e4c086771 (patch)
tree8b045309c238226c32a563b1df6b9c30a2f0e0b3 /oaep.cpp
downloadcryptopp-git-a3b6ece7ab341b5b14135baeccea7d5e4c086771.tar.gz
Initial revision
Diffstat (limited to 'oaep.cpp')
-rw-r--r--oaep.cpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/oaep.cpp b/oaep.cpp
new file mode 100644
index 00000000..9391f5b4
--- /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 <functional>
+
+NAMESPACE_BEGIN(CryptoPP)
+
+// ********************************************************
+
+ANONYMOUS_NAMESPACE_BEGIN
+ template <class H, byte *P, unsigned int PLen>
+ struct PHashComputation
+ {
+ PHashComputation() {H().CalculateDigest(pHash, P, PLen);}
+ byte pHash[H::DIGESTSIZE];
+ };
+
+ template <class H, byte *P, unsigned int PLen>
+ const byte *PHash()
+ {
+ static PHashComputation<H,P,PLen> pHash;
+ return pHash.pHash;
+ }
+NAMESPACE_END
+
+template <class H, class MGF, byte *P, unsigned int PLen>
+unsigned int OAEP<H,MGF,P,PLen>::MaxUnpaddedLength(unsigned int paddedLength) const
+{
+ return paddedLength/8 > 1+2*H::DIGESTSIZE ? paddedLength/8-1-2*H::DIGESTSIZE : 0;
+}
+
+template <class H, class MGF, byte *P, unsigned int PLen>
+void OAEP<H,MGF,P,PLen>::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<H,P,PLen>(), 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 <class H, class MGF, byte *P, unsigned int PLen>
+DecodingResult OAEP<H,MGF,P,PLen>::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<byte>(), 0)) != M) || invalid;
+ invalid = (memcmp(maskedDB, PHash<H,P,PLen>(), hLen) != 0) || invalid;
+
+ if (invalid)
+ return DecodingResult();
+
+ M++;
+ memcpy(output, M, maskedDB+dbLen-M);
+ return DecodingResult(maskedDB+dbLen-M);
+}
+
+NAMESPACE_END