Adam Ierymenko 6 years ago
parent
commit
82b7e1dbcb
3 changed files with 65 additions and 36 deletions
  1. 19 0
      node/AES.hpp
  2. 37 4
      node/SHA512.cpp
  3. 9 32
      node/SHA512.hpp

+ 19 - 0
node/AES.hpp

@@ -16,6 +16,7 @@
 
 #include "Constants.hpp"
 #include "Utils.hpp"
+#include "SHA512.hpp"
 
 #if (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64))
 #include <wmmintrin.h>
@@ -246,6 +247,24 @@ public:
 #endif
 	}
 
+	/**
+	 * Use HMAC-SHA-384 as a PRF to generate four AES keys from one master
+	 *
+	 * @param masterKey Master 256-bit key
+	 * @param k1 GMAC key
+	 * @param k2 GMAC auth tag masking (ECB encryption) key
+	 * @param k3 CTR IV masking (ECB encryption) key
+	 * @param k4 AES-CTR key
+	 */
+	static inline void initGmacCtrKeys(const uint8_t masterKey[32],AES &k1,AES &k2,AES &k3,AES &k4)
+	{
+		uint64_t kbuf[6];
+		for(uint8_t kno=0;kno<4;++kno) {
+			HMACSHA384(masterKey,&kno,1,(uint8_t *)kbuf);
+			k1.init((const uint8_t *)kbuf);
+		}
+	}
+
 private:
 	static const uint32_t Te0[256];
 	static const uint32_t Te1[256];

+ 37 - 4
node/SHA512.cpp

@@ -10,10 +10,10 @@
 #include <utility>
 #include <algorithm>
 
-#ifndef ZT_HAVE_NATIVE_SHA512
-
 namespace ZeroTier {
 
+#ifndef ZT_HAVE_NATIVE_SHA512
+
 namespace {
 
 struct sha512_state {
@@ -239,6 +239,39 @@ void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,u
 	memcpy(digest,tmp,48);
 }
 
-} // namespace ZeroTier
-
 #endif // !ZT_HAVE_NATIVE_SHA512
+
+void HMACSHA384(const uint8_t key[32],const void *msg,const unsigned int msglen,uint8_t mac[48])
+{
+	uint64_t kInPadded[16]; // input padded key
+	uint64_t outer[22]; // output padded key | H(input padded key | msg)
+
+#ifdef ZT_NO_TYPE_PUNNING
+	for(int i=0;i<32;++i) ((uint8_t *)kInPadded)[i] = key[i] ^ 0x36;
+	for(int i=4;i<16;++i) kInPadded[i] = 0x3636363636363636ULL;
+	for(int i=0;i<32;++i) ((uint8_t *)outer)[i] = key[i] ^ 0x5c;
+	for(int i=4;i<16;++i) outer[i] = 0x5c5c5c5c5c5c5c5cULL;
+#else
+	{
+		const uint64_t k0 = ((const uint64_t *)key)[0];
+		const uint64_t k1 = ((const uint64_t *)key)[1];
+		const uint64_t k2 = ((const uint64_t *)key)[2];
+		const uint64_t k3 = ((const uint64_t *)key)[3];
+		kInPadded[0] = k0 ^ 0x3636363636363636ULL;
+		kInPadded[1] = k1 ^ 0x3636363636363636ULL;
+		kInPadded[2] = k2 ^ 0x3636363636363636ULL;
+		kInPadded[3] = k3 ^ 0x3636363636363636ULL;
+		for(int i=4;i<16;++i) kInPadded[i] = 0x3636363636363636ULL;
+		outer[0] = k0 ^ 0x5c5c5c5c5c5c5c5cULL;
+		outer[1] = k1 ^ 0x5c5c5c5c5c5c5c5cULL;
+		outer[2] = k2 ^ 0x5c5c5c5c5c5c5c5cULL;
+		outer[3] = k3 ^ 0x5c5c5c5c5c5c5c5cULL;
+		for(int i=4;i<16;++i) outer[i] = 0x5c5c5c5c5c5c5c5cULL;
+	}
+#endif
+
+	SHA384(((uint8_t *)outer) + 128,kInPadded,128,msg,msglen); // H(input padded key | msg)
+	SHA384(mac,outer,176); // H(output padded key | H(input padded key | msg))
+}
+
+} // namespace ZeroTier

+ 9 - 32
node/SHA512.hpp

@@ -92,38 +92,15 @@ void SHA384(void *digest,const void *data,unsigned int len);
 void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1);
 #endif
 
-static inline void HMACSHA384(const uint8_t key[32],const void *msg,const unsigned int msglen,uint8_t mac[48])
-{
-	uint64_t kInPadded[16];
-	uint64_t outer[22]; // output padded key | H(input padded key | msg)
-
-#ifdef ZT_NO_TYPE_PUNNING
-	for(int i=0;i<32;++i) ((uint8_t *)kInPadded)[i] = key[i] ^ 0x36;
-	for(int i=4;i<16;++i) kInPadded[i] = 0x3636363636363636ULL;
-	for(int i=0;i<32;++i) ((uint8_t *)outer)[i] = key[i] ^ 0x5c;
-	for(int i=4;i<16;++i) outer[i] = 0x5c5c5c5c5c5c5c5cULL;
-#else
-	{
-		const uint64_t k0 = ((const uint64_t *)key)[0];
-		const uint64_t k1 = ((const uint64_t *)key)[1];
-		const uint64_t k2 = ((const uint64_t *)key)[2];
-		const uint64_t k3 = ((const uint64_t *)key)[3];
-		kInPadded[0] = k0 ^ 0x3636363636363636ULL;
-		kInPadded[0] = k1 ^ 0x3636363636363636ULL;
-		kInPadded[0] = k2 ^ 0x3636363636363636ULL;
-		kInPadded[0] = k3 ^ 0x3636363636363636ULL;
-		for(int i=4;i<16;++i) kInPadded[i] = 0x3636363636363636ULL;
-		outer[0] = k0 ^ 0x5c5c5c5c5c5c5c5cULL;
-		outer[1] = k1 ^ 0x5c5c5c5c5c5c5c5cULL;
-		outer[2] = k2 ^ 0x5c5c5c5c5c5c5c5cULL;
-		outer[3] = k3 ^ 0x5c5c5c5c5c5c5c5cULL;
-		for(int i=4;i<16;++i) outer[i] = 0x5c5c5c5c5c5c5c5cULL;
-	}
-#endif
-
-	SHA384(((uint8_t *)outer) + 128,kInPadded,128,msg,msglen); // H(input padded key | msg)
-	SHA384(mac,outer,176); // H(output padded key | H(input padded key | msg))
-}
+/**
+ * Compute HMAC SHA-384 using a 256-bit key
+ *
+ * @param key Secret key
+ * @param msg Message to HMAC
+ * @param msglen Length of message
+ * @param mac Buffer to fill with result
+ */
+void HMACSHA384(const uint8_t key[32],const void *msg,const unsigned int msglen,uint8_t mac[48]);
 
 } // namespace ZeroTier