This commit is contained in:
Adam Ierymenko 2020-03-26 15:55:31 -07:00
parent bedf63e257
commit 3914964a35
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
2 changed files with 27 additions and 24 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 68 KiB

View file

@ -67,9 +67,9 @@ public:
* *
* @param key 256-bit key * @param key 256-bit key
*/ */
explicit ZT_INLINE AES(const void *const key) noexcept : explicit ZT_INLINE AES(const void *const key) noexcept
AES()
{ {
Utils::memoryLock(this,sizeof(AES));
this->init(key); this->init(key);
} }
@ -277,9 +277,9 @@ public:
_output = output; _output = output;
// Initialize GMAC with 64-bit IV (and remaining 32 bits padded to zero). // Initialize GMAC with 64-bit IV (and remaining 32 bits padded to zero).
_iv[0] = iv; _tag[0] = iv;
_iv[1] = 0; _tag[1] = 0;
_gmac.init(reinterpret_cast<const uint8_t *>(_iv)); _gmac.init(reinterpret_cast<const uint8_t *>(_tag));
} }
/** /**
@ -288,6 +288,8 @@ public:
* This must be called prior to update1, finish1, etc. if there is AAD to include * This must be called prior to update1, finish1, etc. if there is AAD to include
* in the MAC that is not included in the plaintext. * in the MAC that is not included in the plaintext.
* *
* This currently only supports one chunk of AAD. Don't call multiple times per message.
*
* @param aad Additional authenticated data * @param aad Additional authenticated data
* @param len Length of AAD in bytes * @param len Length of AAD in bytes
*/ */
@ -296,8 +298,7 @@ public:
// Feed ADD into GMAC first // Feed ADD into GMAC first
_gmac.update(aad,len); _gmac.update(aad,len);
// End of AAD is padded to a multiple of 16 bytes to ensure unique encoding vs. plaintext. // End of AAD is padded to a multiple of 16 bytes to ensure unique encoding.
// AES-GCM-SIV does this as well for the same reason.
len &= 0xfU; len &= 0xfU;
if (len != 0) if (len != 0)
_gmac.update(Utils::ZERO256,16 - len); _gmac.update(Utils::ZERO256,16 - len);
@ -319,24 +320,23 @@ public:
*/ */
ZT_INLINE void finish1() noexcept ZT_INLINE void finish1() noexcept
{ {
// Compute GMAC tag, then encrypt the original 64-bit IV and the first 64 bits uint64_t tmp[2];
// of the GMAC tag with AES (single block) and use this to initialize AES-CTR.
uint64_t gmacTag[2];
_gmac.finish(reinterpret_cast<uint8_t *>(gmacTag));
_iv[1] = gmacTag[0];
_ctr._aes.encrypt(_iv,_iv);
// For CTR we need to mask the least significant 32 bits to zero for a typical // Compute 128-bit GMAC tag.
// 96-bit nonce, since this guarantees compatiblity with the most CTR implementations _gmac.finish(reinterpret_cast<uint8_t *>(tmp));
// and avoids having to do add with carry.
uint64_t ctrIv[2]; // Truncate to 64 bits, concatenate after 64-bit message IV, and encrypt with AES.
ctrIv[0] = _iv[0]; _tag[1] = tmp[0];
_ctr._aes.encrypt(_tag,_tag);
// Mask least significant 32 bits to get CTR IV and initialize CTR.
tmp[0] = _tag[0];
#if __BYTE_ORDER == __BIG_ENDIAN #if __BYTE_ORDER == __BIG_ENDIAN
ctrIv[1] = _iv[1] & 0xffffffff00000000ULL; ctrIv[1] = _iv[1] & 0xffffffff00000000ULL;
#else #else
ctrIv[1] = _iv[1] & 0x00000000ffffffffULL; tmp[1] = _tag[1] & 0x00000000ffffffffULL;
#endif #endif
_ctr.init(reinterpret_cast<const uint8_t *>(ctrIv),_output); _ctr.init(reinterpret_cast<const uint8_t *>(tmp),_output);
} }
/** /**
@ -356,17 +356,20 @@ public:
/** /**
* Finish second pass and return a pointer to the opaque 128-bit IV+MAC block * Finish second pass and return a pointer to the opaque 128-bit IV+MAC block
* *
* @return Pointer to 128-bit opaque IV+MAC * The returned pointer remains valid as long as this object exists and init()
* is not called again.
*
* @return Pointer to 128-bit opaque IV+MAC (packed into two 64-bit integers)
*/ */
ZT_INLINE const uint8_t *finish2() ZT_INLINE const uint64_t *finish2()
{ {
_ctr.finish(); _ctr.finish();
return reinterpret_cast<const uint8_t *>(_iv); return _tag;
} }
private: private:
void *_output; void *_output;
uint64_t _iv[2]; uint64_t _tag[2];
AES::GMAC _gmac; AES::GMAC _gmac;
AES::CTR _ctr; AES::CTR _ctr;
}; };