mirror of https://github.com/wolfSSL/wolfssl.git
Constant time padding and HMAC verification in TLS
parent
cc58d3160f
commit
e684156a1e
343
src/internal.c
343
src/internal.c
|
@ -146,7 +146,7 @@ static const byte tls13Downgrade[7] = {
|
|||
|
||||
#ifndef NO_OLD_TLS
|
||||
static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
|
||||
int content, int verify);
|
||||
int padSz, int content, int verify);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -11860,173 +11860,6 @@ static int SanityCheckCipherText(WOLFSSL* ssl, word32 encryptSz)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifndef NO_OLD_TLS
|
||||
|
||||
static INLINE void Md5Rounds(int rounds, const byte* data, int sz)
|
||||
{
|
||||
wc_Md5 md5;
|
||||
int i;
|
||||
|
||||
wc_InitMd5(&md5); /* no error check on purpose, dummy round */
|
||||
|
||||
for (i = 0; i < rounds; i++)
|
||||
wc_Md5Update(&md5, data, sz);
|
||||
wc_Md5Free(&md5); /* in case needed to release resources */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* do a dummy sha round */
|
||||
static INLINE void ShaRounds(int rounds, const byte* data, int sz)
|
||||
{
|
||||
wc_Sha sha;
|
||||
int i;
|
||||
|
||||
wc_InitSha(&sha); /* no error check on purpose, dummy round */
|
||||
|
||||
for (i = 0; i < rounds; i++)
|
||||
wc_ShaUpdate(&sha, data, sz);
|
||||
wc_ShaFree(&sha); /* in case needed to release resources */
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
|
||||
#ifndef NO_SHA256
|
||||
|
||||
static INLINE void Sha256Rounds(int rounds, const byte* data, int sz)
|
||||
{
|
||||
wc_Sha256 sha256;
|
||||
int i;
|
||||
|
||||
wc_InitSha256(&sha256); /* no error check on purpose, dummy round */
|
||||
|
||||
for (i = 0; i < rounds; i++) {
|
||||
wc_Sha256Update(&sha256, data, sz);
|
||||
/* no error check on purpose, dummy round */
|
||||
}
|
||||
wc_Sha256Free(&sha256); /* in case needed to release resources */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WOLFSSL_SHA384
|
||||
|
||||
static INLINE void Sha384Rounds(int rounds, const byte* data, int sz)
|
||||
{
|
||||
wc_Sha384 sha384;
|
||||
int i;
|
||||
|
||||
wc_InitSha384(&sha384); /* no error check on purpose, dummy round */
|
||||
|
||||
for (i = 0; i < rounds; i++) {
|
||||
wc_Sha384Update(&sha384, data, sz);
|
||||
/* no error check on purpose, dummy round */
|
||||
}
|
||||
wc_Sha384Free(&sha384); /* in case needed to release resources */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WOLFSSL_SHA512
|
||||
|
||||
static INLINE void Sha512Rounds(int rounds, const byte* data, int sz)
|
||||
{
|
||||
wc_Sha512 sha512;
|
||||
int i;
|
||||
|
||||
wc_InitSha512(&sha512); /* no error check on purpose, dummy round */
|
||||
|
||||
for (i = 0; i < rounds; i++) {
|
||||
wc_Sha512Update(&sha512, data, sz);
|
||||
/* no error check on purpose, dummy round */
|
||||
}
|
||||
wc_Sha512Free(&sha512); /* in case needed to release resources */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_RIPEMD
|
||||
|
||||
static INLINE void RmdRounds(int rounds, const byte* data, int sz)
|
||||
{
|
||||
RipeMd ripemd;
|
||||
int i;
|
||||
|
||||
(void)wc_InitRipeMd(&ripemd);
|
||||
|
||||
for (i = 0; i < rounds; i++)
|
||||
(void)wc_RipeMdUpdate(&ripemd, data, sz);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Do dummy rounds */
|
||||
static INLINE void DoRounds(int type, int rounds, const byte* data, int sz)
|
||||
{
|
||||
(void)rounds;
|
||||
(void)data;
|
||||
(void)sz;
|
||||
|
||||
switch (type) {
|
||||
case no_mac :
|
||||
break;
|
||||
|
||||
#ifndef NO_OLD_TLS
|
||||
#ifndef NO_MD5
|
||||
case md5_mac :
|
||||
Md5Rounds(rounds, data, sz);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA
|
||||
case sha_mac :
|
||||
ShaRounds(rounds, data, sz);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case sha256_mac :
|
||||
Sha256Rounds(rounds, data, sz);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case sha384_mac :
|
||||
Sha384Rounds(rounds, data, sz);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case sha512_mac :
|
||||
Sha512Rounds(rounds, data, sz);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_RIPEMD
|
||||
case rmd_mac :
|
||||
RmdRounds(rounds, data, sz);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Bad round type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* do number of compression rounds on dummy data */
|
||||
static INLINE void CompressRounds(WOLFSSL* ssl, int rounds, const byte* dummy)
|
||||
{
|
||||
if (rounds)
|
||||
DoRounds(ssl->specs.mac_algorithm, rounds, dummy, COMPRESS_LOWER);
|
||||
}
|
||||
|
||||
|
||||
/* check all length bytes for the pad value, return 0 on success */
|
||||
static int PadCheck(const byte* a, byte pad, int length)
|
||||
|
@ -12042,81 +11875,127 @@ static int PadCheck(const byte* a, byte pad, int length)
|
|||
}
|
||||
|
||||
|
||||
/* get compression extra rounds */
|
||||
static INLINE int GetRounds(int pLen, int padLen, int t)
|
||||
/* Mask the padding bytes with the expected values.
|
||||
* Constant time implementation - does maximum pad size possible.
|
||||
*
|
||||
* data Message data.
|
||||
* sz Size of the message including MAC and padding and padding length.
|
||||
* macSz Size of the MAC.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static byte MaskPadding(const byte* data, int sz, int macSz)
|
||||
{
|
||||
int roundL1 = 1; /* round up flags */
|
||||
int roundL2 = 1;
|
||||
int i;
|
||||
int checkSz = sz - 1;
|
||||
byte paddingSz = data[sz - 1];
|
||||
byte mask;
|
||||
byte good = ctMaskGT(paddingSz, sz - 1 - macSz);
|
||||
|
||||
int L1 = COMPRESS_CONSTANT + pLen - t;
|
||||
int L2 = COMPRESS_CONSTANT + pLen - padLen - 1 - t;
|
||||
if (checkSz > TLS_MAX_PAD_SZ)
|
||||
checkSz = TLS_MAX_PAD_SZ;
|
||||
|
||||
L1 -= COMPRESS_UPPER;
|
||||
L2 -= COMPRESS_UPPER;
|
||||
for (i = 0; i < checkSz; i++) {
|
||||
mask = ctMaskLTE(i, paddingSz);
|
||||
good |= mask & (data[sz - 1 - i] ^ paddingSz);
|
||||
}
|
||||
|
||||
if ( (L1 % COMPRESS_LOWER) == 0)
|
||||
roundL1 = 0;
|
||||
if ( (L2 % COMPRESS_LOWER) == 0)
|
||||
roundL2 = 0;
|
||||
|
||||
L1 /= COMPRESS_LOWER;
|
||||
L2 /= COMPRESS_LOWER;
|
||||
|
||||
L1 += roundL1;
|
||||
L2 += roundL2;
|
||||
|
||||
return L1 - L2;
|
||||
return good;
|
||||
}
|
||||
|
||||
/* Mask the MAC in the message with the MAC calculated.
|
||||
* Constant time implementation - starts looking for MAC where maximum padding
|
||||
* size has it.
|
||||
*
|
||||
* data Message data.
|
||||
* sz Size of the message including MAC and padding and padding length.
|
||||
* macSz Size of the MAC data.
|
||||
* expMac Expected MAC value.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static byte MaskMac(const byte* data, int sz, int macSz, byte* expMac)
|
||||
{
|
||||
int i, j;
|
||||
unsigned char mac[WC_MAX_DIGEST_SIZE];
|
||||
int scanStart = sz - 1 - TLS_MAX_PAD_SZ - macSz;
|
||||
int macEnd = sz - 1 - data[sz - 1];
|
||||
int macStart = macEnd - macSz;
|
||||
int r = 0;
|
||||
unsigned char started, notEnded;
|
||||
unsigned char good = 0;
|
||||
|
||||
if (scanStart < 0)
|
||||
scanStart = 0;
|
||||
|
||||
/* Div on Intel has different speeds depending on value.
|
||||
* Use a bitwise AND or mod a specific value (converted to mul). */
|
||||
if ((macSz & (macSz - 1)) == 0)
|
||||
r = (macSz - (scanStart - macStart)) & (macSz - 1);
|
||||
#ifndef NO_SHA
|
||||
else if (macSz == WC_SHA_DIGEST_SIZE)
|
||||
r = (macSz - (scanStart - macStart)) % WC_SHA_DIGEST_SIZE;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
else if (macSz == WC_SHA384_DIGEST_SIZE)
|
||||
r = (macSz - (scanStart - macStart)) % WC_SHA384_DIGEST_SIZE;
|
||||
#endif
|
||||
|
||||
XMEMSET(mac, 0, macSz);
|
||||
for (i = scanStart; i < sz; i += macSz) {
|
||||
for (j = 0; j < macSz && j + i < sz; j++) {
|
||||
started = ctMaskGTE(i + j, macStart);
|
||||
notEnded = ctMaskLT(i + j, macEnd);
|
||||
mac[j] |= started & notEnded & data[i + j];
|
||||
}
|
||||
}
|
||||
|
||||
if ((macSz & (macSz - 1)) == 0) {
|
||||
for (i = 0; i < macSz; i++)
|
||||
good |= expMac[i] ^ mac[(i + r) & (macSz - 1)];
|
||||
}
|
||||
#ifndef NO_SHA
|
||||
else if (macSz == WC_SHA_DIGEST_SIZE) {
|
||||
for (i = 0; i < macSz; i++)
|
||||
good |= expMac[i] ^ mac[(i + r) % WC_SHA_DIGEST_SIZE];
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
else if (macSz == WC_SHA384_DIGEST_SIZE) {
|
||||
for (i = 0; i < macSz; i++)
|
||||
good |= expMac[i] ^ mac[(i + r) % WC_SHA384_DIGEST_SIZE];
|
||||
}
|
||||
#endif
|
||||
|
||||
return good;
|
||||
}
|
||||
|
||||
/* timing resistant pad/verify check, return 0 on success */
|
||||
static int TimingPadVerify(WOLFSSL* ssl, const byte* input, int padLen, int t,
|
||||
int pLen, int content)
|
||||
int TimingPadVerify(WOLFSSL* ssl, const byte* input, int padLen, int macSz,
|
||||
int pLen, int content)
|
||||
{
|
||||
byte verify[WC_MAX_DIGEST_SIZE];
|
||||
byte dmy[sizeof(WOLFSSL) >= MAX_PAD_SIZE ? 1 : MAX_PAD_SIZE] = {0};
|
||||
byte* dummy = sizeof(dmy) < MAX_PAD_SIZE ? (byte*) ssl : dmy;
|
||||
byte good;
|
||||
int ret = 0;
|
||||
|
||||
(void)dmy;
|
||||
good = MaskPadding(input, pLen, macSz);
|
||||
ret = ssl->hmac(ssl, verify, input, pLen - macSz - padLen - 1, padLen,
|
||||
content, 1);
|
||||
good |= MaskMac(input, pLen, ssl->specs.hash_size, verify);
|
||||
|
||||
if ( (t + padLen + 1) > pLen) {
|
||||
WOLFSSL_MSG("Plain Len not long enough for pad/mac");
|
||||
PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE);
|
||||
ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */
|
||||
ConstantCompare(verify, input + pLen - t, t);
|
||||
/* Non-zero on failure. */
|
||||
good = ~good;
|
||||
good &= good >> 4;
|
||||
good &= good >> 2;
|
||||
good &= good >> 1;
|
||||
/* Make ret negative on masking failure. */
|
||||
ret -= 1 - good;
|
||||
|
||||
return VERIFY_MAC_ERROR;
|
||||
}
|
||||
|
||||
if (PadCheck(input + pLen - (padLen + 1), (byte)padLen, padLen + 1) != 0) {
|
||||
WOLFSSL_MSG("PadCheck failed");
|
||||
PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
|
||||
ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */
|
||||
ConstantCompare(verify, input + pLen - t, t);
|
||||
|
||||
return VERIFY_MAC_ERROR;
|
||||
}
|
||||
|
||||
PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
|
||||
ret = ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, content, 1);
|
||||
|
||||
CompressRounds(ssl, GetRounds(pLen, padLen, t), dummy);
|
||||
|
||||
if (ConstantCompare(verify, input + (pLen - padLen - 1 - t), t) != 0) {
|
||||
WOLFSSL_MSG("Verify MAC compare failed");
|
||||
return VERIFY_MAC_ERROR;
|
||||
}
|
||||
|
||||
/* treat any faulure as verify MAC error */
|
||||
/* Treat any faulure as verify MAC error. */
|
||||
if (ret != 0)
|
||||
ret = VERIFY_MAC_ERROR;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_NO_TLS12 */
|
||||
|
||||
|
||||
int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
|
||||
{
|
||||
|
@ -12368,8 +12247,8 @@ static INLINE int VerifyMac(WOLFSSL* ssl, const byte* input, word32 msgSz,
|
|||
badPadLen = 1;
|
||||
}
|
||||
PadCheck(dummy, (byte)pad, MAX_PAD_SIZE); /* timing only */
|
||||
ret = ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1,
|
||||
content, 1);
|
||||
ret = ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1, pad,
|
||||
content, 1);
|
||||
if (ConstantCompare(verify, input + msgSz - digestSz - pad - 1,
|
||||
digestSz) != 0)
|
||||
return VERIFY_MAC_ERROR;
|
||||
|
@ -12378,7 +12257,7 @@ static INLINE int VerifyMac(WOLFSSL* ssl, const byte* input, word32 msgSz,
|
|||
}
|
||||
}
|
||||
else if (ssl->specs.cipher_type == stream) {
|
||||
ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, content, 1);
|
||||
ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, -1, content, 1);
|
||||
if (ConstantCompare(verify, input + msgSz - digestSz, digestSz) != 0){
|
||||
return VERIFY_MAC_ERROR;
|
||||
}
|
||||
|
@ -13118,7 +12997,7 @@ int SendChangeCipher(WOLFSSL* ssl)
|
|||
|
||||
#ifndef NO_OLD_TLS
|
||||
static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
|
||||
int content, int verify)
|
||||
int padLen, int content, int verify)
|
||||
{
|
||||
byte result[WC_MAX_DIGEST_SIZE];
|
||||
word32 digestSz = ssl->specs.hash_size; /* actual sizes */
|
||||
|
@ -13133,6 +13012,8 @@ static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
|
|||
byte conLen[ENUM_LEN + LENGTH_SZ]; /* content & length */
|
||||
const byte* macSecret = wolfSSL_GetMacSecret(ssl, verify);
|
||||
|
||||
(void)padLen;
|
||||
|
||||
#ifdef HAVE_FUZZER
|
||||
if (ssl->fuzzerCb)
|
||||
ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
|
||||
|
@ -13609,8 +13490,8 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
|
|||
ERROR_OUT(MEMORY_E, exit_buildmsg);
|
||||
#endif
|
||||
|
||||
ret = ssl->hmac(ssl, hmac, output + args->headerSz + args->ivSz, inSz,
|
||||
type, 0);
|
||||
ret = ssl->hmac(ssl, hmac, output + args->headerSz + args->ivSz,
|
||||
inSz, -1, type, 0);
|
||||
XMEMCPY(output + args->idx, hmac, args->digestSz);
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
|
@ -13619,8 +13500,8 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
|
|||
}
|
||||
else
|
||||
#endif
|
||||
ret = ssl->hmac(ssl, output + args->idx, output + args->headerSz + args->ivSz,
|
||||
inSz, type, 0);
|
||||
ret = ssl->hmac(ssl, output + args->idx, output +
|
||||
args->headerSz + args->ivSz, inSz, -1, type, 0);
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls)
|
||||
DtlsSEQIncrement(ssl, CUR_ORDER);
|
||||
|
|
484
src/tls.c
484
src/tls.c
|
@ -852,13 +852,447 @@ int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content,
|
|||
}
|
||||
|
||||
|
||||
/* TLS type HMAC */
|
||||
int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
|
||||
int content, int verify)
|
||||
#if !defined(WOLFSSL_NO_HASH_RAW) && !defined(HAVE_FIPS)
|
||||
|
||||
/* Update the hash in the HMAC.
|
||||
*
|
||||
* hmac HMAC object.
|
||||
* data Data to be hashed.
|
||||
* sz Size of data to hash.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int Hmac_HashUpdate(Hmac* hmac, const byte* data, word32 sz)
|
||||
{
|
||||
Hmac hmac;
|
||||
int ret = 0;
|
||||
byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
|
||||
int ret = BAD_FUNC_ARG;
|
||||
|
||||
switch (hmac->macType) {
|
||||
#ifndef NO_SHA
|
||||
case WC_SHA:
|
||||
ret = wc_ShaUpdate(&hmac->hash.sha, data, sz);
|
||||
break;
|
||||
#endif /* !NO_SHA */
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case WC_SHA256:
|
||||
ret = wc_Sha256Update(&hmac->hash.sha256, data, sz);
|
||||
break;
|
||||
#endif /* !NO_SHA256 */
|
||||
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case WC_SHA384:
|
||||
ret = wc_Sha384Update(&hmac->hash.sha384, data, sz);
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA384 */
|
||||
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case WC_SHA512:
|
||||
ret = wc_Sha512Update(&hmac->hash.sha512, data, sz);
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA512 */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Finalize the hash but don't put the EOC, padding or length in.
|
||||
*
|
||||
* hmac HMAC object.
|
||||
* hash Hash result.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int Hmac_HashFinalRaw(Hmac* hmac, unsigned char* hash)
|
||||
{
|
||||
int ret = BAD_FUNC_ARG;
|
||||
|
||||
switch (hmac->macType) {
|
||||
#ifndef NO_SHA
|
||||
case WC_SHA:
|
||||
ret = wc_ShaFinalRaw(&hmac->hash.sha, hash);
|
||||
break;
|
||||
#endif /* !NO_SHA */
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case WC_SHA256:
|
||||
ret = wc_Sha256FinalRaw(&hmac->hash.sha256, hash);
|
||||
break;
|
||||
#endif /* !NO_SHA256 */
|
||||
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case WC_SHA384:
|
||||
ret = wc_Sha384FinalRaw(&hmac->hash.sha384, hash);
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA384 */
|
||||
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case WC_SHA512:
|
||||
ret = wc_Sha512FinalRaw(&hmac->hash.sha512, hash);
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA512 */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Finalize the HMAC by performing outer hash.
|
||||
*
|
||||
* hmac HMAC object.
|
||||
* mac MAC result.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int Hmac_OuterHash(Hmac* hmac, unsigned char* mac)
|
||||
{
|
||||
int ret = BAD_FUNC_ARG;
|
||||
|
||||
switch (hmac->macType) {
|
||||
#ifndef NO_SHA
|
||||
case WC_SHA:
|
||||
ret = wc_InitSha(&hmac->hash.sha);
|
||||
if (ret == 0)
|
||||
ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->opad,
|
||||
WC_SHA_BLOCK_SIZE);
|
||||
if (ret == 0)
|
||||
ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->innerHash,
|
||||
WC_SHA_DIGEST_SIZE);
|
||||
if (ret == 0)
|
||||
ret = wc_ShaFinal(&hmac->hash.sha, mac);
|
||||
break;
|
||||
#endif /* !NO_SHA */
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case WC_SHA256:
|
||||
ret = wc_InitSha256(&hmac->hash.sha256);
|
||||
if (ret == 0)
|
||||
ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->opad,
|
||||
WC_SHA256_BLOCK_SIZE);
|
||||
if (ret == 0)
|
||||
ret = wc_Sha256Update(&hmac->hash.sha256,
|
||||
(byte*)hmac->innerHash,
|
||||
WC_SHA256_DIGEST_SIZE);
|
||||
if (ret == 0)
|
||||
ret = wc_Sha256Final(&hmac->hash.sha256, mac);
|
||||
break;
|
||||
#endif /* !NO_SHA256 */
|
||||
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case WC_SHA384:
|
||||
ret = wc_InitSha384(&hmac->hash.sha384);
|
||||
if (ret == 0)
|
||||
ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->opad,
|
||||
WC_SHA384_BLOCK_SIZE);
|
||||
if (ret == 0)
|
||||
ret = wc_Sha384Update(&hmac->hash.sha384,
|
||||
(byte*)hmac->innerHash,
|
||||
WC_SHA384_DIGEST_SIZE);
|
||||
if (ret == 0)
|
||||
ret = wc_Sha384Final(&hmac->hash.sha384, mac);
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA384 */
|
||||
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case WC_SHA512:
|
||||
ret = wc_InitSha512(&hmac->hash.sha512);
|
||||
if (ret == 0)
|
||||
ret = wc_Sha512Update(&hmac->hash.sha512,(byte*)hmac->opad,
|
||||
WC_SHA512_BLOCK_SIZE);
|
||||
if (ret == 0)
|
||||
ret = wc_Sha512Update(&hmac->hash.sha512,
|
||||
(byte*)hmac->innerHash,
|
||||
WC_SHA512_DIGEST_SIZE);
|
||||
if (ret == 0)
|
||||
ret = wc_Sha512Final(&hmac->hash.sha512, mac);
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA512 */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Calculate the HMAC of the header + message data.
|
||||
* Constant time implementation using wc_Sha*FinalRaw().
|
||||
*
|
||||
* hmac HMAC object.
|
||||
* digest MAC result.
|
||||
* in Message data.
|
||||
* sz Size of the message data.
|
||||
* header Constructed record header with length of handshake data.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in,
|
||||
word32 sz, byte* header)
|
||||
{
|
||||
byte lenBytes[8];
|
||||
int i, j, k;
|
||||
int blockBits, blockMask;
|
||||
int realLen, lastBlockLen, macLen, extraLen, eocIndex;
|
||||
int blocks, safeBlocks, lenBlock, eocBlock;
|
||||
int maxLen;
|
||||
int blockSz, padSz;
|
||||
int ret;
|
||||
byte extraBlock;
|
||||
|
||||
switch (hmac->macType) {
|
||||
#ifndef NO_SHA
|
||||
case WC_SHA:
|
||||
blockSz = WC_SHA_BLOCK_SIZE;
|
||||
blockBits = 6;
|
||||
macLen = WC_SHA_DIGEST_SIZE;
|
||||
padSz = WC_SHA_BLOCK_SIZE - WC_SHA_PAD_SIZE + 1;
|
||||
break;
|
||||
#endif /* !NO_SHA */
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case WC_SHA256:
|
||||
blockSz = WC_SHA256_BLOCK_SIZE;
|
||||
blockBits = 6;
|
||||
macLen = WC_SHA256_DIGEST_SIZE;
|
||||
padSz = WC_SHA256_BLOCK_SIZE - WC_SHA256_PAD_SIZE + 1;
|
||||
break;
|
||||
#endif /* !NO_SHA256 */
|
||||
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case WC_SHA384:
|
||||
blockSz = WC_SHA384_BLOCK_SIZE;
|
||||
blockBits = 7;
|
||||
macLen = WC_SHA384_DIGEST_SIZE;
|
||||
padSz = WC_SHA384_BLOCK_SIZE - WC_SHA384_PAD_SIZE + 1;
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA384 */
|
||||
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case WC_SHA512:
|
||||
blockSz = WC_SHA512_BLOCK_SIZE;
|
||||
blockBits = 7;
|
||||
macLen = WC_SHA512_DIGEST_SIZE;
|
||||
padSz = WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE + 1;
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA512 */
|
||||
|
||||
default:
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
blockMask = blockSz - 1;
|
||||
|
||||
/* Size of data to HMAC if padding length byte is zero. */
|
||||
maxLen = WOLFSSL_TLS_HMAC_INNER_SZ + sz - 1 - macLen;
|
||||
/* Complete data (including padding) has block for EOC and/or length. */
|
||||
extraBlock = ctSetLTE((maxLen + padSz) & blockMask, padSz);
|
||||
/* Total number of blocks for data including padding. */
|
||||
blocks = ((maxLen + blockSz - 1) >> blockBits) + extraBlock;
|
||||
/* Up to last 6 blocks can be hashed safely. */
|
||||
safeBlocks = blocks - 6;
|
||||
|
||||
/* Length of message data. */
|
||||
realLen = maxLen - in[sz - 1];
|
||||
/* Number of message bytes in last block. */
|
||||
lastBlockLen = realLen & blockMask;
|
||||
/* Number of padding bytes in last block. */
|
||||
extraLen = ((blockSz * 2 - padSz - lastBlockLen) & blockMask) + 1;
|
||||
/* Number of blocks to create for hash. */
|
||||
lenBlock = (realLen + extraLen) >> blockBits;
|
||||
/* Block containing EOC byte. */
|
||||
eocBlock = realLen >> blockBits;
|
||||
/* Index of EOC byte in block. */
|
||||
eocIndex = realLen & blockMask;
|
||||
|
||||
/* Add length of hmac's ipad to total length. */
|
||||
realLen += blockSz;
|
||||
/* Length as bits - 8 bytes bigendian. */
|
||||
c32toa(realLen >> ((sizeof(word32) * 8) - 3), lenBytes);
|
||||
c32toa(realLen << 3, lenBytes + sizeof(word32));
|
||||
|
||||
ret = Hmac_HashUpdate(hmac, (unsigned char*)hmac->ipad, blockSz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
XMEMSET(hmac->innerHash, 0, macLen);
|
||||
|
||||
if (safeBlocks > 0) {
|
||||
ret = Hmac_HashUpdate(hmac, header, WOLFSSL_TLS_HMAC_INNER_SZ);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = Hmac_HashUpdate(hmac, in, safeBlocks * blockSz -
|
||||
WOLFSSL_TLS_HMAC_INNER_SZ);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
safeBlocks = 0;
|
||||
|
||||
XMEMSET(digest, 0, macLen);
|
||||
k = safeBlocks * blockSz;
|
||||
for (i = safeBlocks; i < blocks; i++) {
|
||||
unsigned char hashBlock[WC_MAX_BLOCK_SIZE];
|
||||
unsigned char isEocBlock = ctMaskEq(i, eocBlock);
|
||||
unsigned char isOutBlock = ctMaskEq(i, lenBlock);
|
||||
|
||||
for (j = 0; j < blockSz; j++, k++) {
|
||||
unsigned char atEoc = ctMaskEq(j, eocIndex) & isEocBlock;
|
||||
unsigned char pastEoc = ctMaskGT(j, eocIndex) & isEocBlock;
|
||||
unsigned char b = 0;
|
||||
|
||||
if (k < WOLFSSL_TLS_HMAC_INNER_SZ)
|
||||
b = header[k];
|
||||
else if (k < maxLen)
|
||||
b = in[k - WOLFSSL_TLS_HMAC_INNER_SZ];
|
||||
|
||||
b = ctMaskSel(atEoc, b, 0x80);
|
||||
b &= ~pastEoc;
|
||||
b &= ~isOutBlock | isEocBlock;
|
||||
|
||||
if (j >= blockSz - 8) {
|
||||
b = ctMaskSel(isOutBlock, b, lenBytes[j - (blockSz - 8)]);
|
||||
}
|
||||
|
||||
hashBlock[j] = b;
|
||||
}
|
||||
|
||||
ret = Hmac_HashUpdate(hmac, hashBlock, blockSz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = Hmac_HashFinalRaw(hmac, hashBlock);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
for (j = 0; j < macLen; j++)
|
||||
((unsigned char*)hmac->innerHash)[j] |= hashBlock[j] & isOutBlock;
|
||||
}
|
||||
|
||||
ret = Hmac_OuterHash(hmac, digest);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_NO_HASH_RAW) || defined(HAVE_FIPS) || defined(HAVE_BLAKE2)
|
||||
|
||||
/* Calculate the HMAC of the header + message data.
|
||||
* Constant time implementation using normal hashing operations.
|
||||
* Update-Final need to be constant time.
|
||||
*
|
||||
* hmac HMAC object.
|
||||
* digest MAC result.
|
||||
* in Message data.
|
||||
* sz Size of the message data.
|
||||
* header Constructed record header with length of handshake data.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int Hmac_UpdateFinal(Hmac* hmac, byte* digest, const byte* in,
|
||||
word32 sz, byte* header)
|
||||
{
|
||||
byte dummy[WC_MAX_BLOCK_SIZE] = {0};
|
||||
int ret;
|
||||
word32 msgSz, blockSz, macSz, padSz, maxSz, realSz;
|
||||
word32 currSz, offset;
|
||||
int msgBlocks, blocks, blockBits;
|
||||
int i;
|
||||
|
||||
switch (hmac->macType) {
|
||||
#ifndef NO_SHA
|
||||
case WC_SHA:
|
||||
blockSz = WC_SHA_BLOCK_SIZE;
|
||||
blockBits = 6;
|
||||
macSz = WC_SHA_DIGEST_SIZE;
|
||||
padSz = WC_SHA_BLOCK_SIZE - WC_SHA_PAD_SIZE + 1;
|
||||
break;
|
||||
#endif /* !NO_SHA */
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case WC_SHA256:
|
||||
blockSz = WC_SHA256_BLOCK_SIZE;
|
||||
blockBits = 6;
|
||||
macSz = WC_SHA256_DIGEST_SIZE;
|
||||
padSz = WC_SHA256_BLOCK_SIZE - WC_SHA256_PAD_SIZE + 1;
|
||||
break;
|
||||
#endif /* !NO_SHA256 */
|
||||
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case WC_SHA384:
|
||||
blockSz = WC_SHA384_BLOCK_SIZE;
|
||||
blockBits = 7;
|
||||
macSz = WC_SHA384_DIGEST_SIZE;
|
||||
padSz = WC_SHA384_BLOCK_SIZE - WC_SHA384_PAD_SIZE + 1;
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA384 */
|
||||
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case WC_SHA512:
|
||||
blockSz = WC_SHA512_BLOCK_SIZE;
|
||||
blockBits = 7;
|
||||
macSz = WC_SHA512_DIGEST_SIZE;
|
||||
padSz = WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE + 1;
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA512 */
|
||||
|
||||
#ifdef HAVE_BLAKE2
|
||||
case WC_HASH_TYPE_BLAKE2B:
|
||||
blockSz = BLAKE2B_BLOCKBYTES;
|
||||
blockBits = 7;
|
||||
macSz = BLAKE2B_256;
|
||||
padSz = 0;
|
||||
break;
|
||||
#endif /* HAVE_BLAK2 */
|
||||
|
||||
default:
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
msgSz = sz - (1 + in[sz - 1] + macSz);
|
||||
/* Make negative result 0 */
|
||||
msgSz &= ~(0 - (msgSz >> 31));
|
||||
realSz = WOLFSSL_TLS_HMAC_INNER_SZ + msgSz;
|
||||
maxSz = WOLFSSL_TLS_HMAC_INNER_SZ + (sz - 1) - macSz;
|
||||
|
||||
/* Calculate #blocks processed in HMAC for max and real data. */
|
||||
blocks = maxSz >> blockBits;
|
||||
blocks += ((maxSz + padSz) % blockSz) < padSz;
|
||||
msgBlocks = realSz >> blockBits;
|
||||
/* #Extra blocks to process. */
|
||||
blocks -= msgBlocks + (((realSz + padSz) % blockSz) < padSz);
|
||||
/* Calculate whole blocks. */
|
||||
msgBlocks--;
|
||||
|
||||
ret = wc_HmacUpdate(hmac, header, WOLFSSL_TLS_HMAC_INNER_SZ);
|
||||
if (ret == 0) {
|
||||
/* Fill the rest of the block with any available data. */
|
||||
currSz = ctMaskLT(msgSz, blockSz) & msgSz;
|
||||
currSz |= ctMaskGTE(msgSz, blockSz) & blockSz;
|
||||
currSz -= WOLFSSL_TLS_HMAC_INNER_SZ;
|
||||
currSz &= ~(0 - (currSz >> 31));
|
||||
ret = wc_HmacUpdate(hmac, in, currSz);
|
||||
offset = currSz;
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* Do the hash operations on a block basis. */
|
||||
for (i = 0; i < msgBlocks; i++, offset += blockSz) {
|
||||
ret = wc_HmacUpdate(hmac, in + offset, blockSz);
|
||||
if (ret != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret == 0)
|
||||
ret = wc_HmacUpdate(hmac, in + offset, msgSz - offset);
|
||||
if (ret == 0)
|
||||
ret = wc_HmacFinal(hmac, digest);
|
||||
if (ret == 0) {
|
||||
/* Do the dummy hash operations. Do at least one. */
|
||||
for (i = 0; i < blocks + 1; i++) {
|
||||
ret = wc_HmacUpdate(hmac, dummy, blockSz);
|
||||
if (ret != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz,
|
||||
int content, int verify)
|
||||
{
|
||||
Hmac hmac;
|
||||
byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
|
||||
int ret = 0;
|
||||
|
||||
if (ssl == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
@ -875,14 +1309,40 @@ int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
|
|||
return ret;
|
||||
|
||||
ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
|
||||
wolfSSL_GetMacSecret(ssl, verify), ssl->specs.hash_size);
|
||||
wolfSSL_GetMacSecret(ssl, verify),
|
||||
ssl->specs.hash_size);
|
||||
if (ret == 0) {
|
||||
ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
|
||||
if (ret == 0)
|
||||
ret = wc_HmacUpdate(&hmac, in, sz); /* content */
|
||||
if (ret == 0)
|
||||
ret = wc_HmacFinal(&hmac, digest);
|
||||
/* Constant time verification required. */
|
||||
if (verify && padSz >= 0) {
|
||||
#if !defined(WOLFSSL_NO_HASH_RAW) && !defined(HAVE_FIPS)
|
||||
#ifdef HAVE_BLAKE2
|
||||
if (wolfSSL_GetHmacType(ssl) == WC_HASH_TYPE_BLAKE2B) {
|
||||
ret = Hmac_UpdateFinal(&hmac, digest, in, sz +
|
||||
ssl->specs.hash_size + padSz + 1,
|
||||
myInner);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ret = Hmac_UpdateFinal_CT(&hmac, digest, in, sz +
|
||||
ssl->specs.hash_size + padSz + 1,
|
||||
myInner);
|
||||
}
|
||||
#else
|
||||
ret = Hmac_UpdateFinal(&hmac, digest, in, sz +
|
||||
ssl->specs.hash_size + padSz + 1,
|
||||
myInner);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
|
||||
if (ret == 0)
|
||||
ret = wc_HmacUpdate(&hmac, in, sz); /* content */
|
||||
if (ret == 0)
|
||||
ret = wc_HmacFinal(&hmac, digest);
|
||||
}
|
||||
}
|
||||
|
||||
wc_HmacFree(&hmac);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -311,6 +311,48 @@ STATIC INLINE word32 btoi(byte b)
|
|||
}
|
||||
|
||||
|
||||
/* Constant time - mask set when a > b. */
|
||||
STATIC INLINE byte ctMaskGT(int a, int b)
|
||||
{
|
||||
return (((word32)a - b - 1) >> 31) - 1;
|
||||
}
|
||||
|
||||
/* Constant time - mask set when a >= b. */
|
||||
STATIC INLINE byte ctMaskGTE(int a, int b)
|
||||
{
|
||||
return (((word32)a - b ) >> 31) - 1;
|
||||
}
|
||||
|
||||
/* Constant time - mask set when a < b. */
|
||||
STATIC INLINE byte ctMaskLT(int a, int b)
|
||||
{
|
||||
return (((word32)b - a - 1) >> 31) - 1;
|
||||
}
|
||||
|
||||
/* Constant time - mask set when a <= b. */
|
||||
STATIC INLINE byte ctMaskLTE(int a, int b)
|
||||
{
|
||||
return (((word32)b - a ) >> 31) - 1;
|
||||
}
|
||||
|
||||
/* Constant time - mask set when a == b. */
|
||||
STATIC INLINE byte ctMaskEq(int a, int b)
|
||||
{
|
||||
return 0 - (a == b);
|
||||
}
|
||||
|
||||
/* Constant time - select b when mask is set and a otherwise. */
|
||||
STATIC INLINE byte ctMaskSel(byte m, byte a, byte b)
|
||||
{
|
||||
return (a & ~m) | (b & m);
|
||||
}
|
||||
|
||||
/* Constant time - bit set when a <= b. */
|
||||
STATIC INLINE byte ctSetLTE(int a, int b)
|
||||
{
|
||||
return ((word32)a - b - 1) >> 31;
|
||||
}
|
||||
|
||||
|
||||
#undef STATIC
|
||||
|
||||
|
|
|
@ -431,6 +431,20 @@ int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int wc_ShaFinalRaw(wc_Sha* sha, byte* hash)
|
||||
{
|
||||
if (sha == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
XMEMCPY(hash, sha->digest, WC_SHA_DIGEST_SIZE);
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords((word32*)hash, (word32*)hash, WC_SHA_DIGEST_SIZE);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wc_ShaFinal(wc_Sha* sha, byte* hash)
|
||||
{
|
||||
byte* local;
|
||||
|
|
|
@ -765,6 +765,20 @@ static int InitSha256(wc_Sha256* sha256)
|
|||
return XTRANSFORM(sha256);
|
||||
}
|
||||
|
||||
int wc_Sha256FinalRaw(wc_Sha256* sha256, byte* hash)
|
||||
{
|
||||
if (sha256 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
XMEMCPY(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);
|
||||
#if defined(LITTLE_ENDIAN_ORDER)
|
||||
ByteReverseWords((word32*)hash, (word32*)hash, WC_SHA256_DIGEST_SIZE);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
|
||||
{
|
||||
int ret;
|
||||
|
|
|
@ -695,6 +695,20 @@ static INLINE int Sha512Final(wc_Sha512* sha512)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int wc_Sha512FinalRaw(wc_Sha512* sha512, byte* hash)
|
||||
{
|
||||
if (sha512 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
XMEMCPY(hash, sha512->digest, WC_SHA512_DIGEST_SIZE);
|
||||
#if defined(LITTLE_ENDIAN_ORDER)
|
||||
ByteReverseWords64((word64*)hash, (word64*)hash, WC_SHA512_DIGEST_SIZE);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wc_Sha512Final(wc_Sha512* sha512, byte* hash)
|
||||
{
|
||||
int ret;
|
||||
|
@ -2588,6 +2602,20 @@ int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)
|
|||
}
|
||||
|
||||
|
||||
int wc_Sha384FinalRaw(wc_Sha384* sha384, byte* hash)
|
||||
{
|
||||
if (sha384 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
XMEMCPY(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
|
||||
#if defined(LITTLE_ENDIAN_ORDER)
|
||||
ByteReverseWords64((word64*)hash, (word64*)hash, WC_SHA384_DIGEST_SIZE);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
|
||||
{
|
||||
int ret;
|
||||
|
|
|
@ -1095,10 +1095,6 @@ enum Misc {
|
|||
PAD_MD5 = 48, /* pad length for finished */
|
||||
PAD_SHA = 40, /* pad length for finished */
|
||||
MAX_PAD_SIZE = 256, /* maximum length of padding */
|
||||
COMPRESS_DUMMY_SIZE = 64, /* compression dummy round size */
|
||||
COMPRESS_CONSTANT = 13, /* compression calc constant */
|
||||
COMPRESS_UPPER = 55, /* compression calc numerator */
|
||||
COMPRESS_LOWER = 64, /* compression calc denominator */
|
||||
|
||||
LENGTH_SZ = 2, /* length field for HMAC, data only */
|
||||
VERSION_SZ = 2, /* length of proctocol version */
|
||||
|
@ -1181,6 +1177,7 @@ enum Misc {
|
|||
OPAQUE8_LEN + WC_MAX_DIGEST_SIZE,
|
||||
MAX_REQUEST_SZ = 256, /* Maximum cert req len (no auth yet */
|
||||
SESSION_FLUSH_COUNT = 256, /* Flush session cache unless user turns off */
|
||||
TLS_MAX_PAD_SZ = 255, /* Max padding in TLS */
|
||||
|
||||
#ifdef HAVE_FIPS
|
||||
MAX_SYM_KEY_SIZE = AES_256_KEY_SIZE,
|
||||
|
@ -1550,6 +1547,8 @@ WOLFSSL_LOCAL int DoTls13ServerHello(WOLFSSL* ssl, const byte* input,
|
|||
word32* inOutIdx, word32 helloSz,
|
||||
byte* extMsgType);
|
||||
#endif
|
||||
int TimingPadVerify(WOLFSSL* ssl, const byte* input, int padLen, int t,
|
||||
int pLen, int content);
|
||||
|
||||
|
||||
enum {
|
||||
|
@ -2853,7 +2852,7 @@ WOLFSSL_SESSION* GetSession(WOLFSSL*, byte*, byte);
|
|||
WOLFSSL_LOCAL
|
||||
int SetSession(WOLFSSL*, WOLFSSL_SESSION*);
|
||||
|
||||
typedef int (*hmacfp) (WOLFSSL*, byte*, const byte*, word32, int, int);
|
||||
typedef int (*hmacfp) (WOLFSSL*, byte*, const byte*, word32, int, int, int);
|
||||
|
||||
#ifndef NO_CLIENT_CACHE
|
||||
WOLFSSL_SESSION* GetSessionClient(WOLFSSL*, const byte*, int);
|
||||
|
@ -3942,7 +3941,7 @@ WOLFSSL_LOCAL int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength);
|
|||
#ifndef NO_TLS
|
||||
WOLFSSL_LOCAL int MakeTlsMasterSecret(WOLFSSL*);
|
||||
WOLFSSL_LOCAL int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in,
|
||||
word32 sz, int content, int verify);
|
||||
word32 sz, int padSz, int content, int verify);
|
||||
#endif
|
||||
|
||||
#ifndef NO_WOLFSSL_CLIENT
|
||||
|
|
|
@ -91,6 +91,15 @@ void ato24(const byte* c, word32* u24);
|
|||
void ato32(const byte* c, word32* u32);
|
||||
word32 btoi(byte b);
|
||||
|
||||
|
||||
WOLFSSL_LOCAL byte ctMaskGT(int a, int b);
|
||||
WOLFSSL_LOCAL byte ctMaskGTE(int a, int b);
|
||||
WOLFSSL_LOCAL byte ctMaskLT(int a, int b);
|
||||
WOLFSSL_LOCAL byte ctMaskLTE(int a, int b);
|
||||
WOLFSSL_LOCAL byte ctMaskEq(int a, int b);
|
||||
WOLFSSL_LOCAL byte ctMaskSel(byte m, byte a, byte b);
|
||||
WOLFSSL_LOCAL byte ctSetLTE(int a, int b);
|
||||
|
||||
#endif /* NO_INLINE */
|
||||
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include <wolfssl/wolfcrypt/types.h>
|
||||
|
||||
#define WOLFSSL_NO_HASH_RAW
|
||||
|
||||
#ifndef WC_CAAM_CTXLEN
|
||||
/* last 8 bytes of context is for length */
|
||||
#define WC_CAAM_CTXLEN 8
|
||||
|
|
|
@ -196,6 +196,8 @@ int wc_Pic32DesCrypt(word32 *key, int keyLen, word32 *iv, int ivLen,
|
|||
#endif
|
||||
|
||||
#ifdef WOLFSSL_PIC32MZ_HASH
|
||||
#define WOLFSSL_NO_HASH_RAW
|
||||
|
||||
int wc_Pic32Hash(const byte* in, int inLen, word32* out, int outLen, int algo);
|
||||
int wc_Pic32HashCopy(hashUpdCache* src, hashUpdCache* dst);
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#ifdef STM32_HASH
|
||||
|
||||
#define WOLFSSL_NO_HASH_RAW
|
||||
|
||||
/* Generic STM32 Hashing Function */
|
||||
/* Supports CubeMX HAL or Standard Peripheral Library */
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#define WOLFSSL_MAX_HASH_SIZE 64
|
||||
#endif
|
||||
|
||||
#define WOLFSSL_NO_HASH_RAW
|
||||
|
||||
typedef struct {
|
||||
byte *msg;
|
||||
word32 used;
|
||||
|
|
|
@ -122,6 +122,7 @@ typedef struct wc_Sha {
|
|||
WOLFSSL_API int wc_InitSha(wc_Sha*);
|
||||
WOLFSSL_API int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId);
|
||||
WOLFSSL_API int wc_ShaUpdate(wc_Sha*, const byte*, word32);
|
||||
WOLFSSL_API int wc_ShaFinalRaw(wc_Sha*, byte*);
|
||||
WOLFSSL_API int wc_ShaFinal(wc_Sha*, byte*);
|
||||
WOLFSSL_API void wc_ShaFree(wc_Sha*);
|
||||
|
||||
|
|
|
@ -139,6 +139,7 @@ typedef struct wc_Sha256 {
|
|||
WOLFSSL_API int wc_InitSha256(wc_Sha256*);
|
||||
WOLFSSL_API int wc_InitSha256_ex(wc_Sha256*, void*, int);
|
||||
WOLFSSL_API int wc_Sha256Update(wc_Sha256*, const byte*, word32);
|
||||
WOLFSSL_API int wc_Sha256FinalRaw(wc_Sha256*, byte*);
|
||||
WOLFSSL_API int wc_Sha256Final(wc_Sha256*, byte*);
|
||||
WOLFSSL_API void wc_Sha256Free(wc_Sha256*);
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ typedef struct wc_Sha512 {
|
|||
WOLFSSL_API int wc_InitSha512(wc_Sha512*);
|
||||
WOLFSSL_API int wc_InitSha512_ex(wc_Sha512*, void*, int);
|
||||
WOLFSSL_API int wc_Sha512Update(wc_Sha512*, const byte*, word32);
|
||||
WOLFSSL_API int wc_Sha512FinalRaw(wc_Sha512*, byte*);
|
||||
WOLFSSL_API int wc_Sha512Final(wc_Sha512*, byte*);
|
||||
WOLFSSL_API void wc_Sha512Free(wc_Sha512*);
|
||||
|
||||
|
@ -144,6 +145,7 @@ typedef wc_Sha512 wc_Sha384;
|
|||
WOLFSSL_API int wc_InitSha384(wc_Sha384*);
|
||||
WOLFSSL_API int wc_InitSha384_ex(wc_Sha384*, void*, int);
|
||||
WOLFSSL_API int wc_Sha384Update(wc_Sha384*, const byte*, word32);
|
||||
WOLFSSL_API int wc_Sha384FinalRaw(wc_Sha384*, byte*);
|
||||
WOLFSSL_API int wc_Sha384Final(wc_Sha384*, byte*);
|
||||
WOLFSSL_API void wc_Sha384Free(wc_Sha384*);
|
||||
|
||||
|
|
Loading…
Reference in New Issue