Merge pull request #922 from SparkiDev/tls_pss

TLS v1.2 and v1.3 RSA PSS
pull/932/head
toddouska 2017-05-23 14:57:10 -07:00 committed by GitHub
commit 6b09a7c6e1
10 changed files with 889 additions and 610 deletions

View File

@ -256,7 +256,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
@ -1332,6 +1331,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)])],
@ -3658,6 +3679,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

@ -22066,6 +22066,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)

231
src/tls.c
View File

@ -4439,7 +4439,6 @@ 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
@ -4448,57 +4447,35 @@ static int TLSX_SetSupportedVersions(TLSX** extensions, const void* 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
/* Creates a bit string of supported hash algorithms with RSA PSS.
* The bit string is used when determining which signature algorithm to use
* when creating the CertificateVerify message.
* Note: Valid data has an even length as each signature algorithm is two bytes.
*
* ssl The SSL/TLS object.
* input The buffer with the list of supported signature algorithms.
* length The length of the list in bytes.
* returns 0 on success, BUFFER_ERROR when the length is not even.
*/
static int 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
if ((length & 1) == 1)
return BUFFER_ERROR;
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];
}
return 0;
}
/* Writes the SignatureAlgorithms extension into the buffer.
@ -4510,69 +4487,15 @@ static word16 TLSX_SignatureAlgorithms_GetSize(void* data)
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.
@ -4583,9 +4506,8 @@ static word16 TLSX_SignatureAlgorithms_Write(void* 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 ret = 0;
word16 len;
(void)ssl;
@ -4595,14 +4517,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;
/* Ignore for now. */
XMEMCPY(suites->hashSigAlgo, input, len);
suites->hashSigAlgoSz = len;
return ret;
return TLSX_SignatureAlgorithms_MapPss(ssl, input, len);
}
/* Sets a new SupportedVersions extension into the extension list.
@ -4625,13 +4549,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 */
@ -6545,9 +6462,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
@ -6669,10 +6584,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
@ -7091,12 +7004,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");
@ -7229,6 +7142,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));
@ -7250,12 +7165,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;
@ -7281,6 +7190,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));
@ -7304,28 +7215,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);
@ -7627,29 +7516,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:
@ -7665,19 +7543,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

