Crypto++ 8.7
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
14NAMESPACE_BEGIN(CryptoPP)
15
16// Typedef/cast change due to Clang, http://github.com/weidai11/cryptopp/issues/300
17template<> 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};
18template<> const unsigned int PKCS_DigestDecoration<Weak1::MD2>::length = (unsigned int)sizeof(PKCS_DigestDecoration<Weak1::MD2>::decoration);
19
20template<> 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};
21template<> const unsigned int PKCS_DigestDecoration<Weak1::MD5>::length = (unsigned int)sizeof(PKCS_DigestDecoration<Weak1::MD5>::decoration);
22
23template<> const byte PKCS_DigestDecoration<RIPEMD160>::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x24,0x03,0x02,0x01,0x05,0x00,0x04,0x14};
24template<> const unsigned int PKCS_DigestDecoration<RIPEMD160>::length = (unsigned int)sizeof(PKCS_DigestDecoration<RIPEMD160>::decoration);
25
26template<> 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};
27template<> 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
31template<> const byte PKCS_DigestDecoration<SHA1>::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14};
32template<> const unsigned int PKCS_DigestDecoration<SHA1>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA1>::decoration);
33
34template<> 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};
35template<> const unsigned int PKCS_DigestDecoration<SHA224>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA224>::decoration);
36
37template<> 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};
38template<> const unsigned int PKCS_DigestDecoration<SHA256>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA256>::decoration);
39
40template<> 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};
41template<> const unsigned int PKCS_DigestDecoration<SHA384>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA384>::decoration);
42
43template<> 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};
44template<> 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
48template<> 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};
49template<> const unsigned int PKCS_DigestDecoration<SHA3_256>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA3_256>::decoration);
50
51template<> 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};
52template<> const unsigned int PKCS_DigestDecoration<SHA3_384>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA3_384>::decoration);
53
54template<> 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};
55template<> const unsigned int PKCS_DigestDecoration<SHA3_512>::length = (unsigned int)sizeof(PKCS_DigestDecoration<SHA3_512>::decoration);
56#endif
57
58size_t PKCS_EncryptionPaddingScheme::MaxUnpaddedLength(size_t paddedLength) const
59{
60 return SaturatingSubtract(paddedLength/8, 10U);
61}
62
63void 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 memcpy(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
84}
85
86DecodingResult 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 memcpy (output, pkcsBlock+i, outputLen);
116 return DecodingResult(outputLen);
117}
118
119// ********************************************************
120
121#ifndef CRYPTOPP_IMPORTS
122
123void 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 memset(pPadding, 0xff, pSeparator-pPadding);
151 *pSeparator = 0;
152 memcpy(pHashId, hashIdentifier.first, hashIdentifier.second);
153 hash.Final(pDigest);
154}
155
156#endif
157
158NAMESPACE_END
159
160#endif
Interface for hash functions and data processing part of MACs.
Definition: cryptlib.h:1113
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:1142
Interface for retrieving values given their names.
Definition: cryptlib.h:322
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:1435
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:1093
Crypto++ library namespace.
Precompiled header file.
Classes for PKCS padding schemes.
Returns a decoding results.
Definition: cryptlib.h:278
Debugging and diagnostic assertions.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68