From 11b540b932912552159fa954d4bc362ec3d0bc0c Mon Sep 17 00:00:00 2001 From: Uri Blumenthal Date: Fri, 1 Jul 2016 14:19:41 -0400 Subject: [PATCH 01/22] Add HMQV implementation (and merge the old FHMQV into the new codebase) --- TestData/fhmqv160.dat | 1 + TestData/fhmqv256.dat | 1 + TestData/fhmqv384.dat | 1 + TestData/fhmqv512.dat | 1 + TestData/hmqv160.dat | 1 + TestData/hmqv256.dat | 1 + TestData/hmqv384.dat | 1 + TestData/hmqv512.dat | 1 + eccrypto.h | 44 +++++- fhmqv.cpp | 14 ++ fhmqv.h | 294 ++++++++++++++++++++++++++++++++++++++++ hmqv.cpp | 14 ++ hmqv.h | 303 ++++++++++++++++++++++++++++++++++++++++++ validat2.cpp | 236 ++++++++++++++++++++++++++++++++ validate.h | 2 + 15 files changed, 913 insertions(+), 2 deletions(-) create mode 100644 TestData/fhmqv160.dat create mode 100644 TestData/fhmqv256.dat create mode 100644 TestData/fhmqv384.dat create mode 100644 TestData/fhmqv512.dat create mode 100644 TestData/hmqv160.dat create mode 100644 TestData/hmqv256.dat create mode 100644 TestData/hmqv384.dat create mode 100644 TestData/hmqv512.dat create mode 100644 fhmqv.cpp create mode 100644 fhmqv.h create mode 100644 hmqv.cpp create mode 100644 hmqv.h diff --git a/TestData/fhmqv160.dat b/TestData/fhmqv160.dat new file mode 100644 index 00000000..0d66deec --- /dev/null +++ b/TestData/fhmqv160.dat @@ -0,0 +1 @@ +3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101 \ No newline at end of file diff --git a/TestData/fhmqv256.dat b/TestData/fhmqv256.dat new file mode 100644 index 00000000..0d66deec --- /dev/null +++ b/TestData/fhmqv256.dat @@ -0,0 +1 @@ +3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101 \ No newline at end of file diff --git a/TestData/fhmqv384.dat b/TestData/fhmqv384.dat new file mode 100644 index 00000000..63037fef --- /dev/null +++ b/TestData/fhmqv384.dat @@ -0,0 +1 @@ +30820140020101303C06072A8648CE3D0101023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF30640430FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC0430B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF046104AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973020101 \ No newline at end of file diff --git a/TestData/fhmqv512.dat b/TestData/fhmqv512.dat new file mode 100644 index 00000000..0053ddf6 --- /dev/null +++ b/TestData/fhmqv512.dat @@ -0,0 +1 @@ +308201AC020101304D06072A8648CE3D0101024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF308188044201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC04420051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F000481850400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409020101 \ No newline at end of file diff --git a/TestData/hmqv160.dat b/TestData/hmqv160.dat new file mode 100644 index 00000000..0d66deec --- /dev/null +++ b/TestData/hmqv160.dat @@ -0,0 +1 @@ +3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101 \ No newline at end of file diff --git a/TestData/hmqv256.dat b/TestData/hmqv256.dat new file mode 100644 index 00000000..0d66deec --- /dev/null +++ b/TestData/hmqv256.dat @@ -0,0 +1 @@ +3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101 \ No newline at end of file diff --git a/TestData/hmqv384.dat b/TestData/hmqv384.dat new file mode 100644 index 00000000..63037fef --- /dev/null +++ b/TestData/hmqv384.dat @@ -0,0 +1 @@ +30820140020101303C06072A8648CE3D0101023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF30640430FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC0430B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF046104AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973020101 \ No newline at end of file diff --git a/TestData/hmqv512.dat b/TestData/hmqv512.dat new file mode 100644 index 00000000..0053ddf6 --- /dev/null +++ b/TestData/hmqv512.dat @@ -0,0 +1 @@ +308201AC020101304D06072A8648CE3D0101024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF308188044201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC04420051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F000481850400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409020101 \ No newline at end of file diff --git a/eccrypto.h b/eccrypto.h index a3d15e95..6642dec5 100644 --- a/eccrypto.h +++ b/eccrypto.h @@ -16,6 +16,8 @@ #include "gfpcrypt.h" #include "dh.h" #include "mqv.h" +#include "hmqv.h" +#include "fhmqv.h" #include "ecp.h" #include "ec2n.h" @@ -213,6 +215,44 @@ struct ECMQV #endif }; +//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! HMQV: A High-Performance Secure Diffie-Hellman Protocol + Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately. +*/ +template ::DefaultCofactorOption, class HASH = SHA256> +struct HMQV +{ + typedef HMQV_Domain, COFACTOR_OPTION, HASH> Domain; + +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~HMQV() {} +#endif +}; + +typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain HMQV160; +typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain HMQV256; +typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain HMQV384; +typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain HMQV512; + +//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! A Secure and Efficient Authenticated Diffie–Hellman Protocol + Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. +*/ +template ::DefaultCofactorOption, class HASH = SHA256> +struct FHMQV +{ + typedef FHMQV_Domain, COFACTOR_OPTION, HASH> Domain; + +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~FHMQV() {} +#endif +}; + +typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain FHMQV160; +typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain FHMQV256; +typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain FHMQV384; +typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain FHMQV512; + //! EC keys template struct DL_Keys_EC @@ -283,10 +323,10 @@ struct ECNR : public DL_SS, DL_Algorithm_ECNR, DL_SignatureMe }; //! Elliptic Curve Integrated Encryption Scheme, AKA ECIES -/*! Default to (NoCofactorMultiplication and DHAES_MODE = false) for compatibilty with SEC1 and Crypto++ 4.2. +/*! Choose NoCofactorMultiplication and DHAES_MODE = false for compatibilty with SEC1 and Crypto++ 4.2. The combination of (IncompatibleCofactorMultiplication and DHAES_MODE = true) is recommended for best efficiency and security. */ -template +template struct ECIES : public DL_ES< DL_Keys_EC, diff --git a/fhmqv.cpp b/fhmqv.cpp new file mode 100644 index 00000000..e6403d49 --- /dev/null +++ b/fhmqv.cpp @@ -0,0 +1,14 @@ +// fhmqv.cpp - written and placed in the public domain by Jeffrey Walton +// Shamelessly based upon Wei Dai's MQV source files + +#include "pch.h" +#include "fhmqv.h" + +NAMESPACE_BEGIN(CryptoPP) + +void TestInstantiations_FHMQV() +{ + FullyHashedMQV fhmqv; +} + +NAMESPACE_END diff --git a/fhmqv.h b/fhmqv.h new file mode 100644 index 00000000..8bec5405 --- /dev/null +++ b/fhmqv.h @@ -0,0 +1,294 @@ +// fhmqv.h - written and placed in the public domain by Jeffrey Walton +// Shamelessly based upon Wei Dai's MQV source files + +#ifndef CRYPTOPP_FHMQV_H +#define CRYPTOPP_FHMQV_H + +/** \file +*/ + +#include "gfpcrypt.h" +#include "algebra.h" +#include "sha.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! A Secure and Efficient Authenticated Diffie–Hellman Protocol + Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. +*/ +template +class FHMQV_Domain: public AuthenticatedKeyAgreementDomain +{ +public: + typedef GROUP_PARAMETERS GroupParameters; + typedef typename GroupParameters::Element Element; + typedef FHMQV_Domain Domain; + + FHMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {} + + FHMQV_Domain(const GroupParameters ¶ms, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} + + FHMQV_Domain(BufferedTransformation &bt, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.BERDecode(bt);} + + template + FHMQV_Domain(T1 v1, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1);} + + template + FHMQV_Domain(T1 v1, T2 v2, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2);} + + template + FHMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3);} + + template + FHMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3, v4);} + +protected: + + inline void Hash(const Element* sigma, + const byte* e1, size_t e1len, const byte* e2, size_t e2len, + const byte* s1, size_t s1len, const byte* s2, size_t s2len, + byte* digest, size_t dlen) const + { + HASH hash; + size_t idx = 0, req = dlen; + size_t blk = std::min(dlen, (size_t)HASH::DIGESTSIZE); + + if(sigma) + { + Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); + SecByteBlock sbb(x.MinEncodedSize()); + x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); + hash.Update(sbb.BytePtr(), sbb.SizeInBytes()); + } + + hash.Update(e1, e1len); + hash.Update(e2, e2len); + hash.Update(s1, s1len); + hash.Update(s2, s2len); + + hash.TruncatedFinal(digest, blk); + req -= blk; + + // All this to catch tail bytes for large curves and small hashes + while(req != 0) + { + hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE); + + idx += (size_t)HASH::DIGESTSIZE; + blk = std::min(req, (size_t)HASH::DIGESTSIZE); + hash.TruncatedFinal(&digest[idx], blk); + + req -= blk; + } + } + +public: + + const GroupParameters & GetGroupParameters() const {return m_groupParameters;} + GroupParameters & AccessGroupParameters(){return m_groupParameters;} + + CryptoParameters & AccessCryptoParameters(){return AccessAbstractGroupParameters();} + + //! return length of agreed value produced + unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} + //! return length of static private keys in this domain + unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} + //! return length of static public keys in this domain + unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);} + + //! generate static private key + /*! \pre size of privateKey == PrivateStaticKeyLength() */ + void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + } + + //! generate static public key + /*! \pre size of publicKey == PublicStaticKeyLength() */ + void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, publicKey); + } + + unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} + unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();} + + //! return length of ephemeral private keys in this domain + void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(rng, Integer::One(), params.GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); + } + + //! return length of ephemeral public keys in this domain + void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); + } + + //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure + /*! \note The ephemeral public key will always be validated. + If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. + \pre size of agreedValue == AgreedValueLength() + \pre length of staticPrivateKey == StaticPrivateKeyLength() + \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() + \pre length of staticOtherPublicKey == StaticPublicKeyLength() + \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() + */ + bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const + { + byte *XX = NULL, *YY = NULL, *AA = NULL, *BB = NULL; + size_t xxs = 0, yys = 0, aas = 0, bbs = 0; + + // Depending on the role, this will hold either A's or B's static + // (long term) public key. AA or BB will then point into tt. + SecByteBlock tt(StaticPublicKeyLength()); + + try + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + + if(m_role == RoleServer) + { + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Element B = params.ExponentiateBase(b); + params.EncodeElement(true, B, tt); + + XX = const_cast(ephemeralOtherPublicKey); + xxs = EphemeralPublicKeyLength(); + YY = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); + yys = EphemeralPublicKeyLength(); + AA = const_cast(staticOtherPublicKey); + aas = StaticPublicKeyLength(); + BB = tt.BytePtr(); + bbs = tt.SizeInBytes(); + } + else if(m_role == RoleClient) + { + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Element A = params.ExponentiateBase(a); + params.EncodeElement(true, A, tt); + + XX = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); + xxs = EphemeralPublicKeyLength(); + YY = const_cast(ephemeralOtherPublicKey); + yys = EphemeralPublicKeyLength(); + AA = tt.BytePtr(); + aas = tt.SizeInBytes(); + BB = const_cast(staticOtherPublicKey); + bbs = StaticPublicKeyLength(); + } + else + { + assert(0); + return false; + } + + // DecodeElement calls ValidateElement at level 1. Level 1 only calls + // VerifyPoint to ensure the element is in G*. If the other's PublicKey is + // requested to be validated, we manually call ValidateElement at level 3. + Element VV1 = params.DecodeElement(staticOtherPublicKey, false); + if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULL)) + return false; + + // DecodeElement calls ValidateElement at level 1. Level 1 only calls + // VerifyPoint to ensure the element is in G*. Crank it up. + Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false); + if(!params.ValidateElement(3, VV2, NULL)) + return false; + + const Integer& p = params.GetGroupOrder(); + const Integer& q = params.GetSubgroupOrder(); + const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); + + Integer d, e; + SecByteBlock dd(len), ee(len); + + Hash(NULL, XX, xxs, YY, yys, AA, aas, BB, bbs, dd.BytePtr(), dd.SizeInBytes()); + d.Decode(dd.BytePtr(), dd.SizeInBytes()); + + Hash(NULL, YY, yys, XX, xxs, AA, aas, BB, bbs, ee.BytePtr(), ee.SizeInBytes()); + e.Decode(ee.BytePtr(), ee.SizeInBytes()); + + Element sigma; + if(m_role == RoleServer) + { + Integer y(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_B = (y + e * b) % q; + + Element A = params.DecodeElement(AA, false); + Element X = params.DecodeElement(XX, false); + + Element t1 = params.ExponentiateElement(A, d); + Element t2 = m_groupParameters.MultiplyElements(X, t1); + + sigma = params.ExponentiateElement(t2, s_B); + } + else + { + Integer x(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_A = (x + d * a) % q; + + Element B = params.DecodeElement(BB, false); + Element Y = params.DecodeElement(YY, false); + + Element t1 = params.ExponentiateElement(B, e); + Element t2 = m_groupParameters.MultiplyElements(Y, t1); + + sigma = params.ExponentiateElement(t2, s_A); + } + + Hash(&sigma, XX, xxs, YY, yys, AA, aas, BB, bbs, agreedValue, AgreedValueLength()); + } + catch (DL_BadElement &) + { + return false; + } + return true; + } + +private: + + // The paper uses Initiator and Recipient - make it classical. + enum KeyAgreementRole{ RoleServer = 1, RoleClient }; + + DL_GroupParameters & AccessAbstractGroupParameters() {return m_groupParameters;} + const DL_GroupParameters & GetAbstractGroupParameters() const{return m_groupParameters;} + + KeyAgreementRole m_role; + GroupParameters m_groupParameters; +}; + +//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! A Secure and Efficient Authenticated Diffie–Hellman Protocol + Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. +*/ +typedef FHMQV_Domain FullyHashedMQV; + +NAMESPACE_END + +#endif diff --git a/hmqv.cpp b/hmqv.cpp new file mode 100644 index 00000000..86a8f97d --- /dev/null +++ b/hmqv.cpp @@ -0,0 +1,14 @@ +// hmqv.cpp - written and placed in the public domain by Uri Blumenthal +// Shamelessly based upon Jeffrey Walton's FHMQV and Wei Dai's MQV source files + +#include "pch.h" +#include "hmqv.h" + +NAMESPACE_BEGIN(CryptoPP) + +void TestInstantiations_HMQV() +{ + HashedMQV hmqv; +} + +NAMESPACE_END diff --git a/hmqv.h b/hmqv.h new file mode 100644 index 00000000..241d4c66 --- /dev/null +++ b/hmqv.h @@ -0,0 +1,303 @@ +// hmqv.h - written and placed in the public domain by Uri Blumenthal +// Shamelessly based upon Jeffrey Walton's FHMQV and Wei Dai's MQV source files + +#ifndef CRYPTOPP_HMQV_H +#define CRYPTOPP_HMQV_H + +/** \file +*/ + +#include "gfpcrypt.h" +#include "algebra.h" +#include "sha.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! HMQV: A High-Performance Secure Diffie-Hellman Protocol + Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately. +*/ +template +class HMQV_Domain: public AuthenticatedKeyAgreementDomain +{ +public: + typedef GROUP_PARAMETERS GroupParameters; + typedef typename GroupParameters::Element Element; + typedef HMQV_Domain Domain; + + HMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {} + + HMQV_Domain(const GroupParameters ¶ms, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} + + HMQV_Domain(BufferedTransformation &bt, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.BERDecode(bt);} + + template + HMQV_Domain(T1 v1, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1);} + + template + HMQV_Domain(T1 v1, T2 v2, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2);} + + template + HMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3);} + + template + HMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3, v4);} + +protected: + // Hash invocation by client and server differ only in what keys + // each provides. + + inline void Hash(const Element* sigma, + const byte* e1, size_t e1len, // Ephemeral key and key length + const byte* s1, size_t s1len, // Static key and key length + byte* digest, size_t dlen) const + { + HASH hash; + size_t idx = 0, req = dlen; + size_t blk = std::min(dlen, (size_t)HASH::DIGESTSIZE); + + if(sigma) + { + if (e1len != 0 || s1len != 0) { + assert(0); + } + Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); + SecByteBlock sbb(x.MinEncodedSize()); + x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); + hash.Update(sbb.BytePtr(), sbb.SizeInBytes()); + } else { + if (e1len == 0 || s1len == 0) { + assert(0); + } + hash.Update(e1, e1len); + hash.Update(s1, s1len); + } + + hash.TruncatedFinal(digest, blk); + req -= blk; + + // All this to catch tail bytes for large curves and small hashes + while(req != 0) + { + hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE); + + idx += (size_t)HASH::DIGESTSIZE; + blk = std::min(req, (size_t)HASH::DIGESTSIZE); + hash.TruncatedFinal(&digest[idx], blk); + + req -= blk; + } + } + +public: + + const GroupParameters & GetGroupParameters() const {return m_groupParameters;} + GroupParameters & AccessGroupParameters(){return m_groupParameters;} + + CryptoParameters & AccessCryptoParameters(){return AccessAbstractGroupParameters();} + + //! return length of agreed value produced + unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} + //! return length of static private keys in this domain + unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} + //! return length of static public keys in this domain + unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);} + + //! generate static private key + /*! \pre size of privateKey == PrivateStaticKeyLength() */ + void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + } + + //! generate static public key + /*! \pre size of publicKey == PublicStaticKeyLength() */ + void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, publicKey); + } + + unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} + unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();} + + //! return length of ephemeral private keys in this domain + void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(rng, Integer::One(), params.GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); + } + + //! return length of ephemeral public keys in this domain + void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); + } + + //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure + /*! \note The ephemeral public key will always be validated. + If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. + \pre size of agreedValue == AgreedValueLength() + \pre length of staticPrivateKey == StaticPrivateKeyLength() + \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() + \pre length of staticOtherPublicKey == StaticPublicKeyLength() + \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() + */ + bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const + { + byte *XX = NULL, *YY = NULL, *AA = NULL, *BB = NULL; + size_t xxs = 0, yys = 0, aas = 0, bbs = 0; + + // Depending on the role, this will hold either A's or B's static + // (long term) public key. AA or BB will then point into tt. + SecByteBlock tt(StaticPublicKeyLength()); + + try + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + + if(m_role == RoleServer) + { + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Element B = params.ExponentiateBase(b); + params.EncodeElement(true, B, tt); + + XX = const_cast(ephemeralOtherPublicKey); + xxs = EphemeralPublicKeyLength(); + YY = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); + yys = EphemeralPublicKeyLength(); + AA = const_cast(staticOtherPublicKey); + aas = StaticPublicKeyLength(); + BB = tt.BytePtr(); + bbs = tt.SizeInBytes(); + } + else if(m_role == RoleClient) + { + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Element A = params.ExponentiateBase(a); + params.EncodeElement(true, A, tt); + + XX = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); + xxs = EphemeralPublicKeyLength(); + YY = const_cast(ephemeralOtherPublicKey); + yys = EphemeralPublicKeyLength(); + AA = tt.BytePtr(); + aas = tt.SizeInBytes(); + BB = const_cast(staticOtherPublicKey); + bbs = StaticPublicKeyLength(); + } + else + { + assert(0); + return false; + } + + // DecodeElement calls ValidateElement at level 1. Level 1 only calls + // VerifyPoint to ensure the element is in G*. If the other's PublicKey is + // requested to be validated, we manually call ValidateElement at level 3. + Element VV1 = params.DecodeElement(staticOtherPublicKey, false); + if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULL)) + return false; + + // DecodeElement calls ValidateElement at level 1. Level 1 only calls + // VerifyPoint to ensure the element is in G*. Crank it up. + Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false); + if(!params.ValidateElement(3, VV2, NULL)) + return false; + +// const Integer& p = params.GetGroupOrder(); // not used, remove later + const Integer& q = params.GetSubgroupOrder(); + const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); + + Integer d, e; + SecByteBlock dd(len), ee(len); + + // Compute $d = \hat{H}(X, \hat{B})$ + Hash(NULL, XX, xxs, BB, bbs, dd.BytePtr(), dd.SizeInBytes()); + d.Decode(dd.BytePtr(), dd.SizeInBytes()); + + // Compute $e = \hat{H}(Y, \hat{A})$ + Hash(NULL, YY, yys, AA, aas, ee.BytePtr(), ee.SizeInBytes()); + e.Decode(ee.BytePtr(), ee.SizeInBytes()); + + Element sigma; + if(m_role == RoleServer) + { + Integer y(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_B = (y + e * b) % q; + + Element A = params.DecodeElement(AA, false); + Element X = params.DecodeElement(XX, false); + + Element t1 = params.ExponentiateElement(A, d); + Element t2 = m_groupParameters.MultiplyElements(X, t1); + + // $\sigma_B}=(X \cdot A^{d})^{s_B} + sigma = params.ExponentiateElement(t2, s_B); + } + else + { + Integer x(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_A = (x + d * a) % q; + + Element B = params.DecodeElement(BB, false); + Element Y = params.DecodeElement(YY, false); + + Element t1 = params.ExponentiateElement(B, e); + Element t2 = m_groupParameters.MultiplyElements(Y, t1); + + // $\sigma_A}=(Y \cdot B^{e})^{s_A} + sigma = params.ExponentiateElement(t2, s_A); + } + Hash(&sigma, NULL, 0, NULL, 0, agreedValue, AgreedValueLength()); + } + catch (DL_BadElement &) + { + return false; + } + return true; + } + +private: + + // The paper uses Initiator and Recipient - make it classical. + enum KeyAgreementRole{ RoleServer = 1, RoleClient }; + + DL_GroupParameters & AccessAbstractGroupParameters() {return m_groupParameters;} + const DL_GroupParameters & GetAbstractGroupParameters() const{return m_groupParameters;} + + KeyAgreementRole m_role; + GroupParameters m_groupParameters; +}; + +//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! HMQV: A High-Performance Secure Diffie-Hellman Protocol + Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately. +*/ +typedef HMQV_Domain HashedMQV; + +NAMESPACE_END + +#endif diff --git a/validat2.cpp b/validat2.cpp index 32885985..ec553a28 100644 --- a/validat2.cpp +++ b/validat2.cpp @@ -18,6 +18,8 @@ #include "dsa.h" #include "dh.h" #include "mqv.h" +#include "hmqv.h" +#include "fhmqv.h" #include "luc.h" #include "xtrcrypt.h" #include "rabin.h" @@ -384,6 +386,240 @@ bool ValidateMQV() return AuthenticatedKeyAgreementValidate(mqv); } +bool ValidateHMQV() +{ + std::cout << "\nHMQV validation suite running...\n\n"; + + //HMQV< ECP >::Domain hmqvB(false /*server*/); + HMQV256 hmqvB(false); + FileSource f256("TestData/hmqv256.dat", true, new HexDecoder()); + FileSource f384("TestData/hmqv384.dat", true, new HexDecoder()); + FileSource f512("TestData/hmqv512.dat", true, new HexDecoder()); + hmqvB.AccessGroupParameters().BERDecode(f256); + + std::cout << "HMQV with NIST P-256 and SHA-256:" << std::endl; + + if (hmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; + return false; + } + + const OID oid = ASN1::secp256r1(); + HMQV< ECP >::Domain hmqvA(oid, true /*client*/); + + if (hmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; + return false; + } + + SecByteBlock sprivA(hmqvA.StaticPrivateKeyLength()), sprivB(hmqvB.StaticPrivateKeyLength()); + SecByteBlock eprivA(hmqvA.EphemeralPrivateKeyLength()), eprivB(hmqvB.EphemeralPrivateKeyLength()); + SecByteBlock spubA(hmqvA.StaticPublicKeyLength()), spubB(hmqvB.StaticPublicKeyLength()); + SecByteBlock epubA(hmqvA.EphemeralPublicKeyLength()), epubB(hmqvB.EphemeralPublicKeyLength()); + SecByteBlock valA(hmqvA.AgreedValueLength()), valB(hmqvB.AgreedValueLength()); + + hmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA); + hmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB); + hmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA); + hmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB); + + memset(valA.begin(), 0x00, valA.size()); + memset(valB.begin(), 0x11, valB.size()); + + if (!(hmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && hmqvB.Agree(valB, sprivB, eprivB, spubA, epubA))) + { + std::cout << "FAILED authenticated key agreement failed" << std::endl; + return false; + } + + if (memcmp(valA.begin(), valB.begin(), hmqvA.AgreedValueLength())) + { + std::cout << "FAILED authenticated agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed authenticated key agreement" << std::endl; + + // Now test HMQV with NIST P-384 curve and SHA384 hash + std::cout << endl; + std::cout << "HMQV with NIST P-384 and SHA-384:" << std::endl; + + HMQV384 hmqvB384(false); + hmqvB384.AccessGroupParameters().BERDecode(f384); + + if (hmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; + return false; + } + + const OID oid384 = ASN1::secp384r1(); + HMQV384 hmqvA384(oid384, true /*client*/); + + if (hmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; + return false; + } + + SecByteBlock sprivA384(hmqvA384.StaticPrivateKeyLength()), sprivB384(hmqvB384.StaticPrivateKeyLength()); + SecByteBlock eprivA384(hmqvA384.EphemeralPrivateKeyLength()), eprivB384(hmqvB384.EphemeralPrivateKeyLength()); + SecByteBlock spubA384(hmqvA384.StaticPublicKeyLength()), spubB384(hmqvB384.StaticPublicKeyLength()); + SecByteBlock epubA384(hmqvA384.EphemeralPublicKeyLength()), epubB384(hmqvB384.EphemeralPublicKeyLength()); + SecByteBlock valA384(hmqvA384.AgreedValueLength()), valB384(hmqvB384.AgreedValueLength()); + + hmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384); + hmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384); + hmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384); + hmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384); + + memset(valA384.begin(), 0x00, valA384.size()); + memset(valB384.begin(), 0x11, valB384.size()); + + if (!(hmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && hmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384))) + { + std::cout << "FAILED authenticated key agreement failed" << std::endl; + return false; + } + + if (memcmp(valA384.begin(), valB384.begin(), hmqvA384.AgreedValueLength())) + { + std::cout << "FAILED authenticated agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed authenticated key agreement" << std::endl; + + return true; +} + +bool ValidateFHMQV() +{ + std::cout << "\nFHMQV validation suite running...\n\n"; + + //FHMQV< ECP >::Domain fhmqvB(false /*server*/); + FHMQV256 fhmqvB(false); + FileSource f256("TestData/fhmqv256.dat", true, new HexDecoder()); + FileSource f384("TestData/fhmqv384.dat", true, new HexDecoder()); + FileSource f512("TestData/fhmqv512.dat", true, new HexDecoder()); + fhmqvB.AccessGroupParameters().BERDecode(f256); + + std::cout << "FHMQV with NIST P-256 and SHA-256:" << std::endl; + + if (fhmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; + return false; + } + + const OID oid = ASN1::secp256r1(); + FHMQV< ECP >::Domain fhmqvA(oid, true /*client*/); + + if (fhmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; + return false; + } + + SecByteBlock sprivA(fhmqvA.StaticPrivateKeyLength()), sprivB(fhmqvB.StaticPrivateKeyLength()); + SecByteBlock eprivA(fhmqvA.EphemeralPrivateKeyLength()), eprivB(fhmqvB.EphemeralPrivateKeyLength()); + SecByteBlock spubA(fhmqvA.StaticPublicKeyLength()), spubB(fhmqvB.StaticPublicKeyLength()); + SecByteBlock epubA(fhmqvA.EphemeralPublicKeyLength()), epubB(fhmqvB.EphemeralPublicKeyLength()); + SecByteBlock valA(fhmqvA.AgreedValueLength()), valB(fhmqvB.AgreedValueLength()); + + fhmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA); + fhmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB); + fhmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA); + fhmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB); + + memset(valA.begin(), 0x00, valA.size()); + memset(valB.begin(), 0x11, valB.size()); + + if (!(fhmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && fhmqvB.Agree(valB, sprivB, eprivB, spubA, epubA))) + { + std::cout << "FAILED authenticated key agreement failed" << std::endl; + return false; + } + + if (memcmp(valA.begin(), valB.begin(), fhmqvA.AgreedValueLength())) + { + std::cout << "FAILED authenticated agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed authenticated key agreement" << std::endl; + + // Now test FHMQV with NIST P-384 curve and SHA384 hash + std::cout << endl; + std::cout << "FHMQV with NIST P-384 and SHA-384:" << std::endl; + + FHMQV384 fhmqvB384(false); + fhmqvB384.AccessGroupParameters().BERDecode(f384); + + if (fhmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; + return false; + } + + const OID oid384 = ASN1::secp384r1(); + FHMQV384 fhmqvA384(oid384, true /*client*/); + + if (fhmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; + return false; + } + + SecByteBlock sprivA384(fhmqvA384.StaticPrivateKeyLength()), sprivB384(fhmqvB384.StaticPrivateKeyLength()); + SecByteBlock eprivA384(fhmqvA384.EphemeralPrivateKeyLength()), eprivB384(fhmqvB384.EphemeralPrivateKeyLength()); + SecByteBlock spubA384(fhmqvA384.StaticPublicKeyLength()), spubB384(fhmqvB384.StaticPublicKeyLength()); + SecByteBlock epubA384(fhmqvA384.EphemeralPublicKeyLength()), epubB384(fhmqvB384.EphemeralPublicKeyLength()); + SecByteBlock valA384(fhmqvA384.AgreedValueLength()), valB384(fhmqvB384.AgreedValueLength()); + + fhmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384); + fhmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384); + fhmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384); + fhmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384); + + memset(valA384.begin(), 0x00, valA384.size()); + memset(valB384.begin(), 0x11, valB384.size()); + + if (!(fhmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && fhmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384))) + { + std::cout << "FAILED authenticated key agreement failed" << std::endl; + return false; + } + + if (memcmp(valA384.begin(), valB384.begin(), fhmqvA384.AgreedValueLength())) + { + std::cout << "FAILED authenticated agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed authenticated key agreement" << std::endl; + + return true; +} + bool ValidateLUC_DH() { cout << "\nLUC-DH validation suite running...\n\n"; diff --git a/validate.h b/validate.h index 6c0c4793..0a388308 100644 --- a/validate.h +++ b/validate.h @@ -71,6 +71,8 @@ bool ValidateCMAC(); bool ValidateBBS(); bool ValidateDH(); bool ValidateMQV(); +bool ValidateHMQV(); +bool ValidateFHMQV(); bool ValidateRSA(); bool ValidateElGamal(); bool ValidateDLIES(); From ec350995893b8388631c023d8884f22c94c212ad Mon Sep 17 00:00:00 2001 From: Uri Blumenthal Date: Fri, 1 Jul 2016 14:19:41 -0400 Subject: [PATCH 02/22] Add HMQV implementation (and merge the old FHMQV into the new codebase) --- TestData/fhmqv160.dat | 1 + TestData/fhmqv256.dat | 1 + TestData/fhmqv384.dat | 1 + TestData/fhmqv512.dat | 1 + TestData/hmqv160.dat | 1 + TestData/hmqv256.dat | 1 + TestData/hmqv384.dat | 1 + TestData/hmqv512.dat | 1 + eccrypto.h | 44 +++++- fhmqv.cpp | 14 ++ fhmqv.h | 294 ++++++++++++++++++++++++++++++++++++++++ hmqv.cpp | 14 ++ hmqv.h | 303 ++++++++++++++++++++++++++++++++++++++++++ validat1.cpp | 2 + validat2.cpp | 236 ++++++++++++++++++++++++++++++++ validate.h | 2 + 16 files changed, 915 insertions(+), 2 deletions(-) create mode 100644 TestData/fhmqv160.dat create mode 100644 TestData/fhmqv256.dat create mode 100644 TestData/fhmqv384.dat create mode 100644 TestData/fhmqv512.dat create mode 100644 TestData/hmqv160.dat create mode 100644 TestData/hmqv256.dat create mode 100644 TestData/hmqv384.dat create mode 100644 TestData/hmqv512.dat create mode 100644 fhmqv.cpp create mode 100644 fhmqv.h create mode 100644 hmqv.cpp create mode 100644 hmqv.h diff --git a/TestData/fhmqv160.dat b/TestData/fhmqv160.dat new file mode 100644 index 00000000..0d66deec --- /dev/null +++ b/TestData/fhmqv160.dat @@ -0,0 +1 @@ +3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101 \ No newline at end of file diff --git a/TestData/fhmqv256.dat b/TestData/fhmqv256.dat new file mode 100644 index 00000000..0d66deec --- /dev/null +++ b/TestData/fhmqv256.dat @@ -0,0 +1 @@ +3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101 \ No newline at end of file diff --git a/TestData/fhmqv384.dat b/TestData/fhmqv384.dat new file mode 100644 index 00000000..63037fef --- /dev/null +++ b/TestData/fhmqv384.dat @@ -0,0 +1 @@ +30820140020101303C06072A8648CE3D0101023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF30640430FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC0430B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF046104AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973020101 \ No newline at end of file diff --git a/TestData/fhmqv512.dat b/TestData/fhmqv512.dat new file mode 100644 index 00000000..0053ddf6 --- /dev/null +++ b/TestData/fhmqv512.dat @@ -0,0 +1 @@ +308201AC020101304D06072A8648CE3D0101024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF308188044201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC04420051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F000481850400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409020101 \ No newline at end of file diff --git a/TestData/hmqv160.dat b/TestData/hmqv160.dat new file mode 100644 index 00000000..0d66deec --- /dev/null +++ b/TestData/hmqv160.dat @@ -0,0 +1 @@ +3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101 \ No newline at end of file diff --git a/TestData/hmqv256.dat b/TestData/hmqv256.dat new file mode 100644 index 00000000..0d66deec --- /dev/null +++ b/TestData/hmqv256.dat @@ -0,0 +1 @@ +3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101 \ No newline at end of file diff --git a/TestData/hmqv384.dat b/TestData/hmqv384.dat new file mode 100644 index 00000000..63037fef --- /dev/null +++ b/TestData/hmqv384.dat @@ -0,0 +1 @@ +30820140020101303C06072A8648CE3D0101023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF30640430FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC0430B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF046104AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973020101 \ No newline at end of file diff --git a/TestData/hmqv512.dat b/TestData/hmqv512.dat new file mode 100644 index 00000000..0053ddf6 --- /dev/null +++ b/TestData/hmqv512.dat @@ -0,0 +1 @@ +308201AC020101304D06072A8648CE3D0101024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF308188044201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC04420051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F000481850400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409020101 \ No newline at end of file diff --git a/eccrypto.h b/eccrypto.h index a3d15e95..6642dec5 100644 --- a/eccrypto.h +++ b/eccrypto.h @@ -16,6 +16,8 @@ #include "gfpcrypt.h" #include "dh.h" #include "mqv.h" +#include "hmqv.h" +#include "fhmqv.h" #include "ecp.h" #include "ec2n.h" @@ -213,6 +215,44 @@ struct ECMQV #endif }; +//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! HMQV: A High-Performance Secure Diffie-Hellman Protocol + Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately. +*/ +template ::DefaultCofactorOption, class HASH = SHA256> +struct HMQV +{ + typedef HMQV_Domain, COFACTOR_OPTION, HASH> Domain; + +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~HMQV() {} +#endif +}; + +typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain HMQV160; +typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain HMQV256; +typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain HMQV384; +typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain HMQV512; + +//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! A Secure and Efficient Authenticated Diffie–Hellman Protocol + Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. +*/ +template ::DefaultCofactorOption, class HASH = SHA256> +struct FHMQV +{ + typedef FHMQV_Domain, COFACTOR_OPTION, HASH> Domain; + +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~FHMQV() {} +#endif +}; + +typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain FHMQV160; +typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain FHMQV256; +typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain FHMQV384; +typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain FHMQV512; + //! EC keys template struct DL_Keys_EC @@ -283,10 +323,10 @@ struct ECNR : public DL_SS, DL_Algorithm_ECNR, DL_SignatureMe }; //! Elliptic Curve Integrated Encryption Scheme, AKA ECIES -/*! Default to (NoCofactorMultiplication and DHAES_MODE = false) for compatibilty with SEC1 and Crypto++ 4.2. +/*! Choose NoCofactorMultiplication and DHAES_MODE = false for compatibilty with SEC1 and Crypto++ 4.2. The combination of (IncompatibleCofactorMultiplication and DHAES_MODE = true) is recommended for best efficiency and security. */ -template +template struct ECIES : public DL_ES< DL_Keys_EC, diff --git a/fhmqv.cpp b/fhmqv.cpp new file mode 100644 index 00000000..e6403d49 --- /dev/null +++ b/fhmqv.cpp @@ -0,0 +1,14 @@ +// fhmqv.cpp - written and placed in the public domain by Jeffrey Walton +// Shamelessly based upon Wei Dai's MQV source files + +#include "pch.h" +#include "fhmqv.h" + +NAMESPACE_BEGIN(CryptoPP) + +void TestInstantiations_FHMQV() +{ + FullyHashedMQV fhmqv; +} + +NAMESPACE_END diff --git a/fhmqv.h b/fhmqv.h new file mode 100644 index 00000000..8bec5405 --- /dev/null +++ b/fhmqv.h @@ -0,0 +1,294 @@ +// fhmqv.h - written and placed in the public domain by Jeffrey Walton +// Shamelessly based upon Wei Dai's MQV source files + +#ifndef CRYPTOPP_FHMQV_H +#define CRYPTOPP_FHMQV_H + +/** \file +*/ + +#include "gfpcrypt.h" +#include "algebra.h" +#include "sha.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! A Secure and Efficient Authenticated Diffie–Hellman Protocol + Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. +*/ +template +class FHMQV_Domain: public AuthenticatedKeyAgreementDomain +{ +public: + typedef GROUP_PARAMETERS GroupParameters; + typedef typename GroupParameters::Element Element; + typedef FHMQV_Domain Domain; + + FHMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {} + + FHMQV_Domain(const GroupParameters ¶ms, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} + + FHMQV_Domain(BufferedTransformation &bt, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.BERDecode(bt);} + + template + FHMQV_Domain(T1 v1, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1);} + + template + FHMQV_Domain(T1 v1, T2 v2, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2);} + + template + FHMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3);} + + template + FHMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3, v4);} + +protected: + + inline void Hash(const Element* sigma, + const byte* e1, size_t e1len, const byte* e2, size_t e2len, + const byte* s1, size_t s1len, const byte* s2, size_t s2len, + byte* digest, size_t dlen) const + { + HASH hash; + size_t idx = 0, req = dlen; + size_t blk = std::min(dlen, (size_t)HASH::DIGESTSIZE); + + if(sigma) + { + Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); + SecByteBlock sbb(x.MinEncodedSize()); + x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); + hash.Update(sbb.BytePtr(), sbb.SizeInBytes()); + } + + hash.Update(e1, e1len); + hash.Update(e2, e2len); + hash.Update(s1, s1len); + hash.Update(s2, s2len); + + hash.TruncatedFinal(digest, blk); + req -= blk; + + // All this to catch tail bytes for large curves and small hashes + while(req != 0) + { + hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE); + + idx += (size_t)HASH::DIGESTSIZE; + blk = std::min(req, (size_t)HASH::DIGESTSIZE); + hash.TruncatedFinal(&digest[idx], blk); + + req -= blk; + } + } + +public: + + const GroupParameters & GetGroupParameters() const {return m_groupParameters;} + GroupParameters & AccessGroupParameters(){return m_groupParameters;} + + CryptoParameters & AccessCryptoParameters(){return AccessAbstractGroupParameters();} + + //! return length of agreed value produced + unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} + //! return length of static private keys in this domain + unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} + //! return length of static public keys in this domain + unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);} + + //! generate static private key + /*! \pre size of privateKey == PrivateStaticKeyLength() */ + void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + } + + //! generate static public key + /*! \pre size of publicKey == PublicStaticKeyLength() */ + void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, publicKey); + } + + unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} + unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();} + + //! return length of ephemeral private keys in this domain + void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(rng, Integer::One(), params.GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); + } + + //! return length of ephemeral public keys in this domain + void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); + } + + //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure + /*! \note The ephemeral public key will always be validated. + If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. + \pre size of agreedValue == AgreedValueLength() + \pre length of staticPrivateKey == StaticPrivateKeyLength() + \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() + \pre length of staticOtherPublicKey == StaticPublicKeyLength() + \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() + */ + bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const + { + byte *XX = NULL, *YY = NULL, *AA = NULL, *BB = NULL; + size_t xxs = 0, yys = 0, aas = 0, bbs = 0; + + // Depending on the role, this will hold either A's or B's static + // (long term) public key. AA or BB will then point into tt. + SecByteBlock tt(StaticPublicKeyLength()); + + try + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + + if(m_role == RoleServer) + { + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Element B = params.ExponentiateBase(b); + params.EncodeElement(true, B, tt); + + XX = const_cast(ephemeralOtherPublicKey); + xxs = EphemeralPublicKeyLength(); + YY = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); + yys = EphemeralPublicKeyLength(); + AA = const_cast(staticOtherPublicKey); + aas = StaticPublicKeyLength(); + BB = tt.BytePtr(); + bbs = tt.SizeInBytes(); + } + else if(m_role == RoleClient) + { + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Element A = params.ExponentiateBase(a); + params.EncodeElement(true, A, tt); + + XX = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); + xxs = EphemeralPublicKeyLength(); + YY = const_cast(ephemeralOtherPublicKey); + yys = EphemeralPublicKeyLength(); + AA = tt.BytePtr(); + aas = tt.SizeInBytes(); + BB = const_cast(staticOtherPublicKey); + bbs = StaticPublicKeyLength(); + } + else + { + assert(0); + return false; + } + + // DecodeElement calls ValidateElement at level 1. Level 1 only calls + // VerifyPoint to ensure the element is in G*. If the other's PublicKey is + // requested to be validated, we manually call ValidateElement at level 3. + Element VV1 = params.DecodeElement(staticOtherPublicKey, false); + if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULL)) + return false; + + // DecodeElement calls ValidateElement at level 1. Level 1 only calls + // VerifyPoint to ensure the element is in G*. Crank it up. + Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false); + if(!params.ValidateElement(3, VV2, NULL)) + return false; + + const Integer& p = params.GetGroupOrder(); + const Integer& q = params.GetSubgroupOrder(); + const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); + + Integer d, e; + SecByteBlock dd(len), ee(len); + + Hash(NULL, XX, xxs, YY, yys, AA, aas, BB, bbs, dd.BytePtr(), dd.SizeInBytes()); + d.Decode(dd.BytePtr(), dd.SizeInBytes()); + + Hash(NULL, YY, yys, XX, xxs, AA, aas, BB, bbs, ee.BytePtr(), ee.SizeInBytes()); + e.Decode(ee.BytePtr(), ee.SizeInBytes()); + + Element sigma; + if(m_role == RoleServer) + { + Integer y(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_B = (y + e * b) % q; + + Element A = params.DecodeElement(AA, false); + Element X = params.DecodeElement(XX, false); + + Element t1 = params.ExponentiateElement(A, d); + Element t2 = m_groupParameters.MultiplyElements(X, t1); + + sigma = params.ExponentiateElement(t2, s_B); + } + else + { + Integer x(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_A = (x + d * a) % q; + + Element B = params.DecodeElement(BB, false); + Element Y = params.DecodeElement(YY, false); + + Element t1 = params.ExponentiateElement(B, e); + Element t2 = m_groupParameters.MultiplyElements(Y, t1); + + sigma = params.ExponentiateElement(t2, s_A); + } + + Hash(&sigma, XX, xxs, YY, yys, AA, aas, BB, bbs, agreedValue, AgreedValueLength()); + } + catch (DL_BadElement &) + { + return false; + } + return true; + } + +private: + + // The paper uses Initiator and Recipient - make it classical. + enum KeyAgreementRole{ RoleServer = 1, RoleClient }; + + DL_GroupParameters & AccessAbstractGroupParameters() {return m_groupParameters;} + const DL_GroupParameters & GetAbstractGroupParameters() const{return m_groupParameters;} + + KeyAgreementRole m_role; + GroupParameters m_groupParameters; +}; + +//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! A Secure and Efficient Authenticated Diffie–Hellman Protocol + Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. +*/ +typedef FHMQV_Domain FullyHashedMQV; + +NAMESPACE_END + +#endif diff --git a/hmqv.cpp b/hmqv.cpp new file mode 100644 index 00000000..86a8f97d --- /dev/null +++ b/hmqv.cpp @@ -0,0 +1,14 @@ +// hmqv.cpp - written and placed in the public domain by Uri Blumenthal +// Shamelessly based upon Jeffrey Walton's FHMQV and Wei Dai's MQV source files + +#include "pch.h" +#include "hmqv.h" + +NAMESPACE_BEGIN(CryptoPP) + +void TestInstantiations_HMQV() +{ + HashedMQV hmqv; +} + +NAMESPACE_END diff --git a/hmqv.h b/hmqv.h new file mode 100644 index 00000000..241d4c66 --- /dev/null +++ b/hmqv.h @@ -0,0 +1,303 @@ +// hmqv.h - written and placed in the public domain by Uri Blumenthal +// Shamelessly based upon Jeffrey Walton's FHMQV and Wei Dai's MQV source files + +#ifndef CRYPTOPP_HMQV_H +#define CRYPTOPP_HMQV_H + +/** \file +*/ + +#include "gfpcrypt.h" +#include "algebra.h" +#include "sha.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! HMQV: A High-Performance Secure Diffie-Hellman Protocol + Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately. +*/ +template +class HMQV_Domain: public AuthenticatedKeyAgreementDomain +{ +public: + typedef GROUP_PARAMETERS GroupParameters; + typedef typename GroupParameters::Element Element; + typedef HMQV_Domain Domain; + + HMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {} + + HMQV_Domain(const GroupParameters ¶ms, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} + + HMQV_Domain(BufferedTransformation &bt, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.BERDecode(bt);} + + template + HMQV_Domain(T1 v1, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1);} + + template + HMQV_Domain(T1 v1, T2 v2, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2);} + + template + HMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3);} + + template + HMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3, v4);} + +protected: + // Hash invocation by client and server differ only in what keys + // each provides. + + inline void Hash(const Element* sigma, + const byte* e1, size_t e1len, // Ephemeral key and key length + const byte* s1, size_t s1len, // Static key and key length + byte* digest, size_t dlen) const + { + HASH hash; + size_t idx = 0, req = dlen; + size_t blk = std::min(dlen, (size_t)HASH::DIGESTSIZE); + + if(sigma) + { + if (e1len != 0 || s1len != 0) { + assert(0); + } + Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); + SecByteBlock sbb(x.MinEncodedSize()); + x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); + hash.Update(sbb.BytePtr(), sbb.SizeInBytes()); + } else { + if (e1len == 0 || s1len == 0) { + assert(0); + } + hash.Update(e1, e1len); + hash.Update(s1, s1len); + } + + hash.TruncatedFinal(digest, blk); + req -= blk; + + // All this to catch tail bytes for large curves and small hashes + while(req != 0) + { + hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE); + + idx += (size_t)HASH::DIGESTSIZE; + blk = std::min(req, (size_t)HASH::DIGESTSIZE); + hash.TruncatedFinal(&digest[idx], blk); + + req -= blk; + } + } + +public: + + const GroupParameters & GetGroupParameters() const {return m_groupParameters;} + GroupParameters & AccessGroupParameters(){return m_groupParameters;} + + CryptoParameters & AccessCryptoParameters(){return AccessAbstractGroupParameters();} + + //! return length of agreed value produced + unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} + //! return length of static private keys in this domain + unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} + //! return length of static public keys in this domain + unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);} + + //! generate static private key + /*! \pre size of privateKey == PrivateStaticKeyLength() */ + void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + } + + //! generate static public key + /*! \pre size of publicKey == PublicStaticKeyLength() */ + void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, publicKey); + } + + unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} + unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();} + + //! return length of ephemeral private keys in this domain + void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(rng, Integer::One(), params.GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); + } + + //! return length of ephemeral public keys in this domain + void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); + } + + //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure + /*! \note The ephemeral public key will always be validated. + If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. + \pre size of agreedValue == AgreedValueLength() + \pre length of staticPrivateKey == StaticPrivateKeyLength() + \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() + \pre length of staticOtherPublicKey == StaticPublicKeyLength() + \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() + */ + bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const + { + byte *XX = NULL, *YY = NULL, *AA = NULL, *BB = NULL; + size_t xxs = 0, yys = 0, aas = 0, bbs = 0; + + // Depending on the role, this will hold either A's or B's static + // (long term) public key. AA or BB will then point into tt. + SecByteBlock tt(StaticPublicKeyLength()); + + try + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + + if(m_role == RoleServer) + { + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Element B = params.ExponentiateBase(b); + params.EncodeElement(true, B, tt); + + XX = const_cast(ephemeralOtherPublicKey); + xxs = EphemeralPublicKeyLength(); + YY = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); + yys = EphemeralPublicKeyLength(); + AA = const_cast(staticOtherPublicKey); + aas = StaticPublicKeyLength(); + BB = tt.BytePtr(); + bbs = tt.SizeInBytes(); + } + else if(m_role == RoleClient) + { + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Element A = params.ExponentiateBase(a); + params.EncodeElement(true, A, tt); + + XX = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); + xxs = EphemeralPublicKeyLength(); + YY = const_cast(ephemeralOtherPublicKey); + yys = EphemeralPublicKeyLength(); + AA = tt.BytePtr(); + aas = tt.SizeInBytes(); + BB = const_cast(staticOtherPublicKey); + bbs = StaticPublicKeyLength(); + } + else + { + assert(0); + return false; + } + + // DecodeElement calls ValidateElement at level 1. Level 1 only calls + // VerifyPoint to ensure the element is in G*. If the other's PublicKey is + // requested to be validated, we manually call ValidateElement at level 3. + Element VV1 = params.DecodeElement(staticOtherPublicKey, false); + if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULL)) + return false; + + // DecodeElement calls ValidateElement at level 1. Level 1 only calls + // VerifyPoint to ensure the element is in G*. Crank it up. + Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false); + if(!params.ValidateElement(3, VV2, NULL)) + return false; + +// const Integer& p = params.GetGroupOrder(); // not used, remove later + const Integer& q = params.GetSubgroupOrder(); + const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); + + Integer d, e; + SecByteBlock dd(len), ee(len); + + // Compute $d = \hat{H}(X, \hat{B})$ + Hash(NULL, XX, xxs, BB, bbs, dd.BytePtr(), dd.SizeInBytes()); + d.Decode(dd.BytePtr(), dd.SizeInBytes()); + + // Compute $e = \hat{H}(Y, \hat{A})$ + Hash(NULL, YY, yys, AA, aas, ee.BytePtr(), ee.SizeInBytes()); + e.Decode(ee.BytePtr(), ee.SizeInBytes()); + + Element sigma; + if(m_role == RoleServer) + { + Integer y(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_B = (y + e * b) % q; + + Element A = params.DecodeElement(AA, false); + Element X = params.DecodeElement(XX, false); + + Element t1 = params.ExponentiateElement(A, d); + Element t2 = m_groupParameters.MultiplyElements(X, t1); + + // $\sigma_B}=(X \cdot A^{d})^{s_B} + sigma = params.ExponentiateElement(t2, s_B); + } + else + { + Integer x(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_A = (x + d * a) % q; + + Element B = params.DecodeElement(BB, false); + Element Y = params.DecodeElement(YY, false); + + Element t1 = params.ExponentiateElement(B, e); + Element t2 = m_groupParameters.MultiplyElements(Y, t1); + + // $\sigma_A}=(Y \cdot B^{e})^{s_A} + sigma = params.ExponentiateElement(t2, s_A); + } + Hash(&sigma, NULL, 0, NULL, 0, agreedValue, AgreedValueLength()); + } + catch (DL_BadElement &) + { + return false; + } + return true; + } + +private: + + // The paper uses Initiator and Recipient - make it classical. + enum KeyAgreementRole{ RoleServer = 1, RoleClient }; + + DL_GroupParameters & AccessAbstractGroupParameters() {return m_groupParameters;} + const DL_GroupParameters & GetAbstractGroupParameters() const{return m_groupParameters;} + + KeyAgreementRole m_role; + GroupParameters m_groupParameters; +}; + +//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! HMQV: A High-Performance Secure Diffie-Hellman Protocol + Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately. +*/ +typedef HMQV_Domain HashedMQV; + +NAMESPACE_END + +#endif diff --git a/validat1.cpp b/validat1.cpp index a6115e5e..55c74e33 100644 --- a/validat1.cpp +++ b/validat1.cpp @@ -149,6 +149,8 @@ bool ValidateAll(bool thorough) pass=ValidateBBS() && pass; pass=ValidateDH() && pass; pass=ValidateMQV() && pass; + pass=ValidateHMQV() && pass; + pass=ValidateFHMQV() && pass; pass=ValidateRSA() && pass; pass=ValidateElGamal() && pass; pass=ValidateDLIES() && pass; diff --git a/validat2.cpp b/validat2.cpp index 32885985..ec553a28 100644 --- a/validat2.cpp +++ b/validat2.cpp @@ -18,6 +18,8 @@ #include "dsa.h" #include "dh.h" #include "mqv.h" +#include "hmqv.h" +#include "fhmqv.h" #include "luc.h" #include "xtrcrypt.h" #include "rabin.h" @@ -384,6 +386,240 @@ bool ValidateMQV() return AuthenticatedKeyAgreementValidate(mqv); } +bool ValidateHMQV() +{ + std::cout << "\nHMQV validation suite running...\n\n"; + + //HMQV< ECP >::Domain hmqvB(false /*server*/); + HMQV256 hmqvB(false); + FileSource f256("TestData/hmqv256.dat", true, new HexDecoder()); + FileSource f384("TestData/hmqv384.dat", true, new HexDecoder()); + FileSource f512("TestData/hmqv512.dat", true, new HexDecoder()); + hmqvB.AccessGroupParameters().BERDecode(f256); + + std::cout << "HMQV with NIST P-256 and SHA-256:" << std::endl; + + if (hmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; + return false; + } + + const OID oid = ASN1::secp256r1(); + HMQV< ECP >::Domain hmqvA(oid, true /*client*/); + + if (hmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; + return false; + } + + SecByteBlock sprivA(hmqvA.StaticPrivateKeyLength()), sprivB(hmqvB.StaticPrivateKeyLength()); + SecByteBlock eprivA(hmqvA.EphemeralPrivateKeyLength()), eprivB(hmqvB.EphemeralPrivateKeyLength()); + SecByteBlock spubA(hmqvA.StaticPublicKeyLength()), spubB(hmqvB.StaticPublicKeyLength()); + SecByteBlock epubA(hmqvA.EphemeralPublicKeyLength()), epubB(hmqvB.EphemeralPublicKeyLength()); + SecByteBlock valA(hmqvA.AgreedValueLength()), valB(hmqvB.AgreedValueLength()); + + hmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA); + hmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB); + hmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA); + hmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB); + + memset(valA.begin(), 0x00, valA.size()); + memset(valB.begin(), 0x11, valB.size()); + + if (!(hmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && hmqvB.Agree(valB, sprivB, eprivB, spubA, epubA))) + { + std::cout << "FAILED authenticated key agreement failed" << std::endl; + return false; + } + + if (memcmp(valA.begin(), valB.begin(), hmqvA.AgreedValueLength())) + { + std::cout << "FAILED authenticated agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed authenticated key agreement" << std::endl; + + // Now test HMQV with NIST P-384 curve and SHA384 hash + std::cout << endl; + std::cout << "HMQV with NIST P-384 and SHA-384:" << std::endl; + + HMQV384 hmqvB384(false); + hmqvB384.AccessGroupParameters().BERDecode(f384); + + if (hmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; + return false; + } + + const OID oid384 = ASN1::secp384r1(); + HMQV384 hmqvA384(oid384, true /*client*/); + + if (hmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; + return false; + } + + SecByteBlock sprivA384(hmqvA384.StaticPrivateKeyLength()), sprivB384(hmqvB384.StaticPrivateKeyLength()); + SecByteBlock eprivA384(hmqvA384.EphemeralPrivateKeyLength()), eprivB384(hmqvB384.EphemeralPrivateKeyLength()); + SecByteBlock spubA384(hmqvA384.StaticPublicKeyLength()), spubB384(hmqvB384.StaticPublicKeyLength()); + SecByteBlock epubA384(hmqvA384.EphemeralPublicKeyLength()), epubB384(hmqvB384.EphemeralPublicKeyLength()); + SecByteBlock valA384(hmqvA384.AgreedValueLength()), valB384(hmqvB384.AgreedValueLength()); + + hmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384); + hmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384); + hmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384); + hmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384); + + memset(valA384.begin(), 0x00, valA384.size()); + memset(valB384.begin(), 0x11, valB384.size()); + + if (!(hmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && hmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384))) + { + std::cout << "FAILED authenticated key agreement failed" << std::endl; + return false; + } + + if (memcmp(valA384.begin(), valB384.begin(), hmqvA384.AgreedValueLength())) + { + std::cout << "FAILED authenticated agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed authenticated key agreement" << std::endl; + + return true; +} + +bool ValidateFHMQV() +{ + std::cout << "\nFHMQV validation suite running...\n\n"; + + //FHMQV< ECP >::Domain fhmqvB(false /*server*/); + FHMQV256 fhmqvB(false); + FileSource f256("TestData/fhmqv256.dat", true, new HexDecoder()); + FileSource f384("TestData/fhmqv384.dat", true, new HexDecoder()); + FileSource f512("TestData/fhmqv512.dat", true, new HexDecoder()); + fhmqvB.AccessGroupParameters().BERDecode(f256); + + std::cout << "FHMQV with NIST P-256 and SHA-256:" << std::endl; + + if (fhmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; + return false; + } + + const OID oid = ASN1::secp256r1(); + FHMQV< ECP >::Domain fhmqvA(oid, true /*client*/); + + if (fhmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; + return false; + } + + SecByteBlock sprivA(fhmqvA.StaticPrivateKeyLength()), sprivB(fhmqvB.StaticPrivateKeyLength()); + SecByteBlock eprivA(fhmqvA.EphemeralPrivateKeyLength()), eprivB(fhmqvB.EphemeralPrivateKeyLength()); + SecByteBlock spubA(fhmqvA.StaticPublicKeyLength()), spubB(fhmqvB.StaticPublicKeyLength()); + SecByteBlock epubA(fhmqvA.EphemeralPublicKeyLength()), epubB(fhmqvB.EphemeralPublicKeyLength()); + SecByteBlock valA(fhmqvA.AgreedValueLength()), valB(fhmqvB.AgreedValueLength()); + + fhmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA); + fhmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB); + fhmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA); + fhmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB); + + memset(valA.begin(), 0x00, valA.size()); + memset(valB.begin(), 0x11, valB.size()); + + if (!(fhmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && fhmqvB.Agree(valB, sprivB, eprivB, spubA, epubA))) + { + std::cout << "FAILED authenticated key agreement failed" << std::endl; + return false; + } + + if (memcmp(valA.begin(), valB.begin(), fhmqvA.AgreedValueLength())) + { + std::cout << "FAILED authenticated agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed authenticated key agreement" << std::endl; + + // Now test FHMQV with NIST P-384 curve and SHA384 hash + std::cout << endl; + std::cout << "FHMQV with NIST P-384 and SHA-384:" << std::endl; + + FHMQV384 fhmqvB384(false); + fhmqvB384.AccessGroupParameters().BERDecode(f384); + + if (fhmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; + return false; + } + + const OID oid384 = ASN1::secp384r1(); + FHMQV384 fhmqvA384(oid384, true /*client*/); + + if (fhmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; + return false; + } + + SecByteBlock sprivA384(fhmqvA384.StaticPrivateKeyLength()), sprivB384(fhmqvB384.StaticPrivateKeyLength()); + SecByteBlock eprivA384(fhmqvA384.EphemeralPrivateKeyLength()), eprivB384(fhmqvB384.EphemeralPrivateKeyLength()); + SecByteBlock spubA384(fhmqvA384.StaticPublicKeyLength()), spubB384(fhmqvB384.StaticPublicKeyLength()); + SecByteBlock epubA384(fhmqvA384.EphemeralPublicKeyLength()), epubB384(fhmqvB384.EphemeralPublicKeyLength()); + SecByteBlock valA384(fhmqvA384.AgreedValueLength()), valB384(fhmqvB384.AgreedValueLength()); + + fhmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384); + fhmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384); + fhmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384); + fhmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384); + + memset(valA384.begin(), 0x00, valA384.size()); + memset(valB384.begin(), 0x11, valB384.size()); + + if (!(fhmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && fhmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384))) + { + std::cout << "FAILED authenticated key agreement failed" << std::endl; + return false; + } + + if (memcmp(valA384.begin(), valB384.begin(), fhmqvA384.AgreedValueLength())) + { + std::cout << "FAILED authenticated agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed authenticated key agreement" << std::endl; + + return true; +} + bool ValidateLUC_DH() { cout << "\nLUC-DH validation suite running...\n\n"; diff --git a/validate.h b/validate.h index 6c0c4793..0a388308 100644 --- a/validate.h +++ b/validate.h @@ -71,6 +71,8 @@ bool ValidateCMAC(); bool ValidateBBS(); bool ValidateDH(); bool ValidateMQV(); +bool ValidateHMQV(); +bool ValidateFHMQV(); bool ValidateRSA(); bool ValidateElGamal(); bool ValidateDLIES(); From 1cf48cf97bd2d3916c76681329844b2ae63c4889 Mon Sep 17 00:00:00 2001 From: Mouse Date: Sat, 2 Jul 2016 21:04:38 -0400 Subject: [PATCH 03/22] Added 8 new files that support HMQV and FHMQV to Filelist.txt --- Filelist.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Filelist.txt b/Filelist.txt index 4080a1a0..45aefbb1 100644 --- a/Filelist.txt +++ b/Filelist.txt @@ -106,6 +106,8 @@ eprecomp.h esign.cpp esign.h factory.h +fhmqv.cpp +fhmqv.h files.cpp files.h filters.cpp @@ -134,6 +136,8 @@ hex.h hkdf.h hmac.cpp hmac.h +hmqv.cpp +hmqv.h hrtimer.cpp hrtimer.h ida.cpp @@ -327,7 +331,15 @@ TestData/elgc1024.dat TestData/esig1023.dat TestData/esig1536.dat TestData/esig2046.dat +TestData/fhmqv160.dat +TestData/fhmqv256.dat +TestData/fhmqv384.dat +TestData/fhmqv512.dat TestData/gostval.dat +TestData/hmqv160.dat +TestData/hmqv256.dat +TestData/hmqv384.dat +TestData/hmqv512.dat TestData/ideaval.dat TestData/luc1024.dat TestData/luc2048.dat From 2733630a3f38e0c5adaaa9b9fc2139dfe3eeb1cc Mon Sep 17 00:00:00 2001 From: Mouse Date: Sun, 3 Jul 2016 10:45:41 -0400 Subject: [PATCH 04/22] Don't re-define a macro that's provided by the native compiler! --- misc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc.h b/misc.h index 894344a2..63ed4e29 100644 --- a/misc.h +++ b/misc.h @@ -66,8 +66,10 @@ # define _tzcnt_u32(x) __tzcnt_u32(x) # define _tzcnt_u64(x) __tzcnt_u64(x) # define _blsr_u32(x) __blsr_u32(x) +#ifndef _blsr_u64 # define _blsr_u64(x) __blsr_u64(x) # endif +# endif #endif #endif // CRYPTOPP_DOXYGEN_PROCESSING From e36270fa7c15b1a47bd7336d09ccc0d7e9e81eec Mon Sep 17 00:00:00 2001 From: Mouse Date: Mon, 4 Jul 2016 13:11:15 -0400 Subject: [PATCH 05/22] Do not re-define macros already provided by native compiler --- misc.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/misc.h b/misc.h index a888deef..3e16e0e1 100644 --- a/misc.h +++ b/misc.h @@ -63,10 +63,18 @@ #if defined(__GNUC__) && defined(__BMI__) # include # if defined(__clang__) +#ifndef _tzcnt_u32 # define _tzcnt_u32(x) __tzcnt_u32(x) +#endif +#ifndef _tzcnt_u64 # define _tzcnt_u64(x) __tzcnt_u64(x) +#endif +#ifndef _blsr_u32 # define _blsr_u32(x) __blsr_u32(x) +#endif +#ifndef _blsr_u64 # define _blsr_u64(x) __blsr_u64(x) +#endif # endif #endif From 2d0dd95ddaa610559ba2ac4caa3bc196fb398916 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Mon, 4 Jul 2016 17:51:09 -0400 Subject: [PATCH 06/22] Fix "CRYPTOPP_USE_FIPS_202_SHA3 redfined" when using config.recommned with CRYPTOPP_USE_FIPS_202_SHA3 defined on command line --- config.h | 4 +++- config.recommend | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/config.h b/config.h index 7ac17fda..bd25d2cb 100644 --- a/config.h +++ b/config.h @@ -63,7 +63,9 @@ // Define this to choose the FIPS 202 version of SHA3, and not the original version of SHA3. NIST selected Keccak as SHA3 // in January 2013. SHA3 was finalized in FIPS 202 in August 2015, and it was a modified version of the original selection. // If CRYPTOPP_USE_FIPS_202_SHA3 is defined, then sha3_fips_202.txt test vectors will be used instead of sha3.txt. -// #define CRYPTOPP_USE_FIPS_202_SHA3 +// #ifndef CRYPTOPP_USE_FIPS_202_SHA3 +// # define CRYPTOPP_USE_FIPS_202_SHA3 +// #endif // ***************** Less Important Settings *************** diff --git a/config.recommend b/config.recommend index c9064240..7b45b308 100644 --- a/config.recommend +++ b/config.recommend @@ -63,7 +63,9 @@ // Define this to choose the FIPS 202 version of SHA3, and not the original version of SHA3. NIST selected Keccak as SHA3 // in January 2013. SHA3 was finalized in FIPS 202 in August 2015, and it was a modified version of the original selection. // If CRYPTOPP_USE_FIPS_202_SHA3 is defined, then sha3_fips_202.txt test vectors will be used instead of sha3.txt. -#define CRYPTOPP_USE_FIPS_202_SHA3 +#ifndef CRYPTOPP_USE_FIPS_202_SHA3 +# define CRYPTOPP_USE_FIPS_202_SHA3 +#endif // ***************** Less Important Settings *************** From a890e8851e16d75e72a3f1ca06e5f9ff41a0b7e9 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Mon, 4 Jul 2016 18:06:44 -0400 Subject: [PATCH 07/22] Add test for -std=gnu++03 --- cryptest.sh | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/cryptest.sh b/cryptest.sh index c28f80c7..6b04f892 100755 --- a/cryptest.sh +++ b/cryptest.sh @@ -227,6 +227,14 @@ if [[ (-z "$HAVE_CXX03") ]]; then fi fi +if [[ (-z "$HAVE_GNU03") ]]; then + HAVE_GNU03=0 + "$CXX" -DCRYPTOPP_ADHOC_MAIN -std=c++03 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1 + if [[ "$?" -eq "0" ]]; then + HAVE_GNU03=1 + fi +fi + HAVE_O3=0 OPT_O3= "$CXX" -DCRYPTOPP_ADHOC_MAIN -O3 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1 @@ -499,6 +507,7 @@ fi # C++03, C++11, C++14 and C++17 echo | tee -a "$TEST_RESULTS" echo "HAVE_CXX03: $HAVE_CXX03" | tee -a "$TEST_RESULTS" +echo "HAVE_GNU03: $HAVE_GNU03" | tee -a "$TEST_RESULTS" echo "HAVE_CXX11: $HAVE_CXX11" | tee -a "$TEST_RESULTS" echo "HAVE_GNU11: $HAVE_GNU11" | tee -a "$TEST_RESULTS" if [[ ("$HAVE_CXX14" -ne "0" || "$HAVE_CXX17" -ne "0" || "$HAVE_GNU14" -ne "0" || "$HAVE_GNU17" -ne "0") ]]; then @@ -961,6 +970,65 @@ if [[ "$HAVE_CXX03" -ne "0" ]]; then fi fi +############################################ +# gnu++03 debug and release build +if [[ "$HAVE_GNU03" -ne "0" ]]; then + + ############################################ + # Debug build + echo + echo "************************************" | tee -a "$TEST_RESULTS" + echo "Testing: debug, gnu++03" | tee -a "$TEST_RESULTS" + echo + + unset CXXFLAGS + "$MAKE" clean > /dev/null 2>&1 + rm -f adhoc.cpp > /dev/null 2>&1 + + export CXXFLAGS="$DEBUG_CXXFLAGS -std=gnu++03 ${RETAINED_CXXFLAGS[@]}" + "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" + + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" + else + ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" + fi + ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" + fi + fi + + ############################################ + # Release build + echo + echo "************************************" | tee -a "$TEST_RESULTS" + echo "Testing: release, gnu++03" | tee -a "$TEST_RESULTS" + echo + + unset CXXFLAGS + "$MAKE" clean > /dev/null 2>&1 + rm -f adhoc.cpp > /dev/null 2>&1 + + export CXXFLAGS="$RELEASE_CXXFLAGS -std=gnu++03 ${RETAINED_CXXFLAGS[@]}" + "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" + + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" + else + ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" + fi + ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" + fi + fi +fi + ############################################ # c++11 debug and release build if [[ "$HAVE_CXX11" -ne "0" ]]; then From 36a459130422d7e6b8b7a0f6f539b79a0ab32b23 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Mon, 4 Jul 2016 22:14:51 -0400 Subject: [PATCH 08/22] Fix typo for -std=gnu++03 --- cryptest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cryptest.sh b/cryptest.sh index 6b04f892..d177cd1e 100755 --- a/cryptest.sh +++ b/cryptest.sh @@ -229,7 +229,7 @@ fi if [[ (-z "$HAVE_GNU03") ]]; then HAVE_GNU03=0 - "$CXX" -DCRYPTOPP_ADHOC_MAIN -std=c++03 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1 + "$CXX" -DCRYPTOPP_ADHOC_MAIN -std=gnu++03 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1 if [[ "$?" -eq "0" ]]; then HAVE_GNU03=1 fi From fb72dbc8cb750be749a4ec3e2f27d164fe89d431 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Tue, 5 Jul 2016 02:48:27 -0400 Subject: [PATCH 09/22] Add MacPorts GCC compiler and Clang integrated assembler support. This is a merge of the development branch 'clang-ia' --- GNUmakefile | 7 +++++-- blake2.cpp | 2 +- config.h | 12 +++++++----- cpu.cpp | 2 +- cpu.h | 8 ++++---- default.h | 12 ++++++------ eccrypto.h | 24 ++++++++++++------------ gcm.cpp | 14 +++++++------- misc.h | 2 +- panama.h | 4 ++-- rdrand.cpp | 4 ++-- rijndael.h | 2 +- sha.h | 2 +- 13 files changed, 50 insertions(+), 45 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index f1db629b..12b1542c 100755 --- a/GNUmakefile +++ b/GNUmakefile @@ -30,9 +30,9 @@ IS_DARWIN := $(shell $(CXX) -dumpmachine 2>&1 | $(EGREP) -i -c "Darwin") IS_NETBSD := $(shell $(CXX) -dumpmachine 2>&1 | $(EGREP) -i -c "NetBSD") SUN_COMPILER := $(shell $(CXX) -V 2>&1 | $(EGREP) -i -c "CC: Sun") -GCC_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "(gcc|g\+\+)") +GCC_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -v "clang" | $(EGREP) -i -c "(gcc|g\+\+)") CLANG_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "clang") -INTEL_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -c "\(ICC\)") +INTEL_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "\(icc\)") MACPORTS_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "macports") # Sun Studio 12.0 (0x0510) and 12.3 (0x0512) @@ -179,6 +179,9 @@ ifeq ($(GCC_COMPILER)$(MACPORTS_COMPILER),11) ifneq ($(findstring -Wa,-q,$(CXXFLAGS)),-Wa,-q) CXXFLAGS += -Wa,-q endif +ifneq ($(findstring -Wa,-q,$(CXXFLAGS)),-DCRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) +CXXFLAGS += -DCRYPTOPP_CLANG_INTEGRATED_ASSEMBLER=1 +endif endif # Allow use of "/" operator for GNU Assembler. diff --git a/blake2.cpp b/blake2.cpp index 77eef8ce..0cb858b1 100644 --- a/blake2.cpp +++ b/blake2.cpp @@ -35,7 +35,7 @@ NAMESPACE_BEGIN(CryptoPP) // Apple Clang 6.0/Clang 3.5 does not have SSSE3 intrinsics // http://llvm.org/bugs/show_bug.cgi?id=20213 -#if (defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION <= 60000)) || (defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION <= 30500)) +#if (defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION <= 60000)) || (defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION <= 30500)) # undef CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE #endif diff --git a/config.h b/config.h index bd25d2cb..9a40f2ba 100644 --- a/config.h +++ b/config.h @@ -238,9 +238,11 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); // Apple and LLVM's Clang. Apple Clang version 7.0 roughly equals LLVM Clang version 3.7 #if defined(__clang__ ) && !defined(__apple_build_version__) - #define CRYPTOPP_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) + #define CRYPTOPP_LLVM_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) + #define CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER 1 #elif defined(__clang__ ) && defined(__apple_build_version__) #define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) + #define CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER 1 #endif #ifdef _MSC_VER @@ -248,13 +250,13 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); #endif // Need GCC 4.6/Clang 1.7/Apple Clang 2.0 or above due to "GCC diagnostic {push|pop}" -#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000) +#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_LLVM_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000) #define CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 1 #endif // Clang due to "Inline assembly operands don't work with .intel_syntax", http://llvm.org/bugs/show_bug.cgi?id=24232 // TODO: supply the upper version when LLVM fixes it. We set it to 20.0 for compilation purposes. -#if (defined(CRYPTOPP_CLANG_VERSION) && CRYPTOPP_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) +#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && CRYPTOPP_LLVM_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) #define CRYPTOPP_DISABLE_INTEL_ASM 1 #endif @@ -728,7 +730,7 @@ NAMESPACE_END // ************** Deprecated *************** -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) # define CRYPTOPP_DEPRECATED(msg) __attribute__((deprecated (msg))); #elif (CRYPTOPP_GCC_VERSION) # define CRYPTOPP_DEPRECATED(msg) __attribute__((deprecated)); @@ -781,7 +783,7 @@ NAMESPACE_END # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 #elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1200) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 -#elif (CRYPTOPP_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) +#elif (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 #elif (CRYPTOPP_GCC_VERSION >= 40400) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 diff --git a/cpu.cpp b/cpu.cpp index 7c39cccd..b13dd255 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -27,7 +27,7 @@ NAMESPACE_BEGIN(CryptoPP) #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY // MacPorts/GCC does not provide constructor(priority). Apple/GCC and Fink/GCC do provide it. -#define HAVE_GCC_CONSTRUCTOR1 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 300)) && !(MACPORTS_GCC_COMPILER > 0)) +#define HAVE_GCC_CONSTRUCTOR1 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 300)) && !(MACPORTS_GCC_COMPILER > 0)) #define HAVE_GCC_CONSTRUCTOR0 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && !(MACPORTS_GCC_COMPILER > 0)) extern "C" { diff --git a/cpu.h b/cpu.h index 890f53db..91b03b4b 100644 --- a/cpu.h +++ b/cpu.h @@ -52,7 +52,7 @@ #endif // PUSHFB needs Clang 3.3 and Apple Clang 5.0. -#if !defined(__GNUC__) || defined(__SSSE3__)|| defined(__INTEL_COMPILER) || (CRYPTOPP_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) +#if !defined(__GNUC__) || defined(__SSSE3__)|| defined(__INTEL_COMPILER) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) #include #else NAMESPACE_BEGIN(CryptoPP) @@ -66,7 +66,7 @@ NAMESPACE_END #endif // tmmintrin.h // PEXTRD needs Clang 3.3 and Apple Clang 5.0. -#if !defined(__GNUC__) || defined(__SSE4_1__)|| defined(__INTEL_COMPILER) || (CRYPTOPP_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) +#if !defined(__GNUC__) || defined(__SSE4_1__)|| defined(__INTEL_COMPILER) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) #include #else NAMESPACE_BEGIN(CryptoPP) @@ -87,7 +87,7 @@ NAMESPACE_END #endif // smmintrin.h // AES needs Clang 2.8 and Apple Clang 4.6. PCLMUL needs Clang 3.4 and Apple Clang 6.0 -#if !defined(__GNUC__) || (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || (CRYPTOPP_CLANG_VERSION >= 30400) || (CRYPTOPP_APPLE_CLANG_VERSION >= 60000) +#if !defined(__GNUC__) || (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30400) || (CRYPTOPP_APPLE_CLANG_VERSION >= 60000) #include #else NAMESPACE_BEGIN(CryptoPP) @@ -415,7 +415,7 @@ inline int GetCacheLineSize() #else #define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY -#if defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION) +#if defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) #define NEW_LINE "\n" #define INTEL_PREFIX ".intel_syntax;" #define INTEL_NOPREFIX ".intel_syntax;" diff --git a/default.h b/default.h index 00ec6647..6b30f2e4 100644 --- a/default.h +++ b/default.h @@ -48,7 +48,7 @@ private: SecByteBlock m_passphrase; CBC_Mode::Encryption m_cipher; -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) } __attribute__((deprecated ("DefaultEncryptor will be changing in the near future because the algorithms are no longer secure"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); @@ -68,7 +68,7 @@ public: //! \param attachment a BufferedTransformation to attach to this object //! \param throwException a flag specifiying whether an Exception should be thrown on error DefaultDecryptor(const char *passphrase, BufferedTransformation *attachment = NULL, bool throwException=true); - + //! \brief Constructs a DefaultDecryptor //! \param passphrase a byte string password //! \param passphraseLength the length of the byte string password @@ -79,7 +79,7 @@ public: class Err : public Exception { public: - Err(const std::string &s) + Err(const std::string &s) : Exception(DATA_INTEGRITY_CHECK_FAILED, s) {} }; class KeyBadErr : public Err {public: KeyBadErr() : Err("DefaultDecryptor: cannot decrypt message with this passphrase") {}}; @@ -101,7 +101,7 @@ private: member_ptr m_decryptor; bool m_throwException; -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) } __attribute__((deprecated ("DefaultDecryptor will be changing in the near future because the algorithms are no longer secure"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); @@ -139,7 +139,7 @@ protected: private: member_ptr m_mac; -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) } __attribute__((deprecated ("DefaultEncryptorWithMAC will be changing in the near future because the algorithms are no longer secure"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); @@ -188,7 +188,7 @@ private: HashVerifier *m_hashVerifier; bool m_throwException; -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) } __attribute__((deprecated ("DefaultDecryptorWithMAC will be changing in the near future because the algorithms are no longer secure"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); diff --git a/eccrypto.h b/eccrypto.h index a3d15e95..cba037fb 100644 --- a/eccrypto.h +++ b/eccrypto.h @@ -130,7 +130,7 @@ public: const Integer& GetBasePointOrder() const {return this->GetSubgroupOrder();} void LoadRecommendedParameters(const OID &oid) {Initialize(oid);} #endif - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_GroupParameters_EC() {} #endif @@ -160,7 +160,7 @@ public: // X509PublicKey void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size); void DEREncodePublicKey(BufferedTransformation &bt) const; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_PublicKey_EC() {} #endif @@ -185,7 +185,7 @@ public: // PKCS8PrivateKey void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); void DEREncodePrivateKey(BufferedTransformation &bt) const; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_PrivateKey_EC() {} #endif @@ -196,7 +196,7 @@ template , COFACTOR_OPTION> Domain; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~ECDH() {} #endif @@ -207,7 +207,7 @@ template , COFACTOR_OPTION> Domain; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~ECMQV() {} #endif @@ -219,7 +219,7 @@ struct DL_Keys_EC { typedef DL_PublicKey_EC PublicKey; typedef DL_PrivateKey_EC PrivateKey; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_Keys_EC() {} #endif @@ -234,7 +234,7 @@ struct DL_Keys_ECDSA { typedef DL_PublicKey_EC PublicKey; typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest, ECDSA > PrivateKey; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_Keys_ECDSA() {} #endif @@ -246,7 +246,7 @@ class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA { public: static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";} - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_Algorithm_ECDSA() {} #endif @@ -258,7 +258,7 @@ class DL_Algorithm_ECNR : public DL_Algorithm_NR { public: static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECNR";} - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_Algorithm_ECNR() {} #endif @@ -296,12 +296,12 @@ struct ECIES ECIES > { static std::string CRYPTOPP_API StaticAlgorithmName() {return "ECIES";} // TODO: fix this after name is standardized - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~ECIES() {} #endif - -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) + +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) } __attribute__((deprecated ("ECIES will be changing in the near future due to (1) an implementation bug and (2) an interop issue"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); diff --git a/gcm.cpp b/gcm.cpp index fd82bddb..fd6731f0 100644 --- a/gcm.cpp +++ b/gcm.cpp @@ -13,7 +13,7 @@ #ifndef CRYPTOPP_GENERATE_X64_MASM // Clang 3.3 integrated assembler crash on Linux -#if defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION < 30400) +#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION < 30400)) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) # undef CRYPTOPP_X86_ASM_AVAILABLE # undef CRYPTOPP_X32_ASM_AVAILABLE # undef CRYPTOPP_X64_ASM_AVAILABLE @@ -703,9 +703,9 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len) AS2( pxor xmm5, xmm2 ) AS2( psrldq xmm0, 15 ) -#if (CRYPTOPP_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) +#if (CRYPTOPP_LLVM_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) AS2( movd edi, xmm0 ) -#elif (defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) +#elif (defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) AS2( mov WORD_REG(di), xmm0 ) #else // GNU Assembler AS2( movd WORD_REG(di), xmm0 ) @@ -718,9 +718,9 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len) AS2( pxor xmm4, xmm5 ) AS2( psrldq xmm1, 15 ) -#if (CRYPTOPP_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) +#if (CRYPTOPP_LLVM_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) AS2( movd edi, xmm1 ) -#elif (defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) +#elif (defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) AS2( mov WORD_REG(di), xmm1 ) #else AS2( movd WORD_REG(di), xmm1 ) @@ -729,9 +729,9 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len) AS2( shl eax, 8 ) AS2( psrldq xmm0, 15 ) -#if (CRYPTOPP_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) +#if (CRYPTOPP_LLVM_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) AS2( movd edi, xmm0 ) -#elif (defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) +#elif (defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) AS2( mov WORD_REG(di), xmm0 ) #else AS2( movd WORD_REG(di), xmm0 ) diff --git a/misc.h b/misc.h index 3e16e0e1..e3980441 100644 --- a/misc.h +++ b/misc.h @@ -471,7 +471,7 @@ template inline const T& STDMAX(const T& a, const T& b) #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wsign-compare" -# if (CRYPTOPP_CLANG_VERSION >= 20800) || (CRYPTOPP_APPLE_CLANG_VERSION >= 30000) +# if (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) || (CRYPTOPP_APPLE_CLANG_VERSION >= 30000) # pragma GCC diagnostic ignored "-Wtautological-compare" # elif (CRYPTOPP_GCC_VERSION >= 40300) # pragma GCC diagnostic ignored "-Wtype-limits" diff --git a/panama.h b/panama.h index b7db323a..e7f20c95 100644 --- a/panama.h +++ b/panama.h @@ -11,7 +11,7 @@ #include "secblock.h" // Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler error with .intel_syntax -#if CRYPTOPP_BOOL_X32 || (defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION < 30500)) +#if CRYPTOPP_BOOL_X32 || (defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION < 30500)) # define CRYPTOPP_DISABLE_PANAMA_ASM #endif @@ -128,7 +128,7 @@ struct PanamaCipherInfo : public FixedKeyLength<32, SimpleKeyingInterface::UNIQU //! _ template -class PanamaCipherPolicy : public AdditiveCipherConcretePolicy, +class PanamaCipherPolicy : public AdditiveCipherConcretePolicy, public PanamaCipherInfo, protected Panama { diff --git a/rdrand.cpp b/rdrand.cpp index 6149315e..4edb1bd8 100644 --- a/rdrand.cpp +++ b/rdrand.cpp @@ -67,8 +67,8 @@ #endif #if defined(CRYPTOPP_CPUID_AVAILABLE) -# define MSC_INTRIN_COMPILER ((CRYPTOPP_MSC_VERSION >= 1700) || (CRYPTOPP_CLANG_VERSION >= 30200) || (_INTEL_COMPILER >= 1210)) -# define GCC_INTRIN_COMPILER ((CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_CLANG_VERSION >= 30200) || (_INTEL_COMPILER >= 1210)) +# define MSC_INTRIN_COMPILER ((CRYPTOPP_MSC_VERSION >= 1700) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30200) || (_INTEL_COMPILER >= 1210)) +# define GCC_INTRIN_COMPILER ((CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30200) || (_INTEL_COMPILER >= 1210)) #else # define MSC_INTRIN_COMPILER 0 # define GCC_INTRIN_COMPILER 0 diff --git a/rijndael.h b/rijndael.h index ed856d94..50fdf1eb 100644 --- a/rijndael.h +++ b/rijndael.h @@ -12,7 +12,7 @@ #include "secblock.h" // Clang 3.3 integrated assembler crash on Linux -#if CRYPTOPP_BOOL_X32 || (defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION < 30400)) +#if CRYPTOPP_BOOL_X32 || (defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION < 30400)) # define CRYPTOPP_DISABLE_RIJNDAEL_ASM #endif diff --git a/sha.h b/sha.h index 544e8056..c70d9d1f 100644 --- a/sha.h +++ b/sha.h @@ -11,7 +11,7 @@ #include "iterhash.h" // Clang 3.3 integrated assembler crash on Linux -#if defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION < 30400) +#if defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION < 30400) # define CRYPTOPP_DISABLE_SHA_ASM #endif From 34e95a7cde503891b76b2ce35176bf24b4b0c29a Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Tue, 5 Jul 2016 02:49:33 -0400 Subject: [PATCH 10/22] Add MacPorts GCC compiler and Clang integrated assembler support. This is a merge of the development branch 'clang-ia' --- config.recommend | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config.recommend b/config.recommend index 7b45b308..15b7e781 100644 --- a/config.recommend +++ b/config.recommend @@ -238,7 +238,7 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); // Apple and LLVM's Clang. Apple Clang version 7.0 roughly equals LLVM Clang version 3.7 #if defined(__clang__ ) && !defined(__apple_build_version__) - #define CRYPTOPP_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) + #define CRYPTOPP_LLVM_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) #elif defined(__clang__ ) && defined(__apple_build_version__) #define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) #endif @@ -248,13 +248,13 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); #endif // Need GCC 4.6/Clang 1.7/Apple Clang 2.0 or above due to "GCC diagnostic {push|pop}" -#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000) +#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_LLVM_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000) #define CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 1 #endif // Clang due to "Inline assembly operands don't work with .intel_syntax", http://llvm.org/bugs/show_bug.cgi?id=24232 // TODO: supply the upper version when LLVM fixes it. We set it to 20.0 for compilation purposes. -#if (defined(CRYPTOPP_CLANG_VERSION) && CRYPTOPP_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) +#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && CRYPTOPP_LLVM_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) #define CRYPTOPP_DISABLE_INTEL_ASM 1 #endif @@ -726,7 +726,7 @@ NAMESPACE_END // ************** Deprecated *************** -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) # define CRYPTOPP_DEPRECATED(msg) __attribute__((deprecated (msg))); #elif (CRYPTOPP_GCC_VERSION) # define CRYPTOPP_DEPRECATED(msg) __attribute__((deprecated)); @@ -779,7 +779,7 @@ NAMESPACE_END # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 #elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1200) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 -#elif (CRYPTOPP_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) +#elif (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 #elif (CRYPTOPP_GCC_VERSION >= 40400) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 From 66ada4cc61d62afc2ddda4d8d0bc4e5c8d188991 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Tue, 5 Jul 2016 11:49:13 -0400 Subject: [PATCH 11/22] Updated documentation --- cpu.h | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/cpu.h b/cpu.h index 91b03b4b..b1414a91 100644 --- a/cpu.h +++ b/cpu.h @@ -2,9 +2,7 @@ //! \file cpu.h //! \brief Functions for CPU features and intrinsics -//! \details At the moment, the functions are used heavily in X86/X32/X64 code paths -// for SSE, SSE2 and SSE4. The funtions are also used on occassion for AArch32 -//! and AArch64 code paths for NEON. +//! \details The functions are used in X86/X32/X64 and NEON code paths #ifndef CRYPTOPP_CPU_H #define CRYPTOPP_CPU_H @@ -141,11 +139,13 @@ NAMESPACE_END NAMESPACE_BEGIN(CryptoPP) -#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 || CRYPTOPP_DOXYGEN_PROCESSING #define CRYPTOPP_CPUID_AVAILABLE -// these should not be used directly +// Hide from Doxygen +#ifndef CRYPTOPP_DOXYGEN_PROCESSING +// These should not be used directly extern CRYPTOPP_DLL bool g_x86DetectionDone; extern CRYPTOPP_DLL bool g_hasMMX; extern CRYPTOPP_DLL bool g_hasISSE; @@ -166,7 +166,12 @@ extern CRYPTOPP_DLL word32 g_cacheLineSize; CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features(); CRYPTOPP_DLL bool CRYPTOPP_API CpuId(word32 input, word32 output[4]); +#endif // CRYPTOPP_DOXYGEN_PROCESSING +//! \brief Determines MMX availability +//! \returns true if MMX is determined to be available, false otherwise +//! \details MMX, SSE and SSE2 are core processor features for x86_64, and +//! the function always returns true for the platform. inline bool HasMMX() { #if CRYPTOPP_BOOL_X64 @@ -178,6 +183,10 @@ inline bool HasMMX() #endif } +//! \brief Determines SSE availability +//! \returns true if SSE is determined to be available, false otherwise +//! \details MMX, SSE and SSE2 are core processor features for x86_64, and +//! the function always returns true for the platform. inline bool HasISSE() { #if CRYPTOPP_BOOL_X64 @@ -189,6 +198,10 @@ inline bool HasISSE() #endif } +//! \brief Determines SSE2 availability +//! \returns true if SSE2 is determined to be available, false otherwise +//! \details MMX, SSE and SSE2 are core processor features for x86_64, and +//! the function always returns true for the platform. inline bool HasSSE2() { #if CRYPTOPP_BOOL_X64 @@ -200,6 +213,10 @@ inline bool HasSSE2() #endif } +//! \brief Determines SSSE3 availability +//! \returns true if SSSE3 is determined to be available, false otherwise +//! \details HasSSSE3() is a runtime check performed using CPUID +//! \note Some Clang compilers incorrectly omit SSSE3 even though its native to the processor. inline bool HasSSSE3() { if (!g_x86DetectionDone) @@ -207,6 +224,9 @@ inline bool HasSSSE3() return g_hasSSSE3; } +//! \brief Determines SSE4 availability +//! \returns true if SSE4.1 and SSE4.2 are determined to be available, false otherwise +//! \details HasSSE4() is a runtime check performed using CPUID which requires both SSE4.1 and SSE4.2 inline bool HasSSE4() { if (!g_x86DetectionDone) @@ -214,6 +234,9 @@ inline bool HasSSE4() return g_hasSSE4; } +//! \brief Determines AES-NI availability +//! \returns true if AES-NI is determined to be available, false otherwise +//! \details HasAESNI() is a runtime check performed using CPUID inline bool HasAESNI() { if (!g_x86DetectionDone) @@ -221,6 +244,9 @@ inline bool HasAESNI() return g_hasAESNI; } +//! \brief Determines Carryless Multiply availability +//! \returns true if pclmulqdq is determined to be available, false otherwise +//! \details HasCLMUL() is a runtime check performed using CPUID inline bool HasCLMUL() { if (!g_x86DetectionDone) @@ -228,6 +254,9 @@ inline bool HasCLMUL() return g_hasCLMUL; } +//! \brief Determines if the CPU is an Intel P4 +//! \returns true if the CPU is a P4, false otherwise +//! \details IsP4() is a runtime check performed using CPUID inline bool IsP4() { if (!g_x86DetectionDone) @@ -235,6 +264,9 @@ inline bool IsP4() return g_isP4; } +//! \brief Determines RDRAND availability +//! \returns true if RDRAND is determined to be available, false otherwise +//! \details HasRDRAND() is a runtime check performed using CPUID inline bool HasRDRAND() { if (!g_x86DetectionDone) @@ -242,6 +274,9 @@ inline bool HasRDRAND() return g_hasRDRAND; } +//! \brief Determines RDSEED availability +//! \returns true if RDSEED is determined to be available, false otherwise +//! \details HasRDSEED() is a runtime check performed using CPUID inline bool HasRDSEED() { if (!g_x86DetectionDone) @@ -249,6 +284,9 @@ inline bool HasRDSEED() return g_hasRDSEED; } +//! \brief Determines Padlock RNG availability +//! \returns true if VIA Padlock RNG is determined to be available, false otherwise +//! \details HasPadlockRNG() is a runtime check performed using CPUID inline bool HasPadlockRNG() { if (!g_x86DetectionDone) @@ -256,6 +294,9 @@ inline bool HasPadlockRNG() return g_hasPadlockRNG; } +//! \brief Determines Padlock ACE availability +//! \returns true if VIA Padlock ACE is determined to be available, false otherwise +//! \details HasPadlockACE() is a runtime check performed using CPUID inline bool HasPadlockACE() { if (!g_x86DetectionDone) @@ -263,6 +304,9 @@ inline bool HasPadlockACE() return g_hasPadlockACE; } +//! \brief Determines Padlock ACE2 availability +//! \returns true if VIA Padlock ACE2 is determined to be available, false otherwise +//! \details HasPadlockACE2() is a runtime check performed using CPUID inline bool HasPadlockACE2() { if (!g_x86DetectionDone) @@ -270,6 +314,9 @@ inline bool HasPadlockACE2() return g_hasPadlockACE2; } +//! \brief Determines Padlock PHE availability +//! \returns true if VIA Padlock PHE is determined to be available, false otherwise +//! \details HasPadlockPHE() is a runtime check performed using CPUID inline bool HasPadlockPHE() { if (!g_x86DetectionDone) @@ -277,6 +324,9 @@ inline bool HasPadlockPHE() return g_hasPadlockPHE; } +//! \brief Determines Padlock PMM availability +//! \returns true if VIA Padlock PMM is determined to be available, false otherwise +//! \details HasPadlockPMM() is a runtime check performed using CPUID inline bool HasPadlockPMM() { if (!g_x86DetectionDone) @@ -284,6 +334,13 @@ inline bool HasPadlockPMM() return g_hasPadlockPMM; } +//! \brief Provides the cache line size +//! \returns lower bound on the size of a cache line in bytes, if available +//! \details GetCacheLineSize() returns the lower bound on the size of a cache line, if it +//! is available. If the value is not available at runtime, then 32 is returned for a 32-bit +//! processor and 64 is returned for a 64-bit processor. +//! \details x86/x32/x64 uses CPUID to determine the value and its usually accurate. The ARM +//! processor equivalent is a privileged instruction, so a compile time value is returned. inline int GetCacheLineSize() { if (!g_x86DetectionDone) From 657bf41da0e21f8cdffd9b86593060ab97a13c62 Mon Sep 17 00:00:00 2001 From: Mouse Date: Wed, 6 Jul 2016 10:26:32 -0400 Subject: [PATCH 12/22] Fix config.recommend --- config.recommend | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config.recommend b/config.recommend index 15b7e781..8ad9f815 100644 --- a/config.recommend +++ b/config.recommend @@ -239,8 +239,10 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); // Apple and LLVM's Clang. Apple Clang version 7.0 roughly equals LLVM Clang version 3.7 #if defined(__clang__ ) && !defined(__apple_build_version__) #define CRYPTOPP_LLVM_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) + #define CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER 1 #elif defined(__clang__ ) && defined(__apple_build_version__) #define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) + #define CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER 1 #endif #ifdef _MSC_VER @@ -254,7 +256,7 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); // Clang due to "Inline assembly operands don't work with .intel_syntax", http://llvm.org/bugs/show_bug.cgi?id=24232 // TODO: supply the upper version when LLVM fixes it. We set it to 20.0 for compilation purposes. -#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && CRYPTOPP_LLVM_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) +#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && CRYPTOPP_LLVM_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) #define CRYPTOPP_DISABLE_INTEL_ASM 1 #endif From 7980738496d0a7c5e03f36a8e8f37802d5598ae1 Mon Sep 17 00:00:00 2001 From: Mouse Date: Wed, 6 Jul 2016 11:59:07 -0400 Subject: [PATCH 13/22] Revert "Fix config.recommend" - was not intended to be merged by me This reverts commit 657bf41da0e21f8cdffd9b86593060ab97a13c62. --- config.recommend | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/config.recommend b/config.recommend index 8ad9f815..15b7e781 100644 --- a/config.recommend +++ b/config.recommend @@ -239,10 +239,8 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); // Apple and LLVM's Clang. Apple Clang version 7.0 roughly equals LLVM Clang version 3.7 #if defined(__clang__ ) && !defined(__apple_build_version__) #define CRYPTOPP_LLVM_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) - #define CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER 1 #elif defined(__clang__ ) && defined(__apple_build_version__) #define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) - #define CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER 1 #endif #ifdef _MSC_VER @@ -256,7 +254,7 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); // Clang due to "Inline assembly operands don't work with .intel_syntax", http://llvm.org/bugs/show_bug.cgi?id=24232 // TODO: supply the upper version when LLVM fixes it. We set it to 20.0 for compilation purposes. -#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && CRYPTOPP_LLVM_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) +#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && CRYPTOPP_LLVM_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) #define CRYPTOPP_DISABLE_INTEL_ASM 1 #endif From 87be783cd1b6f13d8501497dbffa0c8c7502997e Mon Sep 17 00:00:00 2001 From: Mouse Date: Wed, 6 Jul 2016 12:01:28 -0400 Subject: [PATCH 14/22] Revert "Merge remote-tracking branch 'upstream/master'" - not intended to be merged by me This reverts commit 762c315566bce681e380641d1894251f984eac10, reversing changes made to b48866631a5587e9348245fedd6f1e0871df35db. --- GNUmakefile | 7 +-- blake2.cpp | 2 +- config.h | 16 ++--- config.recommend | 14 ++--- cpu.cpp | 2 +- cpu.h | 75 +++-------------------- cryptest.sh | 153 ++--------------------------------------------- default.h | 12 ++-- eccrypto.h | 24 ++++---- gcm.cpp | 14 ++--- misc.h | 10 +--- panama.h | 4 +- rdrand.cpp | 4 +- rijndael.h | 2 +- sha.h | 2 +- wait.h | 11 ---- 16 files changed, 63 insertions(+), 289 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 12b1542c..f1db629b 100755 --- a/GNUmakefile +++ b/GNUmakefile @@ -30,9 +30,9 @@ IS_DARWIN := $(shell $(CXX) -dumpmachine 2>&1 | $(EGREP) -i -c "Darwin") IS_NETBSD := $(shell $(CXX) -dumpmachine 2>&1 | $(EGREP) -i -c "NetBSD") SUN_COMPILER := $(shell $(CXX) -V 2>&1 | $(EGREP) -i -c "CC: Sun") -GCC_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -v "clang" | $(EGREP) -i -c "(gcc|g\+\+)") +GCC_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "(gcc|g\+\+)") CLANG_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "clang") -INTEL_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "\(icc\)") +INTEL_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -c "\(ICC\)") MACPORTS_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "macports") # Sun Studio 12.0 (0x0510) and 12.3 (0x0512) @@ -179,9 +179,6 @@ ifeq ($(GCC_COMPILER)$(MACPORTS_COMPILER),11) ifneq ($(findstring -Wa,-q,$(CXXFLAGS)),-Wa,-q) CXXFLAGS += -Wa,-q endif -ifneq ($(findstring -Wa,-q,$(CXXFLAGS)),-DCRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) -CXXFLAGS += -DCRYPTOPP_CLANG_INTEGRATED_ASSEMBLER=1 -endif endif # Allow use of "/" operator for GNU Assembler. diff --git a/blake2.cpp b/blake2.cpp index 0cb858b1..77eef8ce 100644 --- a/blake2.cpp +++ b/blake2.cpp @@ -35,7 +35,7 @@ NAMESPACE_BEGIN(CryptoPP) // Apple Clang 6.0/Clang 3.5 does not have SSSE3 intrinsics // http://llvm.org/bugs/show_bug.cgi?id=20213 -#if (defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION <= 60000)) || (defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION <= 30500)) +#if (defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION <= 60000)) || (defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION <= 30500)) # undef CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE #endif diff --git a/config.h b/config.h index 9a40f2ba..7ac17fda 100644 --- a/config.h +++ b/config.h @@ -63,9 +63,7 @@ // Define this to choose the FIPS 202 version of SHA3, and not the original version of SHA3. NIST selected Keccak as SHA3 // in January 2013. SHA3 was finalized in FIPS 202 in August 2015, and it was a modified version of the original selection. // If CRYPTOPP_USE_FIPS_202_SHA3 is defined, then sha3_fips_202.txt test vectors will be used instead of sha3.txt. -// #ifndef CRYPTOPP_USE_FIPS_202_SHA3 -// # define CRYPTOPP_USE_FIPS_202_SHA3 -// #endif +// #define CRYPTOPP_USE_FIPS_202_SHA3 // ***************** Less Important Settings *************** @@ -238,11 +236,9 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); // Apple and LLVM's Clang. Apple Clang version 7.0 roughly equals LLVM Clang version 3.7 #if defined(__clang__ ) && !defined(__apple_build_version__) - #define CRYPTOPP_LLVM_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) - #define CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER 1 + #define CRYPTOPP_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) #elif defined(__clang__ ) && defined(__apple_build_version__) #define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) - #define CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER 1 #endif #ifdef _MSC_VER @@ -250,13 +246,13 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); #endif // Need GCC 4.6/Clang 1.7/Apple Clang 2.0 or above due to "GCC diagnostic {push|pop}" -#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_LLVM_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000) +#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000) #define CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 1 #endif // Clang due to "Inline assembly operands don't work with .intel_syntax", http://llvm.org/bugs/show_bug.cgi?id=24232 // TODO: supply the upper version when LLVM fixes it. We set it to 20.0 for compilation purposes. -#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && CRYPTOPP_LLVM_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) +#if (defined(CRYPTOPP_CLANG_VERSION) && CRYPTOPP_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) #define CRYPTOPP_DISABLE_INTEL_ASM 1 #endif @@ -730,7 +726,7 @@ NAMESPACE_END // ************** Deprecated *************** -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) # define CRYPTOPP_DEPRECATED(msg) __attribute__((deprecated (msg))); #elif (CRYPTOPP_GCC_VERSION) # define CRYPTOPP_DEPRECATED(msg) __attribute__((deprecated)); @@ -783,7 +779,7 @@ NAMESPACE_END # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 #elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1200) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 -#elif (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) +#elif (CRYPTOPP_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 #elif (CRYPTOPP_GCC_VERSION >= 40400) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 diff --git a/config.recommend b/config.recommend index 15b7e781..c9064240 100644 --- a/config.recommend +++ b/config.recommend @@ -63,9 +63,7 @@ // Define this to choose the FIPS 202 version of SHA3, and not the original version of SHA3. NIST selected Keccak as SHA3 // in January 2013. SHA3 was finalized in FIPS 202 in August 2015, and it was a modified version of the original selection. // If CRYPTOPP_USE_FIPS_202_SHA3 is defined, then sha3_fips_202.txt test vectors will be used instead of sha3.txt. -#ifndef CRYPTOPP_USE_FIPS_202_SHA3 -# define CRYPTOPP_USE_FIPS_202_SHA3 -#endif +#define CRYPTOPP_USE_FIPS_202_SHA3 // ***************** Less Important Settings *************** @@ -238,7 +236,7 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); // Apple and LLVM's Clang. Apple Clang version 7.0 roughly equals LLVM Clang version 3.7 #if defined(__clang__ ) && !defined(__apple_build_version__) - #define CRYPTOPP_LLVM_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) + #define CRYPTOPP_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) #elif defined(__clang__ ) && defined(__apple_build_version__) #define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) #endif @@ -248,13 +246,13 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); #endif // Need GCC 4.6/Clang 1.7/Apple Clang 2.0 or above due to "GCC diagnostic {push|pop}" -#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_LLVM_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000) +#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000) #define CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 1 #endif // Clang due to "Inline assembly operands don't work with .intel_syntax", http://llvm.org/bugs/show_bug.cgi?id=24232 // TODO: supply the upper version when LLVM fixes it. We set it to 20.0 for compilation purposes. -#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && CRYPTOPP_LLVM_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) +#if (defined(CRYPTOPP_CLANG_VERSION) && CRYPTOPP_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) #define CRYPTOPP_DISABLE_INTEL_ASM 1 #endif @@ -726,7 +724,7 @@ NAMESPACE_END // ************** Deprecated *************** -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) # define CRYPTOPP_DEPRECATED(msg) __attribute__((deprecated (msg))); #elif (CRYPTOPP_GCC_VERSION) # define CRYPTOPP_DEPRECATED(msg) __attribute__((deprecated)); @@ -779,7 +777,7 @@ NAMESPACE_END # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 #elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1200) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 -#elif (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) +#elif (CRYPTOPP_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 #elif (CRYPTOPP_GCC_VERSION >= 40400) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 diff --git a/cpu.cpp b/cpu.cpp index b13dd255..7c39cccd 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -27,7 +27,7 @@ NAMESPACE_BEGIN(CryptoPP) #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY // MacPorts/GCC does not provide constructor(priority). Apple/GCC and Fink/GCC do provide it. -#define HAVE_GCC_CONSTRUCTOR1 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 300)) && !(MACPORTS_GCC_COMPILER > 0)) +#define HAVE_GCC_CONSTRUCTOR1 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 300)) && !(MACPORTS_GCC_COMPILER > 0)) #define HAVE_GCC_CONSTRUCTOR0 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && !(MACPORTS_GCC_COMPILER > 0)) extern "C" { diff --git a/cpu.h b/cpu.h index b1414a91..890f53db 100644 --- a/cpu.h +++ b/cpu.h @@ -2,7 +2,9 @@ //! \file cpu.h //! \brief Functions for CPU features and intrinsics -//! \details The functions are used in X86/X32/X64 and NEON code paths +//! \details At the moment, the functions are used heavily in X86/X32/X64 code paths +// for SSE, SSE2 and SSE4. The funtions are also used on occassion for AArch32 +//! and AArch64 code paths for NEON. #ifndef CRYPTOPP_CPU_H #define CRYPTOPP_CPU_H @@ -50,7 +52,7 @@ #endif // PUSHFB needs Clang 3.3 and Apple Clang 5.0. -#if !defined(__GNUC__) || defined(__SSSE3__)|| defined(__INTEL_COMPILER) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) +#if !defined(__GNUC__) || defined(__SSSE3__)|| defined(__INTEL_COMPILER) || (CRYPTOPP_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) #include #else NAMESPACE_BEGIN(CryptoPP) @@ -64,7 +66,7 @@ NAMESPACE_END #endif // tmmintrin.h // PEXTRD needs Clang 3.3 and Apple Clang 5.0. -#if !defined(__GNUC__) || defined(__SSE4_1__)|| defined(__INTEL_COMPILER) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) +#if !defined(__GNUC__) || defined(__SSE4_1__)|| defined(__INTEL_COMPILER) || (CRYPTOPP_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) #include #else NAMESPACE_BEGIN(CryptoPP) @@ -85,7 +87,7 @@ NAMESPACE_END #endif // smmintrin.h // AES needs Clang 2.8 and Apple Clang 4.6. PCLMUL needs Clang 3.4 and Apple Clang 6.0 -#if !defined(__GNUC__) || (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30400) || (CRYPTOPP_APPLE_CLANG_VERSION >= 60000) +#if !defined(__GNUC__) || (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || (CRYPTOPP_CLANG_VERSION >= 30400) || (CRYPTOPP_APPLE_CLANG_VERSION >= 60000) #include #else NAMESPACE_BEGIN(CryptoPP) @@ -139,13 +141,11 @@ NAMESPACE_END NAMESPACE_BEGIN(CryptoPP) -#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 || CRYPTOPP_DOXYGEN_PROCESSING +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 #define CRYPTOPP_CPUID_AVAILABLE -// Hide from Doxygen -#ifndef CRYPTOPP_DOXYGEN_PROCESSING -// These should not be used directly +// these should not be used directly extern CRYPTOPP_DLL bool g_x86DetectionDone; extern CRYPTOPP_DLL bool g_hasMMX; extern CRYPTOPP_DLL bool g_hasISSE; @@ -166,12 +166,7 @@ extern CRYPTOPP_DLL word32 g_cacheLineSize; CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features(); CRYPTOPP_DLL bool CRYPTOPP_API CpuId(word32 input, word32 output[4]); -#endif // CRYPTOPP_DOXYGEN_PROCESSING -//! \brief Determines MMX availability -//! \returns true if MMX is determined to be available, false otherwise -//! \details MMX, SSE and SSE2 are core processor features for x86_64, and -//! the function always returns true for the platform. inline bool HasMMX() { #if CRYPTOPP_BOOL_X64 @@ -183,10 +178,6 @@ inline bool HasMMX() #endif } -//! \brief Determines SSE availability -//! \returns true if SSE is determined to be available, false otherwise -//! \details MMX, SSE and SSE2 are core processor features for x86_64, and -//! the function always returns true for the platform. inline bool HasISSE() { #if CRYPTOPP_BOOL_X64 @@ -198,10 +189,6 @@ inline bool HasISSE() #endif } -//! \brief Determines SSE2 availability -//! \returns true if SSE2 is determined to be available, false otherwise -//! \details MMX, SSE and SSE2 are core processor features for x86_64, and -//! the function always returns true for the platform. inline bool HasSSE2() { #if CRYPTOPP_BOOL_X64 @@ -213,10 +200,6 @@ inline bool HasSSE2() #endif } -//! \brief Determines SSSE3 availability -//! \returns true if SSSE3 is determined to be available, false otherwise -//! \details HasSSSE3() is a runtime check performed using CPUID -//! \note Some Clang compilers incorrectly omit SSSE3 even though its native to the processor. inline bool HasSSSE3() { if (!g_x86DetectionDone) @@ -224,9 +207,6 @@ inline bool HasSSSE3() return g_hasSSSE3; } -//! \brief Determines SSE4 availability -//! \returns true if SSE4.1 and SSE4.2 are determined to be available, false otherwise -//! \details HasSSE4() is a runtime check performed using CPUID which requires both SSE4.1 and SSE4.2 inline bool HasSSE4() { if (!g_x86DetectionDone) @@ -234,9 +214,6 @@ inline bool HasSSE4() return g_hasSSE4; } -//! \brief Determines AES-NI availability -//! \returns true if AES-NI is determined to be available, false otherwise -//! \details HasAESNI() is a runtime check performed using CPUID inline bool HasAESNI() { if (!g_x86DetectionDone) @@ -244,9 +221,6 @@ inline bool HasAESNI() return g_hasAESNI; } -//! \brief Determines Carryless Multiply availability -//! \returns true if pclmulqdq is determined to be available, false otherwise -//! \details HasCLMUL() is a runtime check performed using CPUID inline bool HasCLMUL() { if (!g_x86DetectionDone) @@ -254,9 +228,6 @@ inline bool HasCLMUL() return g_hasCLMUL; } -//! \brief Determines if the CPU is an Intel P4 -//! \returns true if the CPU is a P4, false otherwise -//! \details IsP4() is a runtime check performed using CPUID inline bool IsP4() { if (!g_x86DetectionDone) @@ -264,9 +235,6 @@ inline bool IsP4() return g_isP4; } -//! \brief Determines RDRAND availability -//! \returns true if RDRAND is determined to be available, false otherwise -//! \details HasRDRAND() is a runtime check performed using CPUID inline bool HasRDRAND() { if (!g_x86DetectionDone) @@ -274,9 +242,6 @@ inline bool HasRDRAND() return g_hasRDRAND; } -//! \brief Determines RDSEED availability -//! \returns true if RDSEED is determined to be available, false otherwise -//! \details HasRDSEED() is a runtime check performed using CPUID inline bool HasRDSEED() { if (!g_x86DetectionDone) @@ -284,9 +249,6 @@ inline bool HasRDSEED() return g_hasRDSEED; } -//! \brief Determines Padlock RNG availability -//! \returns true if VIA Padlock RNG is determined to be available, false otherwise -//! \details HasPadlockRNG() is a runtime check performed using CPUID inline bool HasPadlockRNG() { if (!g_x86DetectionDone) @@ -294,9 +256,6 @@ inline bool HasPadlockRNG() return g_hasPadlockRNG; } -//! \brief Determines Padlock ACE availability -//! \returns true if VIA Padlock ACE is determined to be available, false otherwise -//! \details HasPadlockACE() is a runtime check performed using CPUID inline bool HasPadlockACE() { if (!g_x86DetectionDone) @@ -304,9 +263,6 @@ inline bool HasPadlockACE() return g_hasPadlockACE; } -//! \brief Determines Padlock ACE2 availability -//! \returns true if VIA Padlock ACE2 is determined to be available, false otherwise -//! \details HasPadlockACE2() is a runtime check performed using CPUID inline bool HasPadlockACE2() { if (!g_x86DetectionDone) @@ -314,9 +270,6 @@ inline bool HasPadlockACE2() return g_hasPadlockACE2; } -//! \brief Determines Padlock PHE availability -//! \returns true if VIA Padlock PHE is determined to be available, false otherwise -//! \details HasPadlockPHE() is a runtime check performed using CPUID inline bool HasPadlockPHE() { if (!g_x86DetectionDone) @@ -324,9 +277,6 @@ inline bool HasPadlockPHE() return g_hasPadlockPHE; } -//! \brief Determines Padlock PMM availability -//! \returns true if VIA Padlock PMM is determined to be available, false otherwise -//! \details HasPadlockPMM() is a runtime check performed using CPUID inline bool HasPadlockPMM() { if (!g_x86DetectionDone) @@ -334,13 +284,6 @@ inline bool HasPadlockPMM() return g_hasPadlockPMM; } -//! \brief Provides the cache line size -//! \returns lower bound on the size of a cache line in bytes, if available -//! \details GetCacheLineSize() returns the lower bound on the size of a cache line, if it -//! is available. If the value is not available at runtime, then 32 is returned for a 32-bit -//! processor and 64 is returned for a 64-bit processor. -//! \details x86/x32/x64 uses CPUID to determine the value and its usually accurate. The ARM -//! processor equivalent is a privileged instruction, so a compile time value is returned. inline int GetCacheLineSize() { if (!g_x86DetectionDone) @@ -472,7 +415,7 @@ inline int GetCacheLineSize() #else #define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY -#if defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) +#if defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION) #define NEW_LINE "\n" #define INTEL_PREFIX ".intel_syntax;" #define INTEL_NOPREFIX ".intel_syntax;" diff --git a/cryptest.sh b/cryptest.sh index d177cd1e..f88287d4 100755 --- a/cryptest.sh +++ b/cryptest.sh @@ -128,8 +128,6 @@ fi SUN_COMPILER=$("$CXX" -V 2>&1 | "$EGREP" -i -c "CC: Sun") GCC_COMPILER=$("$CXX" --version 2>&1 | "$EGREP" -i -c "(gcc|g\+\+)") -INTEL_COMPILER=$("$CXX" --version 2>&1 | "$EGREP" -i -c "\(ICC\)") -MACPORTS_COMPILER=$("$CXX" --version 2>&1 | "$EGREP" -i -c "MacPorts") CLANG_COMPILER=$("$CXX" --version 2>&1 | "$EGREP" -i -c "clang") if [[ ($("$CXX" -dM -E - /dev/null | "$EGREP" -c '(__x64_64__|__amd64__)') -ne "0") && ($("$CXX" -dM -E -/dev/null | "$EGREP" -c '(__ILP32|__ILP32)') -ne "0") ]]; then @@ -137,7 +135,6 @@ if [[ ($("$CXX" -dM -E - /dev/null | "$EGREP" -c '(__x64_64__|__amd fi # Now that the compiler is fixed, see if its GCC 5.1 or above with -Wabi, -Wabi-tag and -Wodr -GCC_60_OR_ABOVE=$("$CXX" -v 2>&1 | "$EGREP" -i -c 'gcc version (6\.[0-9]|[7-9])') GCC_51_OR_ABOVE=$("$CXX" -v 2>&1 | "$EGREP" -i -c 'gcc version (5\.[1-9]|[6-9])') GCC_48_COMPILER=$("$CXX" -v 2>&1 | "$EGREP" -i -c 'gcc version 4\.8') # SunCC 12.2 and below needs one set of CXXFLAGS; SunCC 12.3 and above needs another set of CXXFLAGS @@ -227,14 +224,6 @@ if [[ (-z "$HAVE_CXX03") ]]; then fi fi -if [[ (-z "$HAVE_GNU03") ]]; then - HAVE_GNU03=0 - "$CXX" -DCRYPTOPP_ADHOC_MAIN -std=gnu++03 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1 - if [[ "$?" -eq "0" ]]; then - HAVE_GNU03=1 - fi -fi - HAVE_O3=0 OPT_O3= "$CXX" -DCRYPTOPP_ADHOC_MAIN -O3 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1 @@ -507,7 +496,6 @@ fi # C++03, C++11, C++14 and C++17 echo | tee -a "$TEST_RESULTS" echo "HAVE_CXX03: $HAVE_CXX03" | tee -a "$TEST_RESULTS" -echo "HAVE_GNU03: $HAVE_GNU03" | tee -a "$TEST_RESULTS" echo "HAVE_CXX11: $HAVE_CXX11" | tee -a "$TEST_RESULTS" echo "HAVE_GNU11: $HAVE_GNU11" | tee -a "$TEST_RESULTS" if [[ ("$HAVE_CXX14" -ne "0" || "$HAVE_CXX17" -ne "0" || "$HAVE_GNU14" -ne "0" || "$HAVE_GNU17" -ne "0") ]]; then @@ -708,9 +696,6 @@ if [[ ("$GCC_COMPILER" -ne "0") ]]; then "-Wno-unknown-pragmas" "-Wstrict-aliasing=3" "-Wstrict-overflow" "-Waggressive-loop-optimizations" "-Wcast-align" "-Wwrite-strings" "-Wformat=2" "-Wformat-security" "-Wtrampolines") - if [[ ("$GCC_60_OR_ABOVE" -ne "0") ]]; then - ELEVATED_CXXFLAGS+=("-Wshift-negative-value -Wshift-overflow=2 -Wnull-dereference -Wduplicated-cond -Wodr-type-mismatch") - fi if [[ ("$GCC_51_OR_ABOVE" -ne "0") ]]; then ELEVATED_CXXFLAGS+=("-Wabi" "-Wodr") fi @@ -970,65 +955,6 @@ if [[ "$HAVE_CXX03" -ne "0" ]]; then fi fi -############################################ -# gnu++03 debug and release build -if [[ "$HAVE_GNU03" -ne "0" ]]; then - - ############################################ - # Debug build - echo - echo "************************************" | tee -a "$TEST_RESULTS" - echo "Testing: debug, gnu++03" | tee -a "$TEST_RESULTS" - echo - - unset CXXFLAGS - "$MAKE" clean > /dev/null 2>&1 - rm -f adhoc.cpp > /dev/null 2>&1 - - export CXXFLAGS="$DEBUG_CXXFLAGS -std=gnu++03 ${RETAINED_CXXFLAGS[@]}" - "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" - - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" - else - ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" - fi - ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" - fi - fi - - ############################################ - # Release build - echo - echo "************************************" | tee -a "$TEST_RESULTS" - echo "Testing: release, gnu++03" | tee -a "$TEST_RESULTS" - echo - - unset CXXFLAGS - "$MAKE" clean > /dev/null 2>&1 - rm -f adhoc.cpp > /dev/null 2>&1 - - export CXXFLAGS="$RELEASE_CXXFLAGS -std=gnu++03 ${RETAINED_CXXFLAGS[@]}" - "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" - - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" - else - ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" - fi - ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" - fi - fi -fi - ############################################ # c++11 debug and release build if [[ "$HAVE_CXX11" -ne "0" ]]; then @@ -3958,75 +3884,6 @@ if [[ ("$INTEL_COMPILER" -eq "0") ]]; then fi fi -############################################ -# Perform a quick check with MacPorts compilers, if available. -if [[ ("$MACPORTS_COMPILER" -eq "0") ]]; then - - MACPORTS_CXX=$(find /opt/local/bin -name 'g++*' 2>/dev/null | head -1) - if [[ (-z "$MACPORTS_CXX") ]]; then - "$MACPORTS_CXX" -x c++ -DCRYPTOPP_ADHOC_MAIN adhoc.cpp.proto -o "$TMP/adhoc.exe" > /dev/null 2>&1 - if [[ "$?" -eq "0" ]]; then - - ############################################ - # GCC build - echo - echo "************************************" | tee -a "$TEST_RESULTS" - echo "Testing: MacPorts GCC compiler" | tee -a "$TEST_RESULTS" - echo - - unset CXXFLAGS - "$MAKE" clean > /dev/null 2>&1 - rm -f adhoc.cpp > /dev/null 2>&1 - - "$MAKE" "${MAKEARGS[@]}" CXX="$MACPORTS_CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" - else - ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" - fi - ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" - fi - fi - fi - fi - - MACPORTS_CXX=$(find /opt/local/bin -name 'clang++*' 2>/dev/null | head -1) - if [[ (-z "$MACPORTS_CXX") ]]; then - "$MACPORTS_CXX" -x c++ -DCRYPTOPP_ADHOC_MAIN adhoc.cpp.proto -o "$TMP/adhoc.exe" > /dev/null 2>&1 - if [[ "$?" -eq "0" ]]; then - - ############################################ - # Clang build - echo - echo "************************************" | tee -a "$TEST_RESULTS" - echo "Testing: MacPorts Clang compiler" | tee -a "$TEST_RESULTS" - echo - - unset CXXFLAGS - "$MAKE" clean > /dev/null 2>&1 - rm -f adhoc.cpp > /dev/null 2>&1 - - "$MAKE" "${MAKEARGS[@]}" CXX="$MACPORTS_CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" - else - ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" - fi - ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" - fi - fi - fi - fi -fi - ############################################ # Perform a quick check with Xcode compiler, if available. if [[ "$IS_DARWIN" -ne "0" ]]; then @@ -4233,14 +4090,14 @@ fi # Report warnings echo -echo "************************************************" | tee -a "$TEST_RESULTS" "$WARN_RESULTS" -echo | tee -a "$TEST_RESULTS" "$WARN_RESULTS" +echo "************************************************" | tee -a "$WARN_RESULTS" +echo | tee -a "$WARN_RESULTS" WCOUNT=$("$EGREP" -a '(warning:)' $WARN_RESULTS | "$GREP" -v 'deprecated-declarations' | wc -l | "$AWK" '{print $1}') if (( "$WCOUNT" == "0" )); then - echo "No warnings detected" | tee -a "$TEST_RESULTS" "$WARN_RESULTS" | tee -a "$TEST_RESULTS" "$WARN_RESULTS" + echo "No warnings detected" | tee -a "$WARN_RESULTS" | tee -a "$WARN_RESULTS" else - echo "$WCOUNT warnings detected. See $WARN_RESULTS for details" | tee -a "$TEST_RESULTS" "$WARN_RESULTS" + echo "$WCOUNT warnings detected. See $WARN_RESULTS for details" | tee -a "$WARN_RESULTS" # "$EGREP" -an '(warning:)' $WARN_RESULTS | "$GREP" -v 'deprecated-declarations' fi @@ -4249,8 +4106,8 @@ fi echo echo "************************************************" | tee -a "$TEST_RESULTS" "$WARN_RESULTS" -echo | tee -a "$TEST_RESULTS" "$WARN_RESULTS" +echo echo "Testing started: $TEST_BEGIN" | tee -a "$TEST_RESULTS" "$WARN_RESULTS" echo "Testing finished: $TEST_END" | tee -a "$TEST_RESULTS" "$WARN_RESULTS" echo diff --git a/default.h b/default.h index 6b30f2e4..00ec6647 100644 --- a/default.h +++ b/default.h @@ -48,7 +48,7 @@ private: SecByteBlock m_passphrase; CBC_Mode::Encryption m_cipher; -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) } __attribute__((deprecated ("DefaultEncryptor will be changing in the near future because the algorithms are no longer secure"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); @@ -68,7 +68,7 @@ public: //! \param attachment a BufferedTransformation to attach to this object //! \param throwException a flag specifiying whether an Exception should be thrown on error DefaultDecryptor(const char *passphrase, BufferedTransformation *attachment = NULL, bool throwException=true); - + //! \brief Constructs a DefaultDecryptor //! \param passphrase a byte string password //! \param passphraseLength the length of the byte string password @@ -79,7 +79,7 @@ public: class Err : public Exception { public: - Err(const std::string &s) + Err(const std::string &s) : Exception(DATA_INTEGRITY_CHECK_FAILED, s) {} }; class KeyBadErr : public Err {public: KeyBadErr() : Err("DefaultDecryptor: cannot decrypt message with this passphrase") {}}; @@ -101,7 +101,7 @@ private: member_ptr m_decryptor; bool m_throwException; -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) } __attribute__((deprecated ("DefaultDecryptor will be changing in the near future because the algorithms are no longer secure"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); @@ -139,7 +139,7 @@ protected: private: member_ptr m_mac; -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) } __attribute__((deprecated ("DefaultEncryptorWithMAC will be changing in the near future because the algorithms are no longer secure"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); @@ -188,7 +188,7 @@ private: HashVerifier *m_hashVerifier; bool m_throwException; -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) } __attribute__((deprecated ("DefaultDecryptorWithMAC will be changing in the near future because the algorithms are no longer secure"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); diff --git a/eccrypto.h b/eccrypto.h index a809f661..6642dec5 100644 --- a/eccrypto.h +++ b/eccrypto.h @@ -132,7 +132,7 @@ public: const Integer& GetBasePointOrder() const {return this->GetSubgroupOrder();} void LoadRecommendedParameters(const OID &oid) {Initialize(oid);} #endif - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_GroupParameters_EC() {} #endif @@ -162,7 +162,7 @@ public: // X509PublicKey void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size); void DEREncodePublicKey(BufferedTransformation &bt) const; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_PublicKey_EC() {} #endif @@ -187,7 +187,7 @@ public: // PKCS8PrivateKey void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); void DEREncodePrivateKey(BufferedTransformation &bt) const; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_PrivateKey_EC() {} #endif @@ -198,7 +198,7 @@ template , COFACTOR_OPTION> Domain; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~ECDH() {} #endif @@ -209,7 +209,7 @@ template , COFACTOR_OPTION> Domain; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~ECMQV() {} #endif @@ -259,7 +259,7 @@ struct DL_Keys_EC { typedef DL_PublicKey_EC PublicKey; typedef DL_PrivateKey_EC PrivateKey; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_Keys_EC() {} #endif @@ -274,7 +274,7 @@ struct DL_Keys_ECDSA { typedef DL_PublicKey_EC PublicKey; typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest, ECDSA > PrivateKey; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_Keys_ECDSA() {} #endif @@ -286,7 +286,7 @@ class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA { public: static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";} - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_Algorithm_ECDSA() {} #endif @@ -298,7 +298,7 @@ class DL_Algorithm_ECNR : public DL_Algorithm_NR { public: static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECNR";} - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_Algorithm_ECNR() {} #endif @@ -336,12 +336,12 @@ struct ECIES ECIES > { static std::string CRYPTOPP_API StaticAlgorithmName() {return "ECIES";} // TODO: fix this after name is standardized - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~ECIES() {} #endif - -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) + +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) } __attribute__((deprecated ("ECIES will be changing in the near future due to (1) an implementation bug and (2) an interop issue"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); diff --git a/gcm.cpp b/gcm.cpp index fd6731f0..fd82bddb 100644 --- a/gcm.cpp +++ b/gcm.cpp @@ -13,7 +13,7 @@ #ifndef CRYPTOPP_GENERATE_X64_MASM // Clang 3.3 integrated assembler crash on Linux -#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION < 30400)) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) +#if defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION < 30400) # undef CRYPTOPP_X86_ASM_AVAILABLE # undef CRYPTOPP_X32_ASM_AVAILABLE # undef CRYPTOPP_X64_ASM_AVAILABLE @@ -703,9 +703,9 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len) AS2( pxor xmm5, xmm2 ) AS2( psrldq xmm0, 15 ) -#if (CRYPTOPP_LLVM_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) +#if (CRYPTOPP_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) AS2( movd edi, xmm0 ) -#elif (defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) +#elif (defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) AS2( mov WORD_REG(di), xmm0 ) #else // GNU Assembler AS2( movd WORD_REG(di), xmm0 ) @@ -718,9 +718,9 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len) AS2( pxor xmm4, xmm5 ) AS2( psrldq xmm1, 15 ) -#if (CRYPTOPP_LLVM_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) +#if (CRYPTOPP_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) AS2( movd edi, xmm1 ) -#elif (defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) +#elif (defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) AS2( mov WORD_REG(di), xmm1 ) #else AS2( movd WORD_REG(di), xmm1 ) @@ -729,9 +729,9 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len) AS2( shl eax, 8 ) AS2( psrldq xmm0, 15 ) -#if (CRYPTOPP_LLVM_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) +#if (CRYPTOPP_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) AS2( movd edi, xmm0 ) -#elif (defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) +#elif (defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) AS2( mov WORD_REG(di), xmm0 ) #else AS2( movd WORD_REG(di), xmm0 ) diff --git a/misc.h b/misc.h index e3980441..655100f6 100644 --- a/misc.h +++ b/misc.h @@ -63,18 +63,12 @@ #if defined(__GNUC__) && defined(__BMI__) # include # if defined(__clang__) -#ifndef _tzcnt_u32 # define _tzcnt_u32(x) __tzcnt_u32(x) -#endif -#ifndef _tzcnt_u64 # define _tzcnt_u64(x) __tzcnt_u64(x) -#endif -#ifndef _blsr_u32 # define _blsr_u32(x) __blsr_u32(x) -#endif #ifndef _blsr_u64 # define _blsr_u64(x) __blsr_u64(x) -#endif +# endif # endif #endif @@ -471,7 +465,7 @@ template inline const T& STDMAX(const T& a, const T& b) #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wsign-compare" -# if (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) || (CRYPTOPP_APPLE_CLANG_VERSION >= 30000) +# if (CRYPTOPP_CLANG_VERSION >= 20800) || (CRYPTOPP_APPLE_CLANG_VERSION >= 30000) # pragma GCC diagnostic ignored "-Wtautological-compare" # elif (CRYPTOPP_GCC_VERSION >= 40300) # pragma GCC diagnostic ignored "-Wtype-limits" diff --git a/panama.h b/panama.h index e7f20c95..b7db323a 100644 --- a/panama.h +++ b/panama.h @@ -11,7 +11,7 @@ #include "secblock.h" // Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler error with .intel_syntax -#if CRYPTOPP_BOOL_X32 || (defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION < 30500)) +#if CRYPTOPP_BOOL_X32 || (defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION < 30500)) # define CRYPTOPP_DISABLE_PANAMA_ASM #endif @@ -128,7 +128,7 @@ struct PanamaCipherInfo : public FixedKeyLength<32, SimpleKeyingInterface::UNIQU //! _ template -class PanamaCipherPolicy : public AdditiveCipherConcretePolicy, +class PanamaCipherPolicy : public AdditiveCipherConcretePolicy, public PanamaCipherInfo, protected Panama { diff --git a/rdrand.cpp b/rdrand.cpp index 4edb1bd8..6149315e 100644 --- a/rdrand.cpp +++ b/rdrand.cpp @@ -67,8 +67,8 @@ #endif #if defined(CRYPTOPP_CPUID_AVAILABLE) -# define MSC_INTRIN_COMPILER ((CRYPTOPP_MSC_VERSION >= 1700) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30200) || (_INTEL_COMPILER >= 1210)) -# define GCC_INTRIN_COMPILER ((CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30200) || (_INTEL_COMPILER >= 1210)) +# define MSC_INTRIN_COMPILER ((CRYPTOPP_MSC_VERSION >= 1700) || (CRYPTOPP_CLANG_VERSION >= 30200) || (_INTEL_COMPILER >= 1210)) +# define GCC_INTRIN_COMPILER ((CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_CLANG_VERSION >= 30200) || (_INTEL_COMPILER >= 1210)) #else # define MSC_INTRIN_COMPILER 0 # define GCC_INTRIN_COMPILER 0 diff --git a/rijndael.h b/rijndael.h index 50fdf1eb..ed856d94 100644 --- a/rijndael.h +++ b/rijndael.h @@ -12,7 +12,7 @@ #include "secblock.h" // Clang 3.3 integrated assembler crash on Linux -#if CRYPTOPP_BOOL_X32 || (defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION < 30400)) +#if CRYPTOPP_BOOL_X32 || (defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION < 30400)) # define CRYPTOPP_DISABLE_RIJNDAEL_ASM #endif diff --git a/sha.h b/sha.h index c70d9d1f..544e8056 100644 --- a/sha.h +++ b/sha.h @@ -11,7 +11,7 @@ #include "iterhash.h" // Clang 3.3 integrated assembler crash on Linux -#if defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION < 30400) +#if defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION < 30400) # define CRYPTOPP_DISABLE_SHA_ASM #endif diff --git a/wait.h b/wait.h index e274b19f..13e6ba33 100644 --- a/wait.h +++ b/wait.h @@ -32,13 +32,6 @@ # endif #endif -// http://connect.microsoft.com/VisualStudio/feedback/details/1581706 -// and http://github.com/weidai11/cryptopp/issues/214 -#if CRYPTOPP_MSC_VERSION == 1900 -# pragma warning(push) -# pragma warning(disable: 4589) -#endif - NAMESPACE_BEGIN(CryptoPP) class Tracer @@ -230,10 +223,6 @@ private: NAMESPACE_END -#if CRYPTOPP_MSC_VERSION == 1900 -# pragma warning(pop) -#endif - #endif #endif From fd1a8830d3702d5197975a49d5d2a7717c146c57 Mon Sep 17 00:00:00 2001 From: Mouse Date: Wed, 6 Jul 2016 12:11:41 -0400 Subject: [PATCH 15/22] Revert "Merge remote-tracking branch 'upstream/master'" - shouldn't be merged by me This reverts commit a424635a14f4ac192ba06dbb7bcd00ec2e22b587, reversing changes made to 1cf48cf97bd2d3916c76681329844b2ae63c4889. --- cryptest.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cryptest.sh b/cryptest.sh index f88287d4..e4508728 100755 --- a/cryptest.sh +++ b/cryptest.sh @@ -136,7 +136,6 @@ fi # Now that the compiler is fixed, see if its GCC 5.1 or above with -Wabi, -Wabi-tag and -Wodr GCC_51_OR_ABOVE=$("$CXX" -v 2>&1 | "$EGREP" -i -c 'gcc version (5\.[1-9]|[6-9])') -GCC_48_COMPILER=$("$CXX" -v 2>&1 | "$EGREP" -i -c 'gcc version 4\.8') # SunCC 12.2 and below needs one set of CXXFLAGS; SunCC 12.3 and above needs another set of CXXFLAGS SUNCC_123_OR_ABOVE=$("$CXX" -E -xdumpmacros /dev/null 2>&1 | "$GREP" " __SUNPRO_CC " 2>/dev/null | "$AWK" '{print ($2 >= 0x5120) ? "1" : "0"}' ) @@ -290,11 +289,6 @@ if [[ (-z "$HAVE_ASAN") ]]; then fi fi -# Fixup; see http://github.com/weidai11/cryptopp/issues/212 -if [[ ("$GCC_48_COMPILER" -ne "0" && "$IS_ARM32" -ne "0") ]]; then - HAVE_ASAN=0 -fi - # Darwin and Intel multiarch if [[ (-z "$HAVE_INTEL_MULTIARCH") ]]; then HAVE_INTEL_MULTIARCH=0 From dcb97ca574f00edda431003546a3eeb348cf3344 Mon Sep 17 00:00:00 2001 From: Mouse Date: Wed, 6 Jul 2016 12:12:25 -0400 Subject: [PATCH 16/22] Revert "Added 8 new files that support HMQV and FHMQV to Filelist.txt" - shouldn't be merged by me This reverts commit 1cf48cf97bd2d3916c76681329844b2ae63c4889. --- Filelist.txt | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Filelist.txt b/Filelist.txt index 45aefbb1..4080a1a0 100644 --- a/Filelist.txt +++ b/Filelist.txt @@ -106,8 +106,6 @@ eprecomp.h esign.cpp esign.h factory.h -fhmqv.cpp -fhmqv.h files.cpp files.h filters.cpp @@ -136,8 +134,6 @@ hex.h hkdf.h hmac.cpp hmac.h -hmqv.cpp -hmqv.h hrtimer.cpp hrtimer.h ida.cpp @@ -331,15 +327,7 @@ TestData/elgc1024.dat TestData/esig1023.dat TestData/esig1536.dat TestData/esig2046.dat -TestData/fhmqv160.dat -TestData/fhmqv256.dat -TestData/fhmqv384.dat -TestData/fhmqv512.dat TestData/gostval.dat -TestData/hmqv160.dat -TestData/hmqv256.dat -TestData/hmqv384.dat -TestData/hmqv512.dat TestData/ideaval.dat TestData/luc1024.dat TestData/luc2048.dat From efd1b9e3d546b853f1ef14a548ce4e3b896dce41 Mon Sep 17 00:00:00 2001 From: Mouse Date: Wed, 6 Jul 2016 12:14:12 -0400 Subject: [PATCH 17/22] Revert "Merge remote-tracking branch 'upstream/master'" - shouldn't be merged by me This reverts commit b48866631a5587e9348245fedd6f1e0871df35db, reversing changes made to 2733630a3f38e0c5adaaa9b9fc2139dfe3eeb1cc. --- cryptest.sh | 209 +-------------------------------------------------- misc.h | 13 ++-- socketft.cpp | 6 -- 3 files changed, 7 insertions(+), 221 deletions(-) diff --git a/cryptest.sh b/cryptest.sh index e4508728..5e26aebf 100755 --- a/cryptest.sh +++ b/cryptest.sh @@ -172,14 +172,6 @@ if [[ (-z "$HAVE_CXX17") ]]; then fi fi -if [[ (-z "$HAVE_GNU17") ]]; then - HAVE_GNU17=0 - "$CXX" -DCRYPTOPP_ADHOC_MAIN -std=gnu++17 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1 - if [[ "$?" -eq "0" ]]; then - HAVE_GNU17=1 - fi -fi - # Hit or miss, mostly miss. if [[ (-z "$HAVE_CXX14") ]]; then HAVE_CXX14=0 @@ -189,14 +181,6 @@ if [[ (-z "$HAVE_CXX14") ]]; then fi fi -if [[ (-z "$HAVE_GNU14") ]]; then - HAVE_GNU14=0 - "$CXX" -DCRYPTOPP_ADHOC_MAIN -std=gnu++14 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1 - if [[ "$?" -eq "0" ]]; then - HAVE_GNU14=1 - fi -fi - # Hit or miss, mostly hit. if [[ (-z "$HAVE_CXX11") ]]; then HAVE_CXX11=0 @@ -206,14 +190,6 @@ if [[ (-z "$HAVE_CXX11") ]]; then fi fi -if [[ (-z "$HAVE_GNU11") ]]; then - HAVE_GNU11=0 - "$CXX" -DCRYPTOPP_ADHOC_MAIN -std=gnu++11 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1 - if [[ "$?" -eq "0" ]]; then - HAVE_GNU11=1 - fi -fi - # OpenBSD 5.7 and OS X 10.5 cannot consume -std=c++03 if [[ (-z "$HAVE_CXX03") ]]; then HAVE_CXX03=0 @@ -452,9 +428,6 @@ elif [[ "$IS_DARWIN" -ne "0" ]]; then echo "IS_DARWIN: $IS_DARWIN" | tee -a "$TEST_RESULTS" fi -if [[ "$IS_PPC" -ne "0" ]]; then - echo "IS_PPC: $IS_PPC" | tee -a "$TEST_RESULTS" -fi if [[ "$IS_ARM64" -ne "0" ]]; then echo "IS_ARM64: $IS_ARM64" | tee -a "$TEST_RESULTS" elif [[ "$IS_ARM32" -ne "0" ]]; then @@ -491,12 +464,9 @@ fi echo | tee -a "$TEST_RESULTS" echo "HAVE_CXX03: $HAVE_CXX03" | tee -a "$TEST_RESULTS" echo "HAVE_CXX11: $HAVE_CXX11" | tee -a "$TEST_RESULTS" -echo "HAVE_GNU11: $HAVE_GNU11" | tee -a "$TEST_RESULTS" -if [[ ("$HAVE_CXX14" -ne "0" || "$HAVE_CXX17" -ne "0" || "$HAVE_GNU14" -ne "0" || "$HAVE_GNU17" -ne "0") ]]; then +if [[ ("$HAVE_CXX14" -ne "0" || "$HAVE_CXX17" -ne "0") ]]; then echo "HAVE_CXX14: $HAVE_CXX14" | tee -a "$TEST_RESULTS" - echo "HAVE_GNU14: $HAVE_GNU14" | tee -a "$TEST_RESULTS" echo "HAVE_CXX17: $HAVE_CXX17" | tee -a "$TEST_RESULTS" - echo "HAVE_GNU17: $HAVE_GNU17" | tee -a "$TEST_RESULTS" fi if [[ "$HAVE_LDGOLD" -ne "0" ]]; then echo "HAVE_LDGOLD: $HAVE_LDGOLD" | tee -a "$TEST_RESULTS" @@ -1008,65 +978,6 @@ if [[ "$HAVE_CXX11" -ne "0" ]]; then fi fi -############################################ -# gnu++11 debug and release build -if [[ "$HAVE_GNU11" -ne "0" ]]; then - - ############################################ - # Debug build - echo - echo "************************************" | tee -a "$TEST_RESULTS" - echo "Testing: debug, gnu++11" | tee -a "$TEST_RESULTS" - echo - - unset CXXFLAGS - "$MAKE" clean > /dev/null 2>&1 - rm -f adhoc.cpp > /dev/null 2>&1 - - export CXXFLAGS="$DEBUG_CXXFLAGS -std=gnu++11 ${RETAINED_CXXFLAGS[@]}" - "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" - - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" - else - ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" - fi - ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" - fi - fi - - ############################################ - # Release build - echo - echo "************************************" | tee -a "$TEST_RESULTS" - echo "Testing: release, gnu++11" | tee -a "$TEST_RESULTS" - echo - - unset CXXFLAGS - "$MAKE" clean > /dev/null 2>&1 - rm -f adhoc.cpp > /dev/null 2>&1 - - export CXXFLAGS="$RELEASE_CXXFLAGS -std=gnu++11 ${RETAINED_CXXFLAGS[@]}" - "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" - - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" - else - ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" - fi - ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" - fi - fi -fi - ############################################ # c++14 debug and release build if [[ "$HAVE_CXX14" -ne "0" ]]; then @@ -1126,65 +1037,6 @@ if [[ "$HAVE_CXX14" -ne "0" ]]; then fi fi -############################################ -# gnu++14 debug and release build -if [[ "$HAVE_GNU14" -ne "0" ]]; then - - ############################################ - # Debug build - echo - echo "************************************" | tee -a "$TEST_RESULTS" - echo "Testing: debug, gnu++14" | tee -a "$TEST_RESULTS" - echo - - unset CXXFLAGS - "$MAKE" clean > /dev/null 2>&1 - rm -f adhoc.cpp > /dev/null 2>&1 - - export CXXFLAGS="$DEBUG_CXXFLAGS -std=gnu++14 ${RETAINED_CXXFLAGS[@]}" - "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" - - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" - else - ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" - fi - ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" - fi - fi - - ############################################ - # Release build - echo - echo "************************************" | tee -a "$TEST_RESULTS" - echo "Testing: release, gnu++14" | tee -a "$TEST_RESULTS" - echo - - unset CXXFLAGS - "$MAKE" clean > /dev/null 2>&1 - rm -f adhoc.cpp > /dev/null 2>&1 - - export CXXFLAGS="$RELEASE_CXXFLAGS -std=gnu++14 ${RETAINED_CXXFLAGS[@]}" - "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" - - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" - else - ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" - fi - ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" - fi - fi -fi - ############################################ # c++17 debug and release build if [[ "$HAVE_CXX17" -ne "0" ]]; then @@ -1244,65 +1096,6 @@ if [[ "$HAVE_CXX17" -ne "0" ]]; then fi fi -############################################ -# gnu++17 debug and release build -if [[ "$HAVE_GNU17" -ne "0" ]]; then - - ############################################ - # Debug build - echo - echo "************************************" | tee -a "$TEST_RESULTS" - echo "Testing: debug, gnu++17" | tee -a "$TEST_RESULTS" - echo - - unset CXXFLAGS - "$MAKE" clean > /dev/null 2>&1 - rm -f adhoc.cpp > /dev/null 2>&1 - - export CXXFLAGS="$DEBUG_CXXFLAGS -std=gnu++17 ${RETAINED_CXXFLAGS[@]}" - "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" - - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" - else - ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" - fi - ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" - fi - fi - - ############################################ - # Release build - echo - echo "************************************" | tee -a "$TEST_RESULTS" - echo "Testing: release, gnu++17" | tee -a "$TEST_RESULTS" - echo - - unset CXXFLAGS - "$MAKE" clean > /dev/null 2>&1 - rm -f adhoc.cpp > /dev/null 2>&1 - - export CXXFLAGS="$RELEASE_CXXFLAGS -std=gnu++17 ${RETAINED_CXXFLAGS[@]}" - "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" - - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" - else - ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" - fi - ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" - if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then - echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" - fi - fi -fi - ############################################ # X32 debug and release build if [[ "$HAVE_X32" -ne "0" ]]; then diff --git a/misc.h b/misc.h index 655100f6..63ed4e29 100644 --- a/misc.h +++ b/misc.h @@ -221,11 +221,10 @@ struct NewObject //! \brief A memory barrier //! \details MEMORY_BARRIER attempts to ensure reads and writes are completed //! in the absence of a language synchronization point. It is used by the -//! Singleton class if the compiler supports it. The barrier is provided at the -//! customary places in a double-checked initialization. -//! \details Internally, MEMORY_BARRIER uses std::atomic_thread_fence if -//! C++11 atomics are available. Otherwise, intrinsic(_ReadWriteBarrier), -//! _ReadWriteBarrier() or __asm__("" ::: "memory") is used. +//! Singleton class if the compiler supports it. The use is provided at the +//! customary check points in a double-checked initialization. +//! \details Internally, MEMORY_BARRIER uses intrinsic(_ReadWriteBarrier), +//! _ReadWriteBarrier() or __asm__("" ::: "memory"). #define MEMORY_BARRIER ... #else #if defined(CRYPTOPP_CXX11_ATOMICS) @@ -249,8 +248,8 @@ struct NewObject //! \details This class safely initializes a static object in a multithreaded environment. For C++03 //! and below it will do so without using locks for portability. If two threads call Ref() at the same //! time, they may get back different references, and one object may end up being memory leaked. This -//! is by design. For C++11 and above, a standard double-checked locking pattern with thread fences -//! are used. The locks and fences are standard and do not hinder portability. +//! is by design. For C++11 and above, a standard double-checked locking pattern with memory fences +//! is used. The locks and fences are standard and do not hinder portability. //! \sa Double-Checked Locking is Fixed In C++11 template , int instance=0> class Singleton diff --git a/socketft.cpp b/socketft.cpp index ff6e0d40..42a00182 100644 --- a/socketft.cpp +++ b/socketft.cpp @@ -109,12 +109,10 @@ void Socket::CloseSocket() BOOL result = CancelIoEx((HANDLE) m_s, NULL); assert(result || (!result && GetLastError() == ERROR_NOT_FOUND)); CheckAndHandleError_int("closesocket", closesocket(m_s)); - CRYPTOPP_UNUSED(result); // Used by assert in debug builds # else BOOL result = CancelIo((HANDLE) m_s); assert(result || (!result && GetLastError() == ERROR_NOT_FOUND)); CheckAndHandleError_int("closesocket", closesocket(m_s)); - CRYPTOPP_UNUSED(result); # endif #else CheckAndHandleError_int("close", close(m_s)); @@ -370,11 +368,9 @@ SocketReceiver::~SocketReceiver() # if defined(USE_WINDOWS8_API) BOOL result = CancelIoEx((HANDLE) m_s.GetSocket(), NULL); assert(result || (!result && GetLastError() == ERROR_NOT_FOUND)); - CRYPTOPP_UNUSED(result); // Used by assert in debug builds # else BOOL result = CancelIo((HANDLE) m_s.GetSocket()); assert(result || (!result && GetLastError() == ERROR_NOT_FOUND)); - CRYPTOPP_UNUSED(result); # endif #endif } @@ -460,11 +456,9 @@ SocketSender::~SocketSender() # if defined(USE_WINDOWS8_API) BOOL result = CancelIoEx((HANDLE) m_s.GetSocket(), NULL); assert(result || (!result && GetLastError() == ERROR_NOT_FOUND)); - CRYPTOPP_UNUSED(result); // Used by assert in debug builds # else BOOL result = CancelIo((HANDLE) m_s.GetSocket()); assert(result || (!result && GetLastError() == ERROR_NOT_FOUND)); - CRYPTOPP_UNUSED(result); # endif #endif } From c6c0bdeebe7ae5399045ef2360d8ae54d76d209b Mon Sep 17 00:00:00 2001 From: Mouse Date: Wed, 6 Jul 2016 12:15:47 -0400 Subject: [PATCH 18/22] Revert "Add HMQV implementation (and merge the old FHMQV into the new codebase)" This reverts commit ec350995893b8388631c023d8884f22c94c212ad. --- TestData/fhmqv160.dat | 1 - TestData/fhmqv256.dat | 1 - TestData/fhmqv384.dat | 1 - TestData/fhmqv512.dat | 1 - TestData/hmqv160.dat | 1 - TestData/hmqv256.dat | 1 - TestData/hmqv384.dat | 1 - TestData/hmqv512.dat | 1 - eccrypto.h | 44 +----- fhmqv.cpp | 14 -- fhmqv.h | 294 ---------------------------------------- hmqv.cpp | 14 -- hmqv.h | 303 ------------------------------------------ validat1.cpp | 2 - validat2.cpp | 236 -------------------------------- validate.h | 2 - 16 files changed, 2 insertions(+), 915 deletions(-) delete mode 100644 TestData/fhmqv160.dat delete mode 100644 TestData/fhmqv256.dat delete mode 100644 TestData/fhmqv384.dat delete mode 100644 TestData/fhmqv512.dat delete mode 100644 TestData/hmqv160.dat delete mode 100644 TestData/hmqv256.dat delete mode 100644 TestData/hmqv384.dat delete mode 100644 TestData/hmqv512.dat delete mode 100644 fhmqv.cpp delete mode 100644 fhmqv.h delete mode 100644 hmqv.cpp delete mode 100644 hmqv.h diff --git a/TestData/fhmqv160.dat b/TestData/fhmqv160.dat deleted file mode 100644 index 0d66deec..00000000 --- a/TestData/fhmqv160.dat +++ /dev/null @@ -1 +0,0 @@ -3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101 \ No newline at end of file diff --git a/TestData/fhmqv256.dat b/TestData/fhmqv256.dat deleted file mode 100644 index 0d66deec..00000000 --- a/TestData/fhmqv256.dat +++ /dev/null @@ -1 +0,0 @@ -3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101 \ No newline at end of file diff --git a/TestData/fhmqv384.dat b/TestData/fhmqv384.dat deleted file mode 100644 index 63037fef..00000000 --- a/TestData/fhmqv384.dat +++ /dev/null @@ -1 +0,0 @@ -30820140020101303C06072A8648CE3D0101023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF30640430FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC0430B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF046104AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973020101 \ No newline at end of file diff --git a/TestData/fhmqv512.dat b/TestData/fhmqv512.dat deleted file mode 100644 index 0053ddf6..00000000 --- a/TestData/fhmqv512.dat +++ /dev/null @@ -1 +0,0 @@ -308201AC020101304D06072A8648CE3D0101024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF308188044201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC04420051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F000481850400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409020101 \ No newline at end of file diff --git a/TestData/hmqv160.dat b/TestData/hmqv160.dat deleted file mode 100644 index 0d66deec..00000000 --- a/TestData/hmqv160.dat +++ /dev/null @@ -1 +0,0 @@ -3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101 \ No newline at end of file diff --git a/TestData/hmqv256.dat b/TestData/hmqv256.dat deleted file mode 100644 index 0d66deec..00000000 --- a/TestData/hmqv256.dat +++ /dev/null @@ -1 +0,0 @@ -3081E0020101302C06072A8648CE3D0101022100FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF30440420FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC04205AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B0441046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5022100FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551020101 \ No newline at end of file diff --git a/TestData/hmqv384.dat b/TestData/hmqv384.dat deleted file mode 100644 index 63037fef..00000000 --- a/TestData/hmqv384.dat +++ /dev/null @@ -1 +0,0 @@ -30820140020101303C06072A8648CE3D0101023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF30640430FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC0430B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF046104AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973020101 \ No newline at end of file diff --git a/TestData/hmqv512.dat b/TestData/hmqv512.dat deleted file mode 100644 index 0053ddf6..00000000 --- a/TestData/hmqv512.dat +++ /dev/null @@ -1 +0,0 @@ -308201AC020101304D06072A8648CE3D0101024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF308188044201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC04420051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F000481850400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650024201FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409020101 \ No newline at end of file diff --git a/eccrypto.h b/eccrypto.h index 6642dec5..a3d15e95 100644 --- a/eccrypto.h +++ b/eccrypto.h @@ -16,8 +16,6 @@ #include "gfpcrypt.h" #include "dh.h" #include "mqv.h" -#include "hmqv.h" -#include "fhmqv.h" #include "ecp.h" #include "ec2n.h" @@ -215,44 +213,6 @@ struct ECMQV #endif }; -//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation, -/*! HMQV: A High-Performance Secure Diffie-Hellman Protocol - Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately. -*/ -template ::DefaultCofactorOption, class HASH = SHA256> -struct HMQV -{ - typedef HMQV_Domain, COFACTOR_OPTION, HASH> Domain; - -#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~HMQV() {} -#endif -}; - -typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain HMQV160; -typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain HMQV256; -typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain HMQV384; -typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain HMQV512; - -//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation, -/*! A Secure and Efficient Authenticated Diffie–Hellman Protocol - Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. -*/ -template ::DefaultCofactorOption, class HASH = SHA256> -struct FHMQV -{ - typedef FHMQV_Domain, COFACTOR_OPTION, HASH> Domain; - -#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~FHMQV() {} -#endif -}; - -typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain FHMQV160; -typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain FHMQV256; -typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain FHMQV384; -typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain FHMQV512; - //! EC keys template struct DL_Keys_EC @@ -323,10 +283,10 @@ struct ECNR : public DL_SS, DL_Algorithm_ECNR, DL_SignatureMe }; //! Elliptic Curve Integrated Encryption Scheme, AKA ECIES -/*! Choose NoCofactorMultiplication and DHAES_MODE = false for compatibilty with SEC1 and Crypto++ 4.2. +/*! Default to (NoCofactorMultiplication and DHAES_MODE = false) for compatibilty with SEC1 and Crypto++ 4.2. The combination of (IncompatibleCofactorMultiplication and DHAES_MODE = true) is recommended for best efficiency and security. */ -template +template struct ECIES : public DL_ES< DL_Keys_EC, diff --git a/fhmqv.cpp b/fhmqv.cpp deleted file mode 100644 index e6403d49..00000000 --- a/fhmqv.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// fhmqv.cpp - written and placed in the public domain by Jeffrey Walton -// Shamelessly based upon Wei Dai's MQV source files - -#include "pch.h" -#include "fhmqv.h" - -NAMESPACE_BEGIN(CryptoPP) - -void TestInstantiations_FHMQV() -{ - FullyHashedMQV fhmqv; -} - -NAMESPACE_END diff --git a/fhmqv.h b/fhmqv.h deleted file mode 100644 index 8bec5405..00000000 --- a/fhmqv.h +++ /dev/null @@ -1,294 +0,0 @@ -// fhmqv.h - written and placed in the public domain by Jeffrey Walton -// Shamelessly based upon Wei Dai's MQV source files - -#ifndef CRYPTOPP_FHMQV_H -#define CRYPTOPP_FHMQV_H - -/** \file -*/ - -#include "gfpcrypt.h" -#include "algebra.h" -#include "sha.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation, -/*! A Secure and Efficient Authenticated Diffie–Hellman Protocol - Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. -*/ -template -class FHMQV_Domain: public AuthenticatedKeyAgreementDomain -{ -public: - typedef GROUP_PARAMETERS GroupParameters; - typedef typename GroupParameters::Element Element; - typedef FHMQV_Domain Domain; - - FHMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {} - - FHMQV_Domain(const GroupParameters ¶ms, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} - - FHMQV_Domain(BufferedTransformation &bt, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.BERDecode(bt);} - - template - FHMQV_Domain(T1 v1, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1);} - - template - FHMQV_Domain(T1 v1, T2 v2, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1, v2);} - - template - FHMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1, v2, v3);} - - template - FHMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1, v2, v3, v4);} - -protected: - - inline void Hash(const Element* sigma, - const byte* e1, size_t e1len, const byte* e2, size_t e2len, - const byte* s1, size_t s1len, const byte* s2, size_t s2len, - byte* digest, size_t dlen) const - { - HASH hash; - size_t idx = 0, req = dlen; - size_t blk = std::min(dlen, (size_t)HASH::DIGESTSIZE); - - if(sigma) - { - Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); - SecByteBlock sbb(x.MinEncodedSize()); - x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); - hash.Update(sbb.BytePtr(), sbb.SizeInBytes()); - } - - hash.Update(e1, e1len); - hash.Update(e2, e2len); - hash.Update(s1, s1len); - hash.Update(s2, s2len); - - hash.TruncatedFinal(digest, blk); - req -= blk; - - // All this to catch tail bytes for large curves and small hashes - while(req != 0) - { - hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE); - - idx += (size_t)HASH::DIGESTSIZE; - blk = std::min(req, (size_t)HASH::DIGESTSIZE); - hash.TruncatedFinal(&digest[idx], blk); - - req -= blk; - } - } - -public: - - const GroupParameters & GetGroupParameters() const {return m_groupParameters;} - GroupParameters & AccessGroupParameters(){return m_groupParameters;} - - CryptoParameters & AccessCryptoParameters(){return AccessAbstractGroupParameters();} - - //! return length of agreed value produced - unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} - //! return length of static private keys in this domain - unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} - //! return length of static public keys in this domain - unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);} - - //! generate static private key - /*! \pre size of privateKey == PrivateStaticKeyLength() */ - void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const - { - Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); - x.Encode(privateKey, StaticPrivateKeyLength()); - } - - //! generate static public key - /*! \pre size of publicKey == PublicStaticKeyLength() */ - void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const - { - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - Integer x(privateKey, StaticPrivateKeyLength()); - Element y = params.ExponentiateBase(x); - params.EncodeElement(true, y, publicKey); - } - - unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} - unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();} - - //! return length of ephemeral private keys in this domain - void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const - { - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - Integer x(rng, Integer::One(), params.GetMaxExponent()); - x.Encode(privateKey, StaticPrivateKeyLength()); - Element y = params.ExponentiateBase(x); - params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); - } - - //! return length of ephemeral public keys in this domain - void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const - { - memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); - } - - //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure - /*! \note The ephemeral public key will always be validated. - If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. - \pre size of agreedValue == AgreedValueLength() - \pre length of staticPrivateKey == StaticPrivateKeyLength() - \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() - \pre length of staticOtherPublicKey == StaticPublicKeyLength() - \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() - */ - bool Agree(byte *agreedValue, - const byte *staticPrivateKey, const byte *ephemeralPrivateKey, - const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, - bool validateStaticOtherPublicKey=true) const - { - byte *XX = NULL, *YY = NULL, *AA = NULL, *BB = NULL; - size_t xxs = 0, yys = 0, aas = 0, bbs = 0; - - // Depending on the role, this will hold either A's or B's static - // (long term) public key. AA or BB will then point into tt. - SecByteBlock tt(StaticPublicKeyLength()); - - try - { - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - - if(m_role == RoleServer) - { - Integer b(staticPrivateKey, StaticPrivateKeyLength()); - Element B = params.ExponentiateBase(b); - params.EncodeElement(true, B, tt); - - XX = const_cast(ephemeralOtherPublicKey); - xxs = EphemeralPublicKeyLength(); - YY = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); - yys = EphemeralPublicKeyLength(); - AA = const_cast(staticOtherPublicKey); - aas = StaticPublicKeyLength(); - BB = tt.BytePtr(); - bbs = tt.SizeInBytes(); - } - else if(m_role == RoleClient) - { - Integer a(staticPrivateKey, StaticPrivateKeyLength()); - Element A = params.ExponentiateBase(a); - params.EncodeElement(true, A, tt); - - XX = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); - xxs = EphemeralPublicKeyLength(); - YY = const_cast(ephemeralOtherPublicKey); - yys = EphemeralPublicKeyLength(); - AA = tt.BytePtr(); - aas = tt.SizeInBytes(); - BB = const_cast(staticOtherPublicKey); - bbs = StaticPublicKeyLength(); - } - else - { - assert(0); - return false; - } - - // DecodeElement calls ValidateElement at level 1. Level 1 only calls - // VerifyPoint to ensure the element is in G*. If the other's PublicKey is - // requested to be validated, we manually call ValidateElement at level 3. - Element VV1 = params.DecodeElement(staticOtherPublicKey, false); - if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULL)) - return false; - - // DecodeElement calls ValidateElement at level 1. Level 1 only calls - // VerifyPoint to ensure the element is in G*. Crank it up. - Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false); - if(!params.ValidateElement(3, VV2, NULL)) - return false; - - const Integer& p = params.GetGroupOrder(); - const Integer& q = params.GetSubgroupOrder(); - const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); - - Integer d, e; - SecByteBlock dd(len), ee(len); - - Hash(NULL, XX, xxs, YY, yys, AA, aas, BB, bbs, dd.BytePtr(), dd.SizeInBytes()); - d.Decode(dd.BytePtr(), dd.SizeInBytes()); - - Hash(NULL, YY, yys, XX, xxs, AA, aas, BB, bbs, ee.BytePtr(), ee.SizeInBytes()); - e.Decode(ee.BytePtr(), ee.SizeInBytes()); - - Element sigma; - if(m_role == RoleServer) - { - Integer y(ephemeralPrivateKey, StaticPrivateKeyLength()); - Integer b(staticPrivateKey, StaticPrivateKeyLength()); - Integer s_B = (y + e * b) % q; - - Element A = params.DecodeElement(AA, false); - Element X = params.DecodeElement(XX, false); - - Element t1 = params.ExponentiateElement(A, d); - Element t2 = m_groupParameters.MultiplyElements(X, t1); - - sigma = params.ExponentiateElement(t2, s_B); - } - else - { - Integer x(ephemeralPrivateKey, StaticPrivateKeyLength()); - Integer a(staticPrivateKey, StaticPrivateKeyLength()); - Integer s_A = (x + d * a) % q; - - Element B = params.DecodeElement(BB, false); - Element Y = params.DecodeElement(YY, false); - - Element t1 = params.ExponentiateElement(B, e); - Element t2 = m_groupParameters.MultiplyElements(Y, t1); - - sigma = params.ExponentiateElement(t2, s_A); - } - - Hash(&sigma, XX, xxs, YY, yys, AA, aas, BB, bbs, agreedValue, AgreedValueLength()); - } - catch (DL_BadElement &) - { - return false; - } - return true; - } - -private: - - // The paper uses Initiator and Recipient - make it classical. - enum KeyAgreementRole{ RoleServer = 1, RoleClient }; - - DL_GroupParameters & AccessAbstractGroupParameters() {return m_groupParameters;} - const DL_GroupParameters & GetAbstractGroupParameters() const{return m_groupParameters;} - - KeyAgreementRole m_role; - GroupParameters m_groupParameters; -}; - -//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation, -/*! A Secure and Efficient Authenticated Diffie–Hellman Protocol - Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. -*/ -typedef FHMQV_Domain FullyHashedMQV; - -NAMESPACE_END - -#endif diff --git a/hmqv.cpp b/hmqv.cpp deleted file mode 100644 index 86a8f97d..00000000 --- a/hmqv.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// hmqv.cpp - written and placed in the public domain by Uri Blumenthal -// Shamelessly based upon Jeffrey Walton's FHMQV and Wei Dai's MQV source files - -#include "pch.h" -#include "hmqv.h" - -NAMESPACE_BEGIN(CryptoPP) - -void TestInstantiations_HMQV() -{ - HashedMQV hmqv; -} - -NAMESPACE_END diff --git a/hmqv.h b/hmqv.h deleted file mode 100644 index 241d4c66..00000000 --- a/hmqv.h +++ /dev/null @@ -1,303 +0,0 @@ -// hmqv.h - written and placed in the public domain by Uri Blumenthal -// Shamelessly based upon Jeffrey Walton's FHMQV and Wei Dai's MQV source files - -#ifndef CRYPTOPP_HMQV_H -#define CRYPTOPP_HMQV_H - -/** \file -*/ - -#include "gfpcrypt.h" -#include "algebra.h" -#include "sha.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation, -/*! HMQV: A High-Performance Secure Diffie-Hellman Protocol - Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately. -*/ -template -class HMQV_Domain: public AuthenticatedKeyAgreementDomain -{ -public: - typedef GROUP_PARAMETERS GroupParameters; - typedef typename GroupParameters::Element Element; - typedef HMQV_Domain Domain; - - HMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {} - - HMQV_Domain(const GroupParameters ¶ms, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} - - HMQV_Domain(BufferedTransformation &bt, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.BERDecode(bt);} - - template - HMQV_Domain(T1 v1, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1);} - - template - HMQV_Domain(T1 v1, T2 v2, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1, v2);} - - template - HMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1, v2, v3);} - - template - HMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1, v2, v3, v4);} - -protected: - // Hash invocation by client and server differ only in what keys - // each provides. - - inline void Hash(const Element* sigma, - const byte* e1, size_t e1len, // Ephemeral key and key length - const byte* s1, size_t s1len, // Static key and key length - byte* digest, size_t dlen) const - { - HASH hash; - size_t idx = 0, req = dlen; - size_t blk = std::min(dlen, (size_t)HASH::DIGESTSIZE); - - if(sigma) - { - if (e1len != 0 || s1len != 0) { - assert(0); - } - Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); - SecByteBlock sbb(x.MinEncodedSize()); - x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); - hash.Update(sbb.BytePtr(), sbb.SizeInBytes()); - } else { - if (e1len == 0 || s1len == 0) { - assert(0); - } - hash.Update(e1, e1len); - hash.Update(s1, s1len); - } - - hash.TruncatedFinal(digest, blk); - req -= blk; - - // All this to catch tail bytes for large curves and small hashes - while(req != 0) - { - hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE); - - idx += (size_t)HASH::DIGESTSIZE; - blk = std::min(req, (size_t)HASH::DIGESTSIZE); - hash.TruncatedFinal(&digest[idx], blk); - - req -= blk; - } - } - -public: - - const GroupParameters & GetGroupParameters() const {return m_groupParameters;} - GroupParameters & AccessGroupParameters(){return m_groupParameters;} - - CryptoParameters & AccessCryptoParameters(){return AccessAbstractGroupParameters();} - - //! return length of agreed value produced - unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} - //! return length of static private keys in this domain - unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} - //! return length of static public keys in this domain - unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);} - - //! generate static private key - /*! \pre size of privateKey == PrivateStaticKeyLength() */ - void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const - { - Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); - x.Encode(privateKey, StaticPrivateKeyLength()); - } - - //! generate static public key - /*! \pre size of publicKey == PublicStaticKeyLength() */ - void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const - { - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - Integer x(privateKey, StaticPrivateKeyLength()); - Element y = params.ExponentiateBase(x); - params.EncodeElement(true, y, publicKey); - } - - unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} - unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();} - - //! return length of ephemeral private keys in this domain - void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const - { - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - Integer x(rng, Integer::One(), params.GetMaxExponent()); - x.Encode(privateKey, StaticPrivateKeyLength()); - Element y = params.ExponentiateBase(x); - params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); - } - - //! return length of ephemeral public keys in this domain - void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const - { - memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); - } - - //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure - /*! \note The ephemeral public key will always be validated. - If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. - \pre size of agreedValue == AgreedValueLength() - \pre length of staticPrivateKey == StaticPrivateKeyLength() - \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() - \pre length of staticOtherPublicKey == StaticPublicKeyLength() - \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() - */ - bool Agree(byte *agreedValue, - const byte *staticPrivateKey, const byte *ephemeralPrivateKey, - const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, - bool validateStaticOtherPublicKey=true) const - { - byte *XX = NULL, *YY = NULL, *AA = NULL, *BB = NULL; - size_t xxs = 0, yys = 0, aas = 0, bbs = 0; - - // Depending on the role, this will hold either A's or B's static - // (long term) public key. AA or BB will then point into tt. - SecByteBlock tt(StaticPublicKeyLength()); - - try - { - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - - if(m_role == RoleServer) - { - Integer b(staticPrivateKey, StaticPrivateKeyLength()); - Element B = params.ExponentiateBase(b); - params.EncodeElement(true, B, tt); - - XX = const_cast(ephemeralOtherPublicKey); - xxs = EphemeralPublicKeyLength(); - YY = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); - yys = EphemeralPublicKeyLength(); - AA = const_cast(staticOtherPublicKey); - aas = StaticPublicKeyLength(); - BB = tt.BytePtr(); - bbs = tt.SizeInBytes(); - } - else if(m_role == RoleClient) - { - Integer a(staticPrivateKey, StaticPrivateKeyLength()); - Element A = params.ExponentiateBase(a); - params.EncodeElement(true, A, tt); - - XX = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); - xxs = EphemeralPublicKeyLength(); - YY = const_cast(ephemeralOtherPublicKey); - yys = EphemeralPublicKeyLength(); - AA = tt.BytePtr(); - aas = tt.SizeInBytes(); - BB = const_cast(staticOtherPublicKey); - bbs = StaticPublicKeyLength(); - } - else - { - assert(0); - return false; - } - - // DecodeElement calls ValidateElement at level 1. Level 1 only calls - // VerifyPoint to ensure the element is in G*. If the other's PublicKey is - // requested to be validated, we manually call ValidateElement at level 3. - Element VV1 = params.DecodeElement(staticOtherPublicKey, false); - if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULL)) - return false; - - // DecodeElement calls ValidateElement at level 1. Level 1 only calls - // VerifyPoint to ensure the element is in G*. Crank it up. - Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false); - if(!params.ValidateElement(3, VV2, NULL)) - return false; - -// const Integer& p = params.GetGroupOrder(); // not used, remove later - const Integer& q = params.GetSubgroupOrder(); - const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); - - Integer d, e; - SecByteBlock dd(len), ee(len); - - // Compute $d = \hat{H}(X, \hat{B})$ - Hash(NULL, XX, xxs, BB, bbs, dd.BytePtr(), dd.SizeInBytes()); - d.Decode(dd.BytePtr(), dd.SizeInBytes()); - - // Compute $e = \hat{H}(Y, \hat{A})$ - Hash(NULL, YY, yys, AA, aas, ee.BytePtr(), ee.SizeInBytes()); - e.Decode(ee.BytePtr(), ee.SizeInBytes()); - - Element sigma; - if(m_role == RoleServer) - { - Integer y(ephemeralPrivateKey, StaticPrivateKeyLength()); - Integer b(staticPrivateKey, StaticPrivateKeyLength()); - Integer s_B = (y + e * b) % q; - - Element A = params.DecodeElement(AA, false); - Element X = params.DecodeElement(XX, false); - - Element t1 = params.ExponentiateElement(A, d); - Element t2 = m_groupParameters.MultiplyElements(X, t1); - - // $\sigma_B}=(X \cdot A^{d})^{s_B} - sigma = params.ExponentiateElement(t2, s_B); - } - else - { - Integer x(ephemeralPrivateKey, StaticPrivateKeyLength()); - Integer a(staticPrivateKey, StaticPrivateKeyLength()); - Integer s_A = (x + d * a) % q; - - Element B = params.DecodeElement(BB, false); - Element Y = params.DecodeElement(YY, false); - - Element t1 = params.ExponentiateElement(B, e); - Element t2 = m_groupParameters.MultiplyElements(Y, t1); - - // $\sigma_A}=(Y \cdot B^{e})^{s_A} - sigma = params.ExponentiateElement(t2, s_A); - } - Hash(&sigma, NULL, 0, NULL, 0, agreedValue, AgreedValueLength()); - } - catch (DL_BadElement &) - { - return false; - } - return true; - } - -private: - - // The paper uses Initiator and Recipient - make it classical. - enum KeyAgreementRole{ RoleServer = 1, RoleClient }; - - DL_GroupParameters & AccessAbstractGroupParameters() {return m_groupParameters;} - const DL_GroupParameters & GetAbstractGroupParameters() const{return m_groupParameters;} - - KeyAgreementRole m_role; - GroupParameters m_groupParameters; -}; - -//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation, -/*! HMQV: A High-Performance Secure Diffie-Hellman Protocol - Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately. -*/ -typedef HMQV_Domain HashedMQV; - -NAMESPACE_END - -#endif diff --git a/validat1.cpp b/validat1.cpp index 55c74e33..a6115e5e 100644 --- a/validat1.cpp +++ b/validat1.cpp @@ -149,8 +149,6 @@ bool ValidateAll(bool thorough) pass=ValidateBBS() && pass; pass=ValidateDH() && pass; pass=ValidateMQV() && pass; - pass=ValidateHMQV() && pass; - pass=ValidateFHMQV() && pass; pass=ValidateRSA() && pass; pass=ValidateElGamal() && pass; pass=ValidateDLIES() && pass; diff --git a/validat2.cpp b/validat2.cpp index ec553a28..32885985 100644 --- a/validat2.cpp +++ b/validat2.cpp @@ -18,8 +18,6 @@ #include "dsa.h" #include "dh.h" #include "mqv.h" -#include "hmqv.h" -#include "fhmqv.h" #include "luc.h" #include "xtrcrypt.h" #include "rabin.h" @@ -386,240 +384,6 @@ bool ValidateMQV() return AuthenticatedKeyAgreementValidate(mqv); } -bool ValidateHMQV() -{ - std::cout << "\nHMQV validation suite running...\n\n"; - - //HMQV< ECP >::Domain hmqvB(false /*server*/); - HMQV256 hmqvB(false); - FileSource f256("TestData/hmqv256.dat", true, new HexDecoder()); - FileSource f384("TestData/hmqv384.dat", true, new HexDecoder()); - FileSource f512("TestData/hmqv512.dat", true, new HexDecoder()); - hmqvB.AccessGroupParameters().BERDecode(f256); - - std::cout << "HMQV with NIST P-256 and SHA-256:" << std::endl; - - if (hmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; - return false; - } - - const OID oid = ASN1::secp256r1(); - HMQV< ECP >::Domain hmqvA(oid, true /*client*/); - - if (hmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; - return false; - } - - SecByteBlock sprivA(hmqvA.StaticPrivateKeyLength()), sprivB(hmqvB.StaticPrivateKeyLength()); - SecByteBlock eprivA(hmqvA.EphemeralPrivateKeyLength()), eprivB(hmqvB.EphemeralPrivateKeyLength()); - SecByteBlock spubA(hmqvA.StaticPublicKeyLength()), spubB(hmqvB.StaticPublicKeyLength()); - SecByteBlock epubA(hmqvA.EphemeralPublicKeyLength()), epubB(hmqvB.EphemeralPublicKeyLength()); - SecByteBlock valA(hmqvA.AgreedValueLength()), valB(hmqvB.AgreedValueLength()); - - hmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA); - hmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB); - hmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA); - hmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB); - - memset(valA.begin(), 0x00, valA.size()); - memset(valB.begin(), 0x11, valB.size()); - - if (!(hmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && hmqvB.Agree(valB, sprivB, eprivB, spubA, epubA))) - { - std::cout << "FAILED authenticated key agreement failed" << std::endl; - return false; - } - - if (memcmp(valA.begin(), valB.begin(), hmqvA.AgreedValueLength())) - { - std::cout << "FAILED authenticated agreed values not equal" << std::endl; - return false; - } - - std::cout << "passed authenticated key agreement" << std::endl; - - // Now test HMQV with NIST P-384 curve and SHA384 hash - std::cout << endl; - std::cout << "HMQV with NIST P-384 and SHA-384:" << std::endl; - - HMQV384 hmqvB384(false); - hmqvB384.AccessGroupParameters().BERDecode(f384); - - if (hmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; - return false; - } - - const OID oid384 = ASN1::secp384r1(); - HMQV384 hmqvA384(oid384, true /*client*/); - - if (hmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; - return false; - } - - SecByteBlock sprivA384(hmqvA384.StaticPrivateKeyLength()), sprivB384(hmqvB384.StaticPrivateKeyLength()); - SecByteBlock eprivA384(hmqvA384.EphemeralPrivateKeyLength()), eprivB384(hmqvB384.EphemeralPrivateKeyLength()); - SecByteBlock spubA384(hmqvA384.StaticPublicKeyLength()), spubB384(hmqvB384.StaticPublicKeyLength()); - SecByteBlock epubA384(hmqvA384.EphemeralPublicKeyLength()), epubB384(hmqvB384.EphemeralPublicKeyLength()); - SecByteBlock valA384(hmqvA384.AgreedValueLength()), valB384(hmqvB384.AgreedValueLength()); - - hmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384); - hmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384); - hmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384); - hmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384); - - memset(valA384.begin(), 0x00, valA384.size()); - memset(valB384.begin(), 0x11, valB384.size()); - - if (!(hmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && hmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384))) - { - std::cout << "FAILED authenticated key agreement failed" << std::endl; - return false; - } - - if (memcmp(valA384.begin(), valB384.begin(), hmqvA384.AgreedValueLength())) - { - std::cout << "FAILED authenticated agreed values not equal" << std::endl; - return false; - } - - std::cout << "passed authenticated key agreement" << std::endl; - - return true; -} - -bool ValidateFHMQV() -{ - std::cout << "\nFHMQV validation suite running...\n\n"; - - //FHMQV< ECP >::Domain fhmqvB(false /*server*/); - FHMQV256 fhmqvB(false); - FileSource f256("TestData/fhmqv256.dat", true, new HexDecoder()); - FileSource f384("TestData/fhmqv384.dat", true, new HexDecoder()); - FileSource f512("TestData/fhmqv512.dat", true, new HexDecoder()); - fhmqvB.AccessGroupParameters().BERDecode(f256); - - std::cout << "FHMQV with NIST P-256 and SHA-256:" << std::endl; - - if (fhmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; - return false; - } - - const OID oid = ASN1::secp256r1(); - FHMQV< ECP >::Domain fhmqvA(oid, true /*client*/); - - if (fhmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; - return false; - } - - SecByteBlock sprivA(fhmqvA.StaticPrivateKeyLength()), sprivB(fhmqvB.StaticPrivateKeyLength()); - SecByteBlock eprivA(fhmqvA.EphemeralPrivateKeyLength()), eprivB(fhmqvB.EphemeralPrivateKeyLength()); - SecByteBlock spubA(fhmqvA.StaticPublicKeyLength()), spubB(fhmqvB.StaticPublicKeyLength()); - SecByteBlock epubA(fhmqvA.EphemeralPublicKeyLength()), epubB(fhmqvB.EphemeralPublicKeyLength()); - SecByteBlock valA(fhmqvA.AgreedValueLength()), valB(fhmqvB.AgreedValueLength()); - - fhmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA); - fhmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB); - fhmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA); - fhmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB); - - memset(valA.begin(), 0x00, valA.size()); - memset(valB.begin(), 0x11, valB.size()); - - if (!(fhmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && fhmqvB.Agree(valB, sprivB, eprivB, spubA, epubA))) - { - std::cout << "FAILED authenticated key agreement failed" << std::endl; - return false; - } - - if (memcmp(valA.begin(), valB.begin(), fhmqvA.AgreedValueLength())) - { - std::cout << "FAILED authenticated agreed values not equal" << std::endl; - return false; - } - - std::cout << "passed authenticated key agreement" << std::endl; - - // Now test FHMQV with NIST P-384 curve and SHA384 hash - std::cout << endl; - std::cout << "FHMQV with NIST P-384 and SHA-384:" << std::endl; - - FHMQV384 fhmqvB384(false); - fhmqvB384.AccessGroupParameters().BERDecode(f384); - - if (fhmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; - return false; - } - - const OID oid384 = ASN1::secp384r1(); - FHMQV384 fhmqvA384(oid384, true /*client*/); - - if (fhmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; - return false; - } - - SecByteBlock sprivA384(fhmqvA384.StaticPrivateKeyLength()), sprivB384(fhmqvB384.StaticPrivateKeyLength()); - SecByteBlock eprivA384(fhmqvA384.EphemeralPrivateKeyLength()), eprivB384(fhmqvB384.EphemeralPrivateKeyLength()); - SecByteBlock spubA384(fhmqvA384.StaticPublicKeyLength()), spubB384(fhmqvB384.StaticPublicKeyLength()); - SecByteBlock epubA384(fhmqvA384.EphemeralPublicKeyLength()), epubB384(fhmqvB384.EphemeralPublicKeyLength()); - SecByteBlock valA384(fhmqvA384.AgreedValueLength()), valB384(fhmqvB384.AgreedValueLength()); - - fhmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384); - fhmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384); - fhmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384); - fhmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384); - - memset(valA384.begin(), 0x00, valA384.size()); - memset(valB384.begin(), 0x11, valB384.size()); - - if (!(fhmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && fhmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384))) - { - std::cout << "FAILED authenticated key agreement failed" << std::endl; - return false; - } - - if (memcmp(valA384.begin(), valB384.begin(), fhmqvA384.AgreedValueLength())) - { - std::cout << "FAILED authenticated agreed values not equal" << std::endl; - return false; - } - - std::cout << "passed authenticated key agreement" << std::endl; - - return true; -} - bool ValidateLUC_DH() { cout << "\nLUC-DH validation suite running...\n\n"; diff --git a/validate.h b/validate.h index 0a388308..6c0c4793 100644 --- a/validate.h +++ b/validate.h @@ -71,8 +71,6 @@ bool ValidateCMAC(); bool ValidateBBS(); bool ValidateDH(); bool ValidateMQV(); -bool ValidateHMQV(); -bool ValidateFHMQV(); bool ValidateRSA(); bool ValidateElGamal(); bool ValidateDLIES(); From 9ed99eabb9abb3b3665e93da7e98b0f819d18c37 Mon Sep 17 00:00:00 2001 From: Mouse Date: Wed, 6 Jul 2016 12:19:44 -0400 Subject: [PATCH 19/22] Restore PR #217 Restore merge of PR #217 --- misc.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/misc.h b/misc.h index 63ed4e29..9566293f 100644 --- a/misc.h +++ b/misc.h @@ -63,9 +63,15 @@ #if defined(__GNUC__) && defined(__BMI__) # include # if defined(__clang__) +#ifndef _tzcnt_u32 # define _tzcnt_u32(x) __tzcnt_u32(x) +#endif +#ifndef _tzcnt_u64 # define _tzcnt_u64(x) __tzcnt_u64(x) +#endif +#ifndef _blsr_u32 # define _blsr_u32(x) __blsr_u32(x) +#endif #ifndef _blsr_u64 # define _blsr_u64(x) __blsr_u64(x) # endif From 6c0b120072563ca77c6a3aec4c6c6f143cb984f9 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Wed, 6 Jul 2016 14:39:18 -0400 Subject: [PATCH 20/22] Go back to Commit 66ada4cc61d62afc --- GNUmakefile | 7 +- blake2.cpp | 2 +- config.h | 16 ++- config.recommend | 14 +- cpu.cpp | 2 +- cpu.h | 75 ++++++++-- cryptest.sh | 368 ++++++++++++++++++++++++++++++++++++++++++++++- default.h | 12 +- eccrypto.h | 24 ++-- gcm.cpp | 14 +- misc.h | 17 +-- panama.h | 4 +- rdrand.cpp | 4 +- rijndael.h | 2 +- sha.h | 2 +- socketft.cpp | 6 + wait.h | 11 ++ 17 files changed, 510 insertions(+), 70 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index f1db629b..12b1542c 100755 --- a/GNUmakefile +++ b/GNUmakefile @@ -30,9 +30,9 @@ IS_DARWIN := $(shell $(CXX) -dumpmachine 2>&1 | $(EGREP) -i -c "Darwin") IS_NETBSD := $(shell $(CXX) -dumpmachine 2>&1 | $(EGREP) -i -c "NetBSD") SUN_COMPILER := $(shell $(CXX) -V 2>&1 | $(EGREP) -i -c "CC: Sun") -GCC_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "(gcc|g\+\+)") +GCC_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -v "clang" | $(EGREP) -i -c "(gcc|g\+\+)") CLANG_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "clang") -INTEL_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -c "\(ICC\)") +INTEL_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "\(icc\)") MACPORTS_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "macports") # Sun Studio 12.0 (0x0510) and 12.3 (0x0512) @@ -179,6 +179,9 @@ ifeq ($(GCC_COMPILER)$(MACPORTS_COMPILER),11) ifneq ($(findstring -Wa,-q,$(CXXFLAGS)),-Wa,-q) CXXFLAGS += -Wa,-q endif +ifneq ($(findstring -Wa,-q,$(CXXFLAGS)),-DCRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) +CXXFLAGS += -DCRYPTOPP_CLANG_INTEGRATED_ASSEMBLER=1 +endif endif # Allow use of "/" operator for GNU Assembler. diff --git a/blake2.cpp b/blake2.cpp index 77eef8ce..0cb858b1 100644 --- a/blake2.cpp +++ b/blake2.cpp @@ -35,7 +35,7 @@ NAMESPACE_BEGIN(CryptoPP) // Apple Clang 6.0/Clang 3.5 does not have SSSE3 intrinsics // http://llvm.org/bugs/show_bug.cgi?id=20213 -#if (defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION <= 60000)) || (defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION <= 30500)) +#if (defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION <= 60000)) || (defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION <= 30500)) # undef CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE #endif diff --git a/config.h b/config.h index 7ac17fda..9a40f2ba 100644 --- a/config.h +++ b/config.h @@ -63,7 +63,9 @@ // Define this to choose the FIPS 202 version of SHA3, and not the original version of SHA3. NIST selected Keccak as SHA3 // in January 2013. SHA3 was finalized in FIPS 202 in August 2015, and it was a modified version of the original selection. // If CRYPTOPP_USE_FIPS_202_SHA3 is defined, then sha3_fips_202.txt test vectors will be used instead of sha3.txt. -// #define CRYPTOPP_USE_FIPS_202_SHA3 +// #ifndef CRYPTOPP_USE_FIPS_202_SHA3 +// # define CRYPTOPP_USE_FIPS_202_SHA3 +// #endif // ***************** Less Important Settings *************** @@ -236,9 +238,11 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); // Apple and LLVM's Clang. Apple Clang version 7.0 roughly equals LLVM Clang version 3.7 #if defined(__clang__ ) && !defined(__apple_build_version__) - #define CRYPTOPP_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) + #define CRYPTOPP_LLVM_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) + #define CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER 1 #elif defined(__clang__ ) && defined(__apple_build_version__) #define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) + #define CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER 1 #endif #ifdef _MSC_VER @@ -246,13 +250,13 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); #endif // Need GCC 4.6/Clang 1.7/Apple Clang 2.0 or above due to "GCC diagnostic {push|pop}" -#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000) +#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_LLVM_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000) #define CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 1 #endif // Clang due to "Inline assembly operands don't work with .intel_syntax", http://llvm.org/bugs/show_bug.cgi?id=24232 // TODO: supply the upper version when LLVM fixes it. We set it to 20.0 for compilation purposes. -#if (defined(CRYPTOPP_CLANG_VERSION) && CRYPTOPP_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) +#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && CRYPTOPP_LLVM_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) #define CRYPTOPP_DISABLE_INTEL_ASM 1 #endif @@ -726,7 +730,7 @@ NAMESPACE_END // ************** Deprecated *************** -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) # define CRYPTOPP_DEPRECATED(msg) __attribute__((deprecated (msg))); #elif (CRYPTOPP_GCC_VERSION) # define CRYPTOPP_DEPRECATED(msg) __attribute__((deprecated)); @@ -779,7 +783,7 @@ NAMESPACE_END # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 #elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1200) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 -#elif (CRYPTOPP_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) +#elif (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 #elif (CRYPTOPP_GCC_VERSION >= 40400) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 diff --git a/config.recommend b/config.recommend index c9064240..15b7e781 100644 --- a/config.recommend +++ b/config.recommend @@ -63,7 +63,9 @@ // Define this to choose the FIPS 202 version of SHA3, and not the original version of SHA3. NIST selected Keccak as SHA3 // in January 2013. SHA3 was finalized in FIPS 202 in August 2015, and it was a modified version of the original selection. // If CRYPTOPP_USE_FIPS_202_SHA3 is defined, then sha3_fips_202.txt test vectors will be used instead of sha3.txt. -#define CRYPTOPP_USE_FIPS_202_SHA3 +#ifndef CRYPTOPP_USE_FIPS_202_SHA3 +# define CRYPTOPP_USE_FIPS_202_SHA3 +#endif // ***************** Less Important Settings *************** @@ -236,7 +238,7 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); // Apple and LLVM's Clang. Apple Clang version 7.0 roughly equals LLVM Clang version 3.7 #if defined(__clang__ ) && !defined(__apple_build_version__) - #define CRYPTOPP_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) + #define CRYPTOPP_LLVM_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) #elif defined(__clang__ ) && defined(__apple_build_version__) #define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) #endif @@ -246,13 +248,13 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); #endif // Need GCC 4.6/Clang 1.7/Apple Clang 2.0 or above due to "GCC diagnostic {push|pop}" -#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000) +#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_LLVM_CLANG_VERSION >= 10700) || (CRYPTOPP_APPLE_CLANG_VERSION >= 20000) #define CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 1 #endif // Clang due to "Inline assembly operands don't work with .intel_syntax", http://llvm.org/bugs/show_bug.cgi?id=24232 // TODO: supply the upper version when LLVM fixes it. We set it to 20.0 for compilation purposes. -#if (defined(CRYPTOPP_CLANG_VERSION) && CRYPTOPP_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) +#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && CRYPTOPP_LLVM_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) #define CRYPTOPP_DISABLE_INTEL_ASM 1 #endif @@ -724,7 +726,7 @@ NAMESPACE_END // ************** Deprecated *************** -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) # define CRYPTOPP_DEPRECATED(msg) __attribute__((deprecated (msg))); #elif (CRYPTOPP_GCC_VERSION) # define CRYPTOPP_DEPRECATED(msg) __attribute__((deprecated)); @@ -777,7 +779,7 @@ NAMESPACE_END # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 #elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1200) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 -#elif (CRYPTOPP_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) +#elif (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 #elif (CRYPTOPP_GCC_VERSION >= 40400) # define CRYPTOPP_CXX11_SYNCHRONIZATION 1 diff --git a/cpu.cpp b/cpu.cpp index 7c39cccd..b13dd255 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -27,7 +27,7 @@ NAMESPACE_BEGIN(CryptoPP) #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY // MacPorts/GCC does not provide constructor(priority). Apple/GCC and Fink/GCC do provide it. -#define HAVE_GCC_CONSTRUCTOR1 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 300)) && !(MACPORTS_GCC_COMPILER > 0)) +#define HAVE_GCC_CONSTRUCTOR1 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 300)) && !(MACPORTS_GCC_COMPILER > 0)) #define HAVE_GCC_CONSTRUCTOR0 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && !(MACPORTS_GCC_COMPILER > 0)) extern "C" { diff --git a/cpu.h b/cpu.h index 890f53db..b1414a91 100644 --- a/cpu.h +++ b/cpu.h @@ -2,9 +2,7 @@ //! \file cpu.h //! \brief Functions for CPU features and intrinsics -//! \details At the moment, the functions are used heavily in X86/X32/X64 code paths -// for SSE, SSE2 and SSE4. The funtions are also used on occassion for AArch32 -//! and AArch64 code paths for NEON. +//! \details The functions are used in X86/X32/X64 and NEON code paths #ifndef CRYPTOPP_CPU_H #define CRYPTOPP_CPU_H @@ -52,7 +50,7 @@ #endif // PUSHFB needs Clang 3.3 and Apple Clang 5.0. -#if !defined(__GNUC__) || defined(__SSSE3__)|| defined(__INTEL_COMPILER) || (CRYPTOPP_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) +#if !defined(__GNUC__) || defined(__SSSE3__)|| defined(__INTEL_COMPILER) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) #include #else NAMESPACE_BEGIN(CryptoPP) @@ -66,7 +64,7 @@ NAMESPACE_END #endif // tmmintrin.h // PEXTRD needs Clang 3.3 and Apple Clang 5.0. -#if !defined(__GNUC__) || defined(__SSE4_1__)|| defined(__INTEL_COMPILER) || (CRYPTOPP_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) +#if !defined(__GNUC__) || defined(__SSE4_1__)|| defined(__INTEL_COMPILER) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) #include #else NAMESPACE_BEGIN(CryptoPP) @@ -87,7 +85,7 @@ NAMESPACE_END #endif // smmintrin.h // AES needs Clang 2.8 and Apple Clang 4.6. PCLMUL needs Clang 3.4 and Apple Clang 6.0 -#if !defined(__GNUC__) || (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || (CRYPTOPP_CLANG_VERSION >= 30400) || (CRYPTOPP_APPLE_CLANG_VERSION >= 60000) +#if !defined(__GNUC__) || (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30400) || (CRYPTOPP_APPLE_CLANG_VERSION >= 60000) #include #else NAMESPACE_BEGIN(CryptoPP) @@ -141,11 +139,13 @@ NAMESPACE_END NAMESPACE_BEGIN(CryptoPP) -#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 || CRYPTOPP_DOXYGEN_PROCESSING #define CRYPTOPP_CPUID_AVAILABLE -// these should not be used directly +// Hide from Doxygen +#ifndef CRYPTOPP_DOXYGEN_PROCESSING +// These should not be used directly extern CRYPTOPP_DLL bool g_x86DetectionDone; extern CRYPTOPP_DLL bool g_hasMMX; extern CRYPTOPP_DLL bool g_hasISSE; @@ -166,7 +166,12 @@ extern CRYPTOPP_DLL word32 g_cacheLineSize; CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features(); CRYPTOPP_DLL bool CRYPTOPP_API CpuId(word32 input, word32 output[4]); +#endif // CRYPTOPP_DOXYGEN_PROCESSING +//! \brief Determines MMX availability +//! \returns true if MMX is determined to be available, false otherwise +//! \details MMX, SSE and SSE2 are core processor features for x86_64, and +//! the function always returns true for the platform. inline bool HasMMX() { #if CRYPTOPP_BOOL_X64 @@ -178,6 +183,10 @@ inline bool HasMMX() #endif } +//! \brief Determines SSE availability +//! \returns true if SSE is determined to be available, false otherwise +//! \details MMX, SSE and SSE2 are core processor features for x86_64, and +//! the function always returns true for the platform. inline bool HasISSE() { #if CRYPTOPP_BOOL_X64 @@ -189,6 +198,10 @@ inline bool HasISSE() #endif } +//! \brief Determines SSE2 availability +//! \returns true if SSE2 is determined to be available, false otherwise +//! \details MMX, SSE and SSE2 are core processor features for x86_64, and +//! the function always returns true for the platform. inline bool HasSSE2() { #if CRYPTOPP_BOOL_X64 @@ -200,6 +213,10 @@ inline bool HasSSE2() #endif } +//! \brief Determines SSSE3 availability +//! \returns true if SSSE3 is determined to be available, false otherwise +//! \details HasSSSE3() is a runtime check performed using CPUID +//! \note Some Clang compilers incorrectly omit SSSE3 even though its native to the processor. inline bool HasSSSE3() { if (!g_x86DetectionDone) @@ -207,6 +224,9 @@ inline bool HasSSSE3() return g_hasSSSE3; } +//! \brief Determines SSE4 availability +//! \returns true if SSE4.1 and SSE4.2 are determined to be available, false otherwise +//! \details HasSSE4() is a runtime check performed using CPUID which requires both SSE4.1 and SSE4.2 inline bool HasSSE4() { if (!g_x86DetectionDone) @@ -214,6 +234,9 @@ inline bool HasSSE4() return g_hasSSE4; } +//! \brief Determines AES-NI availability +//! \returns true if AES-NI is determined to be available, false otherwise +//! \details HasAESNI() is a runtime check performed using CPUID inline bool HasAESNI() { if (!g_x86DetectionDone) @@ -221,6 +244,9 @@ inline bool HasAESNI() return g_hasAESNI; } +//! \brief Determines Carryless Multiply availability +//! \returns true if pclmulqdq is determined to be available, false otherwise +//! \details HasCLMUL() is a runtime check performed using CPUID inline bool HasCLMUL() { if (!g_x86DetectionDone) @@ -228,6 +254,9 @@ inline bool HasCLMUL() return g_hasCLMUL; } +//! \brief Determines if the CPU is an Intel P4 +//! \returns true if the CPU is a P4, false otherwise +//! \details IsP4() is a runtime check performed using CPUID inline bool IsP4() { if (!g_x86DetectionDone) @@ -235,6 +264,9 @@ inline bool IsP4() return g_isP4; } +//! \brief Determines RDRAND availability +//! \returns true if RDRAND is determined to be available, false otherwise +//! \details HasRDRAND() is a runtime check performed using CPUID inline bool HasRDRAND() { if (!g_x86DetectionDone) @@ -242,6 +274,9 @@ inline bool HasRDRAND() return g_hasRDRAND; } +//! \brief Determines RDSEED availability +//! \returns true if RDSEED is determined to be available, false otherwise +//! \details HasRDSEED() is a runtime check performed using CPUID inline bool HasRDSEED() { if (!g_x86DetectionDone) @@ -249,6 +284,9 @@ inline bool HasRDSEED() return g_hasRDSEED; } +//! \brief Determines Padlock RNG availability +//! \returns true if VIA Padlock RNG is determined to be available, false otherwise +//! \details HasPadlockRNG() is a runtime check performed using CPUID inline bool HasPadlockRNG() { if (!g_x86DetectionDone) @@ -256,6 +294,9 @@ inline bool HasPadlockRNG() return g_hasPadlockRNG; } +//! \brief Determines Padlock ACE availability +//! \returns true if VIA Padlock ACE is determined to be available, false otherwise +//! \details HasPadlockACE() is a runtime check performed using CPUID inline bool HasPadlockACE() { if (!g_x86DetectionDone) @@ -263,6 +304,9 @@ inline bool HasPadlockACE() return g_hasPadlockACE; } +//! \brief Determines Padlock ACE2 availability +//! \returns true if VIA Padlock ACE2 is determined to be available, false otherwise +//! \details HasPadlockACE2() is a runtime check performed using CPUID inline bool HasPadlockACE2() { if (!g_x86DetectionDone) @@ -270,6 +314,9 @@ inline bool HasPadlockACE2() return g_hasPadlockACE2; } +//! \brief Determines Padlock PHE availability +//! \returns true if VIA Padlock PHE is determined to be available, false otherwise +//! \details HasPadlockPHE() is a runtime check performed using CPUID inline bool HasPadlockPHE() { if (!g_x86DetectionDone) @@ -277,6 +324,9 @@ inline bool HasPadlockPHE() return g_hasPadlockPHE; } +//! \brief Determines Padlock PMM availability +//! \returns true if VIA Padlock PMM is determined to be available, false otherwise +//! \details HasPadlockPMM() is a runtime check performed using CPUID inline bool HasPadlockPMM() { if (!g_x86DetectionDone) @@ -284,6 +334,13 @@ inline bool HasPadlockPMM() return g_hasPadlockPMM; } +//! \brief Provides the cache line size +//! \returns lower bound on the size of a cache line in bytes, if available +//! \details GetCacheLineSize() returns the lower bound on the size of a cache line, if it +//! is available. If the value is not available at runtime, then 32 is returned for a 32-bit +//! processor and 64 is returned for a 64-bit processor. +//! \details x86/x32/x64 uses CPUID to determine the value and its usually accurate. The ARM +//! processor equivalent is a privileged instruction, so a compile time value is returned. inline int GetCacheLineSize() { if (!g_x86DetectionDone) @@ -415,7 +472,7 @@ inline int GetCacheLineSize() #else #define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY -#if defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION) +#if defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) #define NEW_LINE "\n" #define INTEL_PREFIX ".intel_syntax;" #define INTEL_NOPREFIX ".intel_syntax;" diff --git a/cryptest.sh b/cryptest.sh index 5e26aebf..d177cd1e 100755 --- a/cryptest.sh +++ b/cryptest.sh @@ -128,6 +128,8 @@ fi SUN_COMPILER=$("$CXX" -V 2>&1 | "$EGREP" -i -c "CC: Sun") GCC_COMPILER=$("$CXX" --version 2>&1 | "$EGREP" -i -c "(gcc|g\+\+)") +INTEL_COMPILER=$("$CXX" --version 2>&1 | "$EGREP" -i -c "\(ICC\)") +MACPORTS_COMPILER=$("$CXX" --version 2>&1 | "$EGREP" -i -c "MacPorts") CLANG_COMPILER=$("$CXX" --version 2>&1 | "$EGREP" -i -c "clang") if [[ ($("$CXX" -dM -E - /dev/null | "$EGREP" -c '(__x64_64__|__amd64__)') -ne "0") && ($("$CXX" -dM -E -/dev/null | "$EGREP" -c '(__ILP32|__ILP32)') -ne "0") ]]; then @@ -135,7 +137,9 @@ if [[ ($("$CXX" -dM -E - /dev/null | "$EGREP" -c '(__x64_64__|__amd fi # Now that the compiler is fixed, see if its GCC 5.1 or above with -Wabi, -Wabi-tag and -Wodr +GCC_60_OR_ABOVE=$("$CXX" -v 2>&1 | "$EGREP" -i -c 'gcc version (6\.[0-9]|[7-9])') GCC_51_OR_ABOVE=$("$CXX" -v 2>&1 | "$EGREP" -i -c 'gcc version (5\.[1-9]|[6-9])') +GCC_48_COMPILER=$("$CXX" -v 2>&1 | "$EGREP" -i -c 'gcc version 4\.8') # SunCC 12.2 and below needs one set of CXXFLAGS; SunCC 12.3 and above needs another set of CXXFLAGS SUNCC_123_OR_ABOVE=$("$CXX" -E -xdumpmacros /dev/null 2>&1 | "$GREP" " __SUNPRO_CC " 2>/dev/null | "$AWK" '{print ($2 >= 0x5120) ? "1" : "0"}' ) @@ -172,6 +176,14 @@ if [[ (-z "$HAVE_CXX17") ]]; then fi fi +if [[ (-z "$HAVE_GNU17") ]]; then + HAVE_GNU17=0 + "$CXX" -DCRYPTOPP_ADHOC_MAIN -std=gnu++17 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1 + if [[ "$?" -eq "0" ]]; then + HAVE_GNU17=1 + fi +fi + # Hit or miss, mostly miss. if [[ (-z "$HAVE_CXX14") ]]; then HAVE_CXX14=0 @@ -181,6 +193,14 @@ if [[ (-z "$HAVE_CXX14") ]]; then fi fi +if [[ (-z "$HAVE_GNU14") ]]; then + HAVE_GNU14=0 + "$CXX" -DCRYPTOPP_ADHOC_MAIN -std=gnu++14 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1 + if [[ "$?" -eq "0" ]]; then + HAVE_GNU14=1 + fi +fi + # Hit or miss, mostly hit. if [[ (-z "$HAVE_CXX11") ]]; then HAVE_CXX11=0 @@ -190,6 +210,14 @@ if [[ (-z "$HAVE_CXX11") ]]; then fi fi +if [[ (-z "$HAVE_GNU11") ]]; then + HAVE_GNU11=0 + "$CXX" -DCRYPTOPP_ADHOC_MAIN -std=gnu++11 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1 + if [[ "$?" -eq "0" ]]; then + HAVE_GNU11=1 + fi +fi + # OpenBSD 5.7 and OS X 10.5 cannot consume -std=c++03 if [[ (-z "$HAVE_CXX03") ]]; then HAVE_CXX03=0 @@ -199,6 +227,14 @@ if [[ (-z "$HAVE_CXX03") ]]; then fi fi +if [[ (-z "$HAVE_GNU03") ]]; then + HAVE_GNU03=0 + "$CXX" -DCRYPTOPP_ADHOC_MAIN -std=gnu++03 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1 + if [[ "$?" -eq "0" ]]; then + HAVE_GNU03=1 + fi +fi + HAVE_O3=0 OPT_O3= "$CXX" -DCRYPTOPP_ADHOC_MAIN -O3 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1 @@ -265,6 +301,11 @@ if [[ (-z "$HAVE_ASAN") ]]; then fi fi +# Fixup; see http://github.com/weidai11/cryptopp/issues/212 +if [[ ("$GCC_48_COMPILER" -ne "0" && "$IS_ARM32" -ne "0") ]]; then + HAVE_ASAN=0 +fi + # Darwin and Intel multiarch if [[ (-z "$HAVE_INTEL_MULTIARCH") ]]; then HAVE_INTEL_MULTIARCH=0 @@ -428,6 +469,9 @@ elif [[ "$IS_DARWIN" -ne "0" ]]; then echo "IS_DARWIN: $IS_DARWIN" | tee -a "$TEST_RESULTS" fi +if [[ "$IS_PPC" -ne "0" ]]; then + echo "IS_PPC: $IS_PPC" | tee -a "$TEST_RESULTS" +fi if [[ "$IS_ARM64" -ne "0" ]]; then echo "IS_ARM64: $IS_ARM64" | tee -a "$TEST_RESULTS" elif [[ "$IS_ARM32" -ne "0" ]]; then @@ -463,10 +507,14 @@ fi # C++03, C++11, C++14 and C++17 echo | tee -a "$TEST_RESULTS" echo "HAVE_CXX03: $HAVE_CXX03" | tee -a "$TEST_RESULTS" +echo "HAVE_GNU03: $HAVE_GNU03" | tee -a "$TEST_RESULTS" echo "HAVE_CXX11: $HAVE_CXX11" | tee -a "$TEST_RESULTS" -if [[ ("$HAVE_CXX14" -ne "0" || "$HAVE_CXX17" -ne "0") ]]; then +echo "HAVE_GNU11: $HAVE_GNU11" | tee -a "$TEST_RESULTS" +if [[ ("$HAVE_CXX14" -ne "0" || "$HAVE_CXX17" -ne "0" || "$HAVE_GNU14" -ne "0" || "$HAVE_GNU17" -ne "0") ]]; then echo "HAVE_CXX14: $HAVE_CXX14" | tee -a "$TEST_RESULTS" + echo "HAVE_GNU14: $HAVE_GNU14" | tee -a "$TEST_RESULTS" echo "HAVE_CXX17: $HAVE_CXX17" | tee -a "$TEST_RESULTS" + echo "HAVE_GNU17: $HAVE_GNU17" | tee -a "$TEST_RESULTS" fi if [[ "$HAVE_LDGOLD" -ne "0" ]]; then echo "HAVE_LDGOLD: $HAVE_LDGOLD" | tee -a "$TEST_RESULTS" @@ -660,6 +708,9 @@ if [[ ("$GCC_COMPILER" -ne "0") ]]; then "-Wno-unknown-pragmas" "-Wstrict-aliasing=3" "-Wstrict-overflow" "-Waggressive-loop-optimizations" "-Wcast-align" "-Wwrite-strings" "-Wformat=2" "-Wformat-security" "-Wtrampolines") + if [[ ("$GCC_60_OR_ABOVE" -ne "0") ]]; then + ELEVATED_CXXFLAGS+=("-Wshift-negative-value -Wshift-overflow=2 -Wnull-dereference -Wduplicated-cond -Wodr-type-mismatch") + fi if [[ ("$GCC_51_OR_ABOVE" -ne "0") ]]; then ELEVATED_CXXFLAGS+=("-Wabi" "-Wodr") fi @@ -919,6 +970,65 @@ if [[ "$HAVE_CXX03" -ne "0" ]]; then fi fi +############################################ +# gnu++03 debug and release build +if [[ "$HAVE_GNU03" -ne "0" ]]; then + + ############################################ + # Debug build + echo + echo "************************************" | tee -a "$TEST_RESULTS" + echo "Testing: debug, gnu++03" | tee -a "$TEST_RESULTS" + echo + + unset CXXFLAGS + "$MAKE" clean > /dev/null 2>&1 + rm -f adhoc.cpp > /dev/null 2>&1 + + export CXXFLAGS="$DEBUG_CXXFLAGS -std=gnu++03 ${RETAINED_CXXFLAGS[@]}" + "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" + + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" + else + ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" + fi + ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" + fi + fi + + ############################################ + # Release build + echo + echo "************************************" | tee -a "$TEST_RESULTS" + echo "Testing: release, gnu++03" | tee -a "$TEST_RESULTS" + echo + + unset CXXFLAGS + "$MAKE" clean > /dev/null 2>&1 + rm -f adhoc.cpp > /dev/null 2>&1 + + export CXXFLAGS="$RELEASE_CXXFLAGS -std=gnu++03 ${RETAINED_CXXFLAGS[@]}" + "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" + + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" + else + ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" + fi + ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" + fi + fi +fi + ############################################ # c++11 debug and release build if [[ "$HAVE_CXX11" -ne "0" ]]; then @@ -978,6 +1088,65 @@ if [[ "$HAVE_CXX11" -ne "0" ]]; then fi fi +############################################ +# gnu++11 debug and release build +if [[ "$HAVE_GNU11" -ne "0" ]]; then + + ############################################ + # Debug build + echo + echo "************************************" | tee -a "$TEST_RESULTS" + echo "Testing: debug, gnu++11" | tee -a "$TEST_RESULTS" + echo + + unset CXXFLAGS + "$MAKE" clean > /dev/null 2>&1 + rm -f adhoc.cpp > /dev/null 2>&1 + + export CXXFLAGS="$DEBUG_CXXFLAGS -std=gnu++11 ${RETAINED_CXXFLAGS[@]}" + "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" + + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" + else + ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" + fi + ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" + fi + fi + + ############################################ + # Release build + echo + echo "************************************" | tee -a "$TEST_RESULTS" + echo "Testing: release, gnu++11" | tee -a "$TEST_RESULTS" + echo + + unset CXXFLAGS + "$MAKE" clean > /dev/null 2>&1 + rm -f adhoc.cpp > /dev/null 2>&1 + + export CXXFLAGS="$RELEASE_CXXFLAGS -std=gnu++11 ${RETAINED_CXXFLAGS[@]}" + "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" + + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" + else + ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" + fi + ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" + fi + fi +fi + ############################################ # c++14 debug and release build if [[ "$HAVE_CXX14" -ne "0" ]]; then @@ -1037,6 +1206,65 @@ if [[ "$HAVE_CXX14" -ne "0" ]]; then fi fi +############################################ +# gnu++14 debug and release build +if [[ "$HAVE_GNU14" -ne "0" ]]; then + + ############################################ + # Debug build + echo + echo "************************************" | tee -a "$TEST_RESULTS" + echo "Testing: debug, gnu++14" | tee -a "$TEST_RESULTS" + echo + + unset CXXFLAGS + "$MAKE" clean > /dev/null 2>&1 + rm -f adhoc.cpp > /dev/null 2>&1 + + export CXXFLAGS="$DEBUG_CXXFLAGS -std=gnu++14 ${RETAINED_CXXFLAGS[@]}" + "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" + + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" + else + ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" + fi + ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" + fi + fi + + ############################################ + # Release build + echo + echo "************************************" | tee -a "$TEST_RESULTS" + echo "Testing: release, gnu++14" | tee -a "$TEST_RESULTS" + echo + + unset CXXFLAGS + "$MAKE" clean > /dev/null 2>&1 + rm -f adhoc.cpp > /dev/null 2>&1 + + export CXXFLAGS="$RELEASE_CXXFLAGS -std=gnu++14 ${RETAINED_CXXFLAGS[@]}" + "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" + + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" + else + ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" + fi + ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" + fi + fi +fi + ############################################ # c++17 debug and release build if [[ "$HAVE_CXX17" -ne "0" ]]; then @@ -1096,6 +1324,65 @@ if [[ "$HAVE_CXX17" -ne "0" ]]; then fi fi +############################################ +# gnu++17 debug and release build +if [[ "$HAVE_GNU17" -ne "0" ]]; then + + ############################################ + # Debug build + echo + echo "************************************" | tee -a "$TEST_RESULTS" + echo "Testing: debug, gnu++17" | tee -a "$TEST_RESULTS" + echo + + unset CXXFLAGS + "$MAKE" clean > /dev/null 2>&1 + rm -f adhoc.cpp > /dev/null 2>&1 + + export CXXFLAGS="$DEBUG_CXXFLAGS -std=gnu++17 ${RETAINED_CXXFLAGS[@]}" + "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" + + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" + else + ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" + fi + ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" + fi + fi + + ############################################ + # Release build + echo + echo "************************************" | tee -a "$TEST_RESULTS" + echo "Testing: release, gnu++17" | tee -a "$TEST_RESULTS" + echo + + unset CXXFLAGS + "$MAKE" clean > /dev/null 2>&1 + rm -f adhoc.cpp > /dev/null 2>&1 + + export CXXFLAGS="$RELEASE_CXXFLAGS -std=gnu++17 ${RETAINED_CXXFLAGS[@]}" + "$MAKE" "${MAKEARGS[@]}" CXX="$CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" + + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" + else + ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" + fi + ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" + fi + fi +fi + ############################################ # X32 debug and release build if [[ "$HAVE_X32" -ne "0" ]]; then @@ -3671,6 +3958,75 @@ if [[ ("$INTEL_COMPILER" -eq "0") ]]; then fi fi +############################################ +# Perform a quick check with MacPorts compilers, if available. +if [[ ("$MACPORTS_COMPILER" -eq "0") ]]; then + + MACPORTS_CXX=$(find /opt/local/bin -name 'g++*' 2>/dev/null | head -1) + if [[ (-z "$MACPORTS_CXX") ]]; then + "$MACPORTS_CXX" -x c++ -DCRYPTOPP_ADHOC_MAIN adhoc.cpp.proto -o "$TMP/adhoc.exe" > /dev/null 2>&1 + if [[ "$?" -eq "0" ]]; then + + ############################################ + # GCC build + echo + echo "************************************" | tee -a "$TEST_RESULTS" + echo "Testing: MacPorts GCC compiler" | tee -a "$TEST_RESULTS" + echo + + unset CXXFLAGS + "$MAKE" clean > /dev/null 2>&1 + rm -f adhoc.cpp > /dev/null 2>&1 + + "$MAKE" "${MAKEARGS[@]}" CXX="$MACPORTS_CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" + else + ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" + fi + ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" + fi + fi + fi + fi + + MACPORTS_CXX=$(find /opt/local/bin -name 'clang++*' 2>/dev/null | head -1) + if [[ (-z "$MACPORTS_CXX") ]]; then + "$MACPORTS_CXX" -x c++ -DCRYPTOPP_ADHOC_MAIN adhoc.cpp.proto -o "$TMP/adhoc.exe" > /dev/null 2>&1 + if [[ "$?" -eq "0" ]]; then + + ############################################ + # Clang build + echo + echo "************************************" | tee -a "$TEST_RESULTS" + echo "Testing: MacPorts Clang compiler" | tee -a "$TEST_RESULTS" + echo + + unset CXXFLAGS + "$MAKE" clean > /dev/null 2>&1 + rm -f adhoc.cpp > /dev/null 2>&1 + + "$MAKE" "${MAKEARGS[@]}" CXX="$MACPORTS_CXX" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" + else + ./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" + fi + ./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" + if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then + echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" + fi + fi + fi + fi +fi + ############################################ # Perform a quick check with Xcode compiler, if available. if [[ "$IS_DARWIN" -ne "0" ]]; then @@ -3877,14 +4233,14 @@ fi # Report warnings echo -echo "************************************************" | tee -a "$WARN_RESULTS" -echo | tee -a "$WARN_RESULTS" +echo "************************************************" | tee -a "$TEST_RESULTS" "$WARN_RESULTS" +echo | tee -a "$TEST_RESULTS" "$WARN_RESULTS" WCOUNT=$("$EGREP" -a '(warning:)' $WARN_RESULTS | "$GREP" -v 'deprecated-declarations' | wc -l | "$AWK" '{print $1}') if (( "$WCOUNT" == "0" )); then - echo "No warnings detected" | tee -a "$WARN_RESULTS" | tee -a "$WARN_RESULTS" + echo "No warnings detected" | tee -a "$TEST_RESULTS" "$WARN_RESULTS" | tee -a "$TEST_RESULTS" "$WARN_RESULTS" else - echo "$WCOUNT warnings detected. See $WARN_RESULTS for details" | tee -a "$WARN_RESULTS" + echo "$WCOUNT warnings detected. See $WARN_RESULTS for details" | tee -a "$TEST_RESULTS" "$WARN_RESULTS" # "$EGREP" -an '(warning:)' $WARN_RESULTS | "$GREP" -v 'deprecated-declarations' fi @@ -3893,8 +4249,8 @@ fi echo echo "************************************************" | tee -a "$TEST_RESULTS" "$WARN_RESULTS" +echo | tee -a "$TEST_RESULTS" "$WARN_RESULTS" -echo echo "Testing started: $TEST_BEGIN" | tee -a "$TEST_RESULTS" "$WARN_RESULTS" echo "Testing finished: $TEST_END" | tee -a "$TEST_RESULTS" "$WARN_RESULTS" echo diff --git a/default.h b/default.h index 00ec6647..6b30f2e4 100644 --- a/default.h +++ b/default.h @@ -48,7 +48,7 @@ private: SecByteBlock m_passphrase; CBC_Mode::Encryption m_cipher; -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) } __attribute__((deprecated ("DefaultEncryptor will be changing in the near future because the algorithms are no longer secure"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); @@ -68,7 +68,7 @@ public: //! \param attachment a BufferedTransformation to attach to this object //! \param throwException a flag specifiying whether an Exception should be thrown on error DefaultDecryptor(const char *passphrase, BufferedTransformation *attachment = NULL, bool throwException=true); - + //! \brief Constructs a DefaultDecryptor //! \param passphrase a byte string password //! \param passphraseLength the length of the byte string password @@ -79,7 +79,7 @@ public: class Err : public Exception { public: - Err(const std::string &s) + Err(const std::string &s) : Exception(DATA_INTEGRITY_CHECK_FAILED, s) {} }; class KeyBadErr : public Err {public: KeyBadErr() : Err("DefaultDecryptor: cannot decrypt message with this passphrase") {}}; @@ -101,7 +101,7 @@ private: member_ptr m_decryptor; bool m_throwException; -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) } __attribute__((deprecated ("DefaultDecryptor will be changing in the near future because the algorithms are no longer secure"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); @@ -139,7 +139,7 @@ protected: private: member_ptr m_mac; -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) } __attribute__((deprecated ("DefaultEncryptorWithMAC will be changing in the near future because the algorithms are no longer secure"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); @@ -188,7 +188,7 @@ private: HashVerifier *m_hashVerifier; bool m_throwException; -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) } __attribute__((deprecated ("DefaultDecryptorWithMAC will be changing in the near future because the algorithms are no longer secure"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); diff --git a/eccrypto.h b/eccrypto.h index a3d15e95..cba037fb 100644 --- a/eccrypto.h +++ b/eccrypto.h @@ -130,7 +130,7 @@ public: const Integer& GetBasePointOrder() const {return this->GetSubgroupOrder();} void LoadRecommendedParameters(const OID &oid) {Initialize(oid);} #endif - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_GroupParameters_EC() {} #endif @@ -160,7 +160,7 @@ public: // X509PublicKey void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size); void DEREncodePublicKey(BufferedTransformation &bt) const; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_PublicKey_EC() {} #endif @@ -185,7 +185,7 @@ public: // PKCS8PrivateKey void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); void DEREncodePrivateKey(BufferedTransformation &bt) const; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_PrivateKey_EC() {} #endif @@ -196,7 +196,7 @@ template , COFACTOR_OPTION> Domain; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~ECDH() {} #endif @@ -207,7 +207,7 @@ template , COFACTOR_OPTION> Domain; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~ECMQV() {} #endif @@ -219,7 +219,7 @@ struct DL_Keys_EC { typedef DL_PublicKey_EC PublicKey; typedef DL_PrivateKey_EC PrivateKey; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_Keys_EC() {} #endif @@ -234,7 +234,7 @@ struct DL_Keys_ECDSA { typedef DL_PublicKey_EC PublicKey; typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest, ECDSA > PrivateKey; - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_Keys_ECDSA() {} #endif @@ -246,7 +246,7 @@ class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA { public: static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";} - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_Algorithm_ECDSA() {} #endif @@ -258,7 +258,7 @@ class DL_Algorithm_ECNR : public DL_Algorithm_NR { public: static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECNR";} - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DL_Algorithm_ECNR() {} #endif @@ -296,12 +296,12 @@ struct ECIES ECIES > { static std::string CRYPTOPP_API StaticAlgorithmName() {return "ECIES";} // TODO: fix this after name is standardized - + #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~ECIES() {} #endif - -#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800) + +#if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) } __attribute__((deprecated ("ECIES will be changing in the near future due to (1) an implementation bug and (2) an interop issue"))); #elif (CRYPTOPP_GCC_VERSION) } __attribute__((deprecated)); diff --git a/gcm.cpp b/gcm.cpp index fd82bddb..fd6731f0 100644 --- a/gcm.cpp +++ b/gcm.cpp @@ -13,7 +13,7 @@ #ifndef CRYPTOPP_GENERATE_X64_MASM // Clang 3.3 integrated assembler crash on Linux -#if defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION < 30400) +#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION < 30400)) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) # undef CRYPTOPP_X86_ASM_AVAILABLE # undef CRYPTOPP_X32_ASM_AVAILABLE # undef CRYPTOPP_X64_ASM_AVAILABLE @@ -703,9 +703,9 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len) AS2( pxor xmm5, xmm2 ) AS2( psrldq xmm0, 15 ) -#if (CRYPTOPP_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) +#if (CRYPTOPP_LLVM_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) AS2( movd edi, xmm0 ) -#elif (defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) +#elif (defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) AS2( mov WORD_REG(di), xmm0 ) #else // GNU Assembler AS2( movd WORD_REG(di), xmm0 ) @@ -718,9 +718,9 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len) AS2( pxor xmm4, xmm5 ) AS2( psrldq xmm1, 15 ) -#if (CRYPTOPP_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) +#if (CRYPTOPP_LLVM_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) AS2( movd edi, xmm1 ) -#elif (defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) +#elif (defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) AS2( mov WORD_REG(di), xmm1 ) #else AS2( movd WORD_REG(di), xmm1 ) @@ -729,9 +729,9 @@ size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len) AS2( shl eax, 8 ) AS2( psrldq xmm0, 15 ) -#if (CRYPTOPP_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) +#if (CRYPTOPP_LLVM_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70000) AS2( movd edi, xmm0 ) -#elif (defined(CRYPTOPP_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) +#elif (defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)) && defined(CRYPTOPP_X64_ASM_AVAILABLE) AS2( mov WORD_REG(di), xmm0 ) #else AS2( movd WORD_REG(di), xmm0 ) diff --git a/misc.h b/misc.h index 9566293f..e3980441 100644 --- a/misc.h +++ b/misc.h @@ -74,7 +74,7 @@ #endif #ifndef _blsr_u64 # define _blsr_u64(x) __blsr_u64(x) -# endif +#endif # endif #endif @@ -227,10 +227,11 @@ struct NewObject //! \brief A memory barrier //! \details MEMORY_BARRIER attempts to ensure reads and writes are completed //! in the absence of a language synchronization point. It is used by the -//! Singleton class if the compiler supports it. The use is provided at the -//! customary check points in a double-checked initialization. -//! \details Internally, MEMORY_BARRIER uses intrinsic(_ReadWriteBarrier), -//! _ReadWriteBarrier() or __asm__("" ::: "memory"). +//! Singleton class if the compiler supports it. The barrier is provided at the +//! customary places in a double-checked initialization. +//! \details Internally, MEMORY_BARRIER uses std::atomic_thread_fence if +//! C++11 atomics are available. Otherwise, intrinsic(_ReadWriteBarrier), +//! _ReadWriteBarrier() or __asm__("" ::: "memory") is used. #define MEMORY_BARRIER ... #else #if defined(CRYPTOPP_CXX11_ATOMICS) @@ -254,8 +255,8 @@ struct NewObject //! \details This class safely initializes a static object in a multithreaded environment. For C++03 //! and below it will do so without using locks for portability. If two threads call Ref() at the same //! time, they may get back different references, and one object may end up being memory leaked. This -//! is by design. For C++11 and above, a standard double-checked locking pattern with memory fences -//! is used. The locks and fences are standard and do not hinder portability. +//! is by design. For C++11 and above, a standard double-checked locking pattern with thread fences +//! are used. The locks and fences are standard and do not hinder portability. //! \sa Double-Checked Locking is Fixed In C++11 template , int instance=0> class Singleton @@ -470,7 +471,7 @@ template inline const T& STDMAX(const T& a, const T& b) #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wsign-compare" -# if (CRYPTOPP_CLANG_VERSION >= 20800) || (CRYPTOPP_APPLE_CLANG_VERSION >= 30000) +# if (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) || (CRYPTOPP_APPLE_CLANG_VERSION >= 30000) # pragma GCC diagnostic ignored "-Wtautological-compare" # elif (CRYPTOPP_GCC_VERSION >= 40300) # pragma GCC diagnostic ignored "-Wtype-limits" diff --git a/panama.h b/panama.h index b7db323a..e7f20c95 100644 --- a/panama.h +++ b/panama.h @@ -11,7 +11,7 @@ #include "secblock.h" // Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler error with .intel_syntax -#if CRYPTOPP_BOOL_X32 || (defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION < 30500)) +#if CRYPTOPP_BOOL_X32 || (defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION < 30500)) # define CRYPTOPP_DISABLE_PANAMA_ASM #endif @@ -128,7 +128,7 @@ struct PanamaCipherInfo : public FixedKeyLength<32, SimpleKeyingInterface::UNIQU //! _ template -class PanamaCipherPolicy : public AdditiveCipherConcretePolicy, +class PanamaCipherPolicy : public AdditiveCipherConcretePolicy, public PanamaCipherInfo, protected Panama { diff --git a/rdrand.cpp b/rdrand.cpp index 6149315e..4edb1bd8 100644 --- a/rdrand.cpp +++ b/rdrand.cpp @@ -67,8 +67,8 @@ #endif #if defined(CRYPTOPP_CPUID_AVAILABLE) -# define MSC_INTRIN_COMPILER ((CRYPTOPP_MSC_VERSION >= 1700) || (CRYPTOPP_CLANG_VERSION >= 30200) || (_INTEL_COMPILER >= 1210)) -# define GCC_INTRIN_COMPILER ((CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_CLANG_VERSION >= 30200) || (_INTEL_COMPILER >= 1210)) +# define MSC_INTRIN_COMPILER ((CRYPTOPP_MSC_VERSION >= 1700) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30200) || (_INTEL_COMPILER >= 1210)) +# define GCC_INTRIN_COMPILER ((CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30200) || (_INTEL_COMPILER >= 1210)) #else # define MSC_INTRIN_COMPILER 0 # define GCC_INTRIN_COMPILER 0 diff --git a/rijndael.h b/rijndael.h index ed856d94..50fdf1eb 100644 --- a/rijndael.h +++ b/rijndael.h @@ -12,7 +12,7 @@ #include "secblock.h" // Clang 3.3 integrated assembler crash on Linux -#if CRYPTOPP_BOOL_X32 || (defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION < 30400)) +#if CRYPTOPP_BOOL_X32 || (defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION < 30400)) # define CRYPTOPP_DISABLE_RIJNDAEL_ASM #endif diff --git a/sha.h b/sha.h index 544e8056..c70d9d1f 100644 --- a/sha.h +++ b/sha.h @@ -11,7 +11,7 @@ #include "iterhash.h" // Clang 3.3 integrated assembler crash on Linux -#if defined(CRYPTOPP_CLANG_VERSION) && (CRYPTOPP_CLANG_VERSION < 30400) +#if defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION < 30400) # define CRYPTOPP_DISABLE_SHA_ASM #endif diff --git a/socketft.cpp b/socketft.cpp index 42a00182..ff6e0d40 100644 --- a/socketft.cpp +++ b/socketft.cpp @@ -109,10 +109,12 @@ void Socket::CloseSocket() BOOL result = CancelIoEx((HANDLE) m_s, NULL); assert(result || (!result && GetLastError() == ERROR_NOT_FOUND)); CheckAndHandleError_int("closesocket", closesocket(m_s)); + CRYPTOPP_UNUSED(result); // Used by assert in debug builds # else BOOL result = CancelIo((HANDLE) m_s); assert(result || (!result && GetLastError() == ERROR_NOT_FOUND)); CheckAndHandleError_int("closesocket", closesocket(m_s)); + CRYPTOPP_UNUSED(result); # endif #else CheckAndHandleError_int("close", close(m_s)); @@ -368,9 +370,11 @@ SocketReceiver::~SocketReceiver() # if defined(USE_WINDOWS8_API) BOOL result = CancelIoEx((HANDLE) m_s.GetSocket(), NULL); assert(result || (!result && GetLastError() == ERROR_NOT_FOUND)); + CRYPTOPP_UNUSED(result); // Used by assert in debug builds # else BOOL result = CancelIo((HANDLE) m_s.GetSocket()); assert(result || (!result && GetLastError() == ERROR_NOT_FOUND)); + CRYPTOPP_UNUSED(result); # endif #endif } @@ -456,9 +460,11 @@ SocketSender::~SocketSender() # if defined(USE_WINDOWS8_API) BOOL result = CancelIoEx((HANDLE) m_s.GetSocket(), NULL); assert(result || (!result && GetLastError() == ERROR_NOT_FOUND)); + CRYPTOPP_UNUSED(result); // Used by assert in debug builds # else BOOL result = CancelIo((HANDLE) m_s.GetSocket()); assert(result || (!result && GetLastError() == ERROR_NOT_FOUND)); + CRYPTOPP_UNUSED(result); # endif #endif } diff --git a/wait.h b/wait.h index 13e6ba33..e274b19f 100644 --- a/wait.h +++ b/wait.h @@ -32,6 +32,13 @@ # endif #endif +// http://connect.microsoft.com/VisualStudio/feedback/details/1581706 +// and http://github.com/weidai11/cryptopp/issues/214 +#if CRYPTOPP_MSC_VERSION == 1900 +# pragma warning(push) +# pragma warning(disable: 4589) +#endif + NAMESPACE_BEGIN(CryptoPP) class Tracer @@ -223,6 +230,10 @@ private: NAMESPACE_END +#if CRYPTOPP_MSC_VERSION == 1900 +# pragma warning(pop) +#endif + #endif #endif From 2e14d5d7cb8868eb2a376fd7b76e5cb2169574f9 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Wed, 6 Jul 2016 15:08:24 -0400 Subject: [PATCH 21/22] Fix "/usr/bin/ld: -f may not be used without -shared" (Issue 219) --- GNUmakefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 12b1542c..e45f7b3a 100755 --- a/GNUmakefile +++ b/GNUmakefile @@ -303,10 +303,10 @@ endif # Asan # LD gold linker testing. Triggered by 'LD=ld.gold'. ifeq ($(findstring ld.gold,$(LD)),ld.gold) -ifeq ($(findstring -Wl,-fuse-ld=gold,$(LDFLAGS)),) +ifeq ($(findstring -fuse-ld=gold,$(CXXFLAGS)),) ELF_FORMAT := $(shell file `which ld.gold` 2>&1 | cut -d":" -f 2 | $(EGREP) -i -c "elf") ifneq ($(ELF_FORMAT),0) -LDFLAGS += -Wl,-fuse-ld=gold +LDFLAGS += -fuse-ld=gold endif # ELF/ELF64 endif # CXXFLAGS endif # Gold From 86445fb3e988962efb7ec5186742b2df30a3f6fe Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Wed, 6 Jul 2016 18:30:51 -0400 Subject: [PATCH 22/22] Fix integer.cpp compile when using config.recommend --- config.recommend | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/config.recommend b/config.recommend index 15b7e781..713a6780 100644 --- a/config.recommend +++ b/config.recommend @@ -239,8 +239,10 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); // Apple and LLVM's Clang. Apple Clang version 7.0 roughly equals LLVM Clang version 3.7 #if defined(__clang__ ) && !defined(__apple_build_version__) #define CRYPTOPP_LLVM_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) + #define CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER 1 #elif defined(__clang__ ) && defined(__apple_build_version__) #define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) + #define CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER 1 #endif #ifdef _MSC_VER @@ -254,7 +256,7 @@ const lword LWORD_MAX = W64LIT(0xffffffffffffffff); // Clang due to "Inline assembly operands don't work with .intel_syntax", http://llvm.org/bugs/show_bug.cgi?id=24232 // TODO: supply the upper version when LLVM fixes it. We set it to 20.0 for compilation purposes. -#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && CRYPTOPP_LLVM_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) +#if (defined(CRYPTOPP_LLVM_CLANG_VERSION) && CRYPTOPP_LLVM_CLANG_VERSION <= 200000) || (defined(CRYPTOPP_APPLE_CLANG_VERSION) && CRYPTOPP_APPLE_CLANG_VERSION <= 200000) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) #define CRYPTOPP_DISABLE_INTEL_ASM 1 #endif @@ -567,6 +569,8 @@ NAMESPACE_END #define CRYPTOPP_BOOL_ARM32 0 #endif +// Microsoft plans to support ARM-64, but its not clear how to detect it. +// TODO: Add MSC_VER and ARM-64 platform define when available #if defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) #define CRYPTOPP_BOOL_ARM64 1 #else