mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-22 22:32:22 +00:00
cleanup
This commit is contained in:
parent
82b7e1dbcb
commit
55f4f9aaeb
40
node/AES.hpp
40
node/AES.hpp
@ -41,14 +41,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
static const bool HW_ACCEL;
|
static const bool HW_ACCEL;
|
||||||
|
|
||||||
inline AES() {}
|
ZT_ALWAYS_INLINE AES() {}
|
||||||
inline AES(const uint8_t key[32]) { this->init(key); }
|
ZT_ALWAYS_INLINE AES(const uint8_t key[32]) { this->init(key); }
|
||||||
inline ~AES() { Utils::burn(&_k,sizeof(_k)); }
|
ZT_ALWAYS_INLINE ~AES() { Utils::burn(&_k,sizeof(_k)); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set (or re-set) this AES256 cipher's key
|
* Set (or re-set) this AES256 cipher's key
|
||||||
*/
|
*/
|
||||||
inline void init(const uint8_t key[32])
|
ZT_ALWAYS_INLINE void init(const uint8_t key[32])
|
||||||
{
|
{
|
||||||
#ifdef ZT_AES_AESNI
|
#ifdef ZT_AES_AESNI
|
||||||
if (likely(HW_ACCEL)) {
|
if (likely(HW_ACCEL)) {
|
||||||
@ -66,7 +66,7 @@ public:
|
|||||||
* @param in Input block
|
* @param in Input block
|
||||||
* @param out Output block (can be same as input)
|
* @param out Output block (can be same as input)
|
||||||
*/
|
*/
|
||||||
inline void encrypt(const uint8_t in[16],uint8_t out[16]) const
|
ZT_ALWAYS_INLINE void encrypt(const uint8_t in[16],uint8_t out[16]) const
|
||||||
{
|
{
|
||||||
#ifdef ZT_AES_AESNI
|
#ifdef ZT_AES_AESNI
|
||||||
if (likely(HW_ACCEL)) {
|
if (likely(HW_ACCEL)) {
|
||||||
@ -86,7 +86,7 @@ public:
|
|||||||
* @param len Length of input
|
* @param len Length of input
|
||||||
* @param out 128-bit authorization tag from GMAC
|
* @param out 128-bit authorization tag from GMAC
|
||||||
*/
|
*/
|
||||||
inline void gmac(const uint8_t iv[12],const void *in,const unsigned int len,uint8_t out[16]) const
|
ZT_ALWAYS_INLINE void gmac(const uint8_t iv[12],const void *in,const unsigned int len,uint8_t out[16]) const
|
||||||
{
|
{
|
||||||
#ifdef ZT_AES_AESNI
|
#ifdef ZT_AES_AESNI
|
||||||
if (likely(HW_ACCEL)) {
|
if (likely(HW_ACCEL)) {
|
||||||
@ -110,7 +110,7 @@ public:
|
|||||||
* @param len Length of input
|
* @param len Length of input
|
||||||
* @param out Output plaintext or ciphertext
|
* @param out Output plaintext or ciphertext
|
||||||
*/
|
*/
|
||||||
inline void ctr(const uint8_t iv[16],const void *in,unsigned int len,void *out) const
|
ZT_ALWAYS_INLINE void ctr(const uint8_t iv[16],const void *in,unsigned int len,void *out) const
|
||||||
{
|
{
|
||||||
#ifdef ZT_AES_AESNI
|
#ifdef ZT_AES_AESNI
|
||||||
if (likely(HW_ACCEL)) {
|
if (likely(HW_ACCEL)) {
|
||||||
@ -173,7 +173,7 @@ public:
|
|||||||
* @param out Output buffer to receive ciphertext
|
* @param out Output buffer to receive ciphertext
|
||||||
* @param tag Output buffer to receive 64-bit authentication tag
|
* @param tag Output buffer to receive 64-bit authentication tag
|
||||||
*/
|
*/
|
||||||
static inline void ztGmacCtrEncrypt(const AES &k1,const AES &k2,const AES &k3,const AES &k4,const uint8_t iv[12],const void *in,unsigned int len,void *out,uint8_t tag[8])
|
static ZT_ALWAYS_INLINE void ztGmacCtrEncrypt(const AES &k1,const AES &k2,const AES &k3,const AES &k4,const uint8_t iv[12],const void *in,const unsigned int len,void *out,uint8_t tag[8])
|
||||||
{
|
{
|
||||||
uint8_t ctrIv[16];
|
uint8_t ctrIv[16];
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ public:
|
|||||||
* @param tag Authentication tag supplied with message
|
* @param tag Authentication tag supplied with message
|
||||||
* @return True if authentication tags match and message appears authentic
|
* @return True if authentication tags match and message appears authentic
|
||||||
*/
|
*/
|
||||||
static inline bool ztGmacCtrDecrypt(const AES &k1,const AES &k2,const AES &k3,const AES &k4,const uint8_t iv[12],const void *in,unsigned int len,void *out,const uint8_t tag[8])
|
static ZT_ALWAYS_INLINE bool ztGmacCtrDecrypt(const AES &k1,const AES &k2,const AES &k3,const AES &k4,const uint8_t iv[12],const void *in,const unsigned int len,void *out,const uint8_t tag[8])
|
||||||
{
|
{
|
||||||
uint8_t ctrIv[16],gmacOut[16];
|
uint8_t ctrIv[16],gmacOut[16];
|
||||||
|
|
||||||
@ -248,7 +248,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use HMAC-SHA-384 as a PRF to generate four AES keys from one master
|
* Use KBKDF with HMAC-SHA-384 to derive four sub-keys for AES-GMAC-CTR from a single master key
|
||||||
|
*
|
||||||
|
* See section 5.1 at https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-108.pdf
|
||||||
*
|
*
|
||||||
* @param masterKey Master 256-bit key
|
* @param masterKey Master 256-bit key
|
||||||
* @param k1 GMAC key
|
* @param k1 GMAC key
|
||||||
@ -256,12 +258,20 @@ public:
|
|||||||
* @param k3 CTR IV masking (ECB encryption) key
|
* @param k3 CTR IV masking (ECB encryption) key
|
||||||
* @param k4 AES-CTR key
|
* @param k4 AES-CTR key
|
||||||
*/
|
*/
|
||||||
static inline void initGmacCtrKeys(const uint8_t masterKey[32],AES &k1,AES &k2,AES &k3,AES &k4)
|
static ZT_ALWAYS_INLINE void initGmacCtrKeys(const uint8_t masterKey[32],AES &k1,AES &k2,AES &k3,AES &k4)
|
||||||
{
|
{
|
||||||
uint64_t kbuf[6];
|
uint8_t kbuf[48];
|
||||||
for(uint8_t kno=0;kno<4;++kno) {
|
uint8_t kbkdfMsg[16];
|
||||||
HMACSHA384(masterKey,&kno,1,(uint8_t *)kbuf);
|
kbkdfMsg[0] = 0; // key iterator, incremented for each key
|
||||||
k1.init((const uint8_t *)kbuf);
|
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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,8 +143,8 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
|||||||
{
|
{
|
||||||
static Mutex globalLock;
|
static Mutex globalLock;
|
||||||
static bool initialized = false;
|
static bool initialized = false;
|
||||||
static uint64_t randomState[1024];
|
static uint64_t randomState[4];
|
||||||
static uint8_t randomBuf[65536];
|
static uint8_t randomBuf[16384];
|
||||||
static unsigned long randomPtr = sizeof(randomBuf);
|
static unsigned long randomPtr = sizeof(randomBuf);
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
static HCRYPTPROV cryptProvider = NULL;
|
static HCRYPTPROV cryptProvider = NULL;
|
||||||
@ -196,23 +196,18 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
|||||||
|
|
||||||
for(unsigned int i=0;i<bytes;++i) {
|
for(unsigned int i=0;i<bytes;++i) {
|
||||||
if (randomPtr >= sizeof(randomBuf)) {
|
if (randomPtr >= sizeof(randomBuf)) {
|
||||||
for(unsigned int k=0;k<1024;++k) {
|
randomPtr = 0;
|
||||||
|
|
||||||
|
for(unsigned int k=0;k<4;++k) {
|
||||||
if (++randomState[k])
|
if (++randomState[k])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t h[64];
|
uint8_t h[48];
|
||||||
SHA512(h,randomState,sizeof(randomState));
|
HMACSHA384((const uint8_t *)randomState,randomBuf,sizeof(randomBuf),h);
|
||||||
|
|
||||||
if (AES::HW_ACCEL) {
|
AES c(h);
|
||||||
AES c(h);
|
c.ctr(h + 32,randomBuf,sizeof(randomBuf),randomBuf);
|
||||||
c.ctr(h + 32,randomBuf,sizeof(randomBuf),randomBuf);
|
|
||||||
} else {
|
|
||||||
Salsa20 c(h,h + 32);
|
|
||||||
c.crypt12(randomBuf,randomBuf,sizeof(randomBuf));
|
|
||||||
}
|
|
||||||
|
|
||||||
randomPtr = 0;
|
|
||||||
}
|
}
|
||||||
((uint8_t *)buf)[i] = randomBuf[randomPtr++];
|
((uint8_t *)buf)[i] = randomBuf[randomPtr++];
|
||||||
}
|
}
|
||||||
|
103
selftest.cpp
103
selftest.cpp
@ -179,57 +179,62 @@ static int testCrypto()
|
|||||||
|
|
||||||
{
|
{
|
||||||
std::cout << "[crypto] Testing and benchmarking AES-256..." ZT_EOL_S << " AES-256 (test vectors): "; std::cout.flush();
|
std::cout << "[crypto] Testing and benchmarking AES-256..." ZT_EOL_S << " AES-256 (test vectors): "; std::cout.flush();
|
||||||
AES tv(AES_TEST_VECTOR_0_KEY);
|
{
|
||||||
tv.encrypt(AES_TEST_VECTOR_0_IN,(uint8_t *)buf1);
|
AES tv(AES_TEST_VECTOR_0_KEY);
|
||||||
if (memcmp(buf1,AES_TEST_VECTOR_0_OUT,16) != 0) {
|
tv.encrypt(AES_TEST_VECTOR_0_IN,(uint8_t *)buf1);
|
||||||
std::cout << "FAILED (test vector 0 encrypt)" ZT_EOL_S;
|
if (memcmp(buf1,AES_TEST_VECTOR_0_OUT,16) != 0) {
|
||||||
return -1;
|
std::cout << "FAILED (test vector 0 encrypt)" ZT_EOL_S;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
std::cout << "OK" ZT_EOL_S << " GMAC-AES-256 (test vectors): "; std::cout.flush();
|
||||||
|
tv.init(AES_GMAC_VECTOR_0_KEY);
|
||||||
|
tv.gmac(AES_GMAC_VECTOR_0_IV,AES_GMAC_VECTOR_0_IN,sizeof(AES_GMAC_VECTOR_0_IN),(uint8_t *)buf2);
|
||||||
|
if (memcmp(buf2,AES_GMAC_VECTOR_0_OUT,16) != 0) {
|
||||||
|
std::cout << "FAILED (test vector 0) (" << Utils::hex(buf2,16,hexbuf) << ")" ZT_EOL_S;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tv.init(AES_GMAC_VECTOR_1_KEY);
|
||||||
|
tv.gmac(AES_GMAC_VECTOR_1_IV,AES_GMAC_VECTOR_1_IN,sizeof(AES_GMAC_VECTOR_1_IN),(uint8_t *)buf2);
|
||||||
|
if (memcmp(buf2,AES_GMAC_VECTOR_1_OUT,16) != 0) {
|
||||||
|
std::cout << "FAILED (test vector 1) (" << Utils::hex(buf2,16,hexbuf) << ")" ZT_EOL_S;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tv.init(AES_GMAC_VECTOR_2_KEY);
|
||||||
|
tv.gmac(AES_GMAC_VECTOR_2_IV,AES_GMAC_VECTOR_2_IN,sizeof(AES_GMAC_VECTOR_2_IN),(uint8_t *)buf2);
|
||||||
|
if (memcmp(buf2,AES_GMAC_VECTOR_2_OUT,16) != 0) {
|
||||||
|
std::cout << "FAILED (test vector 2) (" << Utils::hex(buf2,16,hexbuf) << ")" ZT_EOL_S;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
std::cout << "OK" ZT_EOL_S << " GMAC-AES-256 (benchmark): "; std::cout.flush();
|
||||||
|
int64_t start = OSUtils::now();
|
||||||
|
for(unsigned long i=0;i<200000;++i) {
|
||||||
|
tv.gmac((const uint8_t *)buf1,buf1,sizeof(buf1),(uint8_t *)buf1);
|
||||||
|
}
|
||||||
|
int64_t end = OSUtils::now();
|
||||||
|
*dummy = hexbuf[0];
|
||||||
|
std::cout << (((double)(200000 * sizeof(buf1)) / 1048576.0) / ((double)(end - start) / 1000.0)) << " MiB/second" ZT_EOL_S;
|
||||||
|
std::cout << " AES-256-CTR (benchmark): "; std::cout.flush();
|
||||||
|
start = OSUtils::now();
|
||||||
|
for(unsigned long i=0;i<200000;++i) {
|
||||||
|
tv.ctr((const uint8_t *)hexbuf,buf1,sizeof(buf1),buf2);
|
||||||
|
hexbuf[0] = buf2[0];
|
||||||
|
}
|
||||||
|
end = OSUtils::now();
|
||||||
|
*dummy = buf2[0];
|
||||||
|
std::cout << (((double)(200000 * sizeof(buf1)) / 1048576.0) / ((double)(end - start) / 1000.0)) << " MiB/second" ZT_EOL_S;
|
||||||
}
|
}
|
||||||
std::cout << "OK" ZT_EOL_S << " GMAC-AES-256 (test vectors): "; std::cout.flush();
|
{
|
||||||
tv.init(AES_GMAC_VECTOR_0_KEY);
|
std::cout << " AES-256-GMAC-CTR (benchmark): "; std::cout.flush();
|
||||||
tv.gmac(AES_GMAC_VECTOR_0_IV,AES_GMAC_VECTOR_0_IN,sizeof(AES_GMAC_VECTOR_0_IN),(uint8_t *)buf2);
|
AES k1,k2,k3,k4;
|
||||||
if (memcmp(buf2,AES_GMAC_VECTOR_0_OUT,16) != 0) {
|
AES::initGmacCtrKeys(AES_TEST_VECTOR_0_KEY,k1,k2,k3,k4);
|
||||||
std::cout << "FAILED (test vector 0) (" << Utils::hex(buf2,16,hexbuf) << ")" ZT_EOL_S;
|
int64_t start = OSUtils::now();
|
||||||
return -1;
|
for(unsigned long i=0;i<200000;++i) {
|
||||||
|
AES::ztGmacCtrEncrypt(k1,k2,k3,k4,(const uint8_t *)hexbuf,buf1,sizeof(buf1),buf1,(uint8_t *)(hexbuf + 8));
|
||||||
|
*dummy = buf1[0];
|
||||||
|
}
|
||||||
|
int64_t end = OSUtils::now();
|
||||||
|
std::cout << (((double)(200000 * sizeof(buf1)) / 1048576.0) / ((double)(end - start) / 1000.0)) << " MiB/second" ZT_EOL_S;
|
||||||
}
|
}
|
||||||
tv.init(AES_GMAC_VECTOR_1_KEY);
|
|
||||||
tv.gmac(AES_GMAC_VECTOR_1_IV,AES_GMAC_VECTOR_1_IN,sizeof(AES_GMAC_VECTOR_1_IN),(uint8_t *)buf2);
|
|
||||||
if (memcmp(buf2,AES_GMAC_VECTOR_1_OUT,16) != 0) {
|
|
||||||
std::cout << "FAILED (test vector 1) (" << Utils::hex(buf2,16,hexbuf) << ")" ZT_EOL_S;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
tv.init(AES_GMAC_VECTOR_2_KEY);
|
|
||||||
tv.gmac(AES_GMAC_VECTOR_2_IV,AES_GMAC_VECTOR_2_IN,sizeof(AES_GMAC_VECTOR_2_IN),(uint8_t *)buf2);
|
|
||||||
if (memcmp(buf2,AES_GMAC_VECTOR_2_OUT,16) != 0) {
|
|
||||||
std::cout << "FAILED (test vector 2) (" << Utils::hex(buf2,16,hexbuf) << ")" ZT_EOL_S;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
std::cout << "OK" ZT_EOL_S << " GMAC-AES-256 (benchmark): "; std::cout.flush();
|
|
||||||
int64_t start = OSUtils::now();
|
|
||||||
for(unsigned long i=0;i<200000;++i) {
|
|
||||||
tv.gmac((const uint8_t *)buf1,buf1,sizeof(buf1),(uint8_t *)buf1);
|
|
||||||
}
|
|
||||||
int64_t end = OSUtils::now();
|
|
||||||
*dummy = hexbuf[0];
|
|
||||||
std::cout << (((double)(200000 * sizeof(buf1)) / 1048576.0) / ((double)(end - start) / 1000.0)) << " MiB/second" ZT_EOL_S;
|
|
||||||
std::cout << " AES-256-CTR (benchmark): "; std::cout.flush();
|
|
||||||
start = OSUtils::now();
|
|
||||||
for(unsigned long i=0;i<200000;++i) {
|
|
||||||
tv.ctr((const uint8_t *)hexbuf,buf1,sizeof(buf1),buf2);
|
|
||||||
hexbuf[0] = buf2[0];
|
|
||||||
}
|
|
||||||
end = OSUtils::now();
|
|
||||||
*dummy = buf2[0];
|
|
||||||
std::cout << (((double)(200000 * sizeof(buf1)) / 1048576.0) / ((double)(end - start) / 1000.0)) << " MiB/second" ZT_EOL_S;
|
|
||||||
std::cout << " AES-256-GMAC-CTR (benchmark): "; std::cout.flush();
|
|
||||||
start = OSUtils::now();
|
|
||||||
for(unsigned long i=0;i<200000;++i) {
|
|
||||||
AES::ztGmacCtrEncrypt(tv,tv,tv,tv,(const uint8_t *)hexbuf,buf1,sizeof(buf1),buf2,(uint8_t *)(hexbuf + 8));
|
|
||||||
hexbuf[0] = buf2[0];
|
|
||||||
}
|
|
||||||
end = OSUtils::now();
|
|
||||||
*dummy = buf2[0];
|
|
||||||
std::cout << (((double)(200000 * sizeof(buf1)) / 1048576.0) / ((double)(end - start) / 1000.0)) << " MiB/second" ZT_EOL_S;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user