Merge pull request #902 from SparkiDev/tls13_interop2

TLS v1.3 Interop changes
This commit is contained in:
toddouska
2017-05-10 09:28:22 -07:00
committed by GitHub
7 changed files with 564 additions and 51 deletions

View File

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

View File

@@ -2773,8 +2773,9 @@ int RsaSign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
return ret;
}
int RsaVerify(WOLFSSL* ssl, byte* in, word32 inSz,
byte** out, RsaKey* key, const byte* keyBuf, word32 keySz, void* ctx)
int RsaVerify(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, int sigAlgo,
int hashAlgo, RsaKey* key, const byte* keyBuf, word32 keySz,
void* ctx)
{
int ret;
@@ -2782,6 +2783,8 @@ int RsaVerify(WOLFSSL* ssl, byte* in, word32 inSz,
(void)keyBuf;
(void)keySz;
(void)ctx;
(void)sigAlgo;
(void)hashAlgo;
WOLFSSL_ENTER("RsaVerify");
@@ -2792,7 +2795,37 @@ int RsaVerify(WOLFSSL* ssl, byte* in, word32 inSz,
else
#endif /*HAVE_PK_CALLBACKS */
{
ret = wc_RsaSSL_VerifyInline(in, inSz, out, key);
#ifdef WOLFSSL_TLS13
#ifdef WC_RSA_PSS
if (sigAlgo == rsa_pss_sa_algo) {
enum wc_HashType hashType = WC_HASH_TYPE_NONE;
int mgf = 0;
switch (hashAlgo) {
case sha512_mac:
#ifdef WOLFSSL_SHA512
hashType = WC_HASH_TYPE_SHA512;
mgf = WC_MGF1SHA512;
#endif
break;
case sha384_mac:
#ifdef WOLFSSL_SHA384
hashType = WC_HASH_TYPE_SHA384;
mgf = WC_MGF1SHA384;
#endif
break;
case sha256_mac:
#ifndef NO_SHA256
hashType = WC_HASH_TYPE_SHA256;
mgf = WC_MGF1SHA256;
#endif
break;
}
ret = wc_RsaPSS_VerifyInline(in, inSz, out, hashType, mgf, key);
}
else
#endif
#endif
ret = wc_RsaSSL_VerifyInline(in, inSz, out, key);
}
/* Handle async pending response */
@@ -16323,6 +16356,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
ret = RsaVerify(ssl,
args->verifySig, args->verifySigSz,
&args->output,
rsa_sa_algo, no_mac,
ssl->peerRsaKey,
#ifdef HAVE_PK_CALLBACKS
ssl->buffers.peerRsaKey.buffer,
@@ -21091,6 +21125,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
input + args->idx,
args->sz,
&args->output,
rsa_sa_algo, no_mac,
ssl->peerRsaKey,
#ifdef HAVE_PK_CALLBACKS
ssl->buffers.peerRsaKey.buffer,

354
src/tls.c
View File

@@ -40,6 +40,10 @@
#include <wolfcrypt/src/misc.c>
#endif
#ifdef HAVE_CURVE25519
#include <wolfssl/wolfcrypt/curve25519.h>
#endif
#ifdef HAVE_NTRU
#include "libntruencrypt/ntru_crypto.h"
#include <wolfssl/wolfcrypt/random.h>
@@ -4304,9 +4308,9 @@ static word16 TLSX_SupportedVersions_Write(byte* data, byte* output)
/* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */
if (pv.minor - i == TLSv1_3_MINOR) {
/* The TLS draft major number. */
*(output++) = 0x7f;
*(output++) = TLS_DRAFT_MAJOR;
/* Version of draft supported. */
*(output++) = 18;
*(output++) = TLS_DRAFT_MINOR;
continue;
}
@@ -4347,7 +4351,8 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL *ssl, byte* input,
/* Find first match. */
for (i = 0; i < len; i += OPAQUE16_LEN) {
/* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */
if (input[i] == 0x7f && input[i + OPAQUE8_LEN] == 18) {
if (input[i] == TLS_DRAFT_MAJOR &&
input[i + OPAQUE8_LEN] == TLS_DRAFT_MINOR) {
ssl->version.minor = TLSv1_3_MINOR;
ssl->options.tls1_3 = 1;
TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input,
@@ -4411,6 +4416,199 @@ static int TLSX_SetSupportedVersions(TLSX** extensions, const void* data,
#endif /* WOLFSSL_TLS13 */
/******************************************************************************/
/* 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)
{
int cnt = 0;
(void)data;
#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
#ifndef NO_SHA256
cnt++;
#endif
#ifdef HAVE_SHA384
cnt++;
#endif
#ifdef HAVE_SHA512
cnt++;
#endif
#endif
#endif
#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;
}
/* Writes the SignatureAlgorithms extension into the buffer.
*
* data Unused
* 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)
{
int idx = OPAQUE16_LEN;
(void)data;
#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
#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
#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;
}
/* Parse the SignatureAlgorithms extension.
*
* ssl The SSL/TLS object.
* input The buffer with the extension data.
* length The length of the extension data.
* returns 0 on success, otherwise failure.
*/
static int TLSX_SignatureAlgorithms_Parse(WOLFSSL *ssl, byte* input,
word16 length)
{
int ret = 0;
word16 len;
(void)ssl;
/* Must contain a length and at least algorithm. */
if (length < OPAQUE16_LEN + OPAQUE16_LEN || (length & 1) != 0)
return BUFFER_ERROR;
ato16(input, &len);
/* Algorithm array must fill rest of data. */
if (length != OPAQUE16_LEN + len)
return BUFFER_ERROR;
/* Ignore for now. */
return ret;
}
/* Sets a new SupportedVersions extension into the extension list.
*
* extensions The list of extensions.
* data The extensions specific data.
* heap The heap used for allocation.
* returns 0 on success, otherwise failure.
*/
static int TLSX_SetSignatureAlgorithms(TLSX** extensions, const void* data,
void* heap)
{
if (extensions == NULL)
return BAD_FUNC_ARG;
return TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS, (void *)data, heap);
}
#define SA_GET_SIZE TLSX_SignatureAlgorithms_GetSize
#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 */
/******************************************************************************/
@@ -4588,9 +4786,52 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse)
#endif
#ifdef HAVE_CURVE25519
case WOLFSSL_ECC_X25519:
curveId = ECC_X25519;
dataSize = keySize = 32;
break;
{
curve25519_key* key;
/* Allocate an ECC key to hold private key. */
key = (curve25519_key*)XMALLOC(sizeof(curve25519_key),
ssl->heap, DYNAMIC_TYPE_TLSX);
if (key == NULL) {
WOLFSSL_MSG("EccTempKey Memory error");
return MEMORY_E;
}
dataSize = keySize = 32;
/* Make an ECC key. */
ret = wc_curve25519_init(key);
if (ret != 0)
goto end;
ret = wc_curve25519_make_key(ssl->rng, keySize, key);
if (ret != 0)
goto end;
/* Allocate space for the public key. */
keyData = XMALLOC(dataSize, ssl->heap, DYNAMIC_TYPE_TLSX);
if (keyData == NULL) {
WOLFSSL_MSG("Key data Memory error");
ret = MEMORY_E;
goto end;
}
/* Export public key. */
if (wc_curve25519_export_public_ex(key, keyData, &dataSize,
EC25519_LITTLE_ENDIAN) != 0) {
ret = ECC_EXPORT_ERROR;
goto end;
}
kse->ke = keyData;
kse->keLen = dataSize;
kse->key = key;
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG("Public ECC Key");
WOLFSSL_BUFFER(keyData, dataSize);
#endif
goto end;
}
#endif
#ifdef HAVE_X448
case WOLFSSL_ECC_X448:
@@ -4922,8 +5163,42 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
#endif
#ifdef HAVE_CURVE25519
case WOLFSSL_ECC_X25519:
curveId = ECC_X25519;
break;
{
curve25519_key* key = (curve25519_key*)keyShareEntry->key;
curve25519_key* peerEccKey;
if (ssl->peerEccKey != NULL)
wc_ecc_free(ssl->peerEccKey);
peerEccKey = (curve25519_key*)XMALLOC(sizeof(curve25519_key),
ssl->heap, DYNAMIC_TYPE_TLSX);
if (peerEccKey == NULL) {
WOLFSSL_MSG("PeerEccKey Memory error");
return MEMORY_ERROR;
}
ret = wc_curve25519_init(peerEccKey);
if (ret != 0)
return ret;
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG("Peer ECC Key");
WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
#endif
/* Point is validated by import function. */
if (wc_curve25519_import_public_ex(keyShareEntry->ke,
keyShareEntry->keLen, peerEccKey,
EC25519_LITTLE_ENDIAN) != 0) {
return ECC_PEERKEY_ERROR;
}
ssl->arrays->preMasterSz = ENCRYPT_LEN;
ret = wc_curve25519_shared_secret_ex(key, peerEccKey,
ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz,
EC25519_LITTLE_ENDIAN);
wc_curve25519_free(peerEccKey);
XFREE(peerEccKey, ssl->heap, DYNAMIC_TYPE_TLSX);
return ret;
}
#endif
#ifdef HAVE_X448
case WOLFSSL_ECC_X448:
@@ -6136,6 +6411,9 @@ void TLSX_FreeAll(TLSX* list, void* heap)
ALPN_FREE_ALL((ALPN*)extension->data, heap);
break;
case TLSX_SIGNATURE_ALGORITHMS:
break;
#ifdef WOLFSSL_TLS13
case TLSX_SUPPORTED_VERSIONS:
break;
@@ -6237,6 +6515,12 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType)
length += ALPN_GET_SIZE((ALPN*)extension->data);
break;
case TLSX_SIGNATURE_ALGORITHMS:
#ifdef WOLFSSL_TLS13
length += SA_GET_SIZE(extension->data);
#endif
break;
#ifdef WOLFSSL_TLS13
case TLSX_SUPPORTED_VERSIONS:
length += SV_GET_SIZE(extension->data);
@@ -6355,6 +6639,13 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
offset += ALPN_WRITE((ALPN*)extension->data, output + offset);
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
case TLSX_SUPPORTED_VERSIONS:
WOLFSSL_MSG("Supported Versions extension to write");
@@ -6760,6 +7051,15 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
if (ret != SSL_SUCCESS) return ret;
#endif
#endif
#ifdef WOLFSSL_TLS13
#if defined(HAVE_CURVE25519)
#ifndef NO_ECC_SECP
ret = TLSX_UseSupportedCurve(&ssl->extensions,
WOLFSSL_ECC_X25519, ssl->heap);
if (ret != SSL_SUCCESS) return ret;
#endif
#endif
#endif
}
#endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */
} /* is not server */
@@ -6771,6 +7071,11 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
if ((ret = TLSX_SetSupportedVersions(&ssl->extensions, ssl,
ssl->heap)) != 0)
return ret;
/* Add TLS v1.3 extension: signature algorithms */
WOLFSSL_MSG("Adding signature algorithms extension");
if ((ret = TLSX_SetSignatureAlgorithms(&ssl->extensions, NULL,
ssl->heap)) != 0)
return ret;
/* Add FFDHE supported groups. */
#ifdef HAVE_FFDHE_2048
@@ -6898,6 +7203,7 @@ word16 TLSX_GetRequestSize(WOLFSSL* ssl)
#if defined(WOLFSSL_TLS13)
if (!IsAtLeastTLSv1_3(ssl->version)) {
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
#ifndef NO_PSK
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
@@ -6914,9 +7220,11 @@ word16 TLSX_GetRequestSize(WOLFSSL* ssl)
client_hello);
}
#ifndef WOLFSSL_TLS13
if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
length += HELLO_EXT_SZ + HELLO_EXT_SIGALGO_SZ
length += HELLO_EXT_SZ + OPAQUE16_LEN +
+ ssl->suites->hashSigAlgoSz;
#endif
#ifdef HAVE_EXTENDED_MASTER
if (ssl->options.haveEMS)
@@ -6946,6 +7254,7 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output)
#if defined(WOLFSSL_TLS13)
if (!IsAtLeastTLSv1_3(ssl->version)) {
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
#ifndef NO_PSK
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
@@ -6964,10 +7273,11 @@ 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(HELLO_EXT_SIG_ALGO, output + offset);
c16toa(TLSX_SIGNATURE_ALGORITHMS, output + offset);
offset += HELLO_EXT_TYPE_SZ;
/* extension data length */
@@ -6983,6 +7293,7 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output)
for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, offset++)
output[offset] = ssl->suites->hashSigAlgo[i];
}
#endif
#ifdef HAVE_EXTENDED_MASTER
if (ssl->options.haveEMS) {
@@ -7285,16 +7596,11 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
ret = ALPN_PARSE(ssl, input + offset, size, isRequest);
break;
case HELLO_EXT_SIG_ALGO:
#ifndef WOLFSSL_TLS13
case TLSX_SIGNATURE_ALGORITHMS:
WOLFSSL_MSG("Extended signature algorithm extension received");
if (isRequest) {
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->version) &&
msgType != client_hello) {
return EXT_NOT_ALLOWED;
}
#endif
/* do not mess with offset inside the switch! */
if (IsAtLeastTLSv1_2(ssl)) {
ato16(input + offset, &suites->hashSigAlgoSz);
@@ -7312,6 +7618,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
}
break;
#endif
#ifdef WOLFSSL_TLS13
case TLSX_SUPPORTED_VERSIONS:
@@ -7327,6 +7634,19 @@ 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_3(ssl->version))
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

