Add PKCS #1 SHA3-based signatures (GH #517)

This commit is contained in:
Jeffrey Walton 2017-10-04 23:24:18 -04:00
parent 73928489f9
commit 1d0df34ae8
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
8 changed files with 196 additions and 21 deletions

77
TestData/rsa2048a.dat Normal file
View File

@ -0,0 +1,77 @@
30 82 04 bd 02 01 00 30 0d 06 09 2a 86 48 86 f7
0d 01 01 01 05 00 04 82 04 a7 30 82 04 a3 02 01
00 02 82 01 01 00 d2 54 95 37 95 5e 3b f5 1e f0
29 dc d3 c7 b7 08 e8 a2 fe 84 ed 16 52 c9 cf 06
73 6b 1b 6d 5b 31 50 21 77 af d6 f9 bf ea 2a c3
ca 7d 52 58 f8 8d 12 bb c1 01 ac 19 7a 33 de 9e
52 91 a4 94 65 04 cb 34 dd 3b 5b 7b db c8 5e 1a
b4 91 48 c2 a1 fd 9e 10 9d a6 df 9f 63 70 e9 3c
ff fc 71 7b dc 08 97 00 64 8c ed 5a 78 ce 56 38
ee 0a 36 0d 4a 9f 3a b7 7f ea 38 9d 83 cd 4a fa
2c 92 fd ae 68 74 7d 25 4b 26 65 97 cc 21 43 ae
ec 6d 5b 90 ec ec 45 de fb f1 7e c3 58 95 a2 e7
e3 16 82 a4 a9 0b 77 05 7c d6 cd b8 95 d1 27 b5
db c5 33 63 f1 92 1c 3f 25 82 bf d1 8a 89 c4 65
c0 e9 07 e5 ba 17 b5 36 30 d7 a7 1c f3 bf 16 00
76 99 f1 d9 7c db 2b 52 ca c6 22 6d d6 ba 7f 16
27 f0 c1 ee 3f 8d ad 4a 69 48 41 57 8d 57 0e a8
a4 bb c6 3c 41 5d 7e 42 49 3b 3b 8d b5 b0 88 f3
2d 50 1b ec 0e ff 02 03 01 00 01 02 82 01 01 00
89 11 50 10 e2 09 80 3f 54 c3 24 34 e1 da d4 00
3d 43 03 64 f2 f0 ca 50 f3 d6 7b 5f 00 87 ba 97
1f 66 40 0e 5a a5 75 99 0f f7 7a 3d 43 6d f1 c4
55 c1 ff 9c ac 60 0a 10 45 72 9d d2 86 13 a2 e5
85 db d4 94 bb 20 b3 71 17 4a 86 03 ec 0b d2 ef
69 93 e0 79 80 5f e9 b9 0a 76 93 48 1b 58 a1 63
03 ac e0 da 2a 4f fc 4c 53 4a 54 6e 59 1d 3e 55
18 39 bf 65 8f 31 af 54 19 19 81 f4 e4 d7 44 ff
fe 73 2b 57 28 4b 2f 43 53 81 d2 b1 e0 ad a4 88
b2 11 ae d3 3a 7f e6 de c4 41 bb 22 07 1a 15 a7
c0 d6 b2 69 4d 01 c8 21 aa b8 9a 3b 3a ad 49 8d
ae 53 b3 8c b4 7f 2a 23 f4 0c 73 53 4f 2f c5 d5
1d 22 68 6a b9 31 0a 9c ba 79 59 12 e9 59 d4 1e
80 7a 2d 45 63 a1 89 2f 27 72 39 60 a3 5f 3e ef
26 47 63 42 ce 40 db 4d 26 01 ca 5e 00 5c 96 ef
77 48 7f 1d 09 45 99 d2 bb c2 ed d3 11 37 a1 91
02 81 81 00 f0 35 21 ff d4 d1 8f 13 ed bf 5f 87
43 37 31 25 03 fe bf be b7 81 da d1 d3 d5 36 e6
35 3d b5 77 eb 8e 86 73 12 e5 4a e7 0d a4 d4 66
7d df 44 bc 2f cb b4 71 65 bd 00 bc 29 2a 08 4f
35 78 31 59 98 56 e0 db 36 89 0a ca 0b ca 6c 94
07 de c9 a4 b4 18 a4 bf 92 92 78 c7 c1 69 da 18
80 ea e3 7c 9a 72 35 1c b3 6e a4 1d ab 5f ae 91
af a0 c9 0f 85 b8 b8 a9 c6 55 39 6e 91 75 c2 0f
8d 04 bf 79 02 81 81 00 e0 28 98 94 00 4a aa f1
a9 9b 17 cd 00 74 81 f6 b3 df e1 d3 98 ca 05 86
b2 e1 42 e4 81 92 df 10 cf c0 92 ec 9d 0b e1 b4
43 9d 9d 14 13 e1 29 78 5c f9 99 ee cb bf 09 09
c7 90 18 dd e6 3c db 38 b2 85 cf db 3f 3d fc 85
ed 78 1a 31 89 41 3c 39 0b ab fa 23 c8 95 c6 f2
a8 c1 ee 82 99 b6 bc 5e ea c6 ee 83 18 2a 27 29
22 d7 e3 34 da f1 e8 8c 82 f0 b5 3f a4 8b be 01
23 37 f3 4b 10 c7 4c 37 02 81 80 4c 18 e9 0e 7d
43 6e 4a 67 f5 4a b4 35 4d 14 da 9f 2b 63 5f 6e
0f 4b 5d 51 f8 a8 0d c2 2c 2c 83 33 32 d1 d1 3e
d9 39 23 7d a5 0c 4c f3 ef 79 7d 0c bf 42 08 f2
ac 2f c1 6c 61 0e 84 d9 71 9c 60 bf ec 36 0b fc
78 e9 dc 1c 64 22 85 bb 00 8f 6d 08 49 0e 58 4a
7c f0 9a 87 e1 9a e0 4c 67 1d 6e 6a 17 68 50 11
60 29 c9 e4 72 c9 81 09 dc ac 15 a8 cd 5e 63 1a
9c 01 37 d0 09 38 53 68 df 6a 31 02 81 80 4d 90
fe ab 48 26 8e 5c ad 8a 03 84 66 c1 ea 2f 0a 33
50 9b bd e5 3a 60 50 09 ee f1 cf 7c 99 3f e2 04
0b 53 61 4c b9 3f 7d 9e 4e ba a1 de 6a 51 42 2b
04 ff 42 f5 ca 14 de 3f 98 bb 40 6e 92 95 5e 01
3b d9 ec 5a 70 c5 8f 54 de 0b 82 29 56 c3 8e ac
66 14 77 d6 8c 4f 6f e2 1b bc 89 a0 58 32 a8 1f
4a 6d 86 b1 1f 77 f6 9c a9 fc a2 3e cf 6f bf e7
b7 70 5c 6a 16 c7 a1 fe 3c 6c 1f 54 37 a5 02 81
80 08 9d 30 ca da d1 af 53 16 e3 77 bf 9f 2b dd
38 a8 20 f9 e5 57 fb 7a cc 4e c6 0d d5 03 22 9f
f8 99 f5 61 69 88 3b 7b a7 c0 ca dd b2 1b b7 34
0b 5d ed 9f 37 fb 02 7d ef 01 2d 29 1d 75 9a ba
1a 5d 7b 77 47 e6 da b5 d7 a9 06 f2 61 5d 46 f9
6d c3 81 de 8f 5d 08 ac a6 b6 b3 51 7a 97 08 36
d3 d8 95 6b 08 e8 e3 10 24 61 67 97 c7 40 68 9e
b7 84 09 14 3f 95 02 3f 75 8b 8e b1 2c 80 b3 5f
03

