Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
3.0 KiB

  1. // oaep.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #ifndef CRYPTOPP_IMPORTS
  4. #include "oaep.h"
  5. #include "stdcpp.h"
  6. #include "smartptr.h"
  7. NAMESPACE_BEGIN(CryptoPP)
  8. // ********************************************************
  9. size_t OAEP_Base::MaxUnpaddedLength(size_t paddedLength) const
  10. {
  11. return SaturatingSubtract(paddedLength/8, 1+2*DigestSize());
  12. }
  13. void OAEP_Base::Pad(RandomNumberGenerator &rng, const byte *input, size_t inputLength, byte *oaepBlock, size_t oaepBlockLen, const NameValuePairs &parameters) const
  14. {
  15. assert (inputLength <= MaxUnpaddedLength(oaepBlockLen));
  16. // convert from bit length to byte length
  17. if (oaepBlockLen % 8 != 0)
  18. {
  19. oaepBlock[0] = 0;
  20. oaepBlock++;
  21. }
  22. oaepBlockLen /= 8;
  23. member_ptr<HashTransformation> pHash(NewHash());
  24. const size_t hLen = pHash->DigestSize();
  25. const size_t seedLen = hLen, dbLen = oaepBlockLen-seedLen;
  26. byte *const maskedSeed = oaepBlock;
  27. byte *const maskedDB = oaepBlock+seedLen;
  28. ConstByteArrayParameter encodingParameters;
  29. parameters.GetValue(Name::EncodingParameters(), encodingParameters);
  30. // DB = pHash || 00 ... || 01 || M
  31. pHash->CalculateDigest(maskedDB, encodingParameters.begin(), encodingParameters.size());
  32. memset(maskedDB+hLen, 0, dbLen-hLen-inputLength-1);
  33. maskedDB[dbLen-inputLength-1] = 0x01;
  34. memcpy(maskedDB+dbLen-inputLength, input, inputLength);
  35. rng.GenerateBlock(maskedSeed, seedLen);
  36. member_ptr<MaskGeneratingFunction> pMGF(NewMGF());
  37. pMGF->GenerateAndMask(*pHash, maskedDB, dbLen, maskedSeed, seedLen);
  38. pMGF->GenerateAndMask(*pHash, maskedSeed, seedLen, maskedDB, dbLen);
  39. }
  40. DecodingResult OAEP_Base::Unpad(const byte *oaepBlock, size_t oaepBlockLen, byte *output, const NameValuePairs &parameters) const
  41. {
  42. bool invalid = false;
  43. // convert from bit length to byte length
  44. if (oaepBlockLen % 8 != 0)
  45. {
  46. invalid = (oaepBlock[0] != 0) || invalid;
  47. oaepBlock++;
  48. }
  49. oaepBlockLen /= 8;
  50. member_ptr<HashTransformation> pHash(NewHash());
  51. const size_t hLen = pHash->DigestSize();
  52. const size_t seedLen = hLen, dbLen = oaepBlockLen-seedLen;
  53. invalid = (oaepBlockLen < 2*hLen+1) || invalid;
  54. SecByteBlock t(oaepBlock, oaepBlockLen);
  55. byte *const maskedSeed = t;
  56. byte *const maskedDB = t+seedLen;
  57. member_ptr<MaskGeneratingFunction> pMGF(NewMGF());
  58. pMGF->GenerateAndMask(*pHash, maskedSeed, seedLen, maskedDB, dbLen);
  59. pMGF->GenerateAndMask(*pHash, maskedDB, dbLen, maskedSeed, seedLen);
  60. ConstByteArrayParameter encodingParameters;
  61. parameters.GetValue(Name::EncodingParameters(), encodingParameters);
  62. // DB = pHash' || 00 ... || 01 || M
  63. byte *M = std::find(maskedDB+hLen, maskedDB+dbLen, 0x01);
  64. invalid = (M == maskedDB+dbLen) || invalid;
  65. invalid = (std::find_if(maskedDB+hLen, M, std::bind2nd(std::not_equal_to<byte>(), byte(0))) != M) || invalid;
  66. invalid = !pHash->VerifyDigest(maskedDB, encodingParameters.begin(), encodingParameters.size()) || invalid;
  67. if (invalid)
  68. return DecodingResult();
  69. M++;
  70. memcpy(output, M, maskedDB+dbLen-M);
  71. return DecodingResult(maskedDB+dbLen-M);
  72. }
  73. NAMESPACE_END
  74. #endif