mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-01 03:34:39 +02:00
TLS v1.2 and PSS
Cleanup the TLS v1.3 PSS code as well. Added RSA API wc_RsaPSS_CheckPadding() to check the padding - no longer a simple memcmp with the digest.
This commit is contained in:
24
configure.ac
24
configure.ac
@@ -243,7 +243,6 @@ AC_ARG_ENABLE([tls13],
|
||||
if test "$ENABLED_TLS13" = "yes"
|
||||
then
|
||||
AM_CFLAGS="-DWOLFSSL_TLS13 -DHAVE_TLS_EXTENSIONS -DHAVE_FFDHE_2048 $AM_CFLAGS"
|
||||
AM_CFLAGS="-DWC_RSA_PSS $AM_CFLAGS"
|
||||
fi
|
||||
|
||||
# check if TLS v1.3 was enabled for conditionally running tls13.test script
|
||||
@@ -1301,6 +1300,28 @@ fi
|
||||
AM_CONDITIONAL([BUILD_RSA], [test "x$ENABLED_RSA" = "xyes"])
|
||||
|
||||
|
||||
# RSA-PSS
|
||||
AC_ARG_ENABLE([rsapss],
|
||||
[ --enable-rsapss Enable RSA-PSS (default: disabled)],
|
||||
[ ENABLED_RSAPSS=$enableval ],
|
||||
[ ENABLED_RSAPSS=no ]
|
||||
)
|
||||
|
||||
if test "$ENABLED_RSA" = "no"
|
||||
then
|
||||
ENABLED_RSAPSS="no"
|
||||
else
|
||||
if test "$ENABLED_TLS13" = "yes"
|
||||
then
|
||||
ENABLED_RSAPSS="yes"
|
||||
fi
|
||||
fi
|
||||
if test "$ENABLED_RSAPSS" = "yes"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWC_RSA_PSS"
|
||||
fi
|
||||
|
||||
|
||||
# DH
|
||||
AC_ARG_ENABLE([dh],
|
||||
[AS_HELP_STRING([--enable-dh],[Enable DH (default: enabled)])],
|
||||
@@ -3627,6 +3648,7 @@ echo " * Poly1305: $ENABLED_POLY1305"
|
||||
echo " * LEANPSK: $ENABLED_LEANPSK"
|
||||
echo " * LEANTLS: $ENABLED_LEANTLS"
|
||||
echo " * RSA: $ENABLED_RSA"
|
||||
echo " * RSA-PSS: $ENABLED_RSAPSS"
|
||||
echo " * DSA: $ENABLED_DSA"
|
||||
echo " * DH: $ENABLED_DH"
|
||||
echo " * ECC: $ENABLED_ECC"
|
||||
|
814
src/internal.c
814
src/internal.c
File diff suppressed because it is too large
Load Diff
47
src/ssl.c
47
src/ssl.c
@@ -22038,6 +22038,53 @@ void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef WC_RSA_PSS
|
||||
void wolfSSL_CTX_SetRsaPssSignCb(WOLFSSL_CTX* ctx, CallbackRsaPssSign cb)
|
||||
{
|
||||
if (ctx)
|
||||
ctx->RsaPssSignCb = cb;
|
||||
}
|
||||
|
||||
|
||||
void wolfSSL_SetRsaPssSignCtx(WOLFSSL* ssl, void *ctx)
|
||||
{
|
||||
if (ssl)
|
||||
ssl->RsaPssSignCtx = ctx;
|
||||
}
|
||||
|
||||
|
||||
void* wolfSSL_GetRsaPssSignCtx(WOLFSSL* ssl)
|
||||
{
|
||||
if (ssl)
|
||||
return ssl->RsaPssSignCtx;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void wolfSSL_CTX_SetRsaPssVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaPssVerify cb)
|
||||
{
|
||||
if (ctx)
|
||||
ctx->RsaPssVerifyCb = cb;
|
||||
}
|
||||
|
||||
|
||||
void wolfSSL_SetRsaPssVerifyCtx(WOLFSSL* ssl, void *ctx)
|
||||
{
|
||||
if (ssl)
|
||||
ssl->RsaPssVerifyCtx = ctx;
|
||||
}
|
||||
|
||||
|
||||
void* wolfSSL_GetRsaPssVerifyCtx(WOLFSSL* ssl)
|
||||
{
|
||||
if (ssl)
|
||||
return ssl->RsaPssVerifyCtx;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
void wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX* ctx, CallbackRsaEnc cb)
|
||||
{
|
||||
if (ctx)
|
||||
|
230
src/tls.c
230
src/tls.c
@@ -4269,7 +4269,7 @@ int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz,
|
||||
* data The SSL/TLS object.
|
||||
* returns the length of data that will be in the extension.
|
||||
*/
|
||||
static word16 TLSX_SupportedVersions_GetSize(byte* data)
|
||||
static word16 TLSX_SupportedVersions_GetSize(void* data)
|
||||
{
|
||||
(void)data;
|
||||
|
||||
@@ -4290,7 +4290,7 @@ static word16 TLSX_SupportedVersions_GetSize(byte* data)
|
||||
* output The buffer to write the extension into.
|
||||
* returns the length of data that was written.
|
||||
*/
|
||||
static word16 TLSX_SupportedVersions_Write(byte* data, byte* output)
|
||||
static word16 TLSX_SupportedVersions_Write(void* data, byte* output)
|
||||
{
|
||||
WOLFSSL* ssl = (WOLFSSL*)data;
|
||||
ProtocolVersion pv = ssl->ctx->method->version;
|
||||
@@ -4420,66 +4420,28 @@ static int TLSX_SetSupportedVersions(TLSX** extensions, const void* data,
|
||||
/* Sugnature Algorithms */
|
||||
/******************************************************************************/
|
||||
|
||||
#ifdef WOLFSSL_TLS13
|
||||
/* Return the size of the SignatureAlgorithms extension's data.
|
||||
*
|
||||
* data Unused
|
||||
* returns the length of data that will be in the extension.
|
||||
*/
|
||||
static word16 TLSX_SignatureAlgorithms_GetSize(byte* data)
|
||||
static word16 TLSX_SignatureAlgorithms_GetSize(void* data)
|
||||
{
|
||||
WOLFSSL* ssl = (WOLFSSL*)data;
|
||||
int cnt = 0;
|
||||
|
||||
(void)data;
|
||||
return OPAQUE16_LEN + ssl->suites->hashSigAlgoSz;
|
||||
}
|
||||
|
||||
#ifndef NO_RSA
|
||||
#ifndef NO_SHA1
|
||||
cnt++;
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
cnt++;
|
||||
#endif
|
||||
#ifdef HAVE_SHA384
|
||||
cnt++;
|
||||
#endif
|
||||
#ifdef HAVE_SHA512
|
||||
cnt++;
|
||||
#endif
|
||||
#ifdef WC_RSA_PSS
|
||||
if (IsAtLeastTLSv1_3(ssl->version)) {
|
||||
#ifndef NO_SHA256
|
||||
cnt++;
|
||||
#endif
|
||||
#ifdef HAVE_SHA384
|
||||
cnt++;
|
||||
#endif
|
||||
#ifdef HAVE_SHA512
|
||||
cnt++;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
static void TLSX_SignatureAlgorithms_MapPss(WOLFSSL *ssl, byte* input,
|
||||
word16 length)
|
||||
{
|
||||
word16 i;
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
#if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
|
||||
#ifndef NO_ECC_SECP
|
||||
cnt++;
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(NO_ECC384) || defined(HAVE_ALL_CURVES)
|
||||
#ifndef NO_ECC_SECP
|
||||
cnt++;
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(NO_ECC521) || defined(HAVE_ALL_CURVES)
|
||||
#ifndef NO_ECC_SECP
|
||||
cnt++;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return OPAQUE16_LEN + cnt * OPAQUE16_LEN;
|
||||
ssl->pssAlgo = 0;
|
||||
for (i = 0; i < length; i += 2) {
|
||||
if (input[i] == rsa_pss_sa_algo && input[i + 1] <= sha512_mac)
|
||||
ssl->pssAlgo |= 1 << input[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
/* Writes the SignatureAlgorithms extension into the buffer.
|
||||
@@ -4488,72 +4450,18 @@ static word16 TLSX_SignatureAlgorithms_GetSize(byte* data)
|
||||
* output The buffer to write the extension into.
|
||||
* returns the length of data that was written.
|
||||
*/
|
||||
static word16 TLSX_SignatureAlgorithms_Write(byte* data, byte* output)
|
||||
static word16 TLSX_SignatureAlgorithms_Write(void* data, byte* output)
|
||||
{
|
||||
WOLFSSL* ssl = (WOLFSSL*)data;
|
||||
int idx = OPAQUE16_LEN;
|
||||
|
||||
c16toa(ssl->suites->hashSigAlgoSz, output);
|
||||
XMEMCPY(output + OPAQUE16_LEN, ssl->suites->hashSigAlgo,
|
||||
ssl->suites->hashSigAlgoSz);
|
||||
|
||||
#ifndef NO_RSA
|
||||
#ifndef NO_SHA1
|
||||
output[idx++] = 0x02;
|
||||
output[idx++] = 0x01;
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
output[idx++] = 0x04;
|
||||
output[idx++] = 0x01;
|
||||
#endif
|
||||
#ifdef HAVE_SHA384
|
||||
output[idx++] = 0x05;
|
||||
output[idx++] = 0x01;
|
||||
#endif
|
||||
#ifdef HAVE_SHA512
|
||||
output[idx++] = 0x06;
|
||||
output[idx++] = 0x01;
|
||||
#endif
|
||||
#ifdef WC_RSA_PSS
|
||||
if (IsAtLeastTLSv1_3(ssl->version)) {
|
||||
#ifndef NO_SHA256
|
||||
output[idx++] = 0x08;
|
||||
output[idx++] = 0x04;
|
||||
#endif
|
||||
#ifdef HAVE_SHA384
|
||||
output[idx++] = 0x08;
|
||||
output[idx++] = 0x05;
|
||||
#endif
|
||||
#ifdef HAVE_SHA512
|
||||
output[idx++] = 0x08;
|
||||
output[idx++] = 0x06;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
TLSX_SignatureAlgorithms_MapPss(ssl, output + OPAQUE16_LEN,
|
||||
ssl->suites->hashSigAlgoSz);
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
#if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
|
||||
#ifndef NO_ECC_SECP
|
||||
output[idx++] = 0x04;
|
||||
output[idx++] = 0x03;
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(NO_ECC384) || defined(HAVE_ALL_CURVES)
|
||||
#ifndef NO_ECC_SECP
|
||||
output[idx++] = 0x05;
|
||||
output[idx++] = 0x03;
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(NO_ECC521) || defined(HAVE_ALL_CURVES)
|
||||
#ifndef NO_ECC_SECP
|
||||
output[idx++] = 0x06;
|
||||
output[idx++] = 0x03;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
output[0] = (idx - OPAQUE16_LEN) >> 8;
|
||||
output[1] = idx - OPAQUE16_LEN;
|
||||
|
||||
return idx;
|
||||
return OPAQUE16_LEN + ssl->suites->hashSigAlgoSz;
|
||||
}
|
||||
|
||||
/* Parse the SignatureAlgorithms extension.
|
||||
@@ -4564,9 +4472,8 @@ static word16 TLSX_SignatureAlgorithms_Write(byte* data, byte* output)
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int TLSX_SignatureAlgorithms_Parse(WOLFSSL *ssl, byte* input,
|
||||
word16 length)
|
||||
word16 length, Suites* suites)
|
||||
{
|
||||
int i;
|
||||
word16 len;
|
||||
|
||||
(void)ssl;
|
||||
@@ -4576,16 +4483,16 @@ static int TLSX_SignatureAlgorithms_Parse(WOLFSSL *ssl, byte* input,
|
||||
return BUFFER_ERROR;
|
||||
|
||||
ato16(input, &len);
|
||||
input += OPAQUE16_LEN;
|
||||
|
||||
/* Algorithm array must fill rest of data. */
|
||||
if (length != OPAQUE16_LEN + len)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
ssl->pssAlgo = 0;
|
||||
for (i = 0; i < len; i += 2) {
|
||||
if (input[i] == 0x08 && input[i + 1] <= 0x06)
|
||||
ssl->pssAlgo |= 1 << input[i + 1];
|
||||
}
|
||||
TLSX_SignatureAlgorithms_MapPss(ssl, input, len);
|
||||
|
||||
XMEMCPY(suites->hashSigAlgo, input, len);
|
||||
suites->hashSigAlgoSz = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -4610,13 +4517,6 @@ static int TLSX_SetSignatureAlgorithms(TLSX** extensions, const void* data,
|
||||
#define SA_WRITE TLSX_SignatureAlgorithms_Write
|
||||
#define SA_PARSE TLSX_SignatureAlgorithms_Parse
|
||||
|
||||
#else
|
||||
|
||||
#define SA_GET_SIZE(a) 0
|
||||
#define SA_WRITE(a, b) 0
|
||||
#define SA_PARSE(a, b, c) 0
|
||||
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/* Key Share */
|
||||
@@ -6525,9 +6425,7 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType)
|
||||
break;
|
||||
|
||||
case TLSX_SIGNATURE_ALGORITHMS:
|
||||
#ifdef WOLFSSL_TLS13
|
||||
length += SA_GET_SIZE(extension->data);
|
||||
#endif
|
||||
break;
|
||||
|
||||
#ifdef WOLFSSL_TLS13
|
||||
@@ -6649,10 +6547,8 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
|
||||
break;
|
||||
|
||||
case TLSX_SIGNATURE_ALGORITHMS:
|
||||
#ifdef WOLFSSL_TLS13
|
||||
WOLFSSL_MSG("Signature Algorithms extension to write");
|
||||
offset += SA_WRITE(extension->data, output + offset);
|
||||
#endif
|
||||
break;
|
||||
|
||||
#ifdef WOLFSSL_TLS13
|
||||
@@ -7073,12 +6969,12 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
|
||||
#endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */
|
||||
} /* is not server */
|
||||
|
||||
#ifdef WOLFSSL_TLS13
|
||||
WOLFSSL_MSG("Adding signature algorithms extension");
|
||||
if ((ret = TLSX_SetSignatureAlgorithms(&ssl->extensions, ssl,
|
||||
ssl->heap)) != 0)
|
||||
return ret;
|
||||
|
||||
#ifdef WOLFSSL_TLS13
|
||||
if (!isServer && IsAtLeastTLSv1_3(ssl->version)) {
|
||||
/* Add mandatory TLS v1.3 extension: supported version */
|
||||
WOLFSSL_MSG("Adding supported versions extension");
|
||||
@@ -7209,6 +7105,8 @@ word16 TLSX_GetRequestSize(WOLFSSL* ssl)
|
||||
EC_VALIDATE_REQUEST(ssl, semaphore);
|
||||
QSH_VALIDATE_REQUEST(ssl, semaphore);
|
||||
WOLF_STK_VALIDATE_REQUEST(ssl);
|
||||
if (ssl->suites->hashSigAlgoSz == 0)
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
|
||||
#if defined(WOLFSSL_TLS13)
|
||||
if (!IsAtLeastTLSv1_2(ssl))
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
|
||||
@@ -7230,12 +7128,6 @@ word16 TLSX_GetRequestSize(WOLFSSL* ssl)
|
||||
client_hello);
|
||||
}
|
||||
|
||||
#ifndef WOLFSSL_TLS13
|
||||
if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
|
||||
length += HELLO_EXT_SZ + OPAQUE16_LEN +
|
||||
+ ssl->suites->hashSigAlgoSz;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EXTENDED_MASTER
|
||||
if (ssl->options.haveEMS)
|
||||
length += HELLO_EXT_SZ;
|
||||
@@ -7261,6 +7153,8 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output)
|
||||
EC_VALIDATE_REQUEST(ssl, semaphore);
|
||||
WOLF_STK_VALIDATE_REQUEST(ssl);
|
||||
QSH_VALIDATE_REQUEST(ssl, semaphore);
|
||||
if (ssl->suites->hashSigAlgoSz == 0)
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
|
||||
#if defined(WOLFSSL_TLS13)
|
||||
if (!IsAtLeastTLSv1_2(ssl))
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
|
||||
@@ -7284,28 +7178,6 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output)
|
||||
offset += TLSX_Write(ssl->ctx->extensions, output + offset,
|
||||
semaphore, client_hello);
|
||||
|
||||
#ifndef WOLFSSL_TLS13
|
||||
if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) {
|
||||
int i;
|
||||
/* extension type */
|
||||
c16toa(TLSX_SIGNATURE_ALGORITHMS, output + offset);
|
||||
offset += HELLO_EXT_TYPE_SZ;
|
||||
|
||||
/* extension data length */
|
||||
c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz,
|
||||
output + offset);
|
||||
offset += OPAQUE16_LEN;
|
||||
|
||||
/* sig algos length */
|
||||
c16toa(ssl->suites->hashSigAlgoSz, output + offset);
|
||||
offset += OPAQUE16_LEN;
|
||||
|
||||
/* sig algos */
|
||||
for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, offset++)
|
||||
output[offset] = ssl->suites->hashSigAlgo[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EXTENDED_MASTER
|
||||
if (ssl->options.haveEMS) {
|
||||
c16toa(HELLO_EXT_EXTMS, output + offset);
|
||||
@@ -7607,29 +7479,18 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
|
||||
ret = ALPN_PARSE(ssl, input + offset, size, isRequest);
|
||||
break;
|
||||
|
||||
#ifndef WOLFSSL_TLS13
|
||||
case TLSX_SIGNATURE_ALGORITHMS:
|
||||
WOLFSSL_MSG("Extended signature algorithm extension received");
|
||||
WOLFSSL_MSG("Signature Algorithms extension received");
|
||||
|
||||
if (isRequest) {
|
||||
/* do not mess with offset inside the switch! */
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
ato16(input + offset, &suites->hashSigAlgoSz);
|
||||
if (!IsAtLeastTLSv1_2(ssl))
|
||||
break;
|
||||
|
||||
if (suites->hashSigAlgoSz > size - OPAQUE16_LEN)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
XMEMCPY(suites->hashSigAlgo,
|
||||
input + offset + OPAQUE16_LEN,
|
||||
min(suites->hashSigAlgoSz,
|
||||
HELLO_EXT_SIGALGO_MAX));
|
||||
}
|
||||
} else {
|
||||
WOLFSSL_MSG("Servers MUST NOT send SIG ALGO extension.");
|
||||
if (IsAtLeastTLSv1_3(ssl->version) &&
|
||||
msgType != client_hello) {
|
||||
return EXT_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
ret = SA_PARSE(ssl, input + offset, size, suites);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_TLS13
|
||||
case TLSX_SUPPORTED_VERSIONS:
|
||||
@@ -7645,19 +7506,6 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
|
||||
ret = SV_PARSE(ssl, input + offset, size);
|
||||
break;
|
||||
|
||||
case TLSX_SIGNATURE_ALGORITHMS:
|
||||
WOLFSSL_MSG("Signature Algorithms extension received");
|
||||
|
||||
if (!IsAtLeastTLSv1_2(ssl))
|
||||
break;
|
||||
|
||||
if (IsAtLeastTLSv1_3(ssl->version) &&
|
||||
msgType != client_hello) {
|
||||
return EXT_NOT_ALLOWED;
|
||||
}
|
||||
ret = SA_PARSE(ssl, input + offset, size);
|
||||
break;
|
||||
|
||||
case TLSX_KEY_SHARE:
|
||||
WOLFSSL_MSG("Key Share extension received");
|
||||
|
||||
|
@@ -3205,11 +3205,12 @@ static int CheckRSASignature(WOLFSSL* ssl, int sigAlgo, int hashAlgo,
|
||||
}
|
||||
|
||||
ret = sigSz = CreateRSAEncodedSig(sigData, sigData, sigDataSz,
|
||||
rsa_pss_sa_algo, hashAlgo);
|
||||
rsa_pss_sa_algo, hashAlgo);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = CheckRsaPssPadding(sigData, sigSz, decSig, decSigSz, hashType);
|
||||
ret = wc_RsaPSS_CheckPadding(sigData, sigSz, decSig, decSigSz,
|
||||
hashType);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -3507,7 +3508,7 @@ typedef struct Scv13Args {
|
||||
int sendSz;
|
||||
word16 length;
|
||||
|
||||
int sigAlgo;
|
||||
byte sigAlgo;
|
||||
byte* sigData;
|
||||
word16 sigDataSz;
|
||||
} Scv13Args;
|
||||
@@ -3937,7 +3938,6 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
|
||||
}
|
||||
DecodeSigAlg(input + args->idx, &args->hashAlgo, &args->sigAlgo);
|
||||
args->idx += OPAQUE16_LEN;
|
||||
/* TODO: [TLS13] was it in SignatureAlgorithms extension? */
|
||||
|
||||
/* Signature length. */
|
||||
if ((args->idx - args->begin) + OPAQUE16_LEN > totalSz) {
|
||||
|
@@ -580,6 +580,10 @@ static int RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock,
|
||||
#endif /* !WC_NO_RSA_OAEP */
|
||||
|
||||
#ifdef WC_RSA_PSS
|
||||
/* 0x00 .. 0x00 0x01 | Salt | Gen Hash | 0xbc
|
||||
* XOR MGF over all bytes down to end of Salt
|
||||
* Gen Hash = HASH(8 * 0x00 | Message Hash | Salt)
|
||||
*/
|
||||
static int RsaPad_PSS(const byte* input, word32 inputLen, byte* pkcsBlock,
|
||||
word32 pkcsBlockLen, WC_RNG* rng, enum wc_HashType hType, int mgf,
|
||||
void* heap)
|
||||
@@ -613,7 +617,8 @@ static int RsaPad_PSS(const byte* input, word32 inputLen, byte* pkcsBlock,
|
||||
ret = RsaMGF(mgf, h, hLen, pkcsBlock, pkcsBlockLen - hLen - 1, heap);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
pkcsBlock[0] &= 0x7f;
|
||||
/* TODO: use the number of bits in the prime */
|
||||
pkcsBlock[0] &= (1 << 7) - 1;
|
||||
|
||||
m = pkcsBlock + pkcsBlockLen - 1 - hLen - hLen - 1;
|
||||
*(m++) ^= 0x01;
|
||||
@@ -835,7 +840,8 @@ static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen,
|
||||
return ret;
|
||||
}
|
||||
|
||||
tmp[0] &= 0x7f;
|
||||
/* TODO: use the number of bits in the prime */
|
||||
tmp[0] &= (1 << 7) - 1;
|
||||
for (i = 0; i < (int)(pkcsBlockLen - 1 - hLen - hLen - 1); i++) {
|
||||
if (tmp[i] != pkcsBlock[i]) {
|
||||
XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
@@ -851,8 +857,11 @@ static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen,
|
||||
|
||||
XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
i = pkcsBlockLen - (RSA_PSS_PAD_SZ + 3 * hLen + 1);
|
||||
XMEMSET(pkcsBlock + i, 0, RSA_PSS_PAD_SZ);
|
||||
|
||||
*output = pkcsBlock + i;
|
||||
return hLen;
|
||||
return RSA_PSS_PAD_SZ + 3 * hLen;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1577,6 +1586,30 @@ int wc_RsaPSS_VerifyInline(byte* in, word32 inLen, byte** out,
|
||||
RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD,
|
||||
hash, mgf, NULL, 0, rng);
|
||||
}
|
||||
|
||||
/* Sig = 8 * 0x00 | Space for Message Hash | Salt | Exp Hash
|
||||
* Exp Hash = HASH(8 * 0x00 | Message Hash | Salt)
|
||||
*/
|
||||
int wc_RsaPSS_CheckPadding(const byte* in, word32 inSz, byte* sig,
|
||||
word32 sigSz, enum wc_HashType hashType)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (in == NULL || sig == NULL ||
|
||||
inSz != (word32)wc_HashGetDigestSize(hashType) ||
|
||||
sigSz != RSA_PSS_PAD_SZ + inSz * 3)
|
||||
ret = BAD_FUNC_ARG;
|
||||
else {
|
||||
XMEMCPY(sig + RSA_PSS_PAD_SZ, in, inSz);
|
||||
wc_Hash(hashType, sig, RSA_PSS_PAD_SZ + inSz * 2, sig, inSz);
|
||||
if (XMEMCMP(sig, sig + RSA_PSS_PAD_SZ + inSz * 2, inSz) != 0)
|
||||
ret = BAD_PADDING_E;
|
||||
else
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
|
||||
|
@@ -2260,6 +2260,10 @@ struct WOLFSSL_CTX {
|
||||
#ifndef NO_RSA
|
||||
CallbackRsaSign RsaSignCb; /* User RsaSign Callback handler */
|
||||
CallbackRsaVerify RsaVerifyCb; /* User RsaVerify Callback handler */
|
||||
#ifdef WC_RSA_PSS
|
||||
CallbackRsaPssSign RsaPssSignCb; /* User RsaPssSign */
|
||||
CallbackRsaPssVerify RsaPssVerifyCb; /* User RsaPssVerify */
|
||||
#endif
|
||||
CallbackRsaEnc RsaEncCb; /* User Rsa Public Encrypt handler */
|
||||
CallbackRsaDec RsaDecCb; /* User Rsa Private Decrypt handler */
|
||||
#endif /* NO_RSA */
|
||||
@@ -3099,8 +3103,8 @@ struct WOLFSSL {
|
||||
#endif
|
||||
#ifdef WOLFSSL_TLS13
|
||||
word16 namedGroup;
|
||||
byte pssAlgo;
|
||||
#endif
|
||||
byte pssAlgo;
|
||||
#ifdef HAVE_NTRU
|
||||
word16 peerNtruKeyLen;
|
||||
byte peerNtruKey[MAX_NTRU_PUB_KEY_SZ];
|
||||
@@ -3224,6 +3228,10 @@ struct WOLFSSL {
|
||||
#ifndef NO_RSA
|
||||
void* RsaSignCtx; /* Rsa Sign Callback Context */
|
||||
void* RsaVerifyCtx; /* Rsa Verify Callback Context */
|
||||
#ifdef WC_RSA_PSS
|
||||
void* RsaPssSignCtx; /* Rsa PSS Sign Callback Context */
|
||||
void* RsaPssVerifyCtx; /* Rsa PSS Verify Callback Context */
|
||||
#endif
|
||||
void* RsaEncCtx; /* Rsa Public Encrypt Callback Context */
|
||||
void* RsaDecCtx; /* Rsa Private Decrypt Callback Context */
|
||||
#endif /* NO_RSA */
|
||||
|
@@ -1523,6 +1523,29 @@ WOLFSSL_API void wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX*, CallbackRsaVerify);
|
||||
WOLFSSL_API void wolfSSL_SetRsaVerifyCtx(WOLFSSL* ssl, void *ctx);
|
||||
WOLFSSL_API void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl);
|
||||
|
||||
#ifdef WC_RSA_PSS
|
||||
typedef int (*CallbackRsaPssSign)(WOLFSSL* ssl,
|
||||
const unsigned char* in, unsigned int inSz,
|
||||
unsigned char* out, unsigned int* outSz,
|
||||
int hash, int mgf,
|
||||
const unsigned char* keyDer, unsigned int keySz,
|
||||
void* ctx);
|
||||
WOLFSSL_API void wolfSSL_CTX_SetRsaPssSignCb(WOLFSSL_CTX*, CallbackRsaPssSign);
|
||||
WOLFSSL_API void wolfSSL_SetRsaPssSignCtx(WOLFSSL* ssl, void *ctx);
|
||||
WOLFSSL_API void* wolfSSL_GetRsaPssSignCtx(WOLFSSL* ssl);
|
||||
|
||||
typedef int (*CallbackRsaPssVerify)(WOLFSSL* ssl,
|
||||
unsigned char* sig, unsigned int sigSz,
|
||||
unsigned char** out,
|
||||
int hash, int mgf,
|
||||
const unsigned char* keyDer, unsigned int keySz,
|
||||
void* ctx);
|
||||
WOLFSSL_API void wolfSSL_CTX_SetRsaPssVerifyCb(WOLFSSL_CTX*,
|
||||
CallbackRsaPssVerify);
|
||||
WOLFSSL_API void wolfSSL_SetRsaPssVerifyCtx(WOLFSSL* ssl, void *ctx);
|
||||
WOLFSSL_API void* wolfSSL_GetRsaPssVerifyCtx(WOLFSSL* ssl);
|
||||
#endif
|
||||
|
||||
/* RSA Public Encrypt cb */
|
||||
typedef int (*CallbackRsaEnc)(WOLFSSL* ssl,
|
||||
const unsigned char* in, unsigned int inSz,
|
||||
|
102
wolfssl/test.h
102
wolfssl/test.h
@@ -1884,6 +1884,104 @@ static INLINE int myRsaVerify(WOLFSSL* ssl, byte* sig, word32 sigSz,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef WC_RSA_PSS
|
||||
static INLINE int myRsaPssSign(WOLFSSL* ssl, const byte* in, word32 inSz,
|
||||
byte* out, word32* outSz, int hash, int mgf, const byte* key,
|
||||
word32 keySz, void* ctx)
|
||||
{
|
||||
enum wc_HashType hashType;
|
||||
WC_RNG rng;
|
||||
int ret;
|
||||
word32 idx = 0;
|
||||
RsaKey myKey;
|
||||
|
||||
(void)ssl;
|
||||
(void)ctx;
|
||||
|
||||
switch (hash) {
|
||||
#ifndef NO_SHA256
|
||||
case SHA256h:
|
||||
hashType = WC_HASH_TYPE_SHA256;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case SHA384h:
|
||||
hashType = WC_HASH_TYPE_SHA384;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case SHA512h:
|
||||
hashType = WC_HASH_TYPE_SHA512;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = wc_InitRng(&rng);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = wc_InitRsaKey(&myKey, NULL);
|
||||
if (ret == 0) {
|
||||
ret = wc_RsaPrivateKeyDecode(key, &idx, &myKey, keySz);
|
||||
if (ret == 0) {
|
||||
ret = wc_RsaPSS_Sign(in, inSz, out, *outSz, hashType, mgf, &myKey,
|
||||
&rng);
|
||||
}
|
||||
if (ret > 0) { /* save and convert to 0 success */
|
||||
*outSz = ret;
|
||||
ret = 0;
|
||||
}
|
||||
wc_FreeRsaKey(&myKey);
|
||||
}
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static INLINE int myRsaPssVerify(WOLFSSL* ssl, byte* sig, word32 sigSz,
|
||||
byte** out, int hash, int mgf, const byte* key, word32 keySz, void* ctx)
|
||||
{
|
||||
enum wc_HashType hashType;
|
||||
int ret;
|
||||
word32 idx = 0;
|
||||
RsaKey myKey;
|
||||
|
||||
(void)ssl;
|
||||
(void)ctx;
|
||||
|
||||
switch (hash) {
|
||||
#ifndef NO_SHA256
|
||||
case SHA256h:
|
||||
hashType = WC_HASH_TYPE_SHA256;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case SHA384h:
|
||||
hashType = WC_HASH_TYPE_SHA384;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case SHA512h:
|
||||
hashType = WC_HASH_TYPE_SHA512;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = wc_InitRsaKey(&myKey, NULL);
|
||||
if (ret == 0) {
|
||||
ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
|
||||
if (ret == 0) {
|
||||
ret = wc_RsaPSS_VerifyInline(sig, sigSz, out, hashType, mgf,
|
||||
&myKey);
|
||||
}
|
||||
wc_FreeRsaKey(&myKey);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static INLINE int myRsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz,
|
||||
byte* out, word32* outSz, const byte* key,
|
||||
@@ -1963,6 +2061,10 @@ static INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
|
||||
#ifndef NO_RSA
|
||||
wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign);
|
||||
wolfSSL_CTX_SetRsaVerifyCb(ctx, myRsaVerify);
|
||||
#ifdef WC_RSA_PSS
|
||||
wolfSSL_CTX_SetRsaPssSignCb(ctx, myRsaPssSign);
|
||||
wolfSSL_CTX_SetRsaPssVerifyCb(ctx, myRsaPssVerify);
|
||||
#endif
|
||||
wolfSSL_CTX_SetRsaEncCb(ctx, myRsaEnc);
|
||||
wolfSSL_CTX_SetRsaDecCb(ctx, myRsaDec);
|
||||
#endif /* NO_RSA */
|
||||
|
@@ -76,7 +76,9 @@ enum {
|
||||
RSA_MIN_SIZE = 512,
|
||||
RSA_MAX_SIZE = 4096,
|
||||
|
||||
RSA_MIN_PAD_SZ = 11 /* separator + 0 + pad value + 8 pads */
|
||||
RSA_MIN_PAD_SZ = 11, /* separator + 0 + pad value + 8 pads */
|
||||
|
||||
RSA_PSS_PAD_SZ = 8
|
||||
};
|
||||
|
||||
|
||||
@@ -132,6 +134,10 @@ WOLFSSL_API int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out,
|
||||
WOLFSSL_API int wc_RsaPSS_VerifyInline(byte* in, word32 inLen, byte** out,
|
||||
enum wc_HashType hash, int mgf,
|
||||
RsaKey* key);
|
||||
WOLFSSL_API int wc_RsaPSS_CheckPadding(const byte* in, word32 inLen, byte* sig,
|
||||
word32 sigSz,
|
||||
enum wc_HashType hashType);
|
||||
|
||||
WOLFSSL_API int wc_RsaEncryptSize(RsaKey* key);
|
||||
|
||||
#ifndef HAVE_FIPS /* to avoid asn duplicate symbols @wc_fips */
|
||||
|
Reference in New Issue
Block a user