@ -2885,18 +2885,24 @@ static INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
{
switch (hsType) {
#ifdef HAVE_ECC
case DYNAMIC_TYPE_ECC:
case ecc_dsa_sa_algo:
output[0] = hashAlgo;
output[1] = ecc_dsa_sa_algo;
break;
#endif
#ifndef NO_RSA
case DYNAMIC_TYPE_RSA:
case rsa_sa_algo:
output[0] = hashAlgo;
output[1] = rsa_sa_algo;
break;
#endif
#ifdef WC_RSA_PSS
/* PSS signatures: 0x080[4-6] */
case rsa_pss_sa_algo:
output[0] = rsa_pss_sa_algo;
output[1] = hashAlgo;
break;
#endif
#endif
/* ED25519: 0x0807 */
/* ED448: 0x0808 */
}
@ -2911,6 +2917,7 @@ static INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
static INLINE void DecodeSigAlg(byte* input, byte* hashAlgo, byte* hsType)
{
switch (input[0]) {
#ifdef WC_RSA_PSS
case 0x08:
/* PSS signatures: 0x080[4-6] */
if (input[1] <= 0x06) {
@ -2918,6 +2925,7 @@ static INLINE void DecodeSigAlg(byte* input, byte* hashAlgo, byte* hsType)
*hashAlgo = input[1];
}
break;
#endif
/* ED25519: 0x0807 */
/* ED448: 0x0808 */
default:
@ -3017,12 +3025,22 @@ static void CreateSigData(WOLFSSL* ssl, byte* sigData, word16* sigDataSz,
* returns the length of the encoded signature or negative on error.
*/
static int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
int hashAlgo)
int sigAlgo, int hashAlgo)
{
Digest digest;
int hashSz = 0;
int hashOid = 0;
int ret = BAD_FUNC_ARG;
byte* hash;
(void)sigAlgo;
#ifdef WC_RSA_PSS
if (sigAlgo == rsa_pss_sa_algo)
hash = sig;
else
#endif
hash = sigData;
/* Digest the signature data. */
switch (hashAlgo) {
@ -3032,7 +3050,7 @@ static int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
if (ret == 0) {
ret = wc_Sha256Update(&digest.sha256, sigData, sigDataSz);
if (ret == 0)
ret = wc_Sha256Final(&digest.sha256, sigData);
ret = wc_Sha256Final(&digest.sha256, hash);
wc_Sha256Free(&digest.sha256);
}
hashSz = SHA256_DIGEST_SIZE;
@ -3045,7 +3063,7 @@ static int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
if (ret == 0) {
ret = wc_Sha384Update(&digest.sha384, sigData, sigDataSz);
if (ret == 0)
ret = wc_Sha384Final(&digest.sha384, sigData);
ret = wc_Sha384Final(&digest.sha384, hash);
wc_Sha384Free(&digest.sha384);
}
hashSz = SHA384_DIGEST_SIZE;
@ -3058,7 +3076,7 @@ static int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
if (ret == 0) {
ret = wc_Sha512Update(&digest.sha512, sigData, sigDataSz);
if (ret == 0)
ret = wc_Sha512Final(&digest.sha512, sigData);
ret = wc_Sha512Final(&digest.sha512, hash);
wc_Sha512Free(&digest.sha512);
}
hashSz = SHA512_DIGEST_SIZE;
@ -3070,8 +3088,15 @@ static int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
if (ret != 0)
return ret;
/* Encode the signature data as per PKCS #1.5 */
return wc_EncodeSignature(sig, sigData, hashSz, hashOid);
#ifdef WC_RSA_PSS
if (sigAlgo == rsa_pss_sa_algo)
return hashSz;
else
#endif
{
/* Encode the signature data as per PKCS #1.5 */
return wc_EncodeSignature(sig, hash, hashSz, hashOid);
}
}
#ifdef HAVE_ECC
@ -3159,7 +3184,40 @@ static int CheckRSASignature(WOLFSSL* ssl, int sigAlgo, int hashAlgo,
#endif
word32 sigSz;
if (sigAlgo == rsa_sa_algo) {
CreateSigData(ssl, sigData, &sigDataSz, 1);
#ifdef WC_RSA_PSS
if (sigAlgo == rsa_pss_sa_algo) {
int hashType = WC_HASH_TYPE_NONE;
switch (hashAlgo) {
case sha512_mac:
#ifdef WOLFSSL_SHA512
hashType = WC_HASH_TYPE_SHA512;
#endif
break;
case sha384_mac:
#ifdef WOLFSSL_SHA384
hashType = WC_HASH_TYPE_SHA384;
#endif
break;
case sha256_mac:
#ifndef NO_SHA256
hashType = WC_HASH_TYPE_SHA256;
#endif
break;
}
ret = sigSz = CreateRSAEncodedSig(sigData, sigData, sigDataSz,
rsa_pss_sa_algo, hashAlgo);
if (ret < 0)
return ret;
ret = wc_RsaPSS_CheckPadding(sigData, sigSz, decSig, decSigSz,
hashType);
}
else
#endif
{
#ifdef WOLFSSL_SMALL_STACK
encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
@ -3169,29 +3227,14 @@ static int CheckRSASignature(WOLFSSL* ssl, int sigAlgo, int hashAlgo,
}
#endif
CreateSigData(ssl, sigData, &sigDataSz, 1);
sigSz = CreateRSAEncodedSig(encodedSig, sigData, sigDataSz, hashAlgo);
sigSz = CreateRSAEncodedSig(encodedSig, sigData, sigDataSz,
DYNAMIC_TYPE_RSA, hashAlgo);
/* Check the encoded and decrypted signature data match. */
if (decSigSz != sigSz || decSig == NULL ||
XMEMCMP(decSig, encodedSig, sigSz) != 0) {
ret = VERIFY_CERT_ERROR;
}
}
else {
CreateSigData(ssl, sigData, &sigDataSz, 1);
sigSz = CreateECCEncodedSig(sigData, sigDataSz, hashAlgo);
if (decSigSz != sigSz || decSig == NULL)
ret = VERIFY_CERT_ERROR;
else {
decSig -= 2 * decSigSz;
XMEMCPY(decSig, sigData, decSigSz);
decSig -= 8;
XMEMSET(decSig, 0, 8);
CreateECCEncodedSig(decSig, 8 + decSigSz * 2, hashAlgo);
if (XMEMCMP(decSig, decSig + 8 + decSigSz * 2, decSigSz) != 0)
ret = VERIFY_CERT_ERROR;
}
}
#ifdef WOLFSSL_SMALL_STACK
end:
@ -3468,6 +3511,7 @@ typedef struct Scv13Args {
int sendSz;
word16 length;
byte sigAlgo;
byte* sigData;
word16 sigDataSz;
} Scv13Args;
@ -3573,7 +3617,17 @@ int SendTls13CertificateVerify(WOLFSSL* ssl)
goto exit_scv;
/* Add signature algorithm. */
EncodeSigAlg(ssl->suites->hashAlgo, ssl->hsType, args->verify);
if (ssl->hsType == DYNAMIC_TYPE_RSA) {
#ifdef WC_RSA_PSS
if (ssl->pssAlgo | (1 << ssl->suites->hashAlgo))
args->sigAlgo = rsa_pss_sa_algo;
else
#endif
args->sigAlgo = rsa_sa_algo;
}
else if (ssl->hsType == DYNAMIC_TYPE_ECC)
args->sigAlgo = ecc_dsa_sa_algo;
EncodeSigAlg(ssl->suites->hashAlgo, args->sigAlgo, args->verify);
/* Create the data to be signed. */
args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap,
@ -3594,9 +3648,8 @@ int SendTls13CertificateVerify(WOLFSSL* ssl)
ERROR_OUT(MEMORY_E, exit_scv);
}
/* Digest the signature data and encode. Used in verify too. */
ret = CreateRSAEncodedSig(sig->buffer, args->sigData,
args->sigDataSz, ssl->suites->hashAlgo);
args->sigDataSz, args->sigAlgo, ssl->suites->hashAlgo);
if (ret < 0)
goto exit_scv;
sig->length = ret;
@ -3648,6 +3701,7 @@ int SendTls13CertificateVerify(WOLFSSL* ssl)
ret = RsaSign(ssl, sig->buffer, sig->length,
args->verify + HASH_SIG_SIZE + VERIFY_HEADER, &args->sigLen,
args->sigAlgo, ssl->suites->hashAlgo,
(RsaKey*)ssl->hsKey,
ssl->buffers.key->buffer, ssl->buffers.key->length,
#ifdef HAVE_PK_CALLBACKS
@ -3693,7 +3747,8 @@ int SendTls13CertificateVerify(WOLFSSL* ssl)
/* check for signature faults */
ret = VerifyRsaSign(ssl, args->verifySig, args->sigLen,
sig->buffer, sig->length, (RsaKey*)ssl->hsKey);
sig->buffer, sig->length, args->sigAlgo,
ssl->suites->hashAlgo, (RsaKey*)ssl->hsKey);
}
#endif /* !NO_RSA */
@ -3886,7 +3941,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,9 +580,13 @@ 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)
int bits, void* heap)
{
int ret;
int hLen, i;
@ -613,7 +617,7 @@ 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;
pkcsBlock[0] &= (1 << ((bits - 1) & 0x7)) - 1;
m = pkcsBlock + pkcsBlockLen - 1 - hLen - hLen - 1;
*(m++) ^= 0x01;
@ -676,7 +680,7 @@ static int RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,
/* helper function to direct which padding is used */
static int wc_RsaPad_ex(const byte* input, word32 inputLen, byte* pkcsBlock,
word32 pkcsBlockLen, byte padValue, WC_RNG* rng, int padType,
enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen,
enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen, int bits,
void* heap)
{
int ret;
@ -700,8 +704,8 @@ static int wc_RsaPad_ex(const byte* input, word32 inputLen, byte* pkcsBlock,
#ifdef WC_RSA_PSS
case WC_RSA_PSS_PAD:
WOLFSSL_MSG("wolfSSL Using RSA PSS padding");
ret = RsaPad_PSS(input, inputLen, pkcsBlock, pkcsBlockLen,
rng, hType, mgf, heap);
ret = RsaPad_PSS(input, inputLen, pkcsBlock, pkcsBlockLen, rng,
hType, mgf, bits, heap);
break;
#endif
@ -715,6 +719,7 @@ static int wc_RsaPad_ex(const byte* input, word32 inputLen, byte* pkcsBlock,
(void)mgf;
(void)optLabel;
(void)labelLen;
(void)bits;
(void)heap;
return ret;
@ -811,7 +816,7 @@ static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen,
#ifdef WC_RSA_PSS
static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen,
byte **output, enum wc_HashType hType, int mgf,
void* heap)
int bits, void* heap)
{
int ret;
byte* tmp;
@ -835,7 +840,7 @@ static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen,
return ret;
}
tmp[0] &= 0x7f;
tmp[0] &= (1 << ((bits - 1) & 0x7)) - 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 +856,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
@ -906,7 +914,8 @@ static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
/* helper function to direct unpadding */
static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out,
byte padValue, int padType, enum wc_HashType hType,
int mgf, byte* optLabel, word32 labelLen, void* heap)
int mgf, byte* optLabel, word32 labelLen, int bits,
void* heap)
{
int ret;
@ -928,7 +937,7 @@ static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out,
case WC_RSA_PSS_PAD:
WOLFSSL_MSG("wolfSSL Using RSA PSS un-padding");
ret = RsaUnPad_PSS((byte*)pkcsBlock, pkcsBlockLen, out, hType, mgf,
heap);
bits, heap);
break;
#endif
@ -942,6 +951,7 @@ static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out,
(void)mgf;
(void)optLabel;
(void)labelLen;
(void)bits;
(void)heap;
return ret;
@ -1276,7 +1286,8 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
#endif
ret = wc_RsaPad_ex(in, inLen, out, sz, pad_value, rng, pad_type, hash,
mgf, label, labelSz, key->heap);
mgf, label, labelSz, mp_count_bits(&key->n),
key->heap);
if (ret < 0) {
break;
}
@ -1409,7 +1420,8 @@ static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out,
{
byte* pad = NULL;
ret = wc_RsaUnPad_ex(key->data, key->dataLen, &pad, pad_value, pad_type,
hash, mgf, label, labelSz, key->heap);
hash, mgf, label, labelSz, mp_count_bits(&key->n),
key->heap);
if (ret > 0 && ret <= (int)outLen && pad != NULL) {
/* only copy output if not inline */
if (outPtr == NULL) {
@ -1577,6 +1589,32 @@ 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);
ret = wc_Hash(hashType, sig, RSA_PSS_PAD_SZ + inSz * 2, sig, inSz);
if (ret != 0)
return ret;
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,
@ -1587,6 +1625,15 @@ int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
}
#ifdef WC_RSA_PSS
int wc_RsaPSS_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
enum wc_HashType hash, int mgf, RsaKey* key, WC_RNG* rng)
{
return RsaPublicEncryptEx(in, inLen, out, outLen, key,
RSA_PRIVATE_ENCRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD,
hash, mgf, NULL, 0, rng);
}
#endif
int wc_RsaEncryptSize(RsaKey* key)
{

View File

@ -2267,6 +2267,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 */
@ -3105,8 +3109,9 @@ struct WOLFSSL {
byte user_set_QSHSchemes;
#endif
#ifdef WOLFSSL_TLS13
word16 namedGroup;
word16 namedGroup;
#endif
byte pssAlgo;
#ifdef HAVE_NTRU
word16 peerNtruKeyLen;
byte peerNtruKey[MAX_NTRU_PUB_KEY_SZ];
@ -3237,6 +3242,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 */
@ -3425,12 +3434,17 @@ WOLFSSL_LOCAL void ShrinkOutputBuffer(WOLFSSL* ssl);
WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl);
#ifndef NO_CERTS
#ifndef NO_RSA
WOLFSSL_LOCAL int CheckRsaPssPadding(const byte* plain, word32 plainSz,
byte* out, word32 sigSz,
enum wc_HashType hashType);
WOLFSSL_LOCAL int VerifyRsaSign(WOLFSSL* ssl,
byte* verifySig, word32 sigSz,
const byte* plain, word32 plainSz,
int sigAlgo, int hashAlgo,
RsaKey* key);
WOLFSSL_LOCAL int RsaSign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
word32* outSz, RsaKey* key, const byte* keyBuf, word32 keySz, void* ctx);
WOLFSSL_LOCAL int RsaSign(WOLFSSL* ssl, const byte* in, word32 inSz,
byte* out, word32* outSz, int sigAlgo, int hashAlgo, RsaKey* key,
const byte* keyBuf, word32 keySz, void* ctx);
WOLFSSL_LOCAL int RsaVerify(WOLFSSL* ssl, byte* in, word32 inSz,
byte** out, int sigAlgo, int hashAlgo, RsaKey* key,
const byte* keyBuf, word32 keySz, void* ctx);

View File

@ -1535,6 +1535,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

@ -1948,6 +1948,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,
@ -2030,6 +2128,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
};
@ -122,6 +124,9 @@ WOLFSSL_API int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
word32 outLen, RsaKey* key);
WOLFSSL_API int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out,
word32 outLen, RsaKey* key, WC_RNG* rng);
WOLFSSL_API int wc_RsaPSS_Sign(const byte* in, word32 inLen, byte* out,
word32 outLen, enum wc_HashType hash, int mgf,
RsaKey* key, WC_RNG* rng);
WOLFSSL_API int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out,
RsaKey* key);
WOLFSSL_API int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out,
@ -129,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 */