11
dll.cpp
View File

@ -36,6 +36,17 @@ template<> const unsigned int PKCS_DigestDecoration<SHA384>::length = sizeof(PKC
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 = 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);
template<> const byte EMSA2HashId<SHA1>::id = 0x33;
template<> const byte EMSA2HashId<SHA224>::id = 0x38;
template<> const byte EMSA2HashId<SHA256>::id = 0x34;

5
oids.h
View File

@ -127,6 +127,11 @@ DEFINE_OID(2, joint_iso_ccitt)
DEFINE_OID(nist_hashalgs()+1, id_sha256)
DEFINE_OID(nist_hashalgs()+2, id_sha384)
DEFINE_OID(nist_hashalgs()+3, id_sha512)
DEFINE_OID(nist_hashalgs()+4, id_sha224)
DEFINE_OID(nist_hashalgs()+7, id_sha3_224)
DEFINE_OID(nist_hashalgs()+8, id_sha3_256)
DEFINE_OID(nist_hashalgs()+9, id_sha3_384)
DEFINE_OID(nist_hashalgs()+10, id_sha3_512)
NAMESPACE_END

View File

@ -39,10 +39,21 @@ template<> const unsigned int PKCS_DigestDecoration<SHA256>::length = (unsigned
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 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);
template<> const byte EMSA2HashId<SHA1>::id = 0x33;
// 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);
template<> const byte EMSA2HashId< SHA1>::id = 0x33;
template<> const byte EMSA2HashId<SHA224>::id = 0x38;
template<> const byte EMSA2HashId<SHA256>::id = 0x34;
template<> const byte EMSA2HashId<SHA384>::id = 0x36;

