pkcspad.cpp
// pkcspad.cpp - originally written and placed in the public domain by Wei Dai
#include "pch.h"
#ifndef CRYPTOPP_PKCSPAD_CPP // SunCC workaround: compiler could cause this file to be included twice
#define CRYPTOPP_PKCSPAD_CPP
#include "pkcspad.h"
#include "emsa2.h"
#include "hashfwd.h"
#include "misc.h"
#include "trap.h"
NAMESPACE_BEGIN(CryptoPP)
// Typedef/cast change due to Clang, http://github.com/weidai11/cryptopp/issues/300
template<> const byte PKCS_DigestDecoration<Weak1::MD2>::decoration[] = {0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x02,0x05,0x00,0x04,0x10};
template<> const unsigned int PKCS_DigestDecoration<Weak1::MD2>::length = (unsigned int)sizeof(PKCS_DigestDecoration<Weak1::MD2>::decoration);
template<> const byte PKCS_DigestDecoration<Weak1::MD5>::decoration[] = {0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x04,0x10};
template<> const unsigned int PKCS_DigestDecoration<Weak1::MD5>::length = (unsigned int)sizeof(PKCS_DigestDecoration<Weak1::MD5>::decoration);
template<> const byte PKCS_DigestDecoration<RIPEMD160>::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x24,0x03,0x02,0x01,0x05,0x00,0x04,0x14};
template<> const unsigned int PKCS_DigestDecoration<RIPEMD160>::length = (unsigned int)sizeof(PKCS_DigestDecoration<RIPEMD160>::decoration);
template<> const byte PKCS_DigestDecoration<Tiger>::decoration[] = {0x30,0x29,0x30,0x0D,0x06,0x09,0x2B,0x06,0x01,0x04,0x01,0xDA,0x47,0x0C,0x02,0x05,0x00,0x04,0x18};
template<> const unsigned int PKCS_DigestDecoration<Tiger>::length = (unsigned int)sizeof(PKCS_DigestDecoration<Tiger>::decoration);
// Inclusion based on DLL due to Clang, http://github.com/weidai11/cryptopp/issues/300
#ifndef CRYPTOPP_IS_DLL
template<> const byte PKCS_DigestDecoration<SHA1>::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14};
template<> const unsigned int PKCS_DigestDecoration<SHA1>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA1>::decoration);
template<> const byte PKCS_DigestDecoration<SHA224>::decoration[] = {0x30,0x2d,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,0x04,0x1c};
template<> const unsigned int PKCS_DigestDecoration<SHA224>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA224>::decoration);
template<> const byte PKCS_DigestDecoration<SHA256>::decoration[] = {0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20};
template<> const unsigned int PKCS_DigestDecoration<SHA256>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA256>::decoration);
template<> const byte PKCS_DigestDecoration<SHA384>::decoration[] = {0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30};
template<> const unsigned int PKCS_DigestDecoration<SHA384>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA384>::decoration);
template<> const byte PKCS_DigestDecoration<SHA512>::decoration[] = {0x30,0x51,0x30,0x0d, 0x06,0x09,0x60,0x86, 0x48,0x01,0x65,0x03, 0x04,0x02,0x03,0x05, 0x00,0x04,0x40};
template<> const unsigned int PKCS_DigestDecoration<SHA512>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA512>::decoration);
// http://github.com/weidai11/cryptopp/issues/517. OIDs and encoded prefixes found at
// http://www.ietf.org/archive/id/draft-jivsov-openpgp-sha3-01.txt
template<> const byte PKCS_DigestDecoration<SHA3_256>::decoration[] = {0x30,0x31,0x30,0x0d, 0x06,0x09,0x60,0x86, 0x48,0x01,0x65,0x03, 0x04,0x02,0x08,0x05, 0x00,0x04,0x20};
template<> const unsigned int PKCS_DigestDecoration<SHA3_256>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA3_256>::decoration);
template<> const byte PKCS_DigestDecoration<SHA3_384>::decoration[] = {0x30,0x41,0x30,0x0d, 0x06,0x09,0x60,0x86, 0x48,0x01,0x65,0x03, 0x04,0x02,0x09,0x05, 0x00,0x04,0x30};
template<> const unsigned int PKCS_DigestDecoration<SHA3_384>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA3_384>::decoration);
template<> const byte PKCS_DigestDecoration<SHA3_512>::decoration[] = {0x30,0x51,0x30,0x0d, 0x06,0x09,0x60,0x86, 0x48,0x01,0x65,0x03, 0x04,0x02,0x0a,0x05, 0x00,0x04,0x40};
template<> const unsigned int PKCS_DigestDecoration<SHA3_512>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA3_512>::decoration);
#endif
size_t PKCS_EncryptionPaddingScheme::MaxUnpaddedLength(size_t paddedLength) const
{
return SaturatingSubtract(paddedLength/8, 10U);
}
void PKCS_EncryptionPaddingScheme::Pad(RandomNumberGenerator& rng, const byte *input, size_t inputLen, byte *pkcsBlock, size_t pkcsBlockLen, const NameValuePairs& parameters) const
{
CRYPTOPP_UNUSED(parameters);
CRYPTOPP_ASSERT (inputLen <= MaxUnpaddedLength(pkcsBlockLen)); // this should be checked by caller
// convert from bit length to byte length
if (pkcsBlockLen % 8 != 0)
{
pkcsBlock[0] = 0;
pkcsBlock++;
}
pkcsBlockLen /= 8;
pkcsBlock[0] = 2; // block type 2
// pad with non-zero random bytes
for (unsigned i = 1; i < pkcsBlockLen-inputLen-1; i++)
pkcsBlock[i] = (byte)rng.GenerateWord32(1, 0xff);
pkcsBlock[pkcsBlockLen-inputLen-1] = 0; // separator
std::memcpy(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
}
DecodingResult PKCS_EncryptionPaddingScheme::Unpad(const byte *pkcsBlock, size_t pkcsBlockLen, byte *output, const NameValuePairs& parameters) const
{
CRYPTOPP_UNUSED(parameters);
bool invalid = false;
size_t maxOutputLen = MaxUnpaddedLength(pkcsBlockLen);
// convert from bit length to byte length
if (pkcsBlockLen % 8 != 0)
{
invalid = (pkcsBlock[0] != 0) || invalid;
pkcsBlock++;
}
pkcsBlockLen /= 8;
// Require block type 2.
invalid = (pkcsBlock[0] != 2) || invalid;
// skip past the padding until we find the separator
size_t i=1;
while (i<pkcsBlockLen && pkcsBlock[i++]) { // null body
}
CRYPTOPP_ASSERT(i==pkcsBlockLen || pkcsBlock[i-1]==0);
size_t outputLen = pkcsBlockLen - i;
invalid = (outputLen > maxOutputLen) || invalid;
if (invalid)
return DecodingResult();
std::memcpy (output, pkcsBlock+i, outputLen);
return DecodingResult(outputLen);
}
// ********************************************************
#ifndef CRYPTOPP_IMPORTS
void PKCS1v15_SignatureMessageEncodingMethod::ComputeMessageRepresentative(RandomNumberGenerator &rng,
const byte *recoverableMessage, size_t recoverableMessageLength,
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
byte *representative, size_t representativeBitLength) const
{
CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength);
CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier);
CRYPTOPP_ASSERT(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize()));
size_t pkcsBlockLen = representativeBitLength;
// convert from bit length to byte length
if (pkcsBlockLen % 8 != 0)
{
representative[0] = 0;
representative++;
}
pkcsBlockLen /= 8;
representative[0] = 1; // block type 1
unsigned int digestSize = hash.DigestSize();
byte *pPadding = representative + 1;
byte *pDigest = representative + pkcsBlockLen - digestSize;
byte *pHashId = pDigest - hashIdentifier.second;
byte *pSeparator = pHashId - 1;
// pad with 0xff
std::memset(pPadding, 0xff, pSeparator-pPadding);
*pSeparator = 0;
std::memcpy(pHashId, hashIdentifier.first, hashIdentifier.second);
hash.Final(pDigest);
}
#endif
NAMESPACE_END
#endif
HashTransformation
Interface for hash functions and data processing part of MACs.
Definition cryptlib.h:1118
HashTransformation::DigestSize
virtual unsigned int DigestSize() const =0
Provides the digest size of the hash.
HashTransformation::Final
virtual void Final(byte *digest)
Computes the hash of the current message.
Definition cryptlib.h:1147
NameValuePairs
Interface for retrieving values given their names.
Definition cryptlib.h:327
PKCS_EncryptionPaddingScheme::MaxUnpaddedLength
size_t MaxUnpaddedLength(size_t paddedLength) const
max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of ...
Definition pkcspad.cpp:58
RandomNumberGenerator
Interface for random number generators.
Definition cryptlib.h:1440
RandomNumberGenerator::GenerateWord32
virtual word32 GenerateWord32(word32 min=0, word32 max=0xffffffffUL)
Generate a random 32 bit word in the range min to max, inclusive.
emsa2.h
Classes and functions for various padding schemes used in public key algorithms.
hashfwd.h
Forward declarations for hash functions used in signature encoding methods.
misc.h
Utility functions for the Crypto++ library.
SaturatingSubtract
T1 SaturatingSubtract(const T1 &a, const T2 &b)
Performs a saturating subtract clamped at 0.
Definition misc.h:1302
CryptoPP
Crypto++ library namespace.
pch.h
Precompiled header file.
pkcspad.h
Classes for PKCS padding schemes.
DecodingResult
Returns a decoding results.
Definition cryptlib.h:283
trap.h
Debugging and diagnostic assertions.
CRYPTOPP_ASSERT
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition trap.h:68