mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 19:24:42 +02:00
Support for Analog Devices MAXQ1080 and MAXQ1065
This commit is contained in:
31
configure.ac
31
configure.ac
@@ -1887,6 +1887,35 @@ then
|
||||
fi
|
||||
|
||||
|
||||
# Maxim Integrated MAXQ10XX
|
||||
ENABLED_MAXQ10XX="no"
|
||||
maxqpartnumber=""
|
||||
AC_ARG_WITH([maxq10xx],
|
||||
[AS_HELP_STRING([--with-maxq10xx=PART],[MAXQ10XX PART Number])],
|
||||
[
|
||||
AC_MSG_CHECKING([for maxq10xx])
|
||||
|
||||
# Read the part number
|
||||
maxqpartnumber=$withval
|
||||
|
||||
if test "$maxqpartnumber" = "MAXQ1065"; then
|
||||
LIB_STATIC_ADD="$LIB_STATIC_ADD lib/libmaxq1065_api.a"
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_MAXQ1065"
|
||||
ENABLED_MAXQ10XX="yes"
|
||||
AC_CHECK_LIB([rt], [clock_gettime])
|
||||
elif test "$maxqpartnumber" = "MAXQ108x"; then
|
||||
LIB_STATIC_ADD="$LIB_STATIC_ADD lib/libmaxq108x_api.a"
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_MAXQ108X"
|
||||
ENABLED_MAXQ10XX="yes"
|
||||
AC_CHECK_LIB([rt], [clock_gettime])
|
||||
else
|
||||
AC_MSG_ERROR([need a valid MAXQ part number])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([yes])
|
||||
]
|
||||
)
|
||||
|
||||
# Microchip/Atmel CryptoAuthLib
|
||||
ENABLED_CRYPTOAUTHLIB="no"
|
||||
trylibatcadir=""
|
||||
@@ -8350,6 +8379,7 @@ AM_CONDITIONAL([BUILD_DTLS13],[test "x$ENABLED_DTLS13" = "xyes"])
|
||||
AM_CONDITIONAL([BUILD_QUIC],[test "x$ENABLED_QUIC" = "xyes"])
|
||||
AM_CONDITIONAL([BUILD_DTLS_CID],[test "x$ENABLED_DTLS_CID" = "xyes"])
|
||||
AM_CONDITIONAL([BUILD_DTLS],[test "x$ENABLED_DTLS" = "xyes"])
|
||||
AM_CONDITIONAL([BUILD_MAXQ10XX],[test "x$ENABLED_MAXQ10XX" = "xyes"])
|
||||
|
||||
if test "$ENABLED_REPRODUCIBLE_BUILD" != "yes" &&
|
||||
(test "$ax_enable_debug" = "yes" ||
|
||||
@@ -8772,6 +8802,7 @@ echo " * i.MX CAAM: $ENABLED_CAAM"
|
||||
echo " * IoT-Safe: $ENABLED_IOTSAFE"
|
||||
echo " * IoT-Safe HWRNG: $ENABLED_IOTSAFE_HWRNG"
|
||||
echo " * NXP SE050: $ENABLED_SE050"
|
||||
echo " * Maxim Integrated MAXQ10XX: $ENABLED_MAXQ10XX"
|
||||
echo " * PSA: $ENABLED_PSA"
|
||||
echo " * System CA certs: $ENABLED_SYS_CA_CERTS"
|
||||
echo ""
|
||||
|
@@ -1777,7 +1777,7 @@ int Dtls13DeriveSnKeys(WOLFSSL* ssl, int provision)
|
||||
WOLFSSL_MSG("Derive SN Client key");
|
||||
ret = Tls13DeriveKey(ssl, key_dig, ssl->specs.key_size,
|
||||
ssl->clientSecret, snLabel, SN_LABEL_SZ, ssl->specs.mac_algorithm,
|
||||
0);
|
||||
0, WOLFSSL_CLIENT_END);
|
||||
if (ret != 0)
|
||||
goto end;
|
||||
|
||||
@@ -1788,7 +1788,7 @@ int Dtls13DeriveSnKeys(WOLFSSL* ssl, int provision)
|
||||
WOLFSSL_MSG("Derive SN Server key");
|
||||
ret = Tls13DeriveKey(ssl, key_dig, ssl->specs.key_size,
|
||||
ssl->serverSecret, snLabel, SN_LABEL_SZ, ssl->specs.mac_algorithm,
|
||||
0);
|
||||
0, WOLFSSL_SERVER_END);
|
||||
if (ret != 0)
|
||||
goto end;
|
||||
|
||||
|
222
src/internal.c
222
src/internal.c
@@ -2388,6 +2388,12 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap)
|
||||
ret = wolfEventQueue_Init(&ctx->event_queue);
|
||||
#endif /* HAVE_WOLF_EVENT */
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_TLS
|
||||
/* Let maxq10xx know what TLS version we are using. */
|
||||
ctx->devId = MAXQ_DEVICE_ID;
|
||||
maxq10xx_SetupPkCallbacks(ctx, &method->version);
|
||||
#endif /* WOLFSSL_MAXQ10XX_TLS */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -4985,7 +4991,8 @@ int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* out,
|
||||
&ssl->eccVerifyRes, ctx);
|
||||
}
|
||||
#if !defined(WOLFSSL_RENESAS_SCEPROTECT) && \
|
||||
!defined(WOLFSSL_RENESAS_TSIP_TLS)
|
||||
!defined(WOLFSSL_RENESAS_TSIP_TLS) && \
|
||||
!defined(WOLFSSL_MAXQ108X)
|
||||
else
|
||||
#else
|
||||
if (!ssl->ctx->EccVerifyCb || ret == CRYPTOCB_UNAVAILABLE)
|
||||
@@ -5825,6 +5832,15 @@ int DhGenKeyPair(WOLFSSL* ssl, DhKey* dhKey,
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PK_CALLBACKS)
|
||||
if (ssl && ssl->ctx && ssl->ctx->DhGenerateKeyPairCb) {
|
||||
ret = ssl->ctx->DhGenerateKeyPairCb(dhKey, ssl->rng, priv, privSz,
|
||||
pub, pubSz);
|
||||
if (ret != NOT_COMPILED_IN)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
ret = wc_DhGenerateKeyPair(dhKey, ssl->rng, priv, privSz, pub, pubSz);
|
||||
PRIVATE_KEY_LOCK();
|
||||
@@ -7048,6 +7064,13 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_MAXQ10XX_TLS)
|
||||
ret = wolfSSL_maxq10xx_load_certificate(ssl);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -12903,6 +12926,18 @@ static int ProcessPeerCertParse(WOLFSSL* ssl, ProcPeerCertArgs* args,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_PUBLIC_ASN) && defined(HAVE_PK_CALLBACKS)
|
||||
/* This block gives the callback a chance to process the peer cert.
|
||||
* If there is no callback set or it returns NOT_COMPILED_IN, then the
|
||||
* original return code is returned. */
|
||||
if (ssl->ctx && ssl->ctx->ProcessPeerCertCb) {
|
||||
int new_ret = ssl->ctx->ProcessPeerCertCb(ssl, args->dCert);
|
||||
if (new_ret != NOT_COMPILED_IN) {
|
||||
ret = new_ret;
|
||||
}
|
||||
}
|
||||
#endif /* WOLFSSL_PUBLIC_ASN && HAVE_PK_CALLBACKS */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -17240,13 +17275,30 @@ static WC_INLINE int EncryptDo(WOLFSSL* ssl, byte* out, const byte* input,
|
||||
XMEMCPY(ssl->encrypt.nonce + AESGCM_IMP_IV_SZ,
|
||||
ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ);
|
||||
#endif
|
||||
ret = aes_auth_fn(ssl->encrypt.aes,
|
||||
out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ,
|
||||
sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
|
||||
ssl->encrypt.nonce, AESGCM_NONCE_SZ,
|
||||
out + sz - ssl->specs.aead_mac_size,
|
||||
ssl->specs.aead_mac_size,
|
||||
ssl->encrypt.additional, AEAD_AUTH_DATA_SZ);
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
ret = NOT_COMPILED_IN;
|
||||
if (ssl->ctx && ssl->ctx->PerformTlsRecordProcessingCb) {
|
||||
ret = ssl->ctx->PerformTlsRecordProcessingCb(ssl, 1,
|
||||
out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ,
|
||||
sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
|
||||
ssl->encrypt.nonce, AESGCM_NONCE_SZ,
|
||||
out + sz - ssl->specs.aead_mac_size,
|
||||
ssl->specs.aead_mac_size,
|
||||
ssl->encrypt.additional, AEAD_AUTH_DATA_SZ);
|
||||
}
|
||||
|
||||
if (ret == NOT_COMPILED_IN)
|
||||
#endif /* HAVE_PK_CALLBACKS */
|
||||
{
|
||||
ret = aes_auth_fn(ssl->encrypt.aes,
|
||||
out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ,
|
||||
sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
|
||||
ssl->encrypt.nonce, AESGCM_NONCE_SZ,
|
||||
out + sz - ssl->specs.aead_mac_size,
|
||||
ssl->specs.aead_mac_size,
|
||||
ssl->encrypt.additional, AEAD_AUTH_DATA_SZ);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_PENDING_E && asyncOkay) {
|
||||
ret = wolfSSL_AsyncPush(ssl, asyncDev);
|
||||
@@ -17527,19 +17579,37 @@ static WC_INLINE int DecryptDo(WOLFSSL* ssl, byte* plain, const byte* input,
|
||||
AESGCM_IMP_IV_SZ);
|
||||
XMEMCPY(ssl->decrypt.nonce + AESGCM_IMP_IV_SZ, input,
|
||||
AESGCM_EXP_IV_SZ);
|
||||
if ((ret = aes_auth_fn(ssl->decrypt.aes,
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
ret = NOT_COMPILED_IN;
|
||||
if (ssl->ctx && ssl->ctx->PerformTlsRecordProcessingCb) {
|
||||
ret = ssl->ctx->PerformTlsRecordProcessingCb(ssl, 0,
|
||||
plain + AESGCM_EXP_IV_SZ,
|
||||
input + AESGCM_EXP_IV_SZ,
|
||||
sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
|
||||
sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
|
||||
ssl->decrypt.nonce, AESGCM_NONCE_SZ,
|
||||
input + sz - ssl->specs.aead_mac_size,
|
||||
(byte *)(input + sz - ssl->specs.aead_mac_size),
|
||||
ssl->specs.aead_mac_size,
|
||||
ssl->decrypt.additional, AEAD_AUTH_DATA_SZ)) < 0) {
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_PENDING_E) {
|
||||
ret = wolfSSL_AsyncPush(ssl, &ssl->decrypt.aes->asyncDev);
|
||||
ssl->decrypt.additional, AEAD_AUTH_DATA_SZ);
|
||||
}
|
||||
|
||||
if (ret == NOT_COMPILED_IN)
|
||||
#endif /* HAVE_PK_CALLBACKS */
|
||||
{
|
||||
if ((ret = aes_auth_fn(ssl->decrypt.aes,
|
||||
plain + AESGCM_EXP_IV_SZ,
|
||||
input + AESGCM_EXP_IV_SZ,
|
||||
sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
|
||||
ssl->decrypt.nonce, AESGCM_NONCE_SZ,
|
||||
input + sz - ssl->specs.aead_mac_size,
|
||||
ssl->specs.aead_mac_size,
|
||||
ssl->decrypt.additional, AEAD_AUTH_DATA_SZ)) < 0) {
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_PENDING_E) {
|
||||
ret = wolfSSL_AsyncPush(ssl,
|
||||
&ssl->decrypt.aes->asyncDev);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -25919,8 +25989,14 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
|
||||
ssl->buffers.sig.length,
|
||||
ssl->buffers.digest.buffer,
|
||||
ssl->buffers.digest.length);
|
||||
XFREE(ssl->buffers.sig.buffer, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
|
||||
ssl->buffers.sig.buffer = NULL;
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
if (ssl->ctx->ProcessServerSigKexCb == NULL)
|
||||
#endif
|
||||
{
|
||||
/* No further processing will be done. It can be freed. */
|
||||
XFREE(ssl->buffers.sig.buffer, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
|
||||
ssl->buffers.sig.buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -28073,17 +28149,30 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
|
||||
#ifdef HAVE_ECC
|
||||
case ecc_dsa_sa_algo:
|
||||
{
|
||||
ret = EccVerify(ssl,
|
||||
args->verifySig, args->verifySigSz,
|
||||
ssl->buffers.digest.buffer,
|
||||
ssl->buffers.digest.length,
|
||||
ssl->peerEccDsaKey,
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
&ssl->buffers.peerEccDsaKey
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
);
|
||||
ret = NOT_COMPILED_IN;
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
if (ssl->ctx && ssl->ctx->ProcessServerSigKexCb) {
|
||||
ret = ssl->ctx->ProcessServerSigKexCb(ssl,
|
||||
args->sigAlgo,
|
||||
args->verifySig, args->verifySigSz,
|
||||
ssl->buffers.sig.buffer, SEED_LEN,
|
||||
&ssl->buffers.sig.buffer[SEED_LEN],
|
||||
(ssl->buffers.sig.length - SEED_LEN));
|
||||
}
|
||||
#endif /* HAVE_PK_CALLBACKS */
|
||||
if (ret == NOT_COMPILED_IN) {
|
||||
ret = EccVerify(ssl,
|
||||
args->verifySig, args->verifySigSz,
|
||||
ssl->buffers.digest.buffer,
|
||||
ssl->buffers.digest.length,
|
||||
ssl->peerEccDsaKey,
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
&ssl->buffers.peerEccDsaKey
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret != WC_PENDING_E)
|
||||
@@ -28691,7 +28780,7 @@ int SendClientKeyExchange(WOLFSSL* ssl)
|
||||
}
|
||||
|
||||
ret = EccMakeKey(ssl, (ecc_key*)ssl->hsKey, peerKey);
|
||||
#endif
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -28833,36 +28922,52 @@ int SendClientKeyExchange(WOLFSSL* ssl)
|
||||
case psk_kea:
|
||||
{
|
||||
byte* pms = ssl->arrays->preMasterSecret;
|
||||
ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
|
||||
int cbret = (int)ssl->options.client_psk_cb(ssl,
|
||||
ssl->arrays->server_hint, ssl->arrays->client_identity,
|
||||
MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
|
||||
if (ssl->arrays->psk_keySz == 0 ||
|
||||
ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
|
||||
ERROR_OUT(PSK_KEY_ERROR, exit_scke);
|
||||
|
||||
if (cbret == 0 || cbret > MAX_PSK_KEY_LEN) {
|
||||
if (cbret != USE_HW_PSK) {
|
||||
ERROR_OUT(PSK_KEY_ERROR, exit_scke);
|
||||
}
|
||||
}
|
||||
ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0'; /* null term */
|
||||
|
||||
if (cbret == USE_HW_PSK) {
|
||||
/* USE_HW_PSK indicates that the hardware has the PSK
|
||||
* and generates the premaster secret. */
|
||||
ssl->arrays->psk_keySz = 0;
|
||||
}
|
||||
else {
|
||||
ssl->arrays->psk_keySz = (word32)cbret;
|
||||
}
|
||||
|
||||
/* Ensure the buffer is null-terminated. */
|
||||
ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0';
|
||||
args->encSz = (word32)XSTRLEN(ssl->arrays->client_identity);
|
||||
if (args->encSz > MAX_PSK_ID_LEN) {
|
||||
ERROR_OUT(CLIENT_ID_ERROR, exit_scke);
|
||||
}
|
||||
XMEMCPY(args->encSecret, ssl->arrays->client_identity,
|
||||
args->encSz);
|
||||
/* CLIENT: Pre-shared Key for peer authentication. */
|
||||
args->encSz);
|
||||
ssl->options.peerAuthGood = 1;
|
||||
if (cbret != USE_HW_PSK) {
|
||||
/* CLIENT: Pre-shared Key for peer authentication. */
|
||||
|
||||
/* make psk pre master secret */
|
||||
/* length of key + length 0s + length of key + key */
|
||||
c16toa((word16)ssl->arrays->psk_keySz, pms);
|
||||
pms += OPAQUE16_LEN;
|
||||
XMEMSET(pms, 0, ssl->arrays->psk_keySz);
|
||||
pms += ssl->arrays->psk_keySz;
|
||||
c16toa((word16)ssl->arrays->psk_keySz, pms);
|
||||
pms += OPAQUE16_LEN;
|
||||
XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
|
||||
ssl->arrays->preMasterSz = (ssl->arrays->psk_keySz * 2) +
|
||||
(2 * OPAQUE16_LEN);
|
||||
ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
|
||||
ssl->arrays->psk_keySz = 0; /* No further need */
|
||||
/* make psk pre master secret */
|
||||
/* length of key + length 0s + length of key + key */
|
||||
c16toa((word16)ssl->arrays->psk_keySz, pms);
|
||||
pms += OPAQUE16_LEN;
|
||||
XMEMSET(pms, 0, ssl->arrays->psk_keySz);
|
||||
pms += ssl->arrays->psk_keySz;
|
||||
c16toa((word16)ssl->arrays->psk_keySz, pms);
|
||||
pms += OPAQUE16_LEN;
|
||||
XMEMCPY(pms, ssl->arrays->psk_key,
|
||||
ssl->arrays->psk_keySz);
|
||||
ssl->arrays->preMasterSz = (ssl->arrays->psk_keySz * 2)
|
||||
+ (2 * OPAQUE16_LEN);
|
||||
ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
|
||||
ssl->arrays->psk_keySz = 0; /* No further need */
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* !NO_PSK */
|
||||
@@ -29296,12 +29401,12 @@ int SendClientKeyExchange(WOLFSSL* ssl)
|
||||
ssl->peerEccDsaKey : ssl->peerEccKey;
|
||||
|
||||
ret = EccSharedSecret(ssl,
|
||||
(ecc_key*)ssl->hsKey, peerKey,
|
||||
args->encSecret + OPAQUE8_LEN, &args->encSz,
|
||||
ssl->arrays->preMasterSecret,
|
||||
&ssl->arrays->preMasterSz,
|
||||
WOLFSSL_CLIENT_END
|
||||
);
|
||||
(ecc_key*)ssl->hsKey, peerKey,
|
||||
args->encSecret + OPAQUE8_LEN, &args->encSz,
|
||||
ssl->arrays->preMasterSecret,
|
||||
&ssl->arrays->preMasterSz,
|
||||
WOLFSSL_CLIENT_END);
|
||||
|
||||
if (!ssl->specs.static_ecdh
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
&& ret != WC_PENDING_E
|
||||
@@ -29885,12 +29990,13 @@ int SendCertificateVerify(WOLFSSL* ssl)
|
||||
case TLS_ASYNC_DO:
|
||||
{
|
||||
#ifdef HAVE_ECC
|
||||
if (ssl->hsType == DYNAMIC_TYPE_ECC) {
|
||||
if (ssl->hsType == DYNAMIC_TYPE_ECC) {
|
||||
ecc_key* key = (ecc_key*)ssl->hsKey;
|
||||
|
||||
ret = EccSign(ssl,
|
||||
ssl->buffers.digest.buffer, ssl->buffers.digest.length,
|
||||
ssl->buffers.sig.buffer, (word32*)&ssl->buffers.sig.length,
|
||||
ssl->buffers.sig.buffer,
|
||||
(word32*)&ssl->buffers.sig.length,
|
||||
key,
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
ssl->buffers.key
|
||||
|
35
src/ssl.c
35
src/ssl.c
@@ -8147,8 +8147,8 @@ static int LoadSystemCaCertsWindows(WOLFSSL_CTX* ctx, byte* loaded)
|
||||
i < sizeof(storeNames)/sizeof(*storeNames); ++i) {
|
||||
handle = CertOpenSystemStoreA(hProv, storeNames[i]);
|
||||
if (handle != NULL) {
|
||||
while (certCtx = CertEnumCertificatesInStore(handle,
|
||||
certCtx)) {
|
||||
while ((certCtx = CertEnumCertificatesInStore(handle, certCtx))
|
||||
!= NULL) {
|
||||
if (certCtx->dwCertEncodingType == X509_ASN_ENCODING) {
|
||||
if (ProcessBuffer(ctx, certCtx->pbCertEncoded,
|
||||
certCtx->cbCertEncoded, WOLFSSL_FILETYPE_ASN1,
|
||||
@@ -29475,10 +29475,41 @@ void* wolfSSL_GetVerifyMacCtx(WOLFSSL* ssl)
|
||||
}
|
||||
#endif /* !WOLFSSL_NO_TLS12 && !WOLFSSL_AEAD_ONLY */
|
||||
|
||||
void wolfSSL_CTX_SetHKDFExpandLabelCb(WOLFSSL_CTX* ctx,
|
||||
CallbackHKDFExpandLabel cb)
|
||||
{
|
||||
if (ctx)
|
||||
ctx->HKDFExpandLabelCb = cb;
|
||||
}
|
||||
#ifdef WOLFSSL_PUBLIC_ASN
|
||||
void wolfSSL_CTX_SetProcessPeerCertCb(WOLFSSL_CTX* ctx,
|
||||
CallbackProcessPeerCert cb)
|
||||
{
|
||||
if (ctx)
|
||||
ctx->ProcessPeerCertCb = cb;
|
||||
}
|
||||
#endif /* WOLFSSL_PUBLIC_ASN */
|
||||
void wolfSSL_CTX_SetProcessServerSigKexCb(WOLFSSL_CTX* ctx,
|
||||
CallbackProcessServerSigKex cb)
|
||||
{
|
||||
if (ctx)
|
||||
ctx->ProcessServerSigKexCb = cb;
|
||||
}
|
||||
void wolfSSL_CTX_SetPerformTlsRecordProcessingCb(WOLFSSL_CTX* ctx,
|
||||
CallbackPerformTlsRecordProcessing cb)
|
||||
{
|
||||
if (ctx)
|
||||
ctx->PerformTlsRecordProcessingCb = cb;
|
||||
}
|
||||
#endif /* HAVE_PK_CALLBACKS */
|
||||
#endif /* NO_CERTS */
|
||||
|
||||
#if defined(HAVE_PK_CALLBACKS) && !defined(NO_DH)
|
||||
void wolfSSL_CTX_SetDhGenerateKeyPair(WOLFSSL_CTX* ctx,
|
||||
CallbackDhGenerateKeyPair cb) {
|
||||
if (ctx)
|
||||
ctx->DhGenerateKeyPairCb = cb;
|
||||
}
|
||||
void wolfSSL_CTX_SetDhAgreeCb(WOLFSSL_CTX* ctx, CallbackDhAgree cb)
|
||||
{
|
||||
if (ctx)
|
||||
|
24
src/tls.c
24
src/tls.c
@@ -215,18 +215,18 @@ int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
|
||||
#if !defined(NO_CERTS) && defined(HAVE_PK_CALLBACKS)
|
||||
if (ssl->ctx->TlsFinishedCb) {
|
||||
void* ctx = wolfSSL_GetTlsFinishedCtx(ssl);
|
||||
ret = ssl->ctx->TlsFinishedCb(ssl, side, handshake_hash,
|
||||
(byte*)hashes, ctx);
|
||||
ret = ssl->ctx->TlsFinishedCb(ssl, side, handshake_hash, hashSz,
|
||||
(byte*)hashes, ctx);
|
||||
}
|
||||
if (!ssl->ctx->TlsFinishedCb || ret == PROTOCOLCB_UNAVAILABLE)
|
||||
#endif
|
||||
{
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
ret = wc_PRF_TLS((byte*)hashes, TLS_FINISHED_SZ,
|
||||
ssl->arrays->masterSecret,
|
||||
SECRET_LEN, side, FINISHED_LABEL_SZ, handshake_hash, hashSz,
|
||||
IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
|
||||
ssl->heap, ssl->devId);
|
||||
ssl->arrays->masterSecret, SECRET_LEN, side,
|
||||
FINISHED_LABEL_SZ, handshake_hash, hashSz,
|
||||
IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
|
||||
ssl->heap, ssl->devId);
|
||||
PRIVATE_KEY_LOCK();
|
||||
}
|
||||
ForceZero(handshake_hash, hashSz);
|
||||
@@ -566,11 +566,13 @@ int MakeTlsMasterSecret(WOLFSSL* ssl)
|
||||
}
|
||||
if (!ssl->ctx->GenMasterCb || ret == PROTOCOLCB_UNAVAILABLE)
|
||||
#endif
|
||||
ret = _MakeTlsMasterSecret(ssl->arrays->masterSecret, SECRET_LEN,
|
||||
ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
|
||||
ssl->arrays->clientRandom, ssl->arrays->serverRandom,
|
||||
IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
|
||||
ssl->heap, ssl->devId);
|
||||
{
|
||||
ret = _MakeTlsMasterSecret(ssl->arrays->masterSecret,
|
||||
SECRET_LEN, ssl->arrays->preMasterSecret,
|
||||
ssl->arrays->preMasterSz, ssl->arrays->clientRandom,
|
||||
ssl->arrays->serverRandom, IsAtLeastTLSv1_2(ssl),
|
||||
ssl->specs.mac_algorithm, ssl->heap, ssl->devId);
|
||||
}
|
||||
}
|
||||
if (ret == 0) {
|
||||
#ifdef SHOW_SECRETS
|
||||
|
348
src/tls13.c
348
src/tls13.c
@@ -165,6 +165,95 @@ static const byte tls13ProtocolLabel[TLS13_PROTOCOL_LABEL_SZ + 1] = "tls13 ";
|
||||
static const byte dtls13ProtocolLabel[DTLS13_PROTOCOL_LABEL_SZ + 1] = "dtls13";
|
||||
#endif /* WOLFSSL_DTLS13 */
|
||||
|
||||
/* Expand data using HMAC, salt and label and info.
|
||||
* TLS v1.3 defines this function. Use callback if available.
|
||||
*
|
||||
* ssl The SSL/TLS object.
|
||||
* okm The generated pseudorandom key - output key material.
|
||||
* okmLen The length of generated pseudorandom key -
|
||||
* output key material.
|
||||
* prk The salt - pseudo-random key.
|
||||
* prkLen The length of the salt - pseudo-random key.
|
||||
* protocol The TLS protocol label.
|
||||
* protocolLen The length of the TLS protocol label.
|
||||
* info The information to expand.
|
||||
* infoLen The length of the information.
|
||||
* digest The type of digest to use.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int Tls13HKDFExpandLabel(WOLFSSL* ssl, byte* okm, word32 okmLen,
|
||||
const byte* prk, word32 prkLen,
|
||||
const byte* protocol, word32 protocolLen,
|
||||
const byte* label, word32 labelLen,
|
||||
const byte* info, word32 infoLen,
|
||||
int digest)
|
||||
{
|
||||
int ret = NOT_COMPILED_IN;
|
||||
|
||||
#if defined(HAVE_PK_CALLBACKS)
|
||||
if (ssl->ctx && ssl->ctx->HKDFExpandLabelCb) {
|
||||
ret = ssl->ctx->HKDFExpandLabelCb(okm, okmLen, prk, prkLen,
|
||||
protocol, protocolLen,
|
||||
label, labelLen,
|
||||
info, infoLen, digest,
|
||||
WOLFSSL_CLIENT_END /* ignored */);
|
||||
}
|
||||
|
||||
if (ret != NOT_COMPILED_IN)
|
||||
return ret;
|
||||
#endif
|
||||
(void)ssl;
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
ret = wc_Tls13_HKDF_Expand_Label(okm, okmLen, prk, prkLen,
|
||||
protocol, protocolLen,
|
||||
label, labelLen,
|
||||
info, infoLen, digest);
|
||||
PRIVATE_KEY_LOCK();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(HAVE_FIPS) || !defined(wc_Tls13_HKDF_Expand_Label)
|
||||
/* Same as above, but pass in the side we are expanding for.
|
||||
*
|
||||
* side The side (WOLFSSL_CLIENT_END or WOLFSSL_SERVER_END).
|
||||
*/
|
||||
static int Tls13HKDFExpandKeyLabel(WOLFSSL* ssl, byte* okm, word32 okmLen,
|
||||
const byte* prk, word32 prkLen,
|
||||
const byte* protocol, word32 protocolLen,
|
||||
const byte* label, word32 labelLen,
|
||||
const byte* info, word32 infoLen,
|
||||
int digest, int side)
|
||||
{
|
||||
#if defined(HAVE_PK_CALLBACKS)
|
||||
int ret = NOT_COMPILED_IN;
|
||||
if (ssl->ctx && ssl->ctx->HKDFExpandLabelCb) {
|
||||
ret = ssl->ctx->HKDFExpandLabelCb(okm, okmLen, prk, prkLen,
|
||||
protocol, protocolLen,
|
||||
label, labelLen,
|
||||
info, infoLen,
|
||||
digest, side);
|
||||
}
|
||||
|
||||
if (ret != NOT_COMPILED_IN)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
/* hash buffer may not be fully initialized, but the sending length won't
|
||||
* extend beyond the initialized span.
|
||||
*/
|
||||
PRAGMA_GCC_DIAG_PUSH;
|
||||
PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"");
|
||||
(void)ssl;
|
||||
(void)side;
|
||||
return wc_Tls13_HKDF_Expand_Label(okm, okmLen, prk, prkLen,
|
||||
protocol, protocolLen,
|
||||
label, labelLen,
|
||||
info, infoLen, digest);
|
||||
PRAGMA_GCC_DIAG_POP;
|
||||
}
|
||||
#endif /* !HAVE_FIPS || !wc_Tls13_HKDF_Expand_Label */
|
||||
|
||||
|
||||
/* Derive a key from a message.
|
||||
*
|
||||
* ssl The SSL/TLS object.
|
||||
@@ -261,11 +350,9 @@ static int DeriveKeyMsg(WOLFSSL* ssl, byte* output, int outputLen,
|
||||
if (outputLen == -1)
|
||||
outputLen = hashSz;
|
||||
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
ret = wc_Tls13_HKDF_Expand_Label(output, outputLen, secret, hashSz,
|
||||
protocol, protocolLen, label, labelLen,
|
||||
hash, hashSz, digestAlg);
|
||||
PRIVATE_KEY_LOCK();
|
||||
ret = Tls13HKDFExpandLabel(ssl, output, outputLen, secret, hashSz,
|
||||
protocol, protocolLen, label, labelLen,
|
||||
hash, hashSz, digestAlg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -279,11 +366,12 @@ static int DeriveKeyMsg(WOLFSSL* ssl, byte* output, int outputLen,
|
||||
* labelLen The length of the label.
|
||||
* hashAlgo The hash algorithm to use in the HMAC.
|
||||
* includeMsgs Whether to include a hash of the handshake messages so far.
|
||||
* side The side that we are deriving the secret for.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
int Tls13DeriveKey(WOLFSSL* ssl, byte* output, int outputLen,
|
||||
const byte* secret, const byte* label, word32 labelLen,
|
||||
int hashAlgo, int includeMsgs)
|
||||
int hashAlgo, int includeMsgs, int side)
|
||||
{
|
||||
int ret = 0;
|
||||
byte hash[WC_MAX_DIGEST_SIZE];
|
||||
@@ -350,13 +438,14 @@ int Tls13DeriveKey(WOLFSSL* ssl, byte* output, int outputLen,
|
||||
PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"");
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
#if defined(HAVE_FIPS) && defined(wc_Tls13_HKDF_Expand_Label)
|
||||
(void)side;
|
||||
ret = wc_Tls13_HKDF_Expand_Label_fips(output, outputLen, secret, hashSz,
|
||||
protocol, protocolLen, label, labelLen,
|
||||
hash, hashOutSz, digestAlg);
|
||||
#else
|
||||
ret = wc_Tls13_HKDF_Expand_Label(output, outputLen, secret, hashSz,
|
||||
protocol, protocolLen, label, labelLen,
|
||||
hash, hashOutSz, digestAlg);
|
||||
ret = Tls13HKDFExpandKeyLabel(ssl, output, outputLen, secret, hashSz,
|
||||
protocol, protocolLen, label, labelLen,
|
||||
hash, hashOutSz, digestAlg, side);
|
||||
#endif
|
||||
PRIVATE_KEY_LOCK();
|
||||
|
||||
@@ -462,9 +551,10 @@ static const byte earlyTrafficLabel[EARLY_TRAFFIC_LABEL_SZ + 1] =
|
||||
*
|
||||
* ssl The SSL/TLS object.
|
||||
* key The derived key.
|
||||
* side The side that we are deriving the secret for.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int DeriveEarlyTrafficSecret(WOLFSSL* ssl, byte* key)
|
||||
static int DeriveEarlyTrafficSecret(WOLFSSL* ssl, byte* key, int side)
|
||||
{
|
||||
int ret;
|
||||
WOLFSSL_MSG("Derive Early Traffic Secret");
|
||||
@@ -473,7 +563,7 @@ static int DeriveEarlyTrafficSecret(WOLFSSL* ssl, byte* key)
|
||||
}
|
||||
ret = Tls13DeriveKey(ssl, key, -1, ssl->arrays->secret,
|
||||
earlyTrafficLabel, EARLY_TRAFFIC_LABEL_SZ,
|
||||
ssl->specs.mac_algorithm, 1);
|
||||
ssl->specs.mac_algorithm, 1, side);
|
||||
#ifdef HAVE_SECRET_CALLBACK
|
||||
if (ret == 0 && ssl->tls13SecretCb != NULL) {
|
||||
ret = ssl->tls13SecretCb(ssl, CLIENT_EARLY_TRAFFIC_SECRET, key,
|
||||
@@ -521,7 +611,7 @@ static int DeriveClientHandshakeSecret(WOLFSSL* ssl, byte* key)
|
||||
|
||||
ret = Tls13DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret,
|
||||
clientHandshakeLabel, CLIENT_HANDSHAKE_LABEL_SZ,
|
||||
ssl->specs.mac_algorithm, 1);
|
||||
ssl->specs.mac_algorithm, 1, WOLFSSL_CLIENT_END);
|
||||
#ifdef HAVE_SECRET_CALLBACK
|
||||
if (ret == 0 && ssl->tls13SecretCb != NULL) {
|
||||
ret = ssl->tls13SecretCb(ssl, CLIENT_HANDSHAKE_TRAFFIC_SECRET, key,
|
||||
@@ -566,7 +656,7 @@ static int DeriveServerHandshakeSecret(WOLFSSL* ssl, byte* key)
|
||||
}
|
||||
ret = Tls13DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret,
|
||||
serverHandshakeLabel, SERVER_HANDSHAKE_LABEL_SZ,
|
||||
ssl->specs.mac_algorithm, 1);
|
||||
ssl->specs.mac_algorithm, 1, WOLFSSL_SERVER_END);
|
||||
#ifdef HAVE_SECRET_CALLBACK
|
||||
if (ret == 0 && ssl->tls13SecretCb != NULL) {
|
||||
ret = ssl->tls13SecretCb(ssl, SERVER_HANDSHAKE_TRAFFIC_SECRET, key,
|
||||
@@ -611,7 +701,7 @@ static int DeriveClientTrafficSecret(WOLFSSL* ssl, byte* key)
|
||||
}
|
||||
ret = Tls13DeriveKey(ssl, key, -1, ssl->arrays->masterSecret,
|
||||
clientAppLabel, CLIENT_APP_LABEL_SZ,
|
||||
ssl->specs.mac_algorithm, 1);
|
||||
ssl->specs.mac_algorithm, 1, WOLFSSL_CLIENT_END);
|
||||
#ifdef HAVE_SECRET_CALLBACK
|
||||
if (ret == 0 && ssl->tls13SecretCb != NULL) {
|
||||
ret = ssl->tls13SecretCb(ssl, CLIENT_TRAFFIC_SECRET, key,
|
||||
@@ -656,7 +746,7 @@ static int DeriveServerTrafficSecret(WOLFSSL* ssl, byte* key)
|
||||
}
|
||||
ret = Tls13DeriveKey(ssl, key, -1, ssl->arrays->masterSecret,
|
||||
serverAppLabel, SERVER_APP_LABEL_SZ,
|
||||
ssl->specs.mac_algorithm, 1);
|
||||
ssl->specs.mac_algorithm, 1, WOLFSSL_SERVER_END);
|
||||
#ifdef HAVE_SECRET_CALLBACK
|
||||
if (ret == 0 && ssl->tls13SecretCb != NULL) {
|
||||
ret = ssl->tls13SecretCb(ssl, SERVER_TRAFFIC_SECRET, key,
|
||||
@@ -702,7 +792,7 @@ static int DeriveExporterSecret(WOLFSSL* ssl, byte* key)
|
||||
}
|
||||
ret = Tls13DeriveKey(ssl, key, -1, ssl->arrays->masterSecret,
|
||||
exporterMasterLabel, EXPORTER_MASTER_LABEL_SZ,
|
||||
ssl->specs.mac_algorithm, 1);
|
||||
ssl->specs.mac_algorithm, 1, 0 /* Unused */);
|
||||
#ifdef HAVE_SECRET_CALLBACK
|
||||
if (ret == 0 && ssl->tls13SecretCb != NULL) {
|
||||
ret = ssl->tls13SecretCb(ssl, EXPORTER_SECRET, key,
|
||||
@@ -805,12 +895,10 @@ int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen,
|
||||
}
|
||||
|
||||
/* Derive-Secret(Secret, label, "") */
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
ret = wc_Tls13_HKDF_Expand_Label(firstExpand, hashLen,
|
||||
ret = Tls13HKDFExpandLabel(ssl, firstExpand, hashLen,
|
||||
ssl->arrays->exporterSecret, hashLen,
|
||||
protocol, protocolLen, (byte*)label, (word32)labelLen,
|
||||
emptyHash, hashLen, hashType);
|
||||
PRIVATE_KEY_LOCK();
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
@@ -819,11 +907,9 @@ int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen,
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
ret = wc_Tls13_HKDF_Expand_Label(out, (word32)outLen, firstExpand, hashLen,
|
||||
ret = Tls13HKDFExpandLabel(ssl, out, (word32)outLen, firstExpand, hashLen,
|
||||
protocol, protocolLen, exporterLabel, EXPORTER_LABEL_SZ,
|
||||
hashOut, hashLen, hashType);
|
||||
PRIVATE_KEY_LOCK();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -857,7 +943,8 @@ int DeriveResumptionSecret(WOLFSSL* ssl, byte* key)
|
||||
masterSecret = ssl->session->masterSecret;
|
||||
}
|
||||
return Tls13DeriveKey(ssl, key, -1, masterSecret, resumeMasterLabel,
|
||||
RESUME_MASTER_LABEL_SZ, ssl->specs.mac_algorithm, 1);
|
||||
RESUME_MASTER_LABEL_SZ, ssl->specs.mac_algorithm, 1,
|
||||
0 /* Unused */);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -870,13 +957,16 @@ static const byte finishedLabel[FINISHED_LABEL_SZ+1] = "finished";
|
||||
* ssl The SSL/TLS object.
|
||||
* key The key to use with the HMAC.
|
||||
* secret The derived secret.
|
||||
* side The side that we are deriving the secret for.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int DeriveFinishedSecret(WOLFSSL* ssl, byte* key, byte* secret)
|
||||
static int DeriveFinishedSecret(WOLFSSL* ssl, byte* key, byte* secret,
|
||||
int side)
|
||||
{
|
||||
WOLFSSL_MSG("Derive Finished Secret");
|
||||
return Tls13DeriveKey(ssl, secret, -1, key, finishedLabel, FINISHED_LABEL_SZ,
|
||||
ssl->specs.mac_algorithm, 0);
|
||||
return Tls13DeriveKey(ssl, secret, -1, key, finishedLabel,
|
||||
FINISHED_LABEL_SZ, ssl->specs.mac_algorithm, 0,
|
||||
side);
|
||||
}
|
||||
|
||||
/* The length of the application traffic label. */
|
||||
@@ -889,14 +979,15 @@ static const byte appTrafficLabel[APP_TRAFFIC_LABEL_SZ + 1] =
|
||||
*
|
||||
* ssl The SSL/TLS object.
|
||||
* secret The previous secret and derived secret.
|
||||
* side The side that we are deriving the secret for.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int DeriveTrafficSecret(WOLFSSL* ssl, byte* secret)
|
||||
static int DeriveTrafficSecret(WOLFSSL* ssl, byte* secret, int side)
|
||||
{
|
||||
WOLFSSL_MSG("Derive New Application Traffic Secret");
|
||||
return Tls13DeriveKey(ssl, secret, -1, secret,
|
||||
appTrafficLabel, APP_TRAFFIC_LABEL_SZ,
|
||||
ssl->specs.mac_algorithm, 0);
|
||||
ssl->specs.mac_algorithm, 0, side);
|
||||
}
|
||||
|
||||
|
||||
@@ -1078,19 +1169,20 @@ int DeriveResumptionPSK(WOLFSSL* ssl, byte* nonce, byte nonceLen, byte* secret)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
ret = wc_Tls13_HKDF_Expand_Label_Alloc(secret, ssl->specs.hash_size,
|
||||
ssl->session->masterSecret, ssl->specs.hash_size, protocol, protocolLen,
|
||||
resumptionLabel, RESUMPTION_LABEL_SZ, nonce, nonceLen, digestAlg,
|
||||
ssl->heap);
|
||||
#else
|
||||
ret = wc_Tls13_HKDF_Expand_Label(secret, ssl->specs.hash_size,
|
||||
ssl->session->masterSecret, ssl->specs.hash_size, protocol, protocolLen,
|
||||
resumptionLabel, RESUMPTION_LABEL_SZ, nonce, nonceLen, digestAlg);
|
||||
#endif /* !defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3) */
|
||||
PRIVATE_KEY_LOCK();
|
||||
#else
|
||||
ret = Tls13HKDFExpandLabel(ssl, secret, ssl->specs.hash_size,
|
||||
ssl->session->masterSecret, ssl->specs.hash_size,
|
||||
protocol, protocolLen, resumptionLabel,
|
||||
RESUMPTION_LABEL_SZ, nonce, nonceLen, digestAlg);
|
||||
#endif /* !defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3) */
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_SESSION_TICKET */
|
||||
@@ -1253,7 +1345,8 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
|
||||
switch (secret) {
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
case early_data_key:
|
||||
ret = DeriveEarlyTrafficSecret(ssl, ssl->clientSecret);
|
||||
ret = DeriveEarlyTrafficSecret(ssl, ssl->clientSecret,
|
||||
WOLFSSL_CLIENT_END);
|
||||
if (ret != 0)
|
||||
goto end;
|
||||
break;
|
||||
@@ -1289,12 +1382,14 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
|
||||
|
||||
case update_traffic_key:
|
||||
if (provision & PROVISION_CLIENT) {
|
||||
ret = DeriveTrafficSecret(ssl, ssl->clientSecret);
|
||||
ret = DeriveTrafficSecret(ssl, ssl->clientSecret,
|
||||
WOLFSSL_CLIENT_END);
|
||||
if (ret != 0)
|
||||
goto end;
|
||||
}
|
||||
if (provision & PROVISION_SERVER) {
|
||||
ret = DeriveTrafficSecret(ssl, ssl->serverSecret);
|
||||
ret = DeriveTrafficSecret(ssl, ssl->serverSecret,
|
||||
WOLFSSL_SERVER_END);
|
||||
if (ret != 0)
|
||||
goto end;
|
||||
}
|
||||
@@ -1322,7 +1417,8 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
|
||||
WOLFSSL_MSG("Derive Client Key");
|
||||
ret = Tls13DeriveKey(ssl, &key_dig[i], ssl->specs.key_size,
|
||||
ssl->clientSecret, writeKeyLabel,
|
||||
WRITE_KEY_LABEL_SZ, ssl->specs.mac_algorithm, 0);
|
||||
WRITE_KEY_LABEL_SZ, ssl->specs.mac_algorithm, 0,
|
||||
WOLFSSL_CLIENT_END);
|
||||
if (ret != 0)
|
||||
goto end;
|
||||
i += ssl->specs.key_size;
|
||||
@@ -1333,7 +1429,8 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
|
||||
WOLFSSL_MSG("Derive Server Key");
|
||||
ret = Tls13DeriveKey(ssl, &key_dig[i], ssl->specs.key_size,
|
||||
ssl->serverSecret, writeKeyLabel,
|
||||
WRITE_KEY_LABEL_SZ, ssl->specs.mac_algorithm, 0);
|
||||
WRITE_KEY_LABEL_SZ, ssl->specs.mac_algorithm, 0,
|
||||
WOLFSSL_SERVER_END);
|
||||
if (ret != 0)
|
||||
goto end;
|
||||
i += ssl->specs.key_size;
|
||||
@@ -1344,7 +1441,8 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
|
||||
WOLFSSL_MSG("Derive Client IV");
|
||||
ret = Tls13DeriveKey(ssl, &key_dig[i], ssl->specs.iv_size,
|
||||
ssl->clientSecret, writeIVLabel,
|
||||
WRITE_IV_LABEL_SZ, ssl->specs.mac_algorithm, 0);
|
||||
WRITE_IV_LABEL_SZ, ssl->specs.mac_algorithm, 0,
|
||||
WOLFSSL_CLIENT_END);
|
||||
if (ret != 0)
|
||||
goto end;
|
||||
i += ssl->specs.iv_size;
|
||||
@@ -1355,7 +1453,8 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
|
||||
WOLFSSL_MSG("Derive Server IV");
|
||||
ret = Tls13DeriveKey(ssl, &key_dig[i], ssl->specs.iv_size,
|
||||
ssl->serverSecret, writeIVLabel,
|
||||
WRITE_IV_LABEL_SZ, ssl->specs.mac_algorithm, 0);
|
||||
WRITE_IV_LABEL_SZ, ssl->specs.mac_algorithm, 0,
|
||||
WOLFSSL_SERVER_END);
|
||||
if (ret != 0)
|
||||
goto end;
|
||||
i += ssl->specs.iv_size;
|
||||
@@ -2364,20 +2463,35 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
|
||||
#endif
|
||||
|
||||
nonceSz = AESGCM_NONCE_SZ;
|
||||
|
||||
#if defined(HAVE_PK_CALLBACKS)
|
||||
ret = NOT_COMPILED_IN;
|
||||
if (ssl->ctx && ssl->ctx->PerformTlsRecordProcessingCb) {
|
||||
ret = ssl->ctx->PerformTlsRecordProcessingCb(ssl, 1,
|
||||
output, input, dataSz,
|
||||
ssl->encrypt.nonce, nonceSz,
|
||||
output + dataSz, macSz,
|
||||
aad, aadSz);
|
||||
}
|
||||
if (ret == NOT_COMPILED_IN)
|
||||
#endif
|
||||
{
|
||||
|
||||
#if ((defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) && \
|
||||
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)))
|
||||
ret = wc_AesGcmEncrypt(ssl->encrypt.aes, output, input,
|
||||
dataSz, ssl->encrypt.nonce, nonceSz,
|
||||
output + dataSz, macSz, aad, aadSz);
|
||||
ret = wc_AesGcmEncrypt(ssl->encrypt.aes, output, input,
|
||||
dataSz, ssl->encrypt.nonce, nonceSz,
|
||||
output + dataSz, macSz, aad, aadSz);
|
||||
#else
|
||||
ret = wc_AesGcmSetExtIV(ssl->encrypt.aes,
|
||||
ssl->encrypt.nonce, nonceSz);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmEncrypt_ex(ssl->encrypt.aes, output,
|
||||
input, dataSz, ssl->encrypt.nonce, nonceSz,
|
||||
output + dataSz, macSz, aad, aadSz);
|
||||
}
|
||||
ret = wc_AesGcmSetExtIV(ssl->encrypt.aes,
|
||||
ssl->encrypt.nonce, nonceSz);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmEncrypt_ex(ssl->encrypt.aes, output,
|
||||
input, dataSz, ssl->encrypt.nonce, nonceSz,
|
||||
output + dataSz, macSz, aad, aadSz);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -2392,20 +2506,33 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
|
||||
#endif
|
||||
|
||||
nonceSz = AESCCM_NONCE_SZ;
|
||||
#if defined(HAVE_PK_CALLBACKS)
|
||||
ret = NOT_COMPILED_IN;
|
||||
if (ssl->ctx && ssl->ctx->PerformTlsRecordProcessingCb) {
|
||||
ret = ssl->ctx->PerformTlsRecordProcessingCb(ssl, 1,
|
||||
output, input, dataSz,
|
||||
ssl->encrypt.nonce, nonceSz,
|
||||
output + dataSz, macSz,
|
||||
aad, aadSz);
|
||||
}
|
||||
if (ret == NOT_COMPILED_IN)
|
||||
#endif
|
||||
{
|
||||
#if ((defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) && \
|
||||
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)))
|
||||
ret = wc_AesCcmEncrypt(ssl->encrypt.aes, output, input,
|
||||
dataSz, ssl->encrypt.nonce, nonceSz,
|
||||
output + dataSz, macSz, aad, aadSz);
|
||||
ret = wc_AesCcmEncrypt(ssl->encrypt.aes, output, input,
|
||||
dataSz, ssl->encrypt.nonce, nonceSz,
|
||||
output + dataSz, macSz, aad, aadSz);
|
||||
#else
|
||||
ret = wc_AesCcmSetNonce(ssl->encrypt.aes,
|
||||
ssl->encrypt.nonce, nonceSz);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesCcmEncrypt_ex(ssl->encrypt.aes, output,
|
||||
input, dataSz, ssl->encrypt.nonce, nonceSz,
|
||||
output + dataSz, macSz, aad, aadSz);
|
||||
}
|
||||
ret = wc_AesCcmSetNonce(ssl->encrypt.aes,
|
||||
ssl->encrypt.nonce, nonceSz);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesCcmEncrypt_ex(ssl->encrypt.aes, output,
|
||||
input, dataSz, ssl->encrypt.nonce, nonceSz,
|
||||
output + dataSz, macSz, aad, aadSz);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -2720,15 +2847,32 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz,
|
||||
#endif
|
||||
|
||||
nonceSz = AESGCM_NONCE_SZ;
|
||||
ret = wc_AesGcmDecrypt(ssl->decrypt.aes, output, input,
|
||||
dataSz, ssl->decrypt.nonce, nonceSz,
|
||||
input + dataSz, macSz, aad, aadSz);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_PENDING_E) {
|
||||
ret = wolfSSL_AsyncPush(ssl,
|
||||
&ssl->decrypt.aes->asyncDev);
|
||||
|
||||
#if defined(HAVE_PK_CALLBACKS)
|
||||
ret = NOT_COMPILED_IN;
|
||||
if (ssl->ctx && ssl->ctx->PerformTlsRecordProcessingCb) {
|
||||
ret = ssl->ctx->PerformTlsRecordProcessingCb(ssl, 0,
|
||||
output, input, dataSz,
|
||||
ssl->decrypt.nonce, nonceSz,
|
||||
(byte *)(input + dataSz), macSz,
|
||||
aad, aadSz);
|
||||
}
|
||||
if (ret == NOT_COMPILED_IN)
|
||||
#endif
|
||||
{
|
||||
|
||||
ret = wc_AesGcmDecrypt(ssl->decrypt.aes, output, input,
|
||||
dataSz, ssl->decrypt.nonce, nonceSz,
|
||||
input + dataSz, macSz, aad, aadSz);
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_PENDING_E) {
|
||||
ret = wolfSSL_AsyncPush(ssl,
|
||||
&ssl->decrypt.aes->asyncDev);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -2743,15 +2887,28 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz,
|
||||
#endif
|
||||
|
||||
nonceSz = AESCCM_NONCE_SZ;
|
||||
ret = wc_AesCcmDecrypt(ssl->decrypt.aes, output, input,
|
||||
dataSz, ssl->decrypt.nonce, nonceSz,
|
||||
input + dataSz, macSz, aad, aadSz);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_PENDING_E) {
|
||||
ret = wolfSSL_AsyncPush(ssl,
|
||||
&ssl->decrypt.aes->asyncDev);
|
||||
#if defined(HAVE_PK_CALLBACKS)
|
||||
ret = NOT_COMPILED_IN;
|
||||
if (ssl->ctx && ssl->ctx->PerformTlsRecordProcessingCb) {
|
||||
ret = ssl->ctx->PerformTlsRecordProcessingCb(ssl, 0,
|
||||
output, input, dataSz,
|
||||
ssl->decrypt.nonce, nonceSz,
|
||||
(byte *)(input + dataSz), macSz,
|
||||
aad, aadSz);
|
||||
}
|
||||
if (ret == NOT_COMPILED_IN)
|
||||
#endif
|
||||
{
|
||||
ret = wc_AesCcmDecrypt(ssl->decrypt.aes, output, input,
|
||||
dataSz, ssl->decrypt.nonce, nonceSz,
|
||||
input + dataSz, macSz, aad, aadSz);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_PENDING_E) {
|
||||
ret = wolfSSL_AsyncPush(ssl,
|
||||
&ssl->decrypt.aes->asyncDev);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -3610,7 +3767,8 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
|
||||
|
||||
/* Derive the Finished message secret. */
|
||||
ret = DeriveFinishedSecret(ssl, binderKey,
|
||||
ssl->keys.client_write_MAC_secret);
|
||||
ssl->keys.client_write_MAC_secret,
|
||||
0 /* neither end */);
|
||||
if (ret != 0)
|
||||
break;
|
||||
|
||||
@@ -5106,7 +5264,8 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz,
|
||||
|
||||
/* Derive the Finished message secret. */
|
||||
ret = DeriveFinishedSecret(ssl, binderKey,
|
||||
ssl->keys.client_write_MAC_secret);
|
||||
ssl->keys.client_write_MAC_secret,
|
||||
0 /* neither end */);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
@@ -6758,23 +6917,14 @@ static WC_INLINE int GetMsgHash(WOLFSSL* ssl, byte* hash)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The length of the certificate verification label - client and server. */
|
||||
#define CERT_VFY_LABEL_SZ 34
|
||||
/* The server certificate verification label. */
|
||||
static const byte serverCertVfyLabel[CERT_VFY_LABEL_SZ] =
|
||||
"TLS 1.3, server CertificateVerify";
|
||||
/* The client certificate verification label. */
|
||||
static const byte clientCertVfyLabel[CERT_VFY_LABEL_SZ] =
|
||||
"TLS 1.3, client CertificateVerify";
|
||||
|
||||
/* The number of prefix bytes for signature data. */
|
||||
#define SIGNING_DATA_PREFIX_SZ 64
|
||||
/* The prefix byte in the signature data. */
|
||||
#define SIGNING_DATA_PREFIX_BYTE 0x20
|
||||
/* Maximum length of the signature data. */
|
||||
#define MAX_SIG_DATA_SZ (SIGNING_DATA_PREFIX_SZ + \
|
||||
CERT_VFY_LABEL_SZ + \
|
||||
WC_MAX_DIGEST_SIZE)
|
||||
|
||||
/* Create the signature data for TLS v1.3 certificate verification.
|
||||
*
|
||||
@@ -6783,8 +6933,8 @@ static const byte clientCertVfyLabel[CERT_VFY_LABEL_SZ] =
|
||||
* sigDataSz The length of the signature data.
|
||||
* check Indicates this is a check not create.
|
||||
*/
|
||||
static int CreateSigData(WOLFSSL* ssl, byte* sigData, word16* sigDataSz,
|
||||
int check)
|
||||
int CreateSigData(WOLFSSL* ssl, byte* sigData, word16* sigDataSz,
|
||||
int check)
|
||||
{
|
||||
word16 idx;
|
||||
int side = ssl->options.side;
|
||||
@@ -6823,8 +6973,8 @@ static int CreateSigData(WOLFSSL* ssl, byte* sigData, word16* sigDataSz,
|
||||
* hashAlgo The hash algorithm to use when signing.
|
||||
* returns the length of the encoded signature or negative on error.
|
||||
*/
|
||||
static int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
|
||||
int sigAlgo, int hashAlgo)
|
||||
int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
|
||||
int sigAlgo, int hashAlgo)
|
||||
{
|
||||
Digest digest;
|
||||
int hashSz = 0;
|
||||
@@ -8573,7 +8723,8 @@ int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
|
||||
if (ssl->options.handShakeDone) {
|
||||
ret = DeriveFinishedSecret(ssl, ssl->clientSecret,
|
||||
ssl->keys.client_write_MAC_secret);
|
||||
ssl->keys.client_write_MAC_secret,
|
||||
WOLFSSL_CLIENT_END);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
@@ -8584,12 +8735,14 @@ int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
* client and server finished keys.
|
||||
*/
|
||||
ret = DeriveFinishedSecret(ssl, ssl->clientSecret,
|
||||
ssl->keys.client_write_MAC_secret);
|
||||
ssl->keys.client_write_MAC_secret,
|
||||
WOLFSSL_CLIENT_END);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = DeriveFinishedSecret(ssl, ssl->serverSecret,
|
||||
ssl->keys.server_write_MAC_secret);
|
||||
ssl->keys.server_write_MAC_secret,
|
||||
WOLFSSL_SERVER_END);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
@@ -8745,7 +8898,8 @@ static int SendTls13Finished(WOLFSSL* ssl)
|
||||
/* make finished hashes */
|
||||
if (ssl->options.handShakeDone) {
|
||||
ret = DeriveFinishedSecret(ssl, ssl->clientSecret,
|
||||
ssl->keys.client_write_MAC_secret);
|
||||
ssl->keys.client_write_MAC_secret,
|
||||
WOLFSSL_CLIENT_END);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
@@ -8758,12 +8912,14 @@ static int SendTls13Finished(WOLFSSL* ssl)
|
||||
* server finished keys.
|
||||
*/
|
||||
ret = DeriveFinishedSecret(ssl, ssl->clientSecret,
|
||||
ssl->keys.client_write_MAC_secret);
|
||||
ssl->keys.client_write_MAC_secret,
|
||||
WOLFSSL_SERVER_END);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = DeriveFinishedSecret(ssl, ssl->serverSecret,
|
||||
ssl->keys.server_write_MAC_secret);
|
||||
ssl->keys.server_write_MAC_secret,
|
||||
WOLFSSL_CLIENT_END);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
|
@@ -2798,6 +2798,12 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
|
||||
word32 localSz = 32;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
if (wc_MAXQ10XX_AesSetKey(aes, userKey, keylen) != 0) {
|
||||
return WC_HW_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_IMX6_CAAM_BLOB
|
||||
if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
|
||||
keylen == (24 + WC_CAAM_BLOB_SZ) ||
|
||||
@@ -10671,6 +10677,9 @@ int wc_AesInit(Aes* aes, void* heap, int devId)
|
||||
DCPAesInit(aes);
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
XMEMSET(&aes->maxq_ctx, 0, sizeof(aes->maxq_ctx));
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
#ifdef OPENSSL_EXTRA
|
||||
@@ -10798,6 +10807,10 @@ void wc_AesFree(Aes* aes)
|
||||
wc_psa_aes_free(aes);
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
wc_MAXQ10XX_AesFree(aes);
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
||||
wc_MemZero_Check(aes, sizeof(Aes));
|
||||
#endif
|
||||
|
@@ -11372,6 +11372,9 @@ static int StoreRsaKey(DecodedCert* cert, const byte* source, word32* srcIdx,
|
||||
#endif
|
||||
cert->pubKeySize = pubLen;
|
||||
cert->publicKey = source + pubIdx;
|
||||
#ifdef WOLFSSL_MAXQ10XX_TLS
|
||||
cert->publicKeyIndex = pubIdx;
|
||||
#endif
|
||||
*srcIdx += length;
|
||||
|
||||
#ifdef HAVE_OCSP
|
||||
@@ -11394,6 +11397,10 @@ static int StoreRsaKey(DecodedCert* cert, const byte* source, word32* srcIdx,
|
||||
GetASN_GetConstRef(&dataASN[RSACERTKEYASN_IDX_STR],
|
||||
&cert->publicKey, &cert->pubKeySize);
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_TLS
|
||||
cert->publicKeyIndex = dataASN[RSACERTKEYASN_IDX_SEQ].offset;
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
|
||||
/* Start of SEQUENCE. */
|
||||
cert->sigCtx.CertAtt.pubkey_n_start =
|
||||
@@ -11493,6 +11500,10 @@ static int StoreEccKey(DecodedCert* cert, const byte* source, word32* srcIdx,
|
||||
cert->sigCtx.CertAtt.pubkey_e_len =
|
||||
cert->sigCtx.CertAtt.pubkey_n_len;
|
||||
#endif
|
||||
#ifdef WOLFSSL_MAXQ10XX_TLS
|
||||
cert->publicKeyIndex = *srcIdx + 1;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OCSP
|
||||
ret = CalcHashId(source + *srcIdx, length, cert->subjectKeyHash);
|
||||
if (ret != 0)
|
||||
@@ -11530,6 +11541,12 @@ static int StoreEccKey(DecodedCert* cert, const byte* source, word32* srcIdx,
|
||||
}
|
||||
/* Ignore explicit parameters. */
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_TLS
|
||||
cert->publicKeyIndex =
|
||||
GetASNItem_DataIdx(dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY], source)
|
||||
+ 1;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OCSP
|
||||
/* Calculate the hash of the subject public key for OCSP. */
|
||||
ret = CalcHashId(dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY].data.ref.data,
|
||||
|
@@ -7345,6 +7345,10 @@ int wc_ecc_free(ecc_key* key)
|
||||
ForceZero(&key->xSec, sizeof(key->xSec));
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
wc_MAXQ10XX_EccFree(key);
|
||||
#endif
|
||||
|
||||
mp_clear(key->pubkey.x);
|
||||
mp_clear(key->pubkey.y);
|
||||
mp_clear(key->pubkey.z);
|
||||
@@ -10104,6 +10108,12 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
|
||||
err = wc_ecc_check_key(key);
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
if (err == MP_OKAY) {
|
||||
err = wc_MAXQ10XX_EccSetKey(key, keysize);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (err != MP_OKAY) {
|
||||
mp_clear(key->pubkey.x);
|
||||
mp_clear(key->pubkey.y);
|
||||
@@ -10448,6 +10458,12 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
|
||||
RESTORE_VECTOR_REGISTERS();
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
if (ret == 0) {
|
||||
ret = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -10838,6 +10854,12 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
|
||||
RESTORE_VECTOR_REGISTERS();
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
if (err == MP_OKAY) {
|
||||
err = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (err != MP_OKAY) {
|
||||
mp_clear(key->pubkey.x);
|
||||
mp_clear(key->pubkey.y);
|
||||
|
@@ -574,6 +574,9 @@ const char* wc_GetErrorString(int error)
|
||||
case SYSLIB_FAILED_E:
|
||||
return "System/library call failed";
|
||||
|
||||
case USE_HW_PSK:
|
||||
return "Callback indicates that HW has PSK";
|
||||
|
||||
default:
|
||||
return "unknown error number";
|
||||
|
||||
|
@@ -296,9 +296,11 @@ int _InitHmac(Hmac* hmac, int type, void* heap)
|
||||
|
||||
int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
|
||||
{
|
||||
#ifndef WOLFSSL_MAXQ108X
|
||||
byte* ip;
|
||||
byte* op;
|
||||
word32 i, hmac_block_size = 0;
|
||||
#endif
|
||||
int ret = 0;
|
||||
void* heap = NULL;
|
||||
|
||||
@@ -341,6 +343,11 @@ int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
|
||||
hmac->keyLen = length;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_MAXQ108X
|
||||
/* For MAXQ108x, nothing left to do. */
|
||||
return 0;
|
||||
#else
|
||||
|
||||
ip = (byte*)hmac->ipad;
|
||||
op = (byte*)hmac->opad;
|
||||
|
||||
@@ -585,6 +592,7 @@ int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
|
||||
}
|
||||
|
||||
return ret;
|
||||
#endif /* WOLFSSL_MAXQ108X */
|
||||
}
|
||||
|
||||
|
||||
|
@@ -200,3 +200,8 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/port/psa/psa_aes.c
|
||||
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/psa/psa_pkcbs.c
|
||||
endif
|
||||
EXTRA_DIST += wolfcrypt/src/port/psa/README.md
|
||||
|
||||
if BUILD_MAXQ10XX
|
||||
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/maxim/maxq10xx.c
|
||||
endif
|
||||
EXTRA_DIST += wolfcrypt/src/port/maxim/README.md
|
||||
|
@@ -834,7 +834,8 @@ WC_STATIC WC_INLINE word32 MakeWordFromHash(const byte* hashID)
|
||||
#endif /* HAVE_SESSION_TICKET || !NO_CERTS || !NO_SESSION_CACHE */
|
||||
|
||||
|
||||
#if !defined(WOLFCRYPT_ONLY) && (!defined(NO_SESSION_CACHE) || defined(HAVE_SESSION_TICKET))
|
||||
#if !defined(WOLFCRYPT_ONLY) && (!defined(NO_SESSION_CACHE) || \
|
||||
defined(HAVE_SESSION_TICKET))
|
||||
|
||||
#include <wolfssl/wolfcrypt/hash.h>
|
||||
|
||||
|
@@ -594,11 +594,12 @@ int wc_Renesas_cmn_RootCertVerify(const byte* cert, word32 cert_len, word32 key_
|
||||
* return FSP_SUCCESS(0) on success, otherwise FSP/TSIP error code
|
||||
*/
|
||||
WOLFSSL_LOCAL int Renesas_cmn_TlsFinished(WOLFSSL* ssl, const byte *side,
|
||||
const byte *handshake_hash,
|
||||
const byte *handshake_hash, word32 hashSz,
|
||||
byte *hashes, void* ctx)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
(void)hashSz;
|
||||
(void)ctx;
|
||||
|
||||
WOLFSSL_ENTER("Renesas_cmn_TlsFinished");
|
||||
|
51
wolfcrypt/src/port/maxim/README.md
Normal file
51
wolfcrypt/src/port/maxim/README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
wolfSSL using Analog Devices MAXQ1065 or MAX1080
|
||||
================================================
|
||||
|
||||
## Overview
|
||||
|
||||
wolfSSL can be configured to use the MAXQ1065 or MAX1080 cryptographic
|
||||
controllers. Product datasheets, user guides and other resources can be found at
|
||||
Analog Devices website:
|
||||
|
||||
https://www.analog.com
|
||||
|
||||
## Build and Usage
|
||||
|
||||
Please use the appropriate SDK or Evkit to build wolfSSL.
|
||||
|
||||
Instructions for setting up the hardware and various other utilities and
|
||||
prerequisite software and then building and using wolfSSL can be found in the
|
||||
MAXQ SDK. The SDK is available upon request to Analog Devices.
|
||||
|
||||
The Evkit comes with all the other necessary utility software and scripts and
|
||||
some prerequisite instructions such as how to copy the headers and library
|
||||
files to the correct location. Once those instructions are followed, you are
|
||||
ready to build wolfSSL.
|
||||
|
||||
To build for MAXQ1065 the following is sufficient:
|
||||
|
||||
```
|
||||
./configure --enable-cryptocb --disable-extended-master --enable-psk \
|
||||
--enable-aesccm --enable-debug --disable-tls13 \
|
||||
--with-maxq10xx=MAXQ1065
|
||||
make all
|
||||
sudo make install
|
||||
```
|
||||
To build for MAXQ1080 the following is sufficient:
|
||||
|
||||
```
|
||||
./configure --enable-cryptocb --disable-extended-master --enable-psk \
|
||||
--enable-aesccm --enable-debug --with-maxq10xx=MAXQ108x
|
||||
make all
|
||||
sudo make install
|
||||
```
|
||||
|
||||
## Example Code
|
||||
|
||||
You can find a very simple example client application in our wolfssl-examples
|
||||
repo on github:
|
||||
|
||||
https://https://github.com/wolfSSL/wolfssl-examples/tree/master/maxq10xx
|
||||
|
||||
NOTE: It assumes you have built wolfSSL using the SDK or Evkit.
|
||||
|
3408
wolfcrypt/src/port/maxim/maxq10xx.c
Normal file
3408
wolfcrypt/src/port/maxim/maxq10xx.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -247,6 +247,10 @@ static int InitSha256(wc_Sha256* sha256)
|
||||
sha256->devId = wc_CryptoCb_DefaultDevID();
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
XMEMSET(&sha256->maxq_ctx, 0, sizeof(sha256->maxq_ctx));
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
@@ -1741,6 +1745,10 @@ void wc_Sha256Free(wc_Sha256* sha256)
|
||||
#ifdef WOLFSSL_IMXRT_DCP
|
||||
DCPSha256Free(sha256);
|
||||
#endif
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
wc_MAXQ10XX_Sha256Free(sha256);
|
||||
#endif
|
||||
|
||||
/* Espressif embedded hardware acceleration specific: */
|
||||
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
|
||||
if (sha256->ctx.lockDepth > 0) {
|
||||
@@ -1974,6 +1982,11 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
XMEMCPY(dst, src, sizeof(wc_Sha256));
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
wc_MAXQ10XX_Sha256Copy(src);
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK_CACHE
|
||||
dst->W = NULL;
|
||||
#endif
|
||||
|
@@ -50,6 +50,10 @@
|
||||
#include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
|
||||
#endif
|
||||
|
||||
#ifdef MAXQ10XX_MODULE_INIT
|
||||
#include <wolfssl/wolfcrypt/port/maxim/maxq10xx.h>
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A) || \
|
||||
defined(WOLFSSL_ATECC608A)
|
||||
#include <wolfssl/wolfcrypt/port/atmel/atmel.h>
|
||||
@@ -257,6 +261,14 @@ int wolfCrypt_Init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MAXQ10XX_MODULE_INIT
|
||||
ret = maxq10xx_port_init();
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("MAXQ10xx port init failed");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SILABS_SE_ACCEL
|
||||
/* init handles if it is already initialized */
|
||||
ret = sl_se_init();
|
||||
@@ -1314,6 +1326,223 @@ int wolfSSL_CryptHwMutexUnLock(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(MAXQ10XX_MUTEX)
|
||||
static pthread_mutex_t *wcCryptHwSharedMutexPtr;
|
||||
static pthread_once_t key_once_own_hw_mutex = PTHREAD_ONCE_INIT;
|
||||
static pthread_key_t key_own_hw_mutex;
|
||||
|
||||
static void destruct_key(void *buf)
|
||||
{
|
||||
if (buf != NULL) {
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void make_key_own_hw_mutex(void)
|
||||
{
|
||||
(void)pthread_key_create(&key_own_hw_mutex, destruct_key);
|
||||
}
|
||||
|
||||
int wc_InitMutex(wolfSSL_Mutex* m)
|
||||
{
|
||||
int created = 0;
|
||||
void *addr = NULL;
|
||||
|
||||
if (m != &wcCryptHwMutex) {
|
||||
if (pthread_mutex_init(m, 0) == 0) {
|
||||
return 0;
|
||||
}
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
/* try to open mutex memory */
|
||||
int shm_fd = shm_open("/maxq-mutex", O_RDWR, 0666);
|
||||
if (shm_fd < 0) {
|
||||
/* create mutex memory */
|
||||
shm_fd = shm_open("/maxq-mutex", O_RDWR | O_CREAT | O_EXCL, 0666);
|
||||
created = 1;
|
||||
}
|
||||
|
||||
if (shm_fd < 0) {
|
||||
WOLFSSL_MSG("wc_InitMutex: shm_open() failed");
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
if (ftruncate(shm_fd, sizeof(pthread_mutex_t))) {
|
||||
WOLFSSL_MSG("wc_InitMutex: ftruncate() failed");
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
addr = mmap(NULL, sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, shm_fd, 0);
|
||||
|
||||
if (addr == MAP_FAILED) {
|
||||
WOLFSSL_MSG("wc_InitMutex: mmap() failed");
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
wcCryptHwSharedMutexPtr = (pthread_mutex_t *)addr;
|
||||
|
||||
if (close(shm_fd)) {
|
||||
WOLFSSL_MSG("wc_InitMutex: close() failed");
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
if (created) {
|
||||
/* initialize mutex */
|
||||
pthread_mutexattr_t attr;
|
||||
if (pthread_mutexattr_init(&attr)) {
|
||||
WOLFSSL_MSG("wc_InitMutex: pthread_mutexattr_init() failed");
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
if (pthread_mutexattr_setpshared(&attr,
|
||||
PTHREAD_PROCESS_SHARED)) {
|
||||
WOLFSSL_MSG(
|
||||
"wc_InitMutex: pthread_mutexattr_setpshared() failed");
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
if (pthread_mutex_init(wcCryptHwSharedMutexPtr, &attr)) {
|
||||
WOLFSSL_MSG("wc_InitMutex: pthread_mutex_init() failed");
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
}
|
||||
|
||||
if (pthread_once(&key_once_own_hw_mutex, make_key_own_hw_mutex)) {
|
||||
WOLFSSL_MSG("wc_InitMutex: pthread_once() failed");
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wc_FreeMutex(wolfSSL_Mutex* m)
|
||||
{
|
||||
void *key_ptr = NULL;
|
||||
if (m != &wcCryptHwMutex) {
|
||||
if (pthread_mutex_destroy(m) == 0) {
|
||||
return 0;
|
||||
}
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
if (wcCryptHwSharedMutexPtr) {
|
||||
if (munmap((void *)wcCryptHwSharedMutexPtr,
|
||||
sizeof(pthread_mutex_t))) {
|
||||
WOLFSSL_MSG("wc_FreeMutex: munmap() failed");
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
wcCryptHwSharedMutexPtr = NULL;
|
||||
}
|
||||
|
||||
key_ptr = pthread_getspecific(key_own_hw_mutex);
|
||||
if (key_ptr) {
|
||||
*((int *)key_ptr) = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int maxq_LockMutex(wolfSSL_Mutex* m, int trylock)
|
||||
{
|
||||
void *key_ptr = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (m != &wcCryptHwMutex) {
|
||||
if (pthread_mutex_lock(m) == 0) {
|
||||
return 0;
|
||||
}
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
if (wcCryptHwSharedMutexPtr == NULL) {
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
key_ptr = pthread_getspecific(key_own_hw_mutex);
|
||||
if (key_ptr == NULL) {
|
||||
key_ptr = malloc(sizeof(int));
|
||||
if (key_ptr == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
memset(key_ptr, 0, sizeof(int));
|
||||
|
||||
if (pthread_setspecific(key_own_hw_mutex, key_ptr)) {
|
||||
return THREAD_STORE_SET_E;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((trylock == 0) && (*((int *)key_ptr) > 0)) {
|
||||
*((int *)key_ptr) = *((int *)key_ptr) + 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (trylock) {
|
||||
ret = pthread_mutex_trylock(wcCryptHwSharedMutexPtr);
|
||||
}
|
||||
else {
|
||||
ret = pthread_mutex_lock(wcCryptHwSharedMutexPtr);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
*((int *)key_ptr) = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wc_LockMutex(wolfSSL_Mutex* m)
|
||||
{
|
||||
return maxq_LockMutex(m, 0);
|
||||
}
|
||||
|
||||
int maxq_CryptHwMutexTryLock()
|
||||
{
|
||||
int ret = BAD_MUTEX_E;
|
||||
/* Make sure HW Mutex has been initialized */
|
||||
ret = wolfSSL_CryptHwMutexInit();
|
||||
if (ret == 0) {
|
||||
ret = maxq_LockMutex(&wcCryptHwMutex, 1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wc_UnLockMutex(wolfSSL_Mutex* m)
|
||||
{
|
||||
void *key_ptr = NULL;
|
||||
|
||||
if (m != &wcCryptHwMutex) {
|
||||
if (pthread_mutex_unlock(m) == 0) {
|
||||
return 0;
|
||||
}
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
if (wcCryptHwSharedMutexPtr == NULL) {
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
key_ptr = pthread_getspecific(key_own_hw_mutex);
|
||||
if (key_ptr) {
|
||||
if (*((int *)key_ptr) > 0) {
|
||||
*((int *)key_ptr) = *((int *)key_ptr) - 1;
|
||||
if (*((int *)key_ptr) > 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pthread_mutex_unlock(wcCryptHwSharedMutexPtr) != 0) {
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(WOLFSSL_PTHREADS)
|
||||
|
||||
int wc_InitMutex(wolfSSL_Mutex* m)
|
||||
|
@@ -1304,6 +1304,8 @@ enum {
|
||||
#define DTLS_AEAD_AES_CCM_FAIL_LIMIT w64From32(0x00B5, 0x04F3)
|
||||
#define DTLS_AEAD_AES_CCM_FAIL_KU_LIMIT w64From32(0x005A, 0x8279)
|
||||
|
||||
#if defined(WOLFSSL_TLS13) || !defined(NO_PSK)
|
||||
|
||||
#define TLS13_TICKET_NONCE_MAX_SZ 255
|
||||
|
||||
#if (defined(HAVE_FIPS) && \
|
||||
@@ -1320,6 +1322,19 @@ enum {
|
||||
#error "Max size for ticket nonce is 255 bytes"
|
||||
#endif
|
||||
|
||||
#endif /* WOLFSSL_TLS13 || !NO_PSK */
|
||||
|
||||
#ifdef WOLFSSL_TLS13
|
||||
/* The length of the certificate verification label - client and server. */
|
||||
#define CERT_VFY_LABEL_SZ 34
|
||||
/* The number of prefix bytes for signature data. */
|
||||
#define SIGNING_DATA_PREFIX_SZ 64
|
||||
/* Maximum length of the signature data. */
|
||||
#define MAX_SIG_DATA_SZ (SIGNING_DATA_PREFIX_SZ + \
|
||||
CERT_VFY_LABEL_SZ + \
|
||||
WC_MAX_DIGEST_SIZE)
|
||||
#endif /* WOLFSSL_TLS13 */
|
||||
|
||||
enum Misc {
|
||||
CIPHER_BYTE = 0x00, /* Default ciphers */
|
||||
ECC_BYTE = 0xC0, /* ECC first cipher suite byte */
|
||||
@@ -1410,8 +1425,10 @@ enum Misc {
|
||||
SESSION_ADD_SZ = 4, /* session age add */
|
||||
TICKET_NONCE_LEN_SZ = 1, /* Ticket nonce length size */
|
||||
DEF_TICKET_NONCE_SZ = 1, /* Default ticket nonce size */
|
||||
#if defined(WOLFSSL_TLS13) || !defined(NO_PSK)
|
||||
MAX_TICKET_NONCE_STATIC_SZ = TLS13_TICKET_NONCE_STATIC_SZ,
|
||||
/* maximum ticket nonce static size */
|
||||
#endif /* WOLFSSL_TLS13 || !NO_PSK */
|
||||
MAX_LIFETIME = 604800, /* maximum ticket lifetime */
|
||||
|
||||
RAN_LEN = 32, /* random length */
|
||||
@@ -1956,6 +1973,10 @@ WOLFSSL_LOCAL int GetPrivateKeySigSize(WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int InitSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx);
|
||||
#endif
|
||||
#endif
|
||||
WOLFSSL_LOCAL int CreateSigData(WOLFSSL* ssl, byte* sigData, word16* sigDataSz,
|
||||
int check);
|
||||
WOLFSSL_LOCAL int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
|
||||
int sigAlgo, int hashAlgo);
|
||||
#ifdef WOLFSSL_ASYNC_IO
|
||||
WOLFSSL_LOCAL void FreeAsyncCtx(WOLFSSL* ssl, byte freeAsync);
|
||||
#endif
|
||||
@@ -2001,7 +2022,7 @@ WOLFSSL_LOCAL int RestartHandshakeHash(WOLFSSL* ssl);
|
||||
|
||||
WOLFSSL_LOCAL int Tls13DeriveKey(WOLFSSL *ssl, byte *output, int outputLen,
|
||||
const byte *secret, const byte *label, word32 labelLen, int hashAlgo,
|
||||
int includeMsgs);
|
||||
int includeMsgs, int side);
|
||||
#endif
|
||||
int TimingPadVerify(WOLFSSL* ssl, const byte* input, int padLen, int macSz,
|
||||
int pLen, int content);
|
||||
@@ -2759,6 +2780,13 @@ WOLFSSL_LOCAL int TLSX_CSR2_ForceRequest(WOLFSSL* ssl);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_PUBLIC_ASN) && defined(HAVE_PK_CALLBACKS)
|
||||
/* Internal callback guarded by WOLFSSL_PUBLIC_ASN because of DecodedCert. */
|
||||
typedef int (*CallbackProcessPeerCert)(WOLFSSL* ssl, DecodedCert* p_cert);
|
||||
WOLFSSL_API void wolfSSL_CTX_SetProcessPeerCertCb(WOLFSSL_CTX* ctx,
|
||||
CallbackProcessPeerCert cb);
|
||||
#endif /* DecodedCert && HAVE_PK_CALLBACKS */
|
||||
|
||||
/** Supported Elliptic Curves - RFC 4492 (session 4) */
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
|
||||
@@ -3378,28 +3406,55 @@ struct WOLFSSL_CTX {
|
||||
CallbackX448SharedSecret X448SharedSecretCb;
|
||||
#endif
|
||||
#ifndef NO_DH
|
||||
CallbackDhAgree DhAgreeCb; /* User DH Agree Callback handler */
|
||||
/* User DH KeyGen Callback handler*/
|
||||
CallbackDhGenerateKeyPair DhGenerateKeyPairCb;
|
||||
/* User DH Agree Callback handler */
|
||||
CallbackDhAgree DhAgreeCb;
|
||||
#endif
|
||||
#ifndef NO_RSA
|
||||
CallbackRsaSign RsaSignCb; /* User RsaSign Callback handler (priv key) */
|
||||
CallbackRsaVerify RsaVerifyCb; /* User RsaVerify Callback handler (pub key) */
|
||||
CallbackRsaVerify RsaSignCheckCb; /* User VerifyRsaSign Callback handler (priv key) */
|
||||
/* User RsaSign Callback handler (priv key) */
|
||||
CallbackRsaSign RsaSignCb;
|
||||
/* User RsaVerify Callback handler (pub key) */
|
||||
CallbackRsaVerify RsaVerifyCb;
|
||||
/* User VerifyRsaSign Callback handler (priv key) */
|
||||
CallbackRsaVerify RsaSignCheckCb;
|
||||
#ifdef WC_RSA_PSS
|
||||
CallbackRsaPssSign RsaPssSignCb; /* User RsaSign (priv key) */
|
||||
CallbackRsaPssVerify RsaPssVerifyCb; /* User RsaVerify (pub key) */
|
||||
CallbackRsaPssVerify RsaPssSignCheckCb; /* User VerifyRsaSign (priv key) */
|
||||
/* User RsaSign (priv key) */
|
||||
CallbackRsaPssSign RsaPssSignCb;
|
||||
/* User RsaVerify (pub key) */
|
||||
CallbackRsaPssVerify RsaPssVerifyCb;
|
||||
/* User VerifyRsaSign (priv key) */
|
||||
CallbackRsaPssVerify RsaPssSignCheckCb;
|
||||
#endif
|
||||
CallbackRsaEnc RsaEncCb; /* User Rsa Public Encrypt handler */
|
||||
CallbackRsaDec RsaDecCb; /* User Rsa Private Decrypt handler */
|
||||
#endif /* NO_RSA */
|
||||
CallbackGenPreMaster GenPreMasterCb; /* Use generate pre-master handler */
|
||||
CallbackGenMasterSecret GenMasterCb; /* Use generate master secret handler */
|
||||
CallbackGenSessionKey GenSessionKeyCb; /* Use generate session key handler */
|
||||
CallbackEncryptKeys EncryptKeysCb;/* Use setting encrypt keys handler */
|
||||
CallbackTlsFinished TlsFinishedCb; /* Use Tls finished handler */
|
||||
|
||||
/* User generate pre-master handler */
|
||||
CallbackGenPreMaster GenPreMasterCb;
|
||||
/* User generate master secret handler */
|
||||
CallbackGenMasterSecret GenMasterCb;
|
||||
/* User generate session key handler */
|
||||
CallbackGenSessionKey GenSessionKeyCb;
|
||||
/* User setting encrypt keys handler */
|
||||
CallbackEncryptKeys EncryptKeysCb;
|
||||
/* User Tls finished handler */
|
||||
CallbackTlsFinished TlsFinishedCb;
|
||||
#if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_AEAD_ONLY)
|
||||
CallbackVerifyMac VerifyMacCb; /* Use Verify mac handler */
|
||||
/* User Verify mac handler */
|
||||
CallbackVerifyMac VerifyMacCb;
|
||||
#endif
|
||||
#if defined(WOLFSSL_PUBLIC_ASN)
|
||||
/* User handler to process a certificate */
|
||||
CallbackProcessPeerCert ProcessPeerCertCb;
|
||||
#endif
|
||||
/* User handler to process the server's key exchange public key */
|
||||
CallbackProcessServerSigKex ProcessServerSigKexCb;
|
||||
/* User handler to process the TLS record */
|
||||
CallbackPerformTlsRecordProcessing PerformTlsRecordProcessingCb;
|
||||
/* User handler to do HKDF expansions */
|
||||
CallbackHKDFExpandLabel HKDFExpandLabelCb;
|
||||
|
||||
#endif /* HAVE_PK_CALLBACKS */
|
||||
#ifdef HAVE_WOLF_EVENT
|
||||
WOLF_EVENT_QUEUE event_queue;
|
||||
@@ -5220,6 +5275,9 @@ struct WOLFSSL {
|
||||
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||
StaticKeyExchangeInfo_t staticKE;
|
||||
#endif
|
||||
#ifdef WOLFSSL_MAXQ10XX_TLS
|
||||
maxq_ssl_t maxq_ctx;
|
||||
#endif
|
||||
#ifdef WOLFSSL_HAVE_TLS_UNIQUE
|
||||
/* Added in libest port: allow applications to get the 'tls-unique' Channel
|
||||
* Binding Type (https://tools.ietf.org/html/rfc5929#section-3). This is
|
||||
|
@@ -3318,13 +3318,19 @@ WOLFSSL_API void wolfSSL_SetHKDFExtractCtx(WOLFSSL* ssl, void *ctx);
|
||||
#ifndef NO_DH
|
||||
/* Public DH Key Callback support */
|
||||
struct DhKey;
|
||||
typedef int (*CallbackDhGenerateKeyPair)(DhKey* key, WC_RNG* rng,
|
||||
byte* priv, word32* privSz,
|
||||
byte* pub, word32* pubSz);
|
||||
typedef int (*CallbackDhAgree)(WOLFSSL* ssl, struct DhKey* key,
|
||||
const unsigned char* priv, unsigned int privSz,
|
||||
const unsigned char* otherPubKeyDer, unsigned int otherPubKeySz,
|
||||
unsigned char* out, word32* outlen,
|
||||
void* ctx);
|
||||
WOLFSSL_API void wolfSSL_CTX_SetDhAgreeCb(WOLFSSL_CTX* ctx, CallbackDhAgree cb);
|
||||
WOLFSSL_API void wolfSSL_SetDhAgreeCtx(WOLFSSL* ssl, void *ctx);
|
||||
WOLFSSL_API void wolfSSL_CTX_SetDhGenerateKeyPair(WOLFSSL_CTX* ctx,
|
||||
CallbackDhGenerateKeyPair cb);
|
||||
WOLFSSL_API void wolfSSL_CTX_SetDhAgreeCb(WOLFSSL_CTX* ctx,
|
||||
CallbackDhAgree cb);
|
||||
WOLFSSL_API void wolfSSL_SetDhAgreeCtx(WOLFSSL* ssl, void *ctx);
|
||||
WOLFSSL_API void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl);
|
||||
#endif /* !NO_DH */
|
||||
|
||||
@@ -3510,7 +3516,7 @@ WOLFSSL_API void* wolfSSL_GetEncryptKeysCtx(WOLFSSL* ssl);
|
||||
|
||||
typedef int (*CallbackTlsFinished)(WOLFSSL* ssl,
|
||||
const byte *side,
|
||||
const byte *handshake_hash,
|
||||
const byte *handshake_hash, word32 hashSz,
|
||||
byte *hashes, void* ctx);
|
||||
WOLFSSL_API void wolfSSL_CTX_SetTlsFinishedCb(WOLFSSL_CTX* ctx, CallbackTlsFinished cb);
|
||||
WOLFSSL_API void wolfSSL_SetTlsFinishedCtx(WOLFSSL* ssl, void *ctx);
|
||||
@@ -3524,6 +3530,30 @@ WOLFSSL_API void wolfSSL_SetVerifyMacCtx(WOLFSSL* ssl, void *ctx);
|
||||
WOLFSSL_API void* wolfSSL_GetVerifyMacCtx(WOLFSSL* ssl);
|
||||
#endif
|
||||
|
||||
typedef int (*CallbackHKDFExpandLabel)(byte* okm, word32 okmLen,
|
||||
const byte* prk, word32 prkLen,
|
||||
const byte* protocol, word32 protocolLen,
|
||||
const byte* label, word32 labelLen,
|
||||
const byte* info, word32 infoLen,
|
||||
int digest, int side);
|
||||
WOLFSSL_API void wolfSSL_CTX_SetHKDFExpandLabelCb(WOLFSSL_CTX* ctx,
|
||||
CallbackHKDFExpandLabel cb);
|
||||
|
||||
typedef int (*CallbackProcessServerSigKex)(WOLFSSL* ssl, byte p_sig_algo,
|
||||
const byte* p_sig, word32 p_sig_len,
|
||||
const byte* p_rand, word32 p_rand_len,
|
||||
const byte* p_server_params, word32 p_server_params_len);
|
||||
WOLFSSL_API void wolfSSL_CTX_SetProcessServerSigKexCb(WOLFSSL_CTX* ctx,
|
||||
CallbackProcessServerSigKex cb);
|
||||
|
||||
typedef int (*CallbackPerformTlsRecordProcessing)(WOLFSSL* ssl, int is_encrypt,
|
||||
byte* out, const byte* in, word32 sz,
|
||||
const byte* iv, word32 ivSz,
|
||||
byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz);
|
||||
WOLFSSL_API void wolfSSL_CTX_SetPerformTlsRecordProcessingCb(WOLFSSL_CTX* ctx,
|
||||
CallbackPerformTlsRecordProcessing cb);
|
||||
|
||||
#endif /* HAVE_PK_CALLBACKS */
|
||||
|
||||
#ifndef NO_CERTS
|
||||
|
@@ -4559,7 +4559,7 @@ static WC_INLINE int myVerifyMac(WOLFSSL *ssl, const byte* message,
|
||||
|
||||
static WC_INLINE int myTlsFinished(WOLFSSL* ssl,
|
||||
const byte *side,
|
||||
const byte *handshake_hash,
|
||||
const byte *handshake_hash, word32 hashSz,
|
||||
byte *hashes, void* ctx)
|
||||
{
|
||||
int ret;
|
||||
@@ -4569,6 +4569,7 @@ static WC_INLINE int myTlsFinished(WOLFSSL* ssl,
|
||||
(void)cbInfo;
|
||||
(void)side;
|
||||
(void)handshake_hash;
|
||||
(void)hashSz;
|
||||
(void)hashes;
|
||||
|
||||
WOLFSSL_PKMSG("Tls Finished Cb");
|
||||
|
@@ -122,6 +122,10 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits
|
||||
#include <wolfssl/wolfcrypt/port/Renesas/renesas_tsip_types.h>
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
#include <wolfssl/wolfcrypt/port/maxim/maxq10xx.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -299,6 +303,9 @@ struct Aes {
|
||||
#if defined(WOLFSSL_SILABS_SE_ACCEL)
|
||||
silabs_aes_t ctx;
|
||||
#endif
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
maxq_aes_t maxq_ctx;
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
|
||||
psa_key_id_t key_id;
|
||||
psa_cipher_operation_t psa_ctx;
|
||||
|
@@ -1816,6 +1816,9 @@ struct DecodedCert {
|
||||
#if defined(WOLFSSL_RENESAS_TSIP) || defined(WOLFSSL_RENESAS_SCEPROTECT)
|
||||
byte* sce_tsip_encRsaKeyIdx;
|
||||
#endif
|
||||
#ifdef WOLFSSL_MAXQ10XX_TLS
|
||||
word32 publicKeyIndex; /* offset to start of public key */
|
||||
#endif
|
||||
|
||||
int badDate;
|
||||
int criticalExt;
|
||||
|
@@ -471,6 +471,9 @@ struct ecc_key {
|
||||
*/
|
||||
byte key_raw[3 * ECC_MAX_CRYPTO_HW_SIZE];
|
||||
#endif
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
maxq_ecc_t maxq_ctx;
|
||||
#endif
|
||||
#ifdef WOLFSSL_KCAPI_ECC
|
||||
struct kcapi_handle* handle;
|
||||
byte pubkey_raw[MAX_ECC_BYTES * 2];
|
||||
|
@@ -252,8 +252,9 @@ enum {
|
||||
|
||||
IO_FAILED_E = -291, /* Input/output failure */
|
||||
SYSLIB_FAILED_E = -292, /* System/library call failed */
|
||||
USE_HW_PSK = -293, /* Callback return to indicate HW has PSK */
|
||||
|
||||
WC_LAST_E = -292, /* Update this to indicate last error */
|
||||
WC_LAST_E = -293, /* Update this to indicate last error */
|
||||
MIN_CODE_E = -300 /* errors -101 - -299 */
|
||||
|
||||
/* add new companion error id strings for any new error codes
|
||||
|
@@ -195,3 +195,7 @@ endif
|
||||
if BUILD_SE050
|
||||
nobase_include_HEADERS+= wolfssl/wolfcrypt/port/nxp/se050_port.h
|
||||
endif
|
||||
|
||||
if BUILD_MAXQ10XX
|
||||
nobase_include_HEADERS+= wolfssl/wolfcrypt/port/maxim/maxq10xx.h
|
||||
endif
|
||||
|
115
wolfssl/wolfcrypt/port/maxim/maxq10xx.h
Normal file
115
wolfssl/wolfcrypt/port/maxim/maxq10xx.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/* maxq10xx.h
|
||||
*
|
||||
* Copyright (C) 2006-2022 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#ifndef _WOLFPORT_MAXQ10XX_H_
|
||||
#define _WOLFPORT_MAXQ10XX_H_
|
||||
|
||||
#if defined(WOLFSSL_MAXQ1065) || defined(WOLFSSL_MAXQ108X)
|
||||
|
||||
#include <wolfssl/wolfcrypt/types.h>
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
#ifdef WOLFSSL_MAXQ1065
|
||||
#define MAXQ_AESGCM
|
||||
#define MAXQ_SHA256
|
||||
#define MAXQ_RNG
|
||||
#define MAXQ_ECC
|
||||
#endif /* WOLFSSL_MAXQ1065 */
|
||||
|
||||
#ifdef WOLFSSL_MAXQ108X
|
||||
#define MAXQ_AESGCM
|
||||
#define MAXQ_SHA256
|
||||
#define MAXQ_RNG
|
||||
#define MAXQ_ECC
|
||||
#define ENABLE_RSA
|
||||
#endif /* WOLFSSL_MAXQ108X */
|
||||
#endif /* WOLF_CRYPTO_CB */
|
||||
|
||||
struct WOLFSSL_CTX;
|
||||
typedef struct WOLFSSL WOLFSSL;
|
||||
typedef struct DecodedCert DecodedCert;
|
||||
typedef struct DerBuffer DerBuffer;
|
||||
typedef struct wc_CryptoInfo wc_CryptoInfo;
|
||||
typedef struct Aes Aes;
|
||||
typedef struct wc_Sha256 wc_Sha256;
|
||||
typedef struct ecc_key ecc_key;
|
||||
typedef struct ProtocolVersion ProtocolVersion;
|
||||
|
||||
typedef struct {
|
||||
int use_hw_keys;
|
||||
DerBuffer* device_cert;
|
||||
} maxq_ssl_t;
|
||||
|
||||
typedef struct {
|
||||
int key_obj_id;
|
||||
int key_pending;
|
||||
unsigned char key[32];
|
||||
} maxq_aes_t;
|
||||
|
||||
typedef struct {
|
||||
int hash_running;
|
||||
int soft_hash;
|
||||
} maxq_sha256_t;
|
||||
|
||||
typedef struct {
|
||||
int key_obj_id;
|
||||
int key_pending;
|
||||
int hw_ecc;
|
||||
int hw_storage;
|
||||
unsigned char ecc_key[32 * 3];
|
||||
} maxq_ecc_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
WOLFSSL_LOCAL int maxq10xx_port_init(void);
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
WOLFSSL_LOCAL int wolfSSL_MAXQ10XX_CryptoDevCb(int devId, wc_CryptoInfo* info,
|
||||
void* ctx);
|
||||
#endif /* WOLF_CRYPTO_CB */
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
WOLFSSL_LOCAL int wc_MAXQ10XX_AesSetKey(Aes* aes, const byte* userKey,
|
||||
word32 keylen);
|
||||
WOLFSSL_LOCAL void wc_MAXQ10XX_AesFree(Aes* aes);
|
||||
WOLFSSL_LOCAL void wc_MAXQ10XX_Sha256Copy(wc_Sha256* sha256);
|
||||
WOLFSSL_LOCAL void wc_MAXQ10XX_Sha256Free(wc_Sha256* sha256);
|
||||
WOLFSSL_LOCAL int wc_MAXQ10XX_EccSetKey(ecc_key* key, word32 keysize);
|
||||
WOLFSSL_LOCAL void wc_MAXQ10XX_EccFree(ecc_key* key);
|
||||
#endif /* WOLFSSL_MAXQ10XX_CRYPTO */
|
||||
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
WOLFSSL_LOCAL void maxq10xx_SetupPkCallbacks(struct WOLFSSL_CTX* ctx,
|
||||
ProtocolVersion *pv);
|
||||
#endif /* HAVE_PK_CALLBACKS */
|
||||
|
||||
#if defined(WOLFSSL_MAXQ10XX_TLS)
|
||||
WOLFSSL_LOCAL int wolfSSL_maxq10xx_load_certificate(WOLFSSL *ssl);
|
||||
#endif /* WOLFSSL_MAXQ10XX_TLS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WOLFSSL_MAXQ1065 || WOLFSSL_MAXQ108X */
|
||||
#endif /* _WOLFPORT_MAXQ10XX_H_ */
|
@@ -256,6 +256,13 @@
|
||||
/* Uncomment next line if building for Dolphin Emulator */
|
||||
/* #define DOLPHIN_EMULATOR */
|
||||
|
||||
/* Uncomment next line if using MAXQ1065 */
|
||||
/* #define WOLFSSL_MAXQ1065 */
|
||||
|
||||
/* Uncomment next line if using MAXQ108x */
|
||||
/* #define WOLFSSL_MAXQ108X */
|
||||
|
||||
|
||||
#include <wolfssl/wolfcrypt/visibility.h>
|
||||
|
||||
#ifdef WOLFSSL_USER_SETTINGS
|
||||
@@ -1318,6 +1325,40 @@ extern void uITRON4_free(void *p) ;
|
||||
#define GCM_TABLE
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_MAXQ1065) || defined(WOLFSSL_MAXQ108X)
|
||||
|
||||
#define MAXQ10XX_MODULE_INIT
|
||||
|
||||
#define HAVE_PK_CALLBACKS
|
||||
#define WOLFSSL_STATIC_PSK
|
||||
/* Server side support to be added at a later date. */
|
||||
#define NO_WOLFSSL_SERVER
|
||||
/* Need WOLFSSL_PUBLIC_ASN to use ProcessPeerCert callback. */
|
||||
#define WOLFSSL_PUBLIC_ASN
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
#define WOLFSSL_CRYPT_HW_MUTEX 1
|
||||
#define MAXQ10XX_MUTEX
|
||||
#endif
|
||||
|
||||
#define WOLFSSL_MAXQ10XX_CRYPTO
|
||||
#define WOLFSSL_MAXQ10XX_TLS
|
||||
|
||||
|
||||
#if defined(WOLFSSL_MAXQ1065)
|
||||
#define MAXQ_DEVICE_ID 1065
|
||||
#elif defined(WOLFSSL_MAXQ108X)
|
||||
#define MAXQ_DEVICE_ID 1080
|
||||
#else
|
||||
#error "There is only support for MAXQ1065 or MAXQ1080"
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_TICKET_NONCE_MALLOC)
|
||||
#error "WOLFSSL_TICKET_NONCE_MALLOC disables the HKDF expand callbacks."
|
||||
#endif
|
||||
|
||||
#endif /* WOLFSSL_MAXQ1065 || WOLFSSL_MAXQ108X */
|
||||
|
||||
#if defined(WOLFSSL_STM32F2) || defined(WOLFSSL_STM32F4) || \
|
||||
defined(WOLFSSL_STM32F7) || defined(WOLFSSL_STM32F1) || \
|
||||
defined(WOLFSSL_STM32L4) || defined(WOLFSSL_STM32L5) || \
|
||||
|
@@ -157,6 +157,10 @@ enum {
|
||||
#include "wolfssl/wolfcrypt/port/nxp/se050_port.h"
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
#include <wolfssl/wolfcrypt/port/maxim/maxq10xx.h>
|
||||
#endif
|
||||
|
||||
/* wc_Sha256 digest */
|
||||
struct wc_Sha256 {
|
||||
#ifdef FREESCALE_LTC_SHA
|
||||
@@ -206,6 +210,9 @@ struct wc_Sha256 {
|
||||
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
|
||||
WC_ESP32SHA ctx;
|
||||
#endif
|
||||
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
|
||||
maxq_sha256_t maxq_ctx;
|
||||
#endif
|
||||
#ifdef WOLFSSL_CRYPTOCELL
|
||||
CRYS_HASHUserContext_t ctx;
|
||||
#endif
|
||||
|
@@ -217,6 +217,12 @@
|
||||
} wolfSSL_Mutex;
|
||||
#elif defined(USE_WINDOWS_API)
|
||||
typedef CRITICAL_SECTION wolfSSL_Mutex;
|
||||
#elif defined(MAXQ10XX_MUTEX)
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
typedef pthread_mutex_t wolfSSL_Mutex;
|
||||
int maxq_CryptHwMutexTryLock(void);
|
||||
#elif defined(WOLFSSL_PTHREADS)
|
||||
typedef pthread_mutex_t wolfSSL_Mutex;
|
||||
#elif defined(THREADX)
|
||||
|
Reference in New Issue
Block a user