View File

@ -47,10 +47,16 @@ class SHA384;
class SHA512;
class Tiger;
class RIPEMD160;
namespace Weak1 {
class MD2;
class MD5;
class MD2;
class MD5;
}
// http://github.com/weidai11/cryptopp/issues/517
class SHA3_256;
class SHA3_384;
class SHA3_512;
// end of list
#if defined(CRYPTOPP_IS_DLL)
@ -59,6 +65,10 @@ CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA224>;
CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA256>;
CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA384>;
CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA512>;
// http://github.com/weidai11/cryptopp/issues/517
CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA3_256>;
CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA3_384>;
CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA3_512>;
#elif defined(__clang__)
// Provide a default definition to avoid Clang warnings. CRTP will provide a
// real definition later. The single element is due to MSVC compile failures
@ -96,12 +106,9 @@ public:
};
};
//! PKCS #1 version 1.5, for use with RSAES and RSASS
/*! Only the following hash functions are supported by this signature standard:
\dontinclude pkcspad.h
\skip can be instantiated
\until end of list
*/
//! \brief PKCS #1 version 1.5, for use with RSAES and RSASS
//! \dontinclude pkcspad.h
struct PKCS1v15 : public SignatureStandard, public EncryptionStandard
{
typedef PKCS_EncryptionPaddingScheme EncryptionMessageEncodingMethod;

View File

@ -12,6 +12,7 @@
#include "pkcspad.h"
#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) && !defined(CRYPTOPP_IS_DLL)
#include "sha3.h"
#include "pssr.h"
NAMESPACE_BEGIN(CryptoPP)
void RSA_TestInstantiations()
@ -31,8 +32,12 @@ void RSA_TestInstantiations()
RSAES<PKCS1v15>::Encryptor x8(x3);
#endif
RSAES<OAEP<SHA1> >::Encryptor x9(x2);
x4 = x2.GetKey();
RSASS<PKCS1v15, SHA3_256>::Verifier x10(1, 1);
RSASS<PKCS1v15, SHA3_256>::Signer x11(NullRNG(), 1);
RSASS<PKCS1v15, SHA3_256>::Verifier x12(x11);
RSASS<PKCS1v15, SHA3_256>::Verifier x13(x11.GetKey());
}
NAMESPACE_END
#endif

26
sha3.h
View File

