Crypto++ 8.9 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
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_DigestDecoration
PKCS #1 decoration data structure.
Definition: pkcspad.h:35
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