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:
Sean Parkinson
2017-05-18 15:32:06 +10:00
parent 9fb6373cfb
commit 4390f4c711
10 changed files with 709 additions and 596 deletions

View File

@@ -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"

File diff suppressed because it is too large Load Diff

View File

@@ -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
View File

@@ -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");

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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 */

View File

@@ -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,

View File

@@ -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 */

View File

@@ -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 */