add HMAC-KDF

This commit is contained in:
toddouska
2013-10-31 18:03:00 -07:00
parent c88d0d5739
commit 5e00d62ea3
4 changed files with 236 additions and 4 deletions

View File

@@ -85,6 +85,7 @@ static int InitHmac(Hmac* hmac, int type)
#endif
default:
return BAD_FUNC_ARG;
break;
}
@@ -92,18 +93,21 @@ static int InitHmac(Hmac* hmac, int type)
}
void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
int HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
{
byte* ip = (byte*) hmac->ipad;
byte* op = (byte*) hmac->opad;
word32 i, hmac_block_size = 0;
int ret;
#ifdef HAVE_CAVIUM
if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC)
return HmacCaviumSetKey(hmac, type, key, length);
#endif
InitHmac(hmac, type);
ret = InitHmac(hmac, type);
if (ret != 0)
return ret;
switch (hmac->macType) {
#ifndef NO_MD5
@@ -203,7 +207,7 @@ void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
#endif
default:
break;
return BAD_FUNC_ARG;
}
if (length < hmac_block_size)
XMEMSET(ip + length, 0, hmac_block_size - length);
@@ -212,6 +216,7 @@ void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
op[i] = ip[i] ^ OPAD;
ip[i] ^= IPAD;
}
return 0;
}
@@ -541,5 +546,121 @@ int CyaSSL_GetHmacMaxSize(void)
return MAX_DIGEST_SIZE;
}
#ifdef HAVE_HKDF
#ifndef min
static INLINE word32 min(word32 a, word32 b)
{
return a > b ? b : a;
}
#endif /* min */
static INLINE int GetHashSizeByType(int type)
{
if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384
|| type == SHA512 || type == BLAKE2B_ID))
return BAD_FUNC_ARG;
switch (type) {
#ifndef NO_MD5
case MD5:
return MD5_DIGEST_SIZE;
break;
#endif
#ifndef NO_SHA
case SHA:
return SHA_DIGEST_SIZE;
break;
#endif
#ifndef NO_SHA256
case SHA256:
return SHA256_DIGEST_SIZE;
break;
#endif
#ifdef CYASSL_SHA384
case SHA384:
return SHA384_DIGEST_SIZE;
break;
#endif
#ifdef CYASSL_SHA512
case SHA512:
return SHA512_DIGEST_SIZE;
break;
#endif
#ifdef HAVE_BLAKE2
case BLAKE2B_ID:
return BLAKE2B_OUTBYTES;
break;
#endif
default:
return BAD_FUNC_ARG;
break;
}
}
/* HMAC-KDF with hash type, optional salt and info, return 0 on success */
int HKDF(int type, const byte* inKey, word32 inKeySz,
const byte* salt, word32 saltSz,
const byte* info, word32 infoSz,
byte* out, word32 outSz)
{
Hmac myHmac;
byte tmp[MAX_DIGEST_SIZE]; /* localSalt helper and T */
byte prk[MAX_DIGEST_SIZE];
const byte* localSalt; /* either points to user input or tmp */
int hashSz = GetHashSizeByType(type);
word32 outIdx = 0;
byte n = 0x1;
if (hashSz < 0)
return BAD_FUNC_ARG;
localSalt = salt;
if (localSalt == NULL) {
XMEMSET(tmp, 0, hashSz);
localSalt = tmp;
saltSz = hashSz;
}
if (HmacSetKey(&myHmac, type, localSalt, saltSz) != 0)
return BAD_FUNC_ARG;
HmacUpdate(&myHmac, inKey, inKeySz);
HmacFinal(&myHmac, prk);
while (outIdx < outSz) {
int tmpSz = (n == 1) ? 0 : hashSz;
word32 left = outSz - outIdx;
if (HmacSetKey(&myHmac, type, prk, hashSz) != 0)
return BAD_FUNC_ARG;
HmacUpdate(&myHmac, tmp, tmpSz);
HmacUpdate(&myHmac, info, infoSz);
HmacUpdate(&myHmac, &n, 1);
HmacFinal(&myHmac, tmp);
left = min(left, (word32)hashSz);
XMEMCPY(out+outIdx, tmp, left);
outIdx += hashSz;
n++;
}
return 0;
}
#endif /* HAVE_HKDF */
#endif /* NO_HMAC */