Crypto++  8.8
Free C++ class library of cryptographic schemes
pkcspad.cpp
1 // pkcspad.cpp - originally written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 
5 #ifndef CRYPTOPP_PKCSPAD_CPP // SunCC workaround: compiler could cause this file to be included twice
6 #define CRYPTOPP_PKCSPAD_CPP
7 
8 #include "pkcspad.h"
9 #include "emsa2.h"
10 #include "hashfwd.h"
11 #include "misc.h"
12 #include "trap.h"
13 
14 NAMESPACE_BEGIN(CryptoPP)
15 
16 // Typedef/cast change due to Clang, http://github.com/weidai11/cryptopp/issues/300
17 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};
18 template<> const unsigned int PKCS_DigestDecoration<Weak1::MD2>::length = (unsigned int)sizeof(PKCS_DigestDecoration<Weak1::MD2>::decoration);
19 
20 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};
21 template<> const unsigned int PKCS_DigestDecoration<Weak1::MD5>::length = (unsigned int)sizeof(PKCS_DigestDecoration<Weak1::MD5>::decoration);
22 
23 template<> const byte PKCS_DigestDecoration<RIPEMD160>::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x24,0x03,0x02,0x01,0x05,0x00,0x04,0x14};
24 template<> const unsigned int PKCS_DigestDecoration<RIPEMD160>::length = (unsigned int)sizeof(PKCS_DigestDecoration<RIPEMD160>::decoration);
25 
26 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};
27 template<> const unsigned int PKCS_DigestDecoration<Tiger>::length = (unsigned int)sizeof(PKCS_DigestDecoration<Tiger>::decoration);
28 
29 // Inclusion based on DLL due to Clang, http://github.com/weidai11/cryptopp/issues/300
30 #ifndef CRYPTOPP_IS_DLL
31 template<> const byte PKCS_DigestDecoration<SHA1>::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14};
32 template<> const unsigned int PKCS_DigestDecoration<SHA1>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA1>::decoration);
33 
34 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};
35 template<> const unsigned int PKCS_DigestDecoration<SHA224>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA224>::decoration);
36 
37 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};
38 template<> const unsigned int PKCS_DigestDecoration<SHA256>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA256>::decoration);
39 
40 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};
41 template<> const unsigned int PKCS_DigestDecoration<SHA384>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA384>::decoration);
42 
43 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};
44 template<> const unsigned int PKCS_DigestDecoration<SHA512>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA512>::decoration);
45 
46 // http://github.com/weidai11/cryptopp/issues/517. OIDs and encoded prefixes found at
47 // http://www.ietf.org/archive/id/draft-jivsov-openpgp-sha3-01.txt
48 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};
49 template<> const unsigned int PKCS_DigestDecoration<SHA3_256>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA3_256>::decoration);
50 
51 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};
52 template<> const unsigned int PKCS_DigestDecoration<SHA3_384>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA3_384>::decoration);
53 
54 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};
55 template<> const unsigned int PKCS_DigestDecoration<SHA3_512>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA3_512>::decoration);
56 #endif
57 
58 size_t PKCS_EncryptionPaddingScheme::MaxUnpaddedLength(size_t paddedLength) const
59 {
60  return SaturatingSubtract(paddedLength/8, 10U);
61 }
62 
63 void PKCS_EncryptionPaddingScheme::Pad(RandomNumberGenerator& rng, const byte *input, size_t inputLen, byte *pkcsBlock, size_t pkcsBlockLen, const NameValuePairs& parameters) const
64 {
65  CRYPTOPP_UNUSED(parameters);
66  CRYPTOPP_ASSERT (inputLen <= MaxUnpaddedLength(pkcsBlockLen)); // this should be checked by caller
67 
68  // convert from bit length to byte length
69  if (pkcsBlockLen % 8 != 0)
70  {
71  pkcsBlock[0] = 0;
72  pkcsBlock++;
73  }
74  pkcsBlockLen /= 8;
75 
76  pkcsBlock[0] = 2; // block type 2
77 
78  // pad with non-zero random bytes
79  for (unsigned i = 1; i < pkcsBlockLen-inputLen-1; i++)
80  pkcsBlock[i] = (byte)rng.GenerateWord32(1, 0xff);
81 
82  pkcsBlock[pkcsBlockLen-inputLen-1] = 0; // separator
83  std::memcpy(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
84 }
85 
86 DecodingResult PKCS_EncryptionPaddingScheme::Unpad(const byte *pkcsBlock, size_t pkcsBlockLen, byte *output, const NameValuePairs& parameters) const
87 {
88  CRYPTOPP_UNUSED(parameters);
89  bool invalid = false;
90  size_t maxOutputLen = MaxUnpaddedLength(pkcsBlockLen);
91 
92  // convert from bit length to byte length
93  if (pkcsBlockLen % 8 != 0)
94  {
95  invalid = (pkcsBlock[0] != 0) || invalid;
96  pkcsBlock++;
97  }
98  pkcsBlockLen /= 8;
99 
100  // Require block type 2.
101  invalid = (pkcsBlock[0] != 2) || invalid;
102 
103  // skip past the padding until we find the separator
104  size_t i=1;
105  while (i<pkcsBlockLen && pkcsBlock[i++]) { // null body
106  }
107  CRYPTOPP_ASSERT(i==pkcsBlockLen || pkcsBlock[i-1]==0);
108 
109  size_t outputLen = pkcsBlockLen - i;
110  invalid = (outputLen > maxOutputLen) || invalid;
111 
112  if (invalid)
113  return DecodingResult();
114 
115  std::memcpy (output, pkcsBlock+i, outputLen);
116  return DecodingResult(outputLen);
117 }
118 
119 // ********************************************************
120 
121 #ifndef CRYPTOPP_IMPORTS
122 
123 void PKCS1v15_SignatureMessageEncodingMethod::ComputeMessageRepresentative(RandomNumberGenerator &rng,
124  const byte *recoverableMessage, size_t recoverableMessageLength,
125  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
126  byte *representative, size_t representativeBitLength) const
127 {
128  CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength);
129  CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier);
130  CRYPTOPP_ASSERT(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize()));
131 
132  size_t pkcsBlockLen = representativeBitLength;
133  // convert from bit length to byte length
134  if (pkcsBlockLen % 8 != 0)
135  {
136  representative[0] = 0;
137  representative++;
138  }
139  pkcsBlockLen /= 8;
140 
141  representative[0] = 1; // block type 1
142 
143  unsigned int digestSize = hash.DigestSize();
144  byte *pPadding = representative + 1;
145  byte *pDigest = representative + pkcsBlockLen - digestSize;
146  byte *pHashId = pDigest - hashIdentifier.second;
147  byte *pSeparator = pHashId - 1;
148 
149  // pad with 0xff
150  std::memset(pPadding, 0xff, pSeparator-pPadding);
151  *pSeparator = 0;
152  std::memcpy(pHashId, hashIdentifier.first, hashIdentifier.second);
153  hash.Final(pDigest);
154 }
155 
156 #endif
157 
158 NAMESPACE_END
159 
160 #endif
Interface for hash functions and data processing part of MACs.
Definition: cryptlib.h:1118
virtual unsigned int DigestSize() const =0
Provides the digest size of the hash.
virtual void Final(byte *digest)
Computes the hash of the current message.
Definition: cryptlib.h:1147
Interface for retrieving values given their names.
Definition: cryptlib.h:327
PKCS #1 decoration data structure.
Definition: pkcspad.h:35
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
Interface for random number generators.
Definition: cryptlib.h:1440
virtual word32 GenerateWord32(word32 min=0, word32 max=0xffffffffUL)
Generate a random 32 bit word in the range min to max, inclusive.
Classes and functions for various padding schemes used in public key algorithms.
Forward declarations for hash functions used in signature encoding methods.
Utility functions for the Crypto++ library.
T1 SaturatingSubtract(const T1 &a, const T2 &b)
Performs a saturating subtract clamped at 0.
Definition: misc.h:1302
Crypto++ library namespace.
Precompiled header file.
Classes for PKCS padding schemes.
Returns a decoding results.
Definition: cryptlib.h:283
Debugging and diagnostic assertions.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68