|
|
@ -387,43 +387,57 @@ namespace crypto |
|
|
|
const uint64_t IPAD = 0x3636363636363636; |
|
|
|
const uint64_t IPAD = 0x3636363636363636; |
|
|
|
const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C; |
|
|
|
const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const uint64_t ipads[] = { IPAD, IPAD, IPAD, IPAD }; |
|
|
|
|
|
|
|
static const uint64_t opads[] = { OPAD, OPAD, OPAD, OPAD }; |
|
|
|
|
|
|
|
|
|
|
|
void HMACMD5Digest (uint8_t * msg, size_t len, const MACKey& key, uint8_t * digest) |
|
|
|
void HMACMD5Digest (uint8_t * msg, size_t len, const MACKey& key, uint8_t * digest) |
|
|
|
// key is 32 bytes
|
|
|
|
// key is 32 bytes
|
|
|
|
// digest is 16 bytes
|
|
|
|
// digest is 16 bytes
|
|
|
|
// block size is 64 bytes
|
|
|
|
// block size is 64 bytes
|
|
|
|
{ |
|
|
|
{ |
|
|
|
uint64_t buf[256]; |
|
|
|
uint64_t buf[256]; |
|
|
|
|
|
|
|
uint64_t hash[12]; // 96 bytes
|
|
|
|
|
|
|
|
#if defined(__AVX__) // for AVX
|
|
|
|
|
|
|
|
__asm__ |
|
|
|
|
|
|
|
( |
|
|
|
|
|
|
|
"vmovups %[key], %%ymm0 \n" |
|
|
|
|
|
|
|
"vmovups %[ipad], %%ymm1 \n" |
|
|
|
|
|
|
|
"vmovups %%ymm1, 32%[buf] \n" |
|
|
|
|
|
|
|
"vxorps %%ymm0, %%ymm1, %%ymm1 \n" |
|
|
|
|
|
|
|
"vmovups %%ymm1, %[buf] \n" |
|
|
|
|
|
|
|
"vmovups %[opad], %%ymm1 \n" |
|
|
|
|
|
|
|
"vmovups %%ymm1, 32%[hash] \n" |
|
|
|
|
|
|
|
"vxorps %%ymm0, %%ymm1, %%ymm1 \n" |
|
|
|
|
|
|
|
"vmovups %%ymm1, %[hash] \n" |
|
|
|
|
|
|
|
: [buf]"=m"(*buf), [hash]"=m"(*hash) |
|
|
|
|
|
|
|
: [key]"m"(*(const uint8_t *)key), [ipad]"m"(*ipads), [opad]"m"(*opads) |
|
|
|
|
|
|
|
: "memory", "%xmm0", "%xmm1" // should be replaced by %ymm0/1 once supported by compiler
|
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
#else |
|
|
|
// ikeypad
|
|
|
|
// ikeypad
|
|
|
|
buf[0] = key.GetLL ()[0] ^ IPAD; |
|
|
|
buf[0] = key.GetLL ()[0] ^ IPAD; |
|
|
|
buf[1] = key.GetLL ()[1] ^ IPAD; |
|
|
|
buf[1] = key.GetLL ()[1] ^ IPAD; |
|
|
|
buf[2] = key.GetLL ()[2] ^ IPAD; |
|
|
|
buf[2] = key.GetLL ()[2] ^ IPAD; |
|
|
|
buf[3] = key.GetLL ()[3] ^ IPAD; |
|
|
|
buf[3] = key.GetLL ()[3] ^ IPAD; |
|
|
|
buf[4] = IPAD; |
|
|
|
memcpy (buf + 4, ipads, 32); |
|
|
|
buf[5] = IPAD; |
|
|
|
// okeypad
|
|
|
|
buf[6] = IPAD; |
|
|
|
hash[0] = key.GetLL ()[0] ^ OPAD; |
|
|
|
buf[7] = IPAD; |
|
|
|
hash[1] = key.GetLL ()[1] ^ OPAD; |
|
|
|
|
|
|
|
hash[2] = key.GetLL ()[2] ^ OPAD; |
|
|
|
|
|
|
|
hash[3] = key.GetLL ()[3] ^ OPAD; |
|
|
|
|
|
|
|
memcpy (hash + 4, opads, 32); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
// concatenate with msg
|
|
|
|
// concatenate with msg
|
|
|
|
memcpy (buf + 8, msg, len); |
|
|
|
memcpy (buf + 8, msg, len); |
|
|
|
// calculate first hash
|
|
|
|
// calculate first hash
|
|
|
|
uint8_t hash[16]; // MD5
|
|
|
|
MD5((uint8_t *)buf, len + 64, (uint8_t *)(hash + 8)); // 16 bytes
|
|
|
|
MD5((uint8_t *)buf, len + 64, hash); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// okeypad
|
|
|
|
// fill last 16 bytes with zeros (first hash size assumed 32 bytes in I2P)
|
|
|
|
buf[0] = key.GetLL ()[0] ^ OPAD; |
|
|
|
memset (hash + 10, 0, 16); |
|
|
|
buf[1] = key.GetLL ()[1] ^ OPAD; |
|
|
|
|
|
|
|
buf[2] = key.GetLL ()[2] ^ OPAD; |
|
|
|
|
|
|
|
buf[3] = key.GetLL ()[3] ^ OPAD; |
|
|
|
|
|
|
|
buf[4] = OPAD; |
|
|
|
|
|
|
|
buf[5] = OPAD; |
|
|
|
|
|
|
|
buf[6] = OPAD; |
|
|
|
|
|
|
|
buf[7] = OPAD; |
|
|
|
|
|
|
|
// copy first hash after okeypad
|
|
|
|
|
|
|
|
memcpy (buf + 8, hash, 16); |
|
|
|
|
|
|
|
// fill next 16 bytes with zeros (first hash size assumed 32 bytes in I2P)
|
|
|
|
|
|
|
|
memset (buf + 10, 0, 16); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// calculate digest
|
|
|
|
// calculate digest
|
|
|
|
MD5((uint8_t *)buf, 96, digest); |
|
|
|
MD5((uint8_t *)hash, 96, digest); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// AES
|
|
|
|
// AES
|
|
|
|