From 44dd52d08fc2c9ab29fe23e5848c39ce0f37b045 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 5 Sep 2019 11:39:16 -0700 Subject: [PATCH] KBKDF --- node/AES.hpp | 22 +++++++++------------- node/SHA512.cpp | 21 +++++++++++++++++++++ node/SHA512.hpp | 17 +++++++++++++++++ 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/node/AES.hpp b/node/AES.hpp index 33817018f..278dc34d5 100644 --- a/node/AES.hpp +++ b/node/AES.hpp @@ -260,19 +260,15 @@ public: */ static ZT_ALWAYS_INLINE void initGmacCtrKeys(const uint8_t masterKey[32],AES &k1,AES &k2,AES &k3,AES &k4) { - uint8_t kbuf[48]; - uint8_t kbkdfMsg[16]; - kbkdfMsg[0] = 0; // key iterator, incremented for each key - for(unsigned int i=0;i<12;++i) - kbkdfMsg[i+1] = (uint8_t)("AES-GMAC-CTR"[i]); // KBKDF "label" indicating the use for these keys - kbkdfMsg[13] = 0; // 0x00 - kbkdfMsg[14] = 0; // KBKDF "context", just 0 as it's not used in this protocol - kbkdfMsg[15] = 32; // bits used in resulting key - while (kbkdfMsg[0] < 4) { - HMACSHA384(masterKey,&kbkdfMsg,sizeof(kbkdfMsg),kbuf); - k1.init(kbuf); - ++kbkdfMsg[0]; - } + uint8_t k[32]; + KBKDFHMACSHA384(masterKey,ZT_PROTO_KBKDF_LABEL_KEY_USE_AES_GMAC_SIV_K1,0,0,k); + k1.init(k); + KBKDFHMACSHA384(masterKey,ZT_PROTO_KBKDF_LABEL_KEY_USE_AES_GMAC_SIV_K2,0,0,k); + k2.init(k); + KBKDFHMACSHA384(masterKey,ZT_PROTO_KBKDF_LABEL_KEY_USE_AES_GMAC_SIV_K3,0,0,k); + k3.init(k); + KBKDFHMACSHA384(masterKey,ZT_PROTO_KBKDF_LABEL_KEY_USE_AES_GMAC_SIV_K4,0,0,k); + k4.init(k); } private: diff --git a/node/SHA512.cpp b/node/SHA512.cpp index 0f9774799..449a839a5 100644 --- a/node/SHA512.cpp +++ b/node/SHA512.cpp @@ -274,4 +274,25 @@ void HMACSHA384(const uint8_t key[32],const void *msg,const unsigned int msglen, SHA384(mac,outer,176); // H(output padded key | H(input padded key | msg)) } +void KBKDFHMACSHA384(const uint8_t key[32],const char label,const char context,const uint32_t iter,uint8_t out[32]) +{ + uint8_t kbkdfMsg[13]; + uint8_t kbuf[48]; + kbkdfMsg[0] = (uint8_t)(iter >> 24); + kbkdfMsg[1] = (uint8_t)(iter >> 16); + kbkdfMsg[2] = (uint8_t)(iter >> 8); + kbkdfMsg[3] = (uint8_t)iter; + kbkdfMsg[4] = (uint8_t)'Z'; + kbkdfMsg[5] = (uint8_t)'T'; // preface our labels with something ZT-specific + kbkdfMsg[6] = (uint8_t)label; + kbkdfMsg[7] = 0; + kbkdfMsg[8] = (uint8_t)context; + kbkdfMsg[9] = 0; + kbkdfMsg[10] = 0; + kbkdfMsg[11] = 1; + kbkdfMsg[12] = 0; // key length: 256 bits as big-endian 32-bit value + HMACSHA384(key,&kbkdfMsg,sizeof(kbkdfMsg),kbuf); + memcpy(out,kbuf,32); +} + } // namespace ZeroTier diff --git a/node/SHA512.hpp b/node/SHA512.hpp index 4762b46a2..7cd26ae31 100644 --- a/node/SHA512.hpp +++ b/node/SHA512.hpp @@ -32,6 +32,12 @@ #define ZT_HMACSHA384_LEN 48 +#define ZT_PROTO_KBKDF_LABEL_KEY_USE_HMAC 'H' +#define ZT_PROTO_KBKDF_LABEL_KEY_USE_AES_GMAC_SIV_K1 '1' +#define ZT_PROTO_KBKDF_LABEL_KEY_USE_AES_GMAC_SIV_K2 '2' +#define ZT_PROTO_KBKDF_LABEL_KEY_USE_AES_GMAC_SIV_K3 '3' +#define ZT_PROTO_KBKDF_LABEL_KEY_USE_AES_GMAC_SIV_K4 '4' + namespace ZeroTier { #ifdef __APPLE__ @@ -102,6 +108,17 @@ void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,u */ void HMACSHA384(const uint8_t key[32],const void *msg,const unsigned int msglen,uint8_t mac[48]); +/** + * Compute KBKDF (key-based key derivation function) using HMAC-SHA-384 as a PRF + * + * @param key Source master key + * @param label A label indicating the key's purpose in the ZeroTier system + * @param context An arbitrary "context" or zero if not applicable + * @param iter Key iteration for generation of multiple keys for the same label/context + * @param out Output to receive derived key + */ +void KBKDFHMACSHA384(const uint8_t key[32],const char label,const char context,const uint32_t iter,uint8_t out[32]); + } // namespace ZeroTier #endif