@@ -2851,12 +2851,18 @@ static INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
static INLINE void DecodeSigAlg(byte* input, byte* hashAlgo, byte* hsType)
{
switch (input[0]) {
/* PSS signatures: 0x080[4-6] */
case 0x08:
/* PSS signatures: 0x080[4-6] */
if (input[1] <= 0x06) {
*hsType = input[0];
*hashAlgo = input[1];
}
break;
/* ED25519: 0x0807 */
/* ED448: 0x0808 */
default:
*hashAlgo = input[0];
*hsType = input[1];
*hsType = input[1];
break;
}
}
@@ -3048,13 +3054,14 @@ static int CreateECCEncodedSig(byte* sigData, int sigDataSz, int hashAlgo)
* based on the digest of the signature data.
*
* ssl The SSL/TLS object.
* hashAlgo The signature algorithm used to generate signature.
* hashAlgo The hash algorithm used to generate signature.
* decSig The decrypted signature.
* decSigSz The size of the decrypted signature.
* returns 0 on success, otherwise failure.
*/
static int CheckRSASignature(WOLFSSL* ssl, int hashAlgo, byte* decSig,
word32 decSigSz)
static int CheckRSASignature(WOLFSSL* ssl, int sigAlgo, int hashAlgo,
byte* decSig, word32 decSigSz)
{
int ret = 0;
byte sigData[MAX_SIG_DATA_SZ];
@@ -3066,21 +3073,38 @@ static int CheckRSASignature(WOLFSSL* ssl, int hashAlgo, byte* decSig,
#endif
word32 sigSz;
if (sigAlgo == rsa_sa_algo) {
#ifdef WOLFSSL_SMALL_STACK
encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (encodedSig == NULL) {
ret = MEMORY_E;
goto end;
}
encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (encodedSig == NULL) {
ret = MEMORY_E;
goto end;
}
#endif
CreateSigData(ssl, sigData, &sigDataSz, 1);
sigSz = CreateRSAEncodedSig(encodedSig, sigData, sigDataSz, hashAlgo);
/* Check the encoded and decrypted signature data match. */
if (decSigSz != sigSz || decSig == NULL ||
XMEMCMP(decSig, encodedSig, sigSz) != 0) {
ret = VERIFY_CERT_ERROR;
CreateSigData(ssl, sigData, &sigDataSz, 1);
sigSz = CreateRSAEncodedSig(encodedSig, sigData, sigDataSz, 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
@@ -3783,8 +3807,9 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
!ssl->peerEccDsaKeyPresent) {
WOLFSSL_MSG("Oops, peer sent ECC key but not in verify");
}
if (args->sigAlgo == rsa_sa_algo &&
(ssl->peerRsaKey == NULL || !ssl->peerRsaKeyPresent)) {
if ((args->sigAlgo == rsa_sa_algo ||
args->sigAlgo == rsa_pss_sa_algo) &&
(ssl->peerRsaKey == NULL || !ssl->peerRsaKeyPresent)) {
WOLFSSL_MSG("Oops, peer sent RSA key but not in verify");
}
@@ -3818,11 +3843,12 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
case TLS_ASYNC_DO:
{
#ifndef NO_RSA
if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent) {
if (args->sigAlgo == rsa_sa_algo ||
args->sigAlgo == rsa_pss_sa_algo) {
WOLFSSL_MSG("Doing RSA peer cert verify");
ret = RsaVerify(ssl, sig->buffer, sig->length, &args->output,
ssl->peerRsaKey,
args->sigAlgo, args->hashAlgo, ssl->peerRsaKey,
#ifdef HAVE_PK_CALLBACKS
ssl->buffers.peerRsaKey.buffer,
ssl->buffers.peerRsaKey.length,
@@ -3868,7 +3894,8 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
{
#ifndef NO_RSA
if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) {
ret = CheckRSASignature(ssl, args->hashAlgo, args->output, args->sendSz);
ret = CheckRSASignature(ssl, args->sigAlgo, args->hashAlgo,
args->output, args->sendSz);
if (ret != 0)
goto exit_dcv;
}

View File

@@ -261,7 +261,7 @@ int wc_FreeRsaKey(RsaKey* key)
}
#ifndef WC_NO_RSA_OAEP
#if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_PSS)
/* Uses MGF1 standard as a mask generation function
hType: hash type used
seed: seed to use for generating mask
@@ -572,6 +572,50 @@ static int RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock,
}
#endif /* !WC_NO_RSA_OAEP */
#ifdef WC_RSA_PSS
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 ret;
int hLen, i;
byte* s;
byte* m;
byte* h;
byte salt[WC_MAX_DIGEST_SIZE];
hLen = wc_HashGetDigestSize(hType);
if (hLen < 0)
return hLen;
s = m = pkcsBlock;
XMEMSET(m, 0, 8);
m += 8;
XMEMCPY(m, input, inputLen);
m += inputLen;
if ((ret = wc_RNG_GenerateBlock(rng, salt, hLen)) != 0)
return ret;
XMEMCPY(m, salt, hLen);
m += hLen;
h = pkcsBlock + pkcsBlockLen - 1 - hLen;
if ((ret = wc_Hash(hType, s, (word32)(m - s), h, hLen)) != 0)
return ret;
pkcsBlock[pkcsBlockLen - 1] = 0xbc;
ret = RsaMGF(mgf, h, hLen, pkcsBlock, pkcsBlockLen - hLen - 1, heap);
if (ret != 0)
return ret;
pkcsBlock[0] &= 0x7f;
m = pkcsBlock + pkcsBlockLen - 1 - hLen - hLen - 1;
*(m++) ^= 0x01;
for (i = 0; i < hLen; i++)
m[i] ^= salt[i];
return 0;
}
#endif
static int RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,
word32 pkcsBlockLen, byte padValue, WC_RNG* rng)
@@ -635,16 +679,25 @@ static int wc_RsaPad_ex(const byte* input, word32 inputLen, byte* pkcsBlock,
case WC_RSA_PKCSV15_PAD:
/*WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 padding");*/
ret = RsaPad(input, inputLen, pkcsBlock, pkcsBlockLen,
padValue, rng);
padValue, rng);
break;
#ifndef WC_NO_RSA_OAEP
case WC_RSA_OAEP_PAD:
WOLFSSL_MSG("wolfSSL Using RSA OAEP padding");
ret = RsaPad_OAEP(input, inputLen, pkcsBlock, pkcsBlockLen,
padValue, rng, hType, mgf, optLabel, labelLen, heap);
padValue, rng, hType, mgf, optLabel, labelLen, heap);
break;
#endif
#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);
break;
#endif
default:
WOLFSSL_MSG("Unknown RSA Pad Type");
ret = RSA_PAD_E;
@@ -748,6 +801,53 @@ static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen,
}
#endif /* WC_NO_RSA_OAEP */
#ifdef WC_RSA_PSS
static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen,
byte **output, enum wc_HashType hType, int mgf,
void* heap)
{
int ret;
byte* tmp;
int hLen, i;
hLen = wc_HashGetDigestSize(hType);
if (hLen < 0)
return hLen;
if (pkcsBlock[pkcsBlockLen - 1] != 0xbc)
return BAD_PADDING_E;
tmp = (byte*)XMALLOC(pkcsBlockLen, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (tmp == NULL) {
return MEMORY_E;
}
if ((ret = RsaMGF(mgf, pkcsBlock + pkcsBlockLen - 1 - hLen, hLen,
tmp, pkcsBlockLen - 1 - hLen, heap)) != 0) {
XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
tmp[0] &= 0x7f;
for (i = 0; i < (int)(pkcsBlockLen - 1 - hLen - hLen - 1); i++) {
if (tmp[i] != pkcsBlock[i]) {
XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
return BAD_PADDING_E;
}
}
if (tmp[i] != (pkcsBlock[i] ^ 0x01)) {
XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
return BAD_PADDING_E;
}
for (i++; i < (int)(pkcsBlockLen - 1 - hLen); i++)
pkcsBlock[i] ^= tmp[i];
XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
*output = pkcsBlock + i;
return hLen;
}
#endif
/* UnPad plaintext, set start to *output, return length of plaintext,
* < 0 on error */
@@ -817,6 +917,14 @@ static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out,
break;
#endif
#ifdef WC_RSA_PSS
case WC_RSA_PSS_PAD:
WOLFSSL_MSG("wolfSSL Using RSA PSS un-padding");
ret = RsaUnPad_PSS((byte*)pkcsBlock, pkcsBlockLen, out, hType, mgf,
heap);
break;
#endif
default:
WOLFSSL_MSG("Unknown RSA UnPad Type");
ret = RSA_PAD_E;
@@ -1105,7 +1213,8 @@ int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT,
RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT
pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2
pad_type : type of padding: WC_RSA_PKCSV15_PAD or WC_RSA_OAEP_PAD
pad_type : type of padding: WC_RSA_PKCSV15_PAD, WC_RSA_OAEP_PAD or
WC_RSA_PSS_PAD
hash : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h
mgf : type of mask generation function to use
label : optional label
@@ -1212,7 +1321,8 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT,
RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT
pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2
pad_type : type of padding: WC_RSA_PKCSV15_PAD or WC_RSA_OAEP_PAD
pad_type : type of padding: WC_RSA_PKCSV15_PAD, WC_RSA_OAEP_PAD
WC_RSA_PSS_PAD
hash : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h
mgf : type of mask generation function to use
label : optional label
@@ -1446,6 +1556,19 @@ int wc_RsaSSL_Verify(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_VerifyInline(byte* in, word32 inLen, byte** out,
enum wc_HashType hash, int mgf, RsaKey* key)
{
WC_RNG* rng = NULL;
#ifdef WC_RSA_BLINDING
rng = key->rng;
#endif
return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD,
hash, mgf, NULL, 0, rng);
}
#endif
int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
RsaKey* key, WC_RNG* rng)

View File

@@ -1747,6 +1747,7 @@ typedef enum {
TLSX_TRUNCATED_HMAC = 0x0004,
TLSX_STATUS_REQUEST = 0x0005, /* a.k.a. OCSP stapling */
TLSX_SUPPORTED_GROUPS = 0x000a, /* a.k.a. Supported Curves */
TLSX_SIGNATURE_ALGORITHMS = 0x000d,
TLSX_APPLICATION_LAYER_PROTOCOL = 0x0010, /* a.k.a. ALPN */
TLSX_STATUS_REQUEST_V2 = 0x0011, /* a.k.a. OCSP stapling v2 */
TLSX_QUANTUM_SAFE_HYBRID = 0x0018, /* a.k.a. QSH */
@@ -2344,10 +2345,11 @@ enum KeyExchangeAlgorithm {
/* Supported Authentication Schemes */
enum SignatureAlgorithm {
anonymous_sa_algo,
rsa_sa_algo,
dsa_sa_algo,
ecc_dsa_sa_algo
anonymous_sa_algo = 0,
rsa_sa_algo = 1,
dsa_sa_algo = 2,
ecc_dsa_sa_algo = 4,
rsa_pss_sa_algo = 8
};
@@ -3406,7 +3408,8 @@ WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl);
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 RsaVerify(WOLFSSL* ssl, byte* in, word32 inSz,
byte** out, RsaKey* key, const byte* keyBuf, word32 keySz, void* ctx);
byte** out, int sigAlgo, int hashAlgo, RsaKey* key,
const byte* keyBuf, word32 keySz, void* ctx);
WOLFSSL_LOCAL int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out,
word32* outSz, RsaKey* key, const byte* keyBuf, word32 keySz, void* ctx);
WOLFSSL_LOCAL int RsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,

View File

@@ -126,6 +126,9 @@ 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,
word32 outLen, RsaKey* key);
WOLFSSL_API int wc_RsaPSS_VerifyInline(byte* in, word32 inLen, byte** out,
enum wc_HashType hash, int mgf,
RsaKey* key);
WOLFSSL_API int wc_RsaEncryptSize(RsaKey* key);
#ifndef HAVE_FIPS /* to avoid asn duplicate symbols @wc_fips */
@@ -156,6 +159,7 @@ WOLFSSL_API int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng);
/* Padding types */
#define WC_RSA_PKCSV15_PAD 0
#define WC_RSA_OAEP_PAD 1
#define WC_RSA_PSS_PAD 2
WOLFSSL_API int wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out,
word32 outLen, RsaKey* key, WC_RNG* rng, int type,