Browse Source

Better CRL implementation, AES fix.

Adam Ierymenko 5 năm trước cách đây
mục cha
commit
cfb0bc4f8e
4 tập tin đã thay đổi với 61 bổ sung24 xóa
  1. 9 12
      core/AES.cpp
  2. 34 2
      core/Certificate.cpp
  3. 8 0
      core/Certificate.hpp
  4. 10 10
      core/zerotier.h

+ 9 - 12
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);

+ 34 - 2
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();
 }
 

+ 8 - 0
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;

+ 10 - 10
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).
 	 */