@ -52,9 +52,9 @@ protected:
};
//! \class SHA3_224
//! \tparam T_DigestSize controls the digest size as a template parameter instead of a per-class constant
//! \brief SHA3-X message digest, template for more fine-grained typedefs
//! \since Crypto++ 6.0.0
//! \brief SHA3 message digest template
//! \tparam T_DigestSize the size of the digest, in bytes
//! \since Crypto++ 5.6.2
template<unsigned int T_DigestSize>
class SHA3_Final : public SHA3
{
@ -75,19 +75,31 @@ private:
//! \brief SHA3-224 message digest
//! \since Crypto++ 5.6.2
typedef SHA3_Final<28> SHA3_224;
// typedef SHA3_Final<28> SHA3_224;
class SHA3_224 : public SHA3_Final<28>
{
};
//! \brief SHA3-256 message digest
//! \since Crypto++ 5.6.2
typedef SHA3_Final<32> SHA3_256;
// typedef SHA3_Final<32> SHA3_256;
class SHA3_256 : public SHA3_Final<32>
{
};
//! \brief SHA3-384 message digest
//! \since Crypto++ 5.6.2
typedef SHA3_Final<48> SHA3_384;
// typedef SHA3_Final<48> SHA3_384;
class SHA3_384 : public SHA3_Final<48>
{
};
//! \brief SHA3-512 message digest
//! \since Crypto++ 5.6.2
typedef SHA3_Final<64> SHA3_512;
// typedef SHA3_Final<64> SHA3_512;
class SHA3_512 : public SHA3_Final<64>
{
};
NAMESPACE_END

View File

@ -37,6 +37,7 @@
#include "esign.h"
#include "osrng.h"
#include "sha.h"
#include "sha3.h"
#include "ripemd.h"
#include "smartptr.h"
#include "pkcspad.h"
@ -284,11 +285,12 @@ bool ValidateRSA()
{
std::cout << "\nRSA validation suite running...\n\n";
byte out[100], outPlain[100];
// Must be large enough for RSA-3072 to test SHA3_256
byte out[256], outPlain[128];
bool pass = true, fail;
{
const char *plain = "Everyone gets Friday off.";
const char plain[] = "Everyone gets Friday off.";
static const byte signature[] =
"\x05\xfa\x6a\x81\x2f\xc7\xdf\x8b\xf4\xf2\x54\x25\x09\xe0\x3e\x84"
"\x6e\x11\xb9\xc6\x20\xbe\x20\x09\xef\xb4\x40\xef\xbc\xc6\x69\x21"
@ -300,7 +302,8 @@ bool ValidateRSA()
Weak::RSASSA_PKCS1v15_MD2_Verifier rsaPub(rsaPriv);
size_t signatureLength = rsaPriv.SignMessage(GlobalRNG(), (byte *)plain, strlen(plain), out);
fail = memcmp(signature, out, 64) != 0;
CRYPTOPP_ASSERT(signatureLength <= sizeof(out));
fail = memcmp(signature, out, signatureLength) != 0;
pass = pass && !fail;
std::cout << (fail ? "FAILED " : "passed ");
@ -319,6 +322,50 @@ bool ValidateRSA()
std::cout << (fail ? "FAILED " : "passed ");
std::cout << "invalid signature verification\n";
}
/////
{
const char plain[] = "Everyone gets Friday off.";
static const byte signature[] =
"\x2e\x87\xda\x1f\xe4\xda\x1d\x7a\xb7\xf2\x42\x36\xe9\xc0\x4e\xab\x3f\x03\x71\xe1"
"\x2b\xc5\x3c\xbf\x21\x21\xa8\xd6\x28\xb0\x08\xfd\x9c\xf6\x94\xbd\x37\x32\xda\xfc"
"\x42\x1c\x8e\xdb\x8a\x81\x90\x46\x45\xb4\xde\x9e\xce\x90\xfe\xa1\xfd\xbc\x5a\xce"
"\xca\x59\x89\x93\xc0\x0f\x2f\xf1\x13\xb0\xf5\x3d\xa3\x9a\x85\xb7\x40\xd9\x34\x88"
"\x29\xb2\x4a\x0f\x9b\xbe\x22\x3a\x5b\x54\x51\xb7\xf0\x10\x72\x50\xc4\x2a\xe9\xe4"
"\xc3\x82\xeb\x32\x33\x14\xb6\xf2\x7b\x30\x7a\xbf\xc2\xf3\x0f\x4d\x72\xa0\x8d\xa1"
"\xc6\xce\xd0\xa3\x3c\xf7\x23\x4b\xb7\x2c\x5e\xca\x83\x01\xc7\x5c\xd5\xd0\xd1\x94"
"\x43\xf0\xad\xa2\xe6\x72\x2b\x13\x39\xb2\x4b\x25\x91\x3a\x4f\x53\x05\x00\x8c\xc7"
"\xcf\x4f\x11\x64\xe6\xf4\x1a\x4d\x90\x7e\xf1\xfe\xed\xec\x8d\xbb\x00\x31\x2e\x03"
"\xbe\x87\x84\x60\xfb\x5e\xef\x9d\x18\x2c\x28\x3d\xaa\x67\x80\xa3\x62\x07\x06\x5e"
"\xce\xee\x3b\xd0\x78\xb5\x98\x38\x1e\xe8\x62\x19\x9c\xc3\xd4\xf7\xc2\xc5\x00\xf0"
"\xeb\x89\x65\x53\x35\xe7\x13\x7e\xbb\x26\xb0\x76\x9c\xf2\x80\xaa\xe1\xb1\x0a\xa6"
"\x47\xfc\x5f\xe0\x7f\x82\xd7\x83\x41\xc3\x50\xa1\xe0\x0e\x1a\xe4";
FileSource keys(CRYPTOPP_DATA_DIR "TestData/rsa2048a.dat", true, new HexDecoder);
RSASS<PKCS1v15, SHA3_256>::Signer rsaPriv(keys);
RSASS<PKCS1v15, SHA3_256>::Verifier rsaPub(rsaPriv);
size_t signatureLength = rsaPriv.SignMessage(GlobalRNG(), (byte *)plain, strlen(plain), out);
CRYPTOPP_ASSERT(signatureLength <= sizeof(out));
fail = memcmp(signature, out, signatureLength) != 0;
pass = pass && !fail;
std::cout << (fail ? "FAILED " : "passed ");
std::cout << "signature check against test vector\n";
fail = !rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength);
pass = pass && !fail;
std::cout << (fail ? "FAILED " : "passed ");
std::cout << "verification check against test vector\n";
out[10]++;
fail = rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength);
pass = pass && !fail;
std::cout << (fail ? "FAILED " : "passed ");
std::cout << "invalid signature verification\n";
}
/////
{
FileSource keys(CRYPTOPP_DATA_DIR "TestData/rsa1024.dat", true, new HexDecoder);
RSAES_PKCS1v15_Decryptor rsaPriv(keys);