diff --git a/core/AES.cpp b/core/AES.cpp index 03c41cf81..14bc82dcc 100644 --- a/core/AES.cpp +++ b/core/AES.cpp @@ -237,7 +237,6 @@ void AES::GMAC::update(const void *const data, unsigned int len) noexcept __m128i a = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(hhhh, d1, 0x00), _mm_clmulepi64_si128(hhh, d2, 0x00)), _mm_xor_si128(_mm_clmulepi64_si128(hh, d3, 0x00), _mm_clmulepi64_si128(h, d4, 0x00))); __m128i b = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(hhhh, d1, 0x11), _mm_clmulepi64_si128(hhh, d2, 0x11)), _mm_xor_si128(_mm_clmulepi64_si128(hh, d3, 0x11), _mm_clmulepi64_si128(h, d4, 0x11))); __m128i c = _mm_xor_si128(_mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(hhhh2, _mm_xor_si128(_mm_shuffle_epi32(d1, 78), d1), 0x00), _mm_clmulepi64_si128(hhh2, _mm_xor_si128(_mm_shuffle_epi32(d2, 78), d2), 0x00)), _mm_xor_si128(_mm_clmulepi64_si128(hh2, _mm_xor_si128(_mm_shuffle_epi32(d3, 78), d3), 0x00), _mm_clmulepi64_si128(h2, _mm_xor_si128(_mm_shuffle_epi32(d4, 78), d4), 0x00))), _mm_xor_si128(a, b)); - _mm_prefetch(in, _MM_HINT_T0); a = _mm_xor_si128(_mm_slli_si128(c, 8), a); b = _mm_xor_si128(_mm_srli_si128(c, 8), b); c = _mm_srli_epi32(a, 31); @@ -478,7 +477,6 @@ void p_aesCtrInnerVAES512(unsigned int &len, const uint64_t c0, uint64_t &c1, co c1 += 4; in += 64; len -= 64; - _mm_prefetch(in, _MM_HINT_T0); d0 = _mm512_xor_si512(d0, kk0); d0 = _mm512_aesenc_epi128(d0, kk1); d0 = _mm512_aesenc_epi128(d0, kk2); @@ -532,7 +530,6 @@ void p_aesCtrInnerVAES256(unsigned int &len, const uint64_t c0, uint64_t &c1, co c1 += 4; in += 64; len -= 64; - _mm_prefetch(in, _MM_HINT_T0); d0 = _mm256_xor_si256(d0, kk0); d1 = _mm256_xor_si256(d1, kk0); d0 = _mm256_aesenc_epi128(d0, kk1); @@ -580,10 +577,6 @@ void AES::CTR::crypt(const void *const input, unsigned int len) noexcept #ifdef ZT_AES_AESNI if (likely(Utils::CPUID.aes)) { - _mm_prefetch(in + 32, _MM_HINT_T0); - _mm_prefetch(in + 64, _MM_HINT_T0); - _mm_prefetch(in + 96, _MM_HINT_T0); - const __m128i dd = _mm_set_epi64x(0, (long long)_ctr[0]); uint64_t c1 = Utils::ntoh(_ctr[1]); @@ -665,12 +658,16 @@ void AES::CTR::crypt(const void *const input, unsigned int len) noexcept const uint8_t *const eof64 = in + (len & ~((unsigned int)63)); len &= 63; + __m128i d0, d1, d2, d3; do { - _mm_prefetch(in, _MM_HINT_T0); - __m128i d0 = _mm_insert_epi64(dd, (long long)Utils::hton(c1), 1); - __m128i d1 = _mm_insert_epi64(dd, (long long)Utils::hton(c1 + 1ULL), 1); - __m128i d2 = _mm_insert_epi64(dd, (long long)Utils::hton(c1 + 2ULL), 1); - __m128i d3 = _mm_insert_epi64(dd, (long long)Utils::hton(c1 + 3ULL), 1); + const uint64_t c10 = Utils::hton(c1); + const uint64_t c11 = Utils::hton(c1 + 1ULL); + const uint64_t c12 = Utils::hton(c1 + 2ULL); + const uint64_t c13 = Utils::hton(c1 + 3ULL); + d0 = _mm_insert_epi64(dd, (long long)c10, 1); + d1 = _mm_insert_epi64(dd, (long long)c11, 1); + d2 = _mm_insert_epi64(dd, (long long)c12, 1); + d3 = _mm_insert_epi64(dd, (long long)c13, 1); c1 += 4; d0 = _mm_xor_si128(d0, k0); d1 = _mm_xor_si128(d1, k0); diff --git a/core/Certificate.cpp b/core/Certificate.cpp index 3231b6671..2755aa9e9 100644 --- a/core/Certificate.cpp +++ b/core/Certificate.cpp @@ -108,6 +108,12 @@ Certificate &Certificate::operator=(const ZT_Certificate &cert) this->maxPathLength = cert.maxPathLength; + if ((cert.crl) && (cert.crlCount > 0)) { + for (unsigned int i = 0; i < cert.crlCount; ++i) { + if (cert.crl[i]) + addCRLCertificate(cert.crl[i]); + } + } if ((cert.signature) && (cert.signatureSize > 0)) { m_signature.assign(cert.signature, cert.signature + cert.signatureSize); this->signature = m_signature.data(); @@ -167,9 +173,9 @@ void Certificate::addSubjectCertificate(const uint8_t serialNo[ZT_SHA384_DIGEST_ // Enlarge array of uint8_t pointers, set new pointer to local copy of serial, and set // certificates to point to potentially reallocated array. - m_subjectCertificates.resize(++this->subject.certificateCount); - m_subjectCertificates.back() = m_serials.front().bytes(); + m_subjectCertificates.push_back(m_serials.front().bytes()); this->subject.certificates = m_subjectCertificates.data(); + this->subject.certificateCount = (unsigned int)m_subjectCertificates.size(); } void Certificate::addSubjectUpdateUrl(const char *url) @@ -217,8 +223,17 @@ bool Certificate::setSubjectUniqueId(const uint8_t uniqueId[ZT_CERTIFICATE_UNIQU return true; } +void Certificate::addCRLCertificate(const uint8_t serialNo[ZT_SHA384_DIGEST_SIZE]) +{ + m_serials.push_front(SHA384Hash(serialNo)); + m_crl.push_back(m_serials.front().bytes()); + this->crl = m_crl.data(); + this->crlCount = (unsigned int)m_crl.size(); +} + Vector< uint8_t > Certificate::encode(const bool omitSignature) const { + char tmp[32]; Vector< uint8_t > enc; Dictionary d; @@ -270,6 +285,14 @@ Vector< uint8_t > Certificate::encode(const bool omitSignature) const if ((this->extendedAttributes) && (this->extendedAttributesSize > 0)) d["x"].assign(this->extendedAttributes, this->extendedAttributes + this->extendedAttributesSize); + if ((this->crl) && (this->crlCount > 0)) { + d.add("r$", (uint64_t)this->crlCount); + for (unsigned int i = 0; i < this->crlCount; ++i) { + if (this->crl[i]) + d[Dictionary::arraySubscript(tmp, sizeof(tmp), "r$", i)].assign(this->crl[i], this->crl[i] + ZT_SHA384_DIGEST_SIZE); + } + } + if ((!omitSignature) && (this->signature) && (this->signatureSize > 0)) d["S"].assign(this->signature, this->signature + this->signatureSize); @@ -400,6 +423,14 @@ bool Certificate::decode(const void *const data, const unsigned int len) this->extendedAttributesSize = (unsigned int)m_extendedAttributes.size(); } + cnt = (unsigned int)d.getUI("r$"); + for (unsigned int i = 0; i < cnt; ++i) { + const Vector< uint8_t > &cr = d[Dictionary::arraySubscript(tmp, sizeof(tmp), "r$", i)]; + if (cr.size() != ZT_SHA384_DIGEST_SIZE) + return false; + this->addCRLCertificate(cr.data()); + } + m_signature = d["S"]; if (!m_signature.empty()) { this->signature = m_signature.data(); @@ -557,6 +588,7 @@ void Certificate::m_clear() m_extendedAttributes.clear(); m_subjectUniqueId.clear(); m_subjectUniqueIdProofSignature.clear(); + m_crl.clear(); m_signature.clear(); } diff --git a/core/Certificate.hpp b/core/Certificate.hpp index bbeff0d62..a37f48326 100644 --- a/core/Certificate.hpp +++ b/core/Certificate.hpp @@ -125,6 +125,13 @@ public: */ bool setSubjectUniqueId(const uint8_t uniqueId[ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_SIZE], const uint8_t uniqueIdPrivate[ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE]); + /** + * Add a serial number to the CRL list + * + * @param serialNo Serial number of certificate to revoke + */ + void addCRLCertificate(const uint8_t serialNo[ZT_SHA384_DIGEST_SIZE]); + /** * Marshal this certificate in binary form * @@ -229,6 +236,7 @@ private: Vector< uint8_t > m_extendedAttributes; Vector< uint8_t > m_subjectUniqueId; Vector< uint8_t > m_subjectUniqueIdProofSignature; + Vector< const uint8_t * > m_crl; Vector< uint8_t > m_signature; std::atomic< int > __refCount; diff --git a/core/zerotier.h b/core/zerotier.h index af2d3768b..424c3dea2 100644 --- a/core/zerotier.h +++ b/core/zerotier.h @@ -308,16 +308,6 @@ typedef struct */ #define ZT_CERTIFICATE_LOCAL_TRUST_FLAG_ZEROTIER_ROOT_SET 0x0002U -/** - * Certificate flag indicating that this certificate is a revocation. - * - * For certificate revocations only the certificates field of the subject - * is significant, and must enumerate the serial numbers (hashes) of - * certificates being revoked. Revoked certificates must be certificates - * signed by the issuer doing the revocation. - */ -#define ZT_CERTIFICATE_FLAG_REVOCATION 0x0001U - /** * Size of a unique ID of the given key type (with type prefix byte) */ @@ -607,6 +597,16 @@ typedef struct */ unsigned int maxPathLength; + /** + * List of certificate serial numbers being revoked. + */ + const uint8_t *const *crl; + + /** + * Number of 48-byte serial numbers in crl list. + */ + unsigned int crlCount; + /** * Signature by issuer (algorithm determined by identity type). */