diff --git a/configure.ac b/configure.ac index a30d2721e..55da7c29e 100644 --- a/configure.ac +++ b/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 "" diff --git a/src/dtls13.c b/src/dtls13.c index c5bd3d6b7..075bbb8cc 100644 --- a/src/dtls13.c +++ b/src/dtls13.c @@ -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; diff --git a/src/internal.c b/src/internal.c index b7afc57f2..744175c18 100644 --- a/src/internal.c +++ b/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 diff --git a/src/ssl.c b/src/ssl.c index 9b54b2c4b..1abd98fa4 100644 --- a/src/ssl.c +++ b/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) diff --git a/src/tls.c b/src/tls.c index c66ccf2dc..cfcbb2b1c 100644 --- a/src/tls.c +++ b/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 diff --git a/src/tls13.c b/src/tls13.c index 4a6bcfd90..0aeb787a1 100644 --- a/src/tls13.c +++ b/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; diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 1e1a0ec27..852072fbc 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -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 diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ec841653f..223f8d02f 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -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, diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index c2bb42f58..5b15258b6 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -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); diff --git a/wolfcrypt/src/error.c b/wolfcrypt/src/error.c index b301ef919..9dbf7a802 100644 --- a/wolfcrypt/src/error.c +++ b/wolfcrypt/src/error.c @@ -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"; diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 8f26aadc6..e5fbfcdaf 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -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 */ } diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 7c16ce078..6e24df974 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -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 diff --git a/wolfcrypt/src/misc.c b/wolfcrypt/src/misc.c index 8dd50c269..1dd5088f4 100644 --- a/wolfcrypt/src/misc.c +++ b/wolfcrypt/src/misc.c @@ -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 diff --git a/wolfcrypt/src/port/Renesas/renesas_common.c b/wolfcrypt/src/port/Renesas/renesas_common.c index a4c016d34..4664c6d8e 100644 --- a/wolfcrypt/src/port/Renesas/renesas_common.c +++ b/wolfcrypt/src/port/Renesas/renesas_common.c @@ -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"); diff --git a/wolfcrypt/src/port/maxim/README.md b/wolfcrypt/src/port/maxim/README.md new file mode 100644 index 000000000..f12d468aa --- /dev/null +++ b/wolfcrypt/src/port/maxim/README.md @@ -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. + diff --git a/wolfcrypt/src/port/maxim/maxq10xx.c b/wolfcrypt/src/port/maxim/maxq10xx.c new file mode 100644 index 000000000..03f6e3730 --- /dev/null +++ b/wolfcrypt/src/port/maxim/maxq10xx.c @@ -0,0 +1,3408 @@ +/* maxq10xx.c + * + * 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 + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_MAXQ1065) || defined(WOLFSSL_MAXQ108X) + +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef MAXQ_DEBUG +void dbg_dumphex(const char *identifier, const uint8_t* pdata, uint32_t plen); +#else +#define dbg_dumphex(identifier, pdata, plen) +#endif /* MAXQ_DEBUG */ + +#if defined(USE_WINDOWS_API) +# define maxq_CryptHwMutexTryLock() (0) +#endif + +#define AES_KEY_ID_START (0x2000) +#define AES_KEY_ID_MAX_NUM (32) +#define ECC_KEY_ID_START (AES_KEY_ID_START + AES_KEY_ID_MAX_NUM) +#define ECC_KEY_ID_MAX_NUM (32) + +#define TEMP_KEY_ID_START (0) +#if defined(WOLFSSL_MAXQ108X) +#define TEMP_KEY_ID_MAX_NUM (16) +#else +#define TEMP_KEY_ID_MAX_NUM (2) +#endif + +#define PUBKEY_IMPORT_OBJID 0x1000 +#define ROOT_CA_CERT_OBJ_ID 0x1003 +#define DEVICE_CERT_OBJ_ID 0x1002 +#define DEVICE_KEY_PAIR_OBJ_ID 0x1004 +#define PSK_OBJ_ID 0x1236 +#define K_CHUNKSIZE 2032 +#define K_CIPHER_BLOCKSIZE 16 +#define ECC256_KEYSIZE 32 +#define MAX_HASH_CHUNKSIZE 2000 +#define MAX_CERT_DATASIZE 2048 +#define MAX_KEY_DATASIZE 256 +#define MAX_SIGNKEY_DATASIZE 96 +#define MAX_SIG_DATASIZE 64 +#define ECC_KEYCOMPLEN 32 + +#ifdef WOLFSSL_MAXQ108X + +#define PSK_KID (0x1235) +static unsigned char tls13active = 0; +static unsigned char tls13early = 0; + +static int tls13_dh_obj_id = -1; +static int tls13_ecc_obj_id = -1; +static int tls13_hs_early_secret_obj_id = -1; +static int tls13_binder_key_obj_id = -1; +static int tls13_shared_secret_obj_id = -1; +static int tls13_early_secret_obj_id = -1; +static int tls13_derived_secret_obj_id = -1; +static int tls13_handshake_secret_obj_id = -1; +static int tls13_master_secret_obj_id = -1; +static int tls13_client_secret_obj_id = -1; +static int tls13_server_secret_obj_id = -1; +static int tls13_client_hs_key_obj_id = -1; +static int tls13_server_hs_key_obj_id = -1; +static int tls13_client_app_key_obj_id = -1; +static int tls13_server_app_key_obj_id = -1; +static int tls13_server_finish_obj_id = -1; +static int tls13_client_finish_obj_id = -1; +static int *tls13_server_key_id = NULL; +static int *tls13_client_key_id = NULL; +static int tls13_res_master_obj_id = -1; +static int tls13_server_cert_id = -1; +static int tls13_server_key_algo = -1; +static int tls13_server_key_len = -1; + +#endif /* WOLFSSL_MAXQ108X */ + +/* Please define MAXQ10XX_PRODUCTION_KEY in your build scripts once you have a + * production key. */ +#if defined(MAXQ10XX_PRODUCTION_KEY) || !defined(DEBUG_WOLFSSL) +#include "maxq10xx_key.h" +#else +/* TEST KEY. This must be changed for production environments!! */ +static const mxq_u1 KeyPairImport[] = { + 0xd0,0x97,0x31,0xc7,0x63,0xc0,0x9e,0xe3,0x9a,0xb4,0xd0,0xce,0xa7,0x89,0xab, + 0x52,0xc8,0x80,0x3a,0x91,0x77,0x29,0xc3,0xa0,0x79,0x2e,0xe6,0x61,0x8b,0x2d, + 0x53,0x70,0xcc,0xa4,0x62,0xd5,0x4a,0x47,0x74,0xea,0x22,0xfa,0xa9,0xd4,0x95, + 0x4e,0xca,0x32,0x70,0x88,0xd6,0xeb,0x58,0x24,0xa3,0xc5,0xbf,0x29,0xdc,0xfd, + 0xe5,0xde,0x8f,0x48,0x19,0xe8,0xc6,0x4f,0xf2,0x46,0x10,0xe2,0x58,0xb9,0xb6, + 0x72,0x5e,0x88,0xaf,0xc2,0xee,0x8b,0x6f,0xe5,0x36,0xe3,0x60,0x7c,0xf8,0x2c, + 0xea,0x3a,0x4f,0xe3,0x6d,0x73 +}; +#endif /* MAXQ10XX_PRODUCTION_KEY || !DEBUG_WOLFSSL */ + +#if defined(WOLFSSL_MAXQ108X) && defined(HAVE_HKDF) + +/* These are from Section 7.1 of the TLS 1.3 specification (RFC 8446). */ +static const char derivedLabel[] = "derived"; +static const char cHsTrafficLabel[] = "c hs traffic"; +static const char sHsTrafficLabel[] = "s hs traffic"; +static const char cAppTrafficLabel[] = "c ap traffic"; +static const char sAppTrafficLabel[] = "s ap traffic"; +static const char appTrafUpdLabel[] = "traffic upd"; +static const char keyLabel[] = "key"; +static const char ivLabel[] = "iv"; +static const char finishedLabel[] = "finished"; +static const char resMasterLabel[] = "res master"; +static const char extBinderLabel[] = "ext binder"; + +static int local_is_psk = 0; +static int is_hs_key = 0; + +#endif /* WOLFSSL_MAXQ108X && HAVE_HKDF */ + +static int aes_key_id_arr[AES_KEY_ID_MAX_NUM]; +static int ecc_key_id_arr[ECC_KEY_ID_MAX_NUM]; + +static int init_pk_callbacks = 0; +static int device_key_len = 32; + +#if defined(WOLFSSL_MAXQ108X) +static int temp_key_id_arr[TEMP_KEY_ID_MAX_NUM] = {0}; +static int *mac_key_obj_id = NULL; +static int mac_comp_active = 0; +#endif /* WOLFSSL_MAXQ108X */ + +#ifdef WOLFSSL_MAXQ10XX_CRYPTO +/* + * Helper Functions + */ +static int crypto_sha256(const uint8_t *buf, uint32_t len, uint8_t *hash, + uint32_t hashSz, uint32_t blkSz) +{ + int ret; + uint32_t i = 0, chunk; + wc_Sha256 sha256; + + /* validate arguments */ + if ((buf == NULL && len > 0) || hash == NULL || + hashSz < WC_SHA256_DIGEST_SIZE || blkSz == 0) { + return BAD_FUNC_ARG; + } + + /* Init Sha256 structure */ + ret = wc_InitSha256(&sha256); + if (ret != 0) { + return ret; + } + + sha256.maxq_ctx.soft_hash = 1; + + while (i < len) { + chunk = blkSz; + if ((chunk + i) > len) { + chunk = len - i; + } + /* Perform chunked update */ + ret = wc_Sha256Update(&sha256, (buf + i), chunk); + if (ret != 0) { + break; + } + i += chunk; + } + + if (ret == 0) { + /* Get final digest result */ + ret = wc_Sha256Final(&sha256, hash); + } + return ret; +} + +static int crypto_ecc_sign(const uint8_t *key, uint32_t keySz, + const uint8_t *hash, uint32_t hashSz, uint8_t *sig, uint32_t* sigSz, + uint32_t curveSz, int curveId, WC_RNG* rng) +{ + int ret; + mp_int r, s; + ecc_key ecc; + + /* validate arguments */ + if (key == NULL || hash == NULL || sig == NULL || sigSz == NULL || + curveSz == 0 || hashSz == 0 || keySz < curveSz || + *sigSz < (curveSz * 2)) { + return BAD_FUNC_ARG; + } + + /* Initialize signature result */ + XMEMSET(sig, 0, curveSz * 2); + + /* Setup the ECC key */ + ret = wc_ecc_init(&ecc); + if (ret < 0) { + return ret; + } + + ecc.maxq_ctx.hw_ecc = -1; + + /* Setup the signature r/s variables */ + ret = mp_init(&r); + if (ret != MP_OKAY) { + wc_ecc_free(&ecc); + return ret; + } + + ret = mp_init(&s); + if (ret != MP_OKAY) { + mp_clear(&r); + wc_ecc_free(&ecc); + return ret; + } + + /* Import private key "k" */ + ret = wc_ecc_import_private_key_ex(key, keySz, /* private key "d" */ + NULL, 0, /* public (optional) */ + &ecc, curveId); + + if (ret == 0) { + ret = wc_ecc_sign_hash_ex(hash, hashSz, /* computed hash digest */ + rng, &ecc, /* random and key context */ + &r, &s); + } + + if (ret == 0) { + /* export r/s */ + mp_to_unsigned_bin_len(&r, sig, curveSz); + mp_to_unsigned_bin_len(&s, sig + curveSz, curveSz); + } + + mp_clear(&r); + mp_clear(&s); + wc_ecc_free(&ecc); + return ret; +} + +#ifdef MAXQ_DEBUG +void dbg_dumphex(const char *identifier, const uint8_t* pdata, uint32_t plen) +{ + uint32_t i; + + printf("%s\n", identifier); + + for (i = 0; i < plen; ++i) { + if ((i > 0) && !(i % 16)) { + printf("\n"); + } + printf("%02X ", pdata[i]); + } + + printf("\n"); +} +#endif /* MAXQ_DEBUG */ + +/* + * Personalized Utility Functions + */ +static void LoadDefaultImportKey(unsigned char* key, int* keylen, + int* curve, int* type) +{ + *curve = MXQ_KEYPARAM_EC_P256R1; + *type = MXQ_KEYTYPE_ECC; + *keylen = 32; + + XMEMCPY(key, KeyPairImport, sizeof(KeyPairImport)); +} + +static int getSignAlgoFromCurve(int c) +{ + switch(c) { + case MXQ_KEYPARAM_EC_P256R1: return ALGO_ECDSA_SHA_256; + case MXQ_KEYPARAM_EC_P384R1: return ALGO_ECDSA_SHA_384; + case MXQ_KEYPARAM_EC_P521R1: return ALGO_ECDSA_SHA_512; +#ifdef HAVE_ECC_BRAINPOOL + case MXQ_KEYPARAM_EC_BP256R1: return ALGO_ECDSA_SHA_256; + case MXQ_KEYPARAM_EC_BP384R1: return ALGO_ECDSA_SHA_384; + case MXQ_KEYPARAM_EC_BP512R1: return ALGO_ECDSA_SHA_512; +#endif + } + return BAD_FUNC_ARG; +} + +#ifdef WOLFSSL_MAXQ108X + +static int wc_MAXQ10XX_HmacSetKey(int type); +static int wc_MAXQ10XX_HmacUpdate(const byte* msg, word32 length); +static int wc_MAXQ10XX_HmacFinal(byte* hash); + +static int getMaxqKeyParamFromCurve(int c) +{ + switch(c) { + case ECC_SECP256R1: return MXQ_KEYPARAM_EC_P256R1; + case ECC_SECP384R1: return MXQ_KEYPARAM_EC_P384R1; + case ECC_SECP521R1: return MXQ_KEYPARAM_EC_P521R1; + case ECC_BRAINPOOLP256R1: return MXQ_KEYPARAM_EC_BP256R1; + case ECC_BRAINPOOLP384R1: return MXQ_KEYPARAM_EC_BP384R1; + case ECC_BRAINPOOLP512R1: return MXQ_KEYPARAM_EC_BP512R1; + } + return BAD_FUNC_ARG; +} + +#endif /* WOLFSSL_MAXQ108X */ + +static int ECDSA_sign(mxq_u1* dest, int* signlen, mxq_u1* key, + mxq_u1* data, mxq_length data_length, int curve) +{ + int ret; + int hashlen = WC_SHA256_DIGEST_SIZE; + unsigned char hash[WC_SHA256_DIGEST_SIZE]; + WC_RNG rng; + int algo = 0; + int wc_curve_id = ECC_SECP256R1; + int wc_curve_size = 32; + uint32_t sigSz = 0; + + if (curve != MXQ_KEYPARAM_EC_P256R1) { + return BAD_FUNC_ARG; + } + + algo = getSignAlgoFromCurve(curve); + if (algo != ALGO_ECDSA_SHA_256) { + return BAD_FUNC_ARG; + } + + sigSz = (2 * wc_curve_size); + if (*signlen < (int)sigSz) { + return BAD_FUNC_ARG; + } + + ret = wc_InitRng(&rng); + if (ret != 0) { + return ret; + } + + ret = crypto_sha256(data, data_length, /* input message */ + hash, hashlen, /* hash digest result */ + 32 /* configurable block/chunk size */ + ); + + if (ret == 0) { + ret = crypto_ecc_sign( + (key + (2 * wc_curve_size)), wc_curve_size, /* private key */ + hash, hashlen, /* computed hash digest */ + dest, &sigSz, /* signature r/s */ + wc_curve_size, /* curve size in bytes */ + wc_curve_id, /* curve id */ + &rng); + + *signlen = sigSz; + } + + wc_FreeRng(&rng); + return ret; +} + +#ifdef MAXQ_AESGCM +static int alloc_aes_key_id(void) +{ + int i; + for (i = 0; i < AES_KEY_ID_MAX_NUM; ++i) { + if (aes_key_id_arr[i] == 0) { + aes_key_id_arr[i] = AES_KEY_ID_START + i; + break; + } + } + + if (i == AES_KEY_ID_MAX_NUM) { + return 0; + } + else { + return aes_key_id_arr[i]; + } +} +#endif /* MAXQ_AESGCM */ + +static void free_aes_key_id(int obj_id) +{ + int idx_for_arr = obj_id - AES_KEY_ID_START; + + if ((idx_for_arr >= 0) && (idx_for_arr < AES_KEY_ID_MAX_NUM)) { + aes_key_id_arr[idx_for_arr] = 0; + } +} + +#ifdef MAXQ_ECC +static int alloc_ecc_key_id(void) +{ + int i; + for (i = 0; i < ECC_KEY_ID_MAX_NUM; ++i) { + if (ecc_key_id_arr[i] == 0) { + ecc_key_id_arr[i] = ECC_KEY_ID_START + i; + break; + } + } + + if (i == ECC_KEY_ID_MAX_NUM) { + return 0; + } + else { + return ecc_key_id_arr[i]; + } +} +#endif /* MAXQ_ECC */ + +static void free_ecc_key_id(int obj_id) +{ + int idx_for_arr = obj_id - ECC_KEY_ID_START; + + if ((idx_for_arr >= 0) && (idx_for_arr < ECC_KEY_ID_MAX_NUM)) { + ecc_key_id_arr[idx_for_arr] = 0; + } +} + +#ifdef WOLFSSL_MAXQ108X +static int alloc_temp_key_id(void) +{ + int i; + for (i = 0; i < TEMP_KEY_ID_MAX_NUM; ++i) { + if (temp_key_id_arr[i] == 0) { + temp_key_id_arr[i] = 1; + break; + } + } + + if (i == TEMP_KEY_ID_MAX_NUM) { + return -1; + } + else { + return i; + } +} + +static void free_temp_key_id(int obj_id) +{ + int idx_for_arr = obj_id - TEMP_KEY_ID_START; + + if (idx_for_arr >=0 && idx_for_arr < TEMP_KEY_ID_MAX_NUM) { + temp_key_id_arr[idx_for_arr] = 0; + } +} +#endif /* WOLFSSL_MAXQ108X */ + +/* + * WolfCrypt Functions + */ +int wc_MAXQ10XX_AesSetKey(Aes* aes, const byte* userKey, word32 keylen) +{ + XMEMCPY(aes->maxq_ctx.key, userKey, keylen); + aes->maxq_ctx.key_pending = 1; + return 0; +} + +int wc_MAXQ10XX_EccSetKey(ecc_key* key, word32 keysize) +{ + int err = 0; + int keytype = key->type; + word32 bufflen = 0; + + if (key->maxq_ctx.hw_ecc == -1) { + err = WC_HW_E; + } + + if (err == 0) { + if (key->dp->id != ECC_SECP256R1) { + err = ECC_CURVE_OID_E; + } + } + + if (err == 0) { + if ((keytype != ECC_PUBLICKEY) && (keytype != ECC_PRIVATEKEY) && + (keytype != ECC_PRIVATEKEY_ONLY)) { + err = BAD_FUNC_ARG; + } + } + + if (err == 0) { + bufflen = keysize; + if ((keytype == ECC_PUBLICKEY) || (keytype == ECC_PRIVATEKEY)) { + err = wc_export_int(key->pubkey.x, key->maxq_ctx.ecc_key, + &bufflen, keysize, WC_TYPE_UNSIGNED_BIN); + } + } + + if (err == 0) { + if ((keytype == ECC_PUBLICKEY) || (keytype == ECC_PRIVATEKEY)) { + err = wc_export_int(key->pubkey.y, key->maxq_ctx.ecc_key + keysize, + &bufflen, keysize, WC_TYPE_UNSIGNED_BIN); + } + } + + if (err == 0) { + if ((keytype == ECC_PRIVATEKEY) || (keytype == ECC_PRIVATEKEY_ONLY)) { + err = wc_export_int(&key->k, key->maxq_ctx.ecc_key + (2 * keysize), + &bufflen, keysize, WC_TYPE_UNSIGNED_BIN); + } + } + + if (err == 0) { + key->maxq_ctx.hw_ecc = 1; + key->maxq_ctx.key_pending = 1; + } + else { + key->maxq_ctx.hw_ecc = -1; + } + + return err; +} + +#ifdef MAXQ_AESGCM +static int aes_set_key(Aes* aes, const byte* userKey, word32 keylen) +{ + mxq_u1 key_buff[MAX_KEY_DATASIZE]; + mxq_err_t mxq_rc; + int rc; + unsigned char sign_key[MAX_SIGNKEY_DATASIZE]; + int sign_key_len, sign_key_curve, sign_key_type; + mxq_u1 signature[MAX_SIG_DATASIZE]; + int signature_len = (int)sizeof(signature); + + + if (aes == NULL || (keylen != AES_128_KEY_SIZE && +#ifdef WOLFSSL_AES_192 + keylen != AES_192_KEY_SIZE && +#endif + keylen != AES_256_KEY_SIZE)) { + return BAD_FUNC_ARG; + } + + rc = maxq_CryptHwMutexTryLock(); + if (rc != 0) { + WOLFSSL_ERROR_MSG("MAXQ: aes_set_key() lock could not be acquired"); + rc = NOT_COMPILED_IN; + return rc; + } + + if (aes->maxq_ctx.key_obj_id) { + wc_MAXQ10XX_AesFree(aes); + } + + int obj_id = alloc_aes_key_id(); + if (!obj_id) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_aes_key_id() failed"); + rc = NOT_COMPILED_IN; + goto end_AesSetKey; + } + + mxq_rc = MXQ_CreateObject(obj_id, keylen, MXQ_OBJTYPE_SECRETKEY, + OBJPROP_PERSISTENT, + (char *)"ahs=rwdgx:ahs=rwdgx:ahs=rwdgx"); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_CreateObject() failed"); + rc = NOT_COMPILED_IN; + goto end_AesSetKey; + } + + /* store the object id in the context */ + aes->maxq_ctx.key_obj_id = obj_id; + + mxq_length key_buff_len = sizeof(key_buff); + mxq_rc = MXQ_BuildKey(key_buff, &key_buff_len, MXQ_KEYTYPE_AES, 0xff, + keylen, keylen, MXQ_KEYUSE_ENCRYPTION, + ALGO_CIPHER_AES_ECB, MXQ_KEYUSE_NONE, ALGO_NONE, + (mxq_u1 *)userKey); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_BuildKey() failed"); + rc = WC_HW_E; + goto end_AesSetKey; + } + + LoadDefaultImportKey(sign_key, &sign_key_len, &sign_key_curve, + &sign_key_type); + + rc = ECDSA_sign(signature, &signature_len, sign_key, key_buff, key_buff_len, + sign_key_curve); + if (rc) { + WOLFSSL_ERROR_MSG("MAXQ: ECDSA_sign() failed"); + goto end_AesSetKey; + } + + mxq_rc = MXQ_ImportKey(obj_id, getSignAlgoFromCurve(sign_key_curve), + PUBKEY_IMPORT_OBJID, key_buff, key_buff_len, + signature, signature_len); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_ImportKey() failed"); + rc = WC_HW_E; + goto end_AesSetKey; + } + + /* key stored successfully */ + aes->maxq_ctx.key_pending = 0; + +end_AesSetKey: + wolfSSL_CryptHwMutexUnLock(); + return rc; +} +#endif /* MAXQ_AESGCM */ + +void wc_MAXQ10XX_AesFree(Aes* aes) +{ + mxq_err_t mxq_rc; + int rc = 1; + + if (aes->maxq_ctx.key_obj_id != 0) { + rc = 0; + } + + if (rc == 0) { + rc = wolfSSL_CryptHwMutexLock(); + } + + if (rc == 0) { + mxq_rc = MXQ_DeleteObject(aes->maxq_ctx.key_obj_id); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_DeleteObject() failed"); + rc = 1; + } + + if (rc == 0) { + free_aes_key_id(aes->maxq_ctx.key_obj_id); + aes->maxq_ctx.key_obj_id = 0; + } + wolfSSL_CryptHwMutexUnLock(); + } +} + +#ifdef MAXQ_ECC +static int ecc_set_key(ecc_key* key, const byte* userKey, word32 keycomplen) +{ + mxq_err_t mxq_rc; + int rc; + word32 keylen; + int objtype; + mxq_u1 key_buff[MAX_KEY_DATASIZE]; + mxq_length key_buff_len = sizeof(key_buff); + unsigned char sign_key[MAX_SIGNKEY_DATASIZE]; + int sign_key_len, sign_key_curve, sign_key_type; + mxq_u1 signature[MAX_SIG_DATASIZE]; + int signature_len = (int)sizeof(signature); + + + if ((key->type != ECC_PUBLICKEY) && (key->type != ECC_PRIVATEKEY) && + (key->type != ECC_PRIVATEKEY_ONLY)) { + return BAD_FUNC_ARG; + } + + if (key->type == ECC_PUBLICKEY) { + keylen = keycomplen * 2; + objtype = MXQ_OBJTYPE_PUBKEY; + } + else { + keylen = keycomplen * 3; + objtype = MXQ_OBJTYPE_KEYPAIR; + } + + rc = maxq_CryptHwMutexTryLock(); + if (rc != 0) { + WOLFSSL_ERROR_MSG("MAXQ: ecc_set_key() lock could not be acquired"); + rc = NOT_COMPILED_IN; + return rc; + } + + if (key->maxq_ctx.key_obj_id) { + wc_MAXQ10XX_EccFree(key); + } + + int obj_id = alloc_ecc_key_id(); + if (!obj_id) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_ecc_key_id() failed"); + rc = NOT_COMPILED_IN; + goto end_EccSetKey; + } + + mxq_rc = MXQ_CreateObject(obj_id, keylen, objtype, OBJPROP_PERSISTENT, + (char *)"ahs=rwdgx:ahs=rwdgx:ahs=rwdgx"); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_CreateObject() failed"); + rc = NOT_COMPILED_IN; + goto end_EccSetKey; + } + + /* store the object id in the context */ + key->maxq_ctx.key_obj_id = obj_id; + + mxq_rc = MXQ_BuildKey(key_buff, &key_buff_len, MXQ_KEYTYPE_ECC, + MXQ_KEYPARAM_EC_P256R1, keycomplen, keylen, + MXQ_KEYUSE_DATASIGNATURE, ALGO_ECDSA_SHA_256, + MXQ_KEYUSE_NONE, ALGO_NONE, (mxq_u1 *)userKey); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_BuildKey() failed"); + rc = WC_HW_E; + goto end_EccSetKey; + } + + LoadDefaultImportKey(sign_key, &sign_key_len, &sign_key_curve, + &sign_key_type); + + rc = ECDSA_sign(signature, &signature_len, sign_key, key_buff, key_buff_len, + sign_key_curve); + if (rc) { + WOLFSSL_ERROR_MSG("MAXQ: ECDSA_sign() failed"); + goto end_EccSetKey; + } + + mxq_rc = MXQ_ImportKey(obj_id, getSignAlgoFromCurve(sign_key_curve), + PUBKEY_IMPORT_OBJID, key_buff, key_buff_len, + signature, signature_len); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_ImportKey() failed"); + rc = WC_HW_E; + goto end_EccSetKey; + } + + /* key stored successfully */ + key->maxq_ctx.key_pending = 0; + +end_EccSetKey: + wolfSSL_CryptHwMutexUnLock(); + return rc; +} +#endif /* MAXQ_ECC */ + +void wc_MAXQ10XX_EccFree(ecc_key* key) +{ + if (key->maxq_ctx.key_obj_id == 0) { + return; + } + + int rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return; + } + + mxq_err_t mxq_rc = MXQ_DeleteObject(key->maxq_ctx.key_obj_id); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_DeleteObject() failed"); + wolfSSL_CryptHwMutexUnLock(); + return; + } + + free_ecc_key_id(key->maxq_ctx.key_obj_id); + key->maxq_ctx.key_obj_id = 0; + wolfSSL_CryptHwMutexUnLock(); +} + +void wc_MAXQ10XX_Sha256Copy(wc_Sha256* sha256) +{ + /* during copying, change to soft hash mode for one context */ + if (sha256->maxq_ctx.hash_running) { + sha256->maxq_ctx.hash_running = 0; + sha256->maxq_ctx.soft_hash = 1; + } +} + +void wc_MAXQ10XX_Sha256Free(wc_Sha256* sha256) +{ + /* release the mutex if a hash operation is running on the maxq10xx device + */ + if (sha256->maxq_ctx.hash_running) { + sha256->maxq_ctx.hash_running = 0; + sha256->maxq_ctx.soft_hash = 1; + wolfSSL_CryptHwMutexUnLock(); + } +} +#endif /* WOLFSSL_MAXQ10XX_CRYPTO */ + +#ifdef WOLF_CRYPTO_CB +#ifdef MAXQ_SHA256 +static int maxq10xx_hash_update_sha256(const mxq_u1* psrc, mxq_length inlen, + int running) +{ + mxq_err_t mxq_rc; + + if (running == 0) { + mxq_rc = MXQ_MD_Init(ALGO_MD_SHA256); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_MD_Init() failed"); + return WC_HW_E; + } + } + + mxq_length data_offset = 0; + mxq_length data_len; + + while (inlen) { + data_len = (inlen < MAX_HASH_CHUNKSIZE) ? inlen : MAX_HASH_CHUNKSIZE; + + mxq_rc = MXQ_MD_Update(&psrc[data_offset], data_len); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_MD_Update() failed"); + return WC_HW_E; + } + + data_offset += data_len; + inlen -= data_len; + } + + return 0; +} + +static int maxq10xx_hash_finish_sha256(mxq_u1* pdest) +{ + mxq_err_t mxq_rc; + mxq_length hashlen = WC_SHA256_DIGEST_SIZE; + + mxq_rc = MXQ_MD_Finish(pdest, &hashlen); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_MD_Finish() failed"); + return WC_HW_E; + } + + return 0; +} +#endif /* MAXQ_SHA256 */ + +static int maxq10xx_cipher_do(mxq_algo_id_t algo_id, mxq_u1 encrypt, + mxq_u2 key_id, mxq_u1* p_in, mxq_u1* p_out, + mxq_length data_size, mxq_u1* p_iv, + mxq_length iv_len, mxq_u1* p_aad, + mxq_length aad_len, mxq_u1* p_tag, + mxq_length tag_len) +{ + mxq_err_t mxq_rc; + ciph_params_t cparams; + + mxq_u1 internal_data[K_CHUNKSIZE + K_CIPHER_BLOCKSIZE]; + mxq_u1 *p_int_data = internal_data; + + mxq_length data_offset = 0; + mxq_length proc_len = 0, req_len = 0; + + XMEMSET(&cparams, 0, sizeof(cparams)); + + cparams.data_length = data_size; + cparams.p_iv = p_iv; + cparams.iv_length = iv_len; + cparams.p_aad = p_aad; + cparams.aad_length = aad_len; + + if (encrypt) { + cparams.aead_tag_len = tag_len; + } + else { + XMEMCPY(cparams.aead_tag, p_tag, tag_len); + cparams.aead_tag_len = tag_len; + } + + mxq_rc = MXQ_Cipher_Init(encrypt, algo_id, key_id, &cparams, 0); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_Cipher_Init() failed"); + return WC_HW_E; + } + + while (data_size) { + proc_len = (data_size < K_CHUNKSIZE) ? data_size : K_CHUNKSIZE; + req_len = proc_len; + + mxq_rc = MXQ_Cipher_Update(&p_out, &p_in[data_offset], &proc_len); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_Cipher_Update() failed"); + return WC_HW_E; + } + + data_offset += req_len; + data_size -= req_len; + } + + if (encrypt) { + proc_len = tag_len; + mxq_rc = MXQ_Cipher_Finish(&p_int_data, &proc_len); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: Encrypt, MXQ_Cipher_Finish() failed"); + return WC_HW_E; + } + + if (proc_len > tag_len) { + XMEMCPY(p_out, internal_data, proc_len - tag_len); + } + + if ((tag_len != 0) && (proc_len >= tag_len)) { + XMEMCPY(p_tag, &internal_data[proc_len - tag_len], tag_len); + } + } + else { + internal_data[0] = 0xDE; + XMEMCPY(&internal_data[1], p_tag, tag_len); + proc_len = tag_len; + + mxq_rc = MXQ_Cipher_Finish(&p_int_data, &proc_len); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: Decrypt, MXQ_Cipher_Finish() failed"); + return WC_HW_E; + } + + if (proc_len) { + XMEMCPY(p_out, internal_data, proc_len); + } + } + + return 0; +} + +static int maxq10xx_ecc_sign_local(mxq_u2 key_id, + mxq_u1* p_in, mxq_u2 data_size, + mxq_u1* p_sign_out, mxq_length* sign_len, + mxq_length keycomplen) +{ + mxq_err_t mxq_rc; + int rc; + mxq_u1 *input_digest = NULL; + mxq_u1 *buff_sign = NULL; + mxq_length buff_len = keycomplen * 2; + byte *r = NULL; + byte *s = NULL; + + input_digest = (mxq_u1 *)XMALLOC(keycomplen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + buff_sign = (mxq_u1 *)XMALLOC(keycomplen * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (input_digest == NULL || buff_sign == NULL) { + XFREE(input_digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(buff_sign, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } + r = &buff_sign[0]; + s = &buff_sign[keycomplen]; + + /* truncate input to match key size */ + if (data_size > keycomplen) { + data_size = keycomplen; + } + + /* build input digest */ + XMEMSET(input_digest, 0, keycomplen); + XMEMCPY(&input_digest[keycomplen - data_size], p_in, data_size); + + mxq_rc = MXQ_Sign(ALGO_ECDSA_PLAIN, key_id, input_digest, + keycomplen, buff_sign, &buff_len); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_Sign() failed"); + return WC_HW_E; + } + + /* convert r and s to signature */ + rc = wc_ecc_rs_raw_to_sig((const byte *)r, keycomplen, (const byte *)s, + keycomplen, p_sign_out, sign_len); + if (rc != 0) { + WOLFSSL_ERROR_MSG("MAXQ: converting r and s to signature failed"); + } + + XFREE(input_digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(buff_sign, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return rc; +} + +#ifdef MAXQ_ECC +static int maxq10xx_ecc_verify_local( + mxq_u2 key_id, mxq_u1* p_in, mxq_u2 data_size, + mxq_u1* p_sign, mxq_u1 sign_len, int *result, + mxq_length keycomplen) +{ + int rc; + mxq_err_t mxq_rc; + mxq_u1 *buff_rs = NULL; + mxq_u1 *input_digest = NULL; + mxq_u1 *buff_signature = NULL; + byte *r = NULL; + byte *s = NULL; + word32 r_len = keycomplen; + word32 s_len = keycomplen; + + input_digest = (mxq_u1 *)XMALLOC(keycomplen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + buff_rs = (mxq_u1 *)XMALLOC(keycomplen * 2, NULL, DYNAMIC_TYPE_TMP_BUFFER); + buff_signature = (mxq_u1 *)XMALLOC(keycomplen * 2, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + + if (input_digest == NULL || buff_rs == NULL || buff_signature == NULL) { + XFREE(input_digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(buff_rs, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(buff_signature, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } + r = &buff_rs[0]; + s = &buff_rs[keycomplen]; + + /* truncate input to match key size */ + if (data_size > keycomplen) { + data_size = keycomplen; + } + + /* build input digest */ + XMEMSET(input_digest, 0, keycomplen); + XMEMCPY(&input_digest[keycomplen - data_size], p_in, data_size); + + /* extract r and s from signature */ + XMEMSET(buff_rs, 0, keycomplen * 2); + + rc = wc_ecc_sig_to_rs(p_sign, sign_len, r, &r_len, s, &s_len); + if (rc != 0) { + XFREE(input_digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(buff_rs, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(buff_signature, NULL, DYNAMIC_TYPE_TMP_BUFFER); + WOLFSSL_ERROR_MSG("MAXQ: extracting r and s from signature failed"); + *result = 0; + return rc; + } + + if ((r_len > keycomplen) || (s_len > keycomplen)) { + XFREE(input_digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(buff_rs, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(buff_signature, NULL, DYNAMIC_TYPE_TMP_BUFFER); + WOLFSSL_ERROR_MSG("MAXQ: r and s corrupted"); + *result = 0; + return BUFFER_E; + } + + /* prepare raw signature */ + XMEMSET(buff_signature, 0, keycomplen * 2); + + /* add leading zeros if necessary */ + XMEMCPY(&buff_signature[keycomplen - r_len], r, r_len); + XMEMCPY(&buff_signature[(keycomplen * 2) - s_len], s, s_len); + + mxq_rc = MXQ_Verify(ALGO_ECDSA_PLAIN, key_id, input_digest, + keycomplen, buff_signature, keycomplen * 2); + + XFREE(input_digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(buff_rs, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(buff_signature, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + *result = (mxq_rc ? 0 : 1); + return 0; +} +#endif /* MAXQ_ECC */ + +#ifdef MAXQ_RNG +static int maxq10xx_random(byte* output, unsigned short sz) +{ +#if defined(WOLFSSL_MAXQ108X) + if (!tls13active) { + return NOT_COMPILED_IN; + } +#endif + + if (output == NULL) { + return BUFFER_E; + } + + int ret = maxq_CryptHwMutexTryLock(); + if (ret != 0) { + WOLFSSL_ERROR_MSG("MAXQ: maxq10xx_random() lock could not be acquired"); + ret = NOT_COMPILED_IN; + return ret; + } + + if (MXQ_Get_Random_Ext(output, sz, 0)) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_Get_Random_Ext() failed"); + wolfSSL_CryptHwMutexUnLock(); + return WC_HW_E; + } + + wolfSSL_CryptHwMutexUnLock(); + return 0; +} +#endif /* MAXQ_RNG */ + +#if !defined(NO_AES) && defined(HAVE_AESGCM) && defined(MAXQ_AESGCM) +static int do_aesgcm(wc_CryptoInfo* info) +{ + int rc; + if (info->cipher.enc) { + if (info->cipher.aesgcm_enc.authTagSz > 16) { + return CRYPTOCB_UNAVAILABLE; + } + + if (info->cipher.aesgcm_enc.sz == 0) { + return CRYPTOCB_UNAVAILABLE; + } + + if (info->cipher.aesgcm_enc.ivSz != 12) { + return CRYPTOCB_UNAVAILABLE; + } + + if (info->cipher.aesgcm_enc.aes->maxq_ctx.key_pending) { + rc = aes_set_key( + info->cipher.aesgcm_enc.aes, + (const byte *)info->cipher.aesgcm_enc.aes->maxq_ctx.key, + info->cipher.aesgcm_enc.aes->keylen); + if (rc != 0) { + return rc; + } + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + rc = maxq10xx_cipher_do( + ALGO_CIPHER_AES_GCM, + 1, + info->cipher.aesgcm_enc.aes->maxq_ctx.key_obj_id, + (byte *)info->cipher.aesgcm_enc.in, + (byte *)info->cipher.aesgcm_enc.out, + info->cipher.aesgcm_enc.sz, + (byte *)info->cipher.aesgcm_enc.iv, + info->cipher.aesgcm_enc.ivSz, + (byte *)info->cipher.aesgcm_enc.authIn, + info->cipher.aesgcm_enc.authInSz, + (byte *)info->cipher.aesgcm_enc.authTag, + info->cipher.aesgcm_enc.authTagSz); + if (rc != 0) { + wolfSSL_CryptHwMutexUnLock(); + return rc; + } + + wolfSSL_CryptHwMutexUnLock(); + } + else { + if (info->cipher.aesgcm_dec.authTagSz != 16) { + return CRYPTOCB_UNAVAILABLE; + } + + if (info->cipher.aesgcm_dec.sz == 0) { + return CRYPTOCB_UNAVAILABLE; + } + + if (info->cipher.aesgcm_dec.ivSz != 12) { + return CRYPTOCB_UNAVAILABLE; + } + + if (info->cipher.aesgcm_dec.aes->maxq_ctx.key_pending) { + rc = aes_set_key( + info->cipher.aesgcm_dec.aes, + (const byte *)info->cipher.aesgcm_dec.aes->maxq_ctx.key, + info->cipher.aesgcm_dec.aes->keylen); + if (rc != 0) { + return rc; + } + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + rc = maxq10xx_cipher_do( + ALGO_CIPHER_AES_GCM, + 0, + info->cipher.aesgcm_dec.aes->maxq_ctx.key_obj_id, + (byte *)info->cipher.aesgcm_dec.in, + (byte *)info->cipher.aesgcm_dec.out, + info->cipher.aesgcm_dec.sz, + (byte *)info->cipher.aesgcm_dec.iv, + info->cipher.aesgcm_dec.ivSz, + (byte *)info->cipher.aesgcm_dec.authIn, + info->cipher.aesgcm_dec.authInSz, + (byte *)info->cipher.aesgcm_dec.authTag, + info->cipher.aesgcm_dec.authTagSz); + if (rc != 0) { + wolfSSL_CryptHwMutexUnLock(); + return rc; + } + + wolfSSL_CryptHwMutexUnLock(); + } + + /* done */ + return 0; +} +#endif /* !NO_AES && HAVE_AESGCM && MAXQ_AESGCM */ + +#if !defined(NO_SHA) && !defined(NO_SHA256) && defined(MAXQ_SHA256) +static int do_sha256(wc_CryptoInfo* info) +{ + int rc; + if (info->hash.sha256->maxq_ctx.soft_hash) { + return CRYPTOCB_UNAVAILABLE; + } + + if ((info->hash.in == NULL) && (info->hash.digest == NULL)) { + return WC_HW_E; + } + + if (info->hash.sha256->maxq_ctx.hash_running == 0) { + rc = maxq_CryptHwMutexTryLock(); + if (rc != 0) { + info->hash.sha256->maxq_ctx.soft_hash = 1; + return CRYPTOCB_UNAVAILABLE; + } + } + + if (info->hash.in != NULL) { + /* wc_Sha256Update */ + if ((info->hash.sha256->maxq_ctx.hash_running == 0) && + (info->hash.inSz == 0)) { + info->hash.sha256->maxq_ctx.soft_hash = 1; + wolfSSL_CryptHwMutexUnLock(); + return CRYPTOCB_UNAVAILABLE; + } + + rc = maxq10xx_hash_update_sha256(info->hash.in, info->hash.inSz, + info->hash.sha256->maxq_ctx.hash_running); + if (rc != 0) { + info->hash.sha256->maxq_ctx.hash_running = 0; + wolfSSL_CryptHwMutexUnLock(); + return rc; + } + + info->hash.sha256->maxq_ctx.hash_running = 1; + + /* save soft hash context in case of wc_Sha256Copy */ + return CRYPTOCB_UNAVAILABLE; + } + else if (info->hash.digest != NULL) { + /* wc_Sha256Final */ + if (info->hash.sha256->maxq_ctx.hash_running == 0) { + info->hash.sha256->maxq_ctx.soft_hash = 1; + wolfSSL_CryptHwMutexUnLock(); + return CRYPTOCB_UNAVAILABLE; + } + + rc = maxq10xx_hash_finish_sha256(info->hash.digest); + if (rc != 0) { + info->hash.sha256->maxq_ctx.hash_running = 0; + wolfSSL_CryptHwMutexUnLock(); + return rc; + } + + info->hash.sha256->maxq_ctx.hash_running = 0; + wolfSSL_CryptHwMutexUnLock(); + /* done */ + rc = 0; + } + return rc; +} +#endif /* !NO_SHA && !NO_SHA256 && MAXQ_SHA256 */ + +int wolfSSL_MAXQ10XX_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx) +{ + int rc = CRYPTOCB_UNAVAILABLE; + (void)devId; + (void)ctx; + +#if defined(WOLFSSL_MAXQ108X) + if (!tls13active) +#endif + return CRYPTOCB_UNAVAILABLE; + + if (info->algo_type == WC_ALGO_TYPE_CIPHER) { +#if !defined(NO_AES) || !defined(NO_DES3) + #if defined(HAVE_AESGCM) && defined(MAXQ_AESGCM) + if (info->cipher.type == WC_CIPHER_AES_GCM) { + rc = do_aesgcm(info); + } + #endif /* HAVE_AESGCM && MAXQ_AESGCM */ + #ifdef HAVE_AES_CBC + if (info->cipher.type == WC_CIPHER_AES_CBC) { + /* TODO */ + return CRYPTOCB_UNAVAILABLE; + } + #endif /* HAVE_AES_CBC */ +#endif /* !NO_AES || !NO_DES3 */ + } +#if !defined(NO_SHA) || !defined(NO_SHA256) + else if (info->algo_type == WC_ALGO_TYPE_HASH) { + #if !defined(NO_SHA) && defined(MAXQ_SHA1) + if (info->hash.type == WC_HASH_TYPE_SHA) { + /* TODO */ + return CRYPTOCB_UNAVAILABLE; + } + else + #endif /* !NO_SHA && MAXQ_SHA1 */ + #if !defined(NO_SHA256) && defined(MAXQ_SHA256) + if (info->hash.type == WC_HASH_TYPE_SHA256) { + rc = do_sha256(info); + } + #endif /* !NO_SHA256 && MAXQ_SHA256 */ + } +#endif /* !NO_SHA || !NO_SHA256 */ +#if !defined(WC_NO_RNG) && defined(MAXQ_RNG) + else if (info->algo_type == WC_ALGO_TYPE_SEED) { + rc = maxq10xx_random(info->seed.seed, info->seed.sz); + } + else if (info->algo_type == WC_ALGO_TYPE_RNG) { + rc = maxq10xx_random(info->rng.out, info->rng.sz); + } +#endif /* !WC_NO_RNG && MAXQ_RNG */ + else if (info->algo_type == WC_ALGO_TYPE_PK) { + #if defined(HAVE_ECC) && defined(MAXQ_ECC) + if (info->pk.type == WC_PK_TYPE_EC_KEYGEN) { + /* TODO */ + return CRYPTOCB_UNAVAILABLE; + } + else if (info->pk.type == WC_PK_TYPE_ECDH) { + /* TODO */ + return CRYPTOCB_UNAVAILABLE; + } + else if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { + if (info->pk.eccsign.key->maxq_ctx.hw_ecc == 0) { + rc = wc_MAXQ10XX_EccSetKey(info->pk.eccsign.key, + info->pk.eccsign.key->dp->size); + if (rc != 0) { + return rc; + } + } + + if (info->pk.eccsign.key->maxq_ctx.hw_ecc == -1) { + return CRYPTOCB_UNAVAILABLE; + } + + if (info->pk.eccsign.key->maxq_ctx.key_pending) { + rc = ecc_set_key(info->pk.eccsign.key, + info->pk.eccsign.key->maxq_ctx.ecc_key, + info->pk.eccsign.key->dp->size); + if (rc != 0) { + return rc; + } + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + rc = maxq10xx_ecc_sign_local( + info->pk.eccsign.key->maxq_ctx.key_obj_id, + (byte *)info->pk.eccsign.in, info->pk.eccsign.inlen, + info->pk.eccsign.out, info->pk.eccsign.outlen, + info->pk.eccsign.key->dp->size); + + if (rc != 0) { + wolfSSL_CryptHwMutexUnLock(); + return rc; + } + + wolfSSL_CryptHwMutexUnLock(); + /* done */ + rc = 0; + } + else if (info->pk.type == WC_PK_TYPE_ECDSA_VERIFY) { + if (info->pk.eccverify.key->type == ECC_PRIVATEKEY_ONLY) { + return CRYPTOCB_UNAVAILABLE; + } + + if (info->pk.eccverify.key->maxq_ctx.hw_ecc == 0) { + rc = wc_MAXQ10XX_EccSetKey(info->pk.eccverify.key, + info->pk.eccverify.key->dp->size); + if (rc != 0) { + return rc; + } + } + + if (info->pk.eccverify.key->maxq_ctx.hw_ecc == -1) { + return CRYPTOCB_UNAVAILABLE; + } + + if (info->pk.eccverify.key->maxq_ctx.key_pending) { + rc = ecc_set_key(info->pk.eccverify.key, + info->pk.eccverify.key->maxq_ctx.ecc_key, + info->pk.eccverify.key->dp->size); + if (rc != 0) { + return rc; + } + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + rc = + maxq10xx_ecc_verify_local( + info->pk.eccverify.key->maxq_ctx.key_obj_id, + (byte *)info->pk.eccverify.hash, + info->pk.eccverify.hashlen, + (byte *)info->pk.eccverify.sig, + info->pk.eccverify.siglen, + info->pk.eccverify.res, + info->pk.eccverify.key->dp->size); + + wolfSSL_CryptHwMutexUnLock(); + + if (rc != 0) { + return rc; + } + + /* Success */ + rc = 0; + } + #endif /* HAVE_ECC && MAXQ_ECC */ + } +#ifdef WOLFSSL_MAXQ108X + else if (info->algo_type == WC_ALGO_TYPE_HMAC) { + if (info->hmac.in != NULL && info->hmac.digest == NULL) { + rc = 0; + if (mac_comp_active == 0) { + rc = wc_MAXQ10XX_HmacSetKey(info->hmac.macType); + } + if (rc == 0) { + rc = wc_MAXQ10XX_HmacUpdate(info->hmac.in, info->hmac.inSz); + } + } + else if (info->hmac.in == NULL && info->hmac.digest != NULL) { + rc = wc_MAXQ10XX_HmacFinal(info->hmac.digest); + } + else { + rc = BAD_FUNC_ARG; + } + } +#endif /* WOLFSSL_MAXQ108X */ + + if (rc != 0 && rc != CRYPTOCB_UNAVAILABLE) { + rc = WC_HW_E; + } + + return rc; +} + +static int wolfSSL_Soft_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx) +{ + (void)devId; + (void)info; + (void)ctx; + + return CRYPTOCB_UNAVAILABLE; +} +#endif /* WOLF_CRYPTO_CB */ + +#ifdef WOLFSSL_MAXQ10XX_TLS +#ifdef WOLFSSL_MAXQ108X +static int calculate_modulus_offset(const unsigned char * cert_data, int offset) +{ + int i; + int l_offset = offset; + for (i = 0; i < 2; i++) { + if ((cert_data[l_offset]) & 0x80) { + if ((cert_data[l_offset] & 0x7f) == 1) { + l_offset += 3; + } + if ((cert_data[l_offset] & 0x7f) == 2) { + l_offset += 4; + } + } + else { + l_offset += 2; + } + } + return l_offset; +} + +static int maxq_curve_wolfssl_id2mxq_id(word32 curve_id, mxq_length *keycomplen) +{ + switch (curve_id) { + case ECC_SECP256R1_OID: + *keycomplen = 32; + return MXQ_KEYPARAM_EC_P256R1; + case ECC_SECP384R1_OID: + *keycomplen = 48; + return MXQ_KEYPARAM_EC_P384R1; + case ECC_SECP521R1_OID: + *keycomplen = 66; + return MXQ_KEYPARAM_EC_P521R1; + case ECC_BRAINPOOLP256R1_OID: + *keycomplen = 32; + return MXQ_KEYPARAM_EC_BP256R1; + case ECC_BRAINPOOLP384R1_OID: + *keycomplen = 48; + return MXQ_KEYPARAM_EC_BP384R1; + case ECC_BRAINPOOLP512R1_OID: + *keycomplen = 64; + return MXQ_KEYPARAM_EC_BP512R1; + default: + return MXQ_UNKNOWN_CURVE; + } +} + +static int mxq_get_sign_alg_from_sig_oid(word32 maxq_id) { + + switch (maxq_id) { + case CTC_SHA256wECDSA: + return ALGO_ECDSA_SHA_256; + case CTC_SHA384wECDSA: + return ALGO_ECDSA_SHA_384; + case CTC_SHA512wECDSA: + return ALGO_ECDSA_SHA_512; + case CTC_SHA256wRSA: + return ALGO_RSASSAPSSPKCS1_V1_5_SHA256; + case CTC_SHA384wRSA: + return ALGO_RSASSAPSSPKCS1_V1_5_SHA384; + case CTC_SHA512wRSA: + return ALGO_RSASSAPSSPKCS1_V1_5_SHA512; + default: + return ALGO_INVALID; + } +} +#endif /* WOLFSSL_MAXQ108X */ + +/* TODO: Get rid of publicKeyIndex. Pass in the information it is parsing. + * Then Improve this to pass in the parts of decoded cert it needs. + */ +static int maxq10xx_process_server_certificate(WOLFSSL* ssl, + DecodedCert* p_cert) +{ + mxq_keytype_id_t key_type = MXQ_KEYTYPE_ECC; + mxq_keyparam_id_t keyparam = MXQ_KEYPARAM_EC_P256R1; + mxq_length totalkeylen; + mxq_algo_id_t sign_algo = ALGO_ECDSA_SHA_256; + int pk_offset = p_cert->publicKeyIndex; + mxq_length keycomplen = ECC_KEYCOMPLEN; + int rc; + mxq_err_t mxq_rc; + mxq_u1 certdata[MAX_CERT_DATASIZE]; + mxq_length certdatalen = sizeof(certdata); + (void)ssl; +#if defined(WOLFSSL_MAXQ1065) + + if (p_cert->signatureOID != CTC_SHA256wECDSA) { + WOLFSSL_MSG("MAXQ: signature algo not supported"); + return NOT_COMPILED_IN; + } + + if (p_cert->keyOID != ECDSAk) { + WOLFSSL_MSG("MAXQ: key algo not supported"); + return NOT_COMPILED_IN; + } + + if (p_cert->pkCurveOID != ECC_SECP256R1_OID) { + WOLFSSL_MSG("MAXQ: key curve not supported"); + return NOT_COMPILED_IN; + } + + totalkeylen = keycomplen * 2; + +#elif defined(WOLFSSL_MAXQ108X) + + if (p_cert->keyOID == ECDSAk ) + { + keyparam = maxq_curve_wolfssl_id2mxq_id(p_cert->pkCurveOID, + &keycomplen); + if (keyparam == MXQ_UNKNOWN_CURVE) { + WOLFSSL_MSG("MAXQ: key curve not supported"); + return NOT_COMPILED_IN; + } + totalkeylen = keycomplen * 2; + } + else if (p_cert->keyOID == RSAk) { + pk_offset = calculate_modulus_offset(p_cert->source, + p_cert->publicKeyIndex+1); + keycomplen = ((p_cert->source[pk_offset-2] << 8) | + p_cert->source[pk_offset-1]); + + /* Is there a more elegant way for checking pub key??? */ + if (p_cert->publicKey[p_cert->pubKeySize-1] == 0x03 && + p_cert->publicKey[p_cert->pubKeySize-2] == 0x01) { + keyparam = MXQ_KEYPARAM_RSA_PUB3; + } + else if (p_cert->publicKey[p_cert->pubKeySize-1] == 0x01 && + p_cert->publicKey[p_cert->pubKeySize-2] == 0x00 && + p_cert->publicKey[p_cert->pubKeySize-3] == 0x01 && + p_cert->publicKey[p_cert->pubKeySize-4] == 0x03) { + keyparam = MXQ_KEYPARAM_RSA_PUB65537; + } + else { + WOLFSSL_MSG("MAXQ: RSA public key not supported"); + return NOT_COMPILED_IN; + } + key_type = MXQ_KEYTYPE_RSA; + totalkeylen = keycomplen; + + } + else { + WOLFSSL_MSG("MAXQ: key algo not supported"); + return NOT_COMPILED_IN; + } + + tls13_server_key_algo = p_cert->keyOID; + tls13_server_key_len = keycomplen; + sign_algo = mxq_get_sign_alg_from_sig_oid(p_cert->signatureOID); + + if (sign_algo == ALGO_INVALID) { + WOLFSSL_MSG("MAXQ: signature algo not supported"); + return NOT_COMPILED_IN; + } +#endif + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + mxq_rc = MXQ_Build_EC_Cert(certdata, &certdatalen, key_type, keyparam, + keycomplen, totalkeylen, pk_offset, + p_cert->certBegin, + (p_cert->sigIndex - p_cert->certBegin), + p_cert->maxIdx, sign_algo, ROOT_CA_CERT_OBJ_ID, + MXQ_KEYUSE_VERIFY_KEY_CERT, ALGO_ECDSA_SHA_any, + MXQ_KEYUSE_DATASIGNATURE, ALGO_ECDSA_SHA_any, + (mxq_u1 *)p_cert->source); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_Build_EC_Cert() failed"); + wolfSSL_CryptHwMutexUnLock(); + return WC_HW_E; + } + +#if defined(WOLFSSL_MAXQ108X) + if (tls13_server_cert_id == -1) { + tls13_server_cert_id = alloc_temp_key_id(); + if (tls13_server_cert_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + wolfSSL_CryptHwMutexUnLock(); + return WC_HW_E; + } + } + + /* temporary certificate stored in object id cert_id */ + mxq_rc = MXQ_ImportChildCert(tls13_server_cert_id, certdata, certdatalen); +#else + /* temporary certificate stored in object id 0 */ + mxq_rc = MXQ_ImportChildCert(0, certdata, certdatalen); +#endif + + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_ImportChildCert() failed"); + wolfSSL_CryptHwMutexUnLock(); + return WC_HW_E; + } + + wolfSSL_CryptHwMutexUnLock(); + return 0; +} + +static int maxq10xx_process_server_sig_kex(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) +{ + int rc; + mxq_err_t mxq_rc; + if (ssl->specs.kea != ecc_diffie_hellman_kea) { + WOLFSSL_MSG("MAXQ: key exchange algo not supported"); + return NOT_COMPILED_IN; + } + + if (ssl->ecdhCurveOID != ECC_SECP256R1_OID) { + WOLFSSL_MSG("MAXQ: key curve not supported"); + return NOT_COMPILED_IN; + } + + if (p_sig_algo != ecc_dsa_sa_algo) { + WOLFSSL_MSG("MAXQ: signature algo not supported"); + return NOT_COMPILED_IN; + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + /* NOTE: this function also does verification of the signature as well! */ + mxq_rc = MXQ_SetECDHEKey(ALGO_ECDSA_SHA_256, MXQ_KEYPARAM_EC_P256R1, 0, + (mxq_u1 *)p_rand, p_rand_len, + (mxq_u1 *)p_server_params, p_server_params_len, + (mxq_u1 *)p_sig, p_sig_len); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_SetECDHEKey() failed"); + wolfSSL_CryptHwMutexUnLock(); + return WC_HW_E; + } + + wolfSSL_CryptHwMutexUnLock(); + return 0; +} + +static int maxq10xx_gen_tls_master_secret(WOLFSSL* ssl, void *ctx) +{ + int rc; + mxq_err_t mxq_rc; + mxq_secret_context_api_t secret_conf; + mxq_u1 tls_rand[SEED_LEN]; + (void)ctx; + + if ((ssl->specs.kea != ecc_diffie_hellman_kea) && + (ssl->specs.kea != psk_kea)) { + WOLFSSL_MSG("MAXQ: key exchange algo not supported"); + return NOT_COMPILED_IN; + } + + if (ssl->specs.kea == ecc_diffie_hellman_kea) { + if ((ssl->hsKey == NULL ) || + (((ecc_key*)ssl->hsKey)->maxq_ctx.hw_storage == 0)) { + return NOT_COMPILED_IN; + } + } + + XMEMCPY(tls_rand, ssl->arrays->clientRandom, RAN_LEN); + XMEMCPY(&tls_rand[RAN_LEN], ssl->arrays->serverRandom, RAN_LEN); + + XMEMSET(&secret_conf, 0 ,sizeof(secret_conf)); + secret_conf.pass = 0; + secret_conf.CSID = ssl->options.cipherSuite | + (ssl->options.cipherSuite0 << 8); + secret_conf.Random = tls_rand; + secret_conf.Random_size = SEED_LEN; + secret_conf.is_session_key_secret = 1; + if (ssl->specs.kea == psk_kea) { + secret_conf.PSK_info.psk_id = PSK_OBJ_ID; + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + mxq_rc = MXQ_Perform_Key_Exchange(&secret_conf); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_Perform_Key_Exchange() failed"); + wolfSSL_CryptHwMutexUnLock(); + return WC_HW_E; + } + + ssl->maxq_ctx.use_hw_keys = 1; + wolfSSL_CryptHwMutexUnLock(); + +#ifdef MAXQ_EXPORT_TLS_KEYS + rc = StoreKeys(ssl, secret_conf.PSK_info.psk_key_bloc, + PROVISION_CLIENT_SERVER); + if (rc != 0) { + WOLFSSL_ERROR_MSG("MAXQ: StoreKeys() failed"); + return rc; + } +#endif + + return 0; +} + +static int maxq10xx_perform_client_finished(WOLFSSL* ssl, const byte* p_label, + const byte* p_seed, word32 seedSz, byte* p_dest, void* ctx) +{ + int rc; + mxq_err_t mxq_rc; + (void)ssl; + (void)ctx; + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + mxq_rc = MXQ_tls_prf_sha_256(0, p_label, FINISHED_LABEL_SZ, + p_seed, seedSz, + p_dest, TLS_FINISHED_SZ); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_tls_prf_sha_256() failed"); + wolfSSL_CryptHwMutexUnLock(); + return WC_HW_E; + } + + wolfSSL_CryptHwMutexUnLock(); + return 0; +} + +static int maxq10xx_perform_tls12_record_processing(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) +{ + int rc; + mxq_err_t mxq_rc; + mxq_u2 key_id = (is_encrypt == 1) ? 1 : 0; + mxq_algo_id_t algo_id = 0; + + if (! ssl->maxq_ctx.use_hw_keys) { + return NOT_COMPILED_IN; + } + + if ((ssl->specs.bulk_cipher_algorithm != wolfssl_aes_gcm) && + (ssl->specs.bulk_cipher_algorithm != wolfssl_aes_ccm)) { + WOLFSSL_MSG("MAXQ: tls record cipher algo not supported"); + return NOT_COMPILED_IN; + } + + if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) { + algo_id = ALGO_CIPHER_AES_GCM; + } + else if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm) { + algo_id = ALGO_CIPHER_AES_CCM; + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + mxq_rc = maxq10xx_cipher_do(algo_id, is_encrypt, key_id, (mxq_u1 *)in, + out, sz, (mxq_u1 *)iv, ivSz, + (mxq_u1 *)authIn, authInSz, authTag, authTagSz); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: maxq10xx_cipher_do() failed"); + wolfSSL_CryptHwMutexUnLock(); + return WC_HW_E; + } + + wolfSSL_CryptHwMutexUnLock(); + return 0; +} + +static int maxq10xx_read_device_cert_der(byte* p_dest_buff, word32* p_len) +{ + int rc; + mxq_err_t mxq_rc; + word32 cert_size = 0; + +#if defined(WOLFSSL_MAXQ108X) + DecodedCert decoded; + mxq_keyparam_id_t keyparam = MXQ_KEYPARAM_EC_P256R1; + int pk_offset = 0; +#endif + + WOLFSSL_ENTER("maxq10xx_read_device_cert_der()"); + if (!p_dest_buff || !p_len) { + return BAD_FUNC_ARG; + } + + if (*p_len < 1024) { + WOLFSSL_ERROR_MSG("MAXQ: insufficient buffer length"); + return BAD_FUNC_ARG; + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + mxq_rc = MXQ_ReadObject(DEVICE_CERT_OBJ_ID, 24, p_dest_buff, p_len); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_ReadObject() failed"); + wolfSSL_CryptHwMutexUnLock(); + return WC_HW_E; + } + wolfSSL_CryptHwMutexUnLock(); + +#if defined(WOLFSSL_MAXQ108X) + wc_InitDecodedCert(&decoded, p_dest_buff, *p_len, NULL); + wc_ParseCert(&decoded, CERT_TYPE, NO_VERIFY, NULL); + pk_offset = decoded.publicKeyIndex; + if (decoded.keyOID == ECDSAk ) { + keyparam = maxq_curve_wolfssl_id2mxq_id(decoded.pkCurveOID, + (unsigned int *)&device_key_len); + if (keyparam == MXQ_UNKNOWN_CURVE) { + WOLFSSL_MSG("MAXQ: key curve not supported"); + return NOT_COMPILED_IN; + } + } + else if (decoded.keyOID == RSAk) { + pk_offset = calculate_modulus_offset(decoded.source, + decoded.publicKeyIndex+1); + device_key_len = ((decoded.source[pk_offset-2] << 8) | + decoded.source[pk_offset-1]); + } +#endif + + cert_size = (p_dest_buff[2] << 8) + p_dest_buff[3] + 4; + if (*p_len < cert_size) { + return BUFFER_E; + } + *p_len = cert_size; + return 0; +} + +#if defined(WOLFSSL_MAXQ10XX_TLS) +int wolfSSL_maxq10xx_load_certificate(WOLFSSL *ssl) { + DerBuffer* maxq_der = NULL; + int ret = 0; + + ret = AllocDer(&maxq_der, FILE_BUFFER_SIZE, CERT_TYPE, ssl->heap); + if (ret != 0) { + return ret; + } + + ret = maxq10xx_read_device_cert_der(maxq_der->buffer, + &maxq_der->length); + if (ret != 0) { + return ret; + } + + ssl->maxq_ctx.device_cert = maxq_der; + + if (ssl->buffers.weOwnCert) { + FreeDer(&ssl->buffers.certificate); + } + + ssl->buffers.certificate = maxq_der; + ssl->buffers.weOwnCert = 1; + return WOLFSSL_SUCCESS; +} +#endif /* WOLFSSL_MAXQ10XX_TLS */ + +static int maxq10xx_ecc_sign(WOLFSSL* ssl, + const unsigned char* p_in, unsigned int p_in_len, + unsigned char* p_out, word32* p_out_len, + const unsigned char* keyDer, unsigned int keySz, void* ctx) +{ + int rc; + (void)ssl; + (void)keyDer; + (void)keySz; + (void)ctx; + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + rc = maxq10xx_ecc_sign_local(DEVICE_KEY_PAIR_OBJ_ID, (byte *)p_in, p_in_len, + p_out, p_out_len, device_key_len); + + wolfSSL_CryptHwMutexUnLock(); + if (rc) { + WOLFSSL_ERROR_MSG("MAXQ: maxq10xx_ecc_sign() failed"); + return rc; + } + + return 0; +} +#endif /* WOLFSSL_MAXQ10XX_TLS */ + +int maxq10xx_port_init(void) +{ + int ret = 0; + mxq_err_t mxq_rc; + + #ifdef WOLF_CRYPTO_CB + ret = wc_CryptoCb_RegisterDevice(0, wolfSSL_Soft_CryptoDevCb, NULL); + if (ret != 0) { + WOLFSSL_ERROR_MSG("MAXQ: wolfSSL_Soft_CryptoDevCb, " + "wc_CryptoCb_RegisterDevice() failed"); + return ret; + } + #endif + + ret = maxq_CryptHwMutexTryLock(); + if (ret) { + WOLFSSL_ERROR_MSG("MAXQ: maxq10xx_port_init() -> device is busy " + "(switching to soft mode)"); + return 0; + } + + mxq_rc = MXQ_Module_Init(); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_Module_Init() failed"); + ret = WC_HW_E; + } + + wolfSSL_CryptHwMutexUnLock(); + + #if defined(WOLF_CRYPTO_CB) + if (ret == 0) { + ret = wc_CryptoCb_RegisterDevice(MAXQ_DEVICE_ID, + wolfSSL_MAXQ10XX_CryptoDevCb, NULL); + if (ret != 0) { + WOLFSSL_ERROR_MSG("MAXQ: wolfSSL_MAXQ10XX_CryptoDevCb, " + "wc_CryptoCb_RegisterDevice() failed"); + } + } + #endif + + return ret; +} + +/* This basically does all the work that SendClientKeyExchange() does in the + * case of ECDSA. That's because if a callback is defined, almost nothing is + * done in SendClientKeyExchange(). */ +static int maxq10xx_tls12_ecc_shared_secret(WOLFSSL* ssl, ecc_key* otherKey, + unsigned char* pubKeyDer, word32* pubKeySz, + unsigned char* out, word32* outlen, + int side, void* ctx) +{ + int rc; + mxq_err_t mxq_rc; + ecc_key *p_key = NULL; + mxq_length key_len_param; + mxq_u1* server_public_key_param; + mxq_u2 csid_param = ssl->options.cipherSuite | + (ssl->options.cipherSuite0 << 8); + byte result_public_key[1 + (2 * ECC256_KEYSIZE)]; + (void)ctx; + (void)otherKey; + (void)out; + (void)outlen; + (void)side; + + WOLFSSL_ENTER("maxq10xx_ecc_shared_secret()"); + + if (ssl->specs.kea != ecc_diffie_hellman_kea) { + WOLFSSL_MSG("MAXQ: key exchange algo not supported"); + return NOT_COMPILED_IN; + } + + if (ssl->ecdhCurveOID != ECC_SECP256R1_OID) { + WOLFSSL_MSG("MAXQ: key curve not supported"); + return NOT_COMPILED_IN; + } + + ssl->hsType = DYNAMIC_TYPE_ECC; + rc = AllocKey(ssl, ssl->hsType, &ssl->hsKey); + if (rc != 0) { + return rc; + } + + p_key = (ecc_key*)ssl->hsKey; + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + XMEMSET(result_public_key, 0, sizeof(result_public_key)); + + server_public_key_param = NULL; + key_len_param = sizeof(result_public_key); + + mxq_rc = MXQ_Ecdh_Compute_Shared(MXQ_KEYPARAM_EC_P256R1, + server_public_key_param, result_public_key, + key_len_param, csid_param); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_Ecdh_Compute_Shared() failed"); + wolfSSL_CryptHwMutexUnLock(); + return WC_HW_E; + } + + wolfSSL_CryptHwMutexUnLock(); + + /* client public key */ + p_key->state = 0; + + rc = wc_ecc_set_curve(p_key, ECC256_KEYSIZE, ECC_SECP256R1); + if (rc != 0) { + WOLFSSL_ERROR_MSG("MAXQ: wc_ecc_set_curve() failed"); + return rc; + } + + p_key->flags = WC_ECC_FLAG_NONE; + p_key->type = ECC_PUBLICKEY; + + rc = mp_read_unsigned_bin(p_key->pubkey.x, &result_public_key[1], + ECC256_KEYSIZE); + if (rc != 0) { + WOLFSSL_ERROR_MSG("MAXQ: mp_read_unsigned_bin() failed"); + return rc; + } + + rc = mp_read_unsigned_bin(p_key->pubkey.y, + &result_public_key[1 + ECC256_KEYSIZE], + ECC256_KEYSIZE); + if (rc != 0) { + WOLFSSL_ERROR_MSG("MAXQ: mp_read_unsigned_bin() failed"); + return rc; + } + + p_key->maxq_ctx.hw_storage = 1; + + PRIVATE_KEY_UNLOCK(); + rc = wc_ecc_export_x963(p_key, pubKeyDer, pubKeySz); + PRIVATE_KEY_LOCK(); + + return rc; +} + +#ifdef WOLFSSL_MAXQ108X +static int wc_MAXQ10XX_HmacSetKey(int type) +{ + mxq_algo_id_t algo; + int rc; + mxq_err_t mxq_rc; + + if (!tls13active) { + return NOT_COMPILED_IN; + } + + if (type == WC_SHA256) { + algo = ALGO_HMAC_SHA256; + } + else if (type == WC_SHA384) { + algo = ALGO_HMAC_SHA384; + } + else { + return NOT_COMPILED_IN; + } + + if (tls13_server_finish_obj_id != -1) { + free_temp_key_id(*tls13_server_key_id); + *tls13_server_key_id = -1; + mac_key_obj_id = &tls13_server_finish_obj_id; + } + else if (tls13_client_finish_obj_id != -1) { + mac_key_obj_id = &tls13_client_finish_obj_id; + } + + if (mac_key_obj_id == NULL) { + WOLFSSL_MSG("MAXQ: wc_MAXQ10XX_HmacSetKey No MAC Key is set"); + return NOT_COMPILED_IN; + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + mxq_rc = MXQ_MAC_Init(0x02, algo, *mac_key_obj_id, NULL, 0); + wolfSSL_CryptHwMutexUnLock(); + + if (mxq_rc == 0) { + mac_comp_active = 1; + } + else { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_MAC_Init() failed"); + rc = WC_HW_E; + } + + return rc; +} + +static int wc_MAXQ10XX_HmacUpdate(const byte* msg, word32 length) +{ + int rc; + mxq_err_t mxq_rc; + if (!tls13active || !mac_comp_active) { + return NOT_COMPILED_IN; + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + mxq_rc = MXQ_MAC_Update((unsigned char *)msg, length); + wolfSSL_CryptHwMutexUnLock(); + + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_MAC_Update() failed"); + rc = WC_HW_E; + } + + return rc; +} + +static int wc_MAXQ10XX_HmacFinal(byte* hash) +{ + int rc; + mxq_err_t mxq_rc; + mxq_length maclen = 64; + if (!tls13active || !mac_comp_active) { + return NOT_COMPILED_IN; + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + mxq_rc = MXQ_MAC_Finish(hash, &maclen); + wolfSSL_CryptHwMutexUnLock(); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_MAC_Finish() failed"); + rc = WC_HW_E; + } + + free_temp_key_id(*mac_key_obj_id); + *mac_key_obj_id = -1; + mac_key_obj_id = NULL; + mac_comp_active = 0; + + return rc; +} + +static int maxq10xx_create_dh_key(byte* p, word32 pSz, byte* g, word32 gSz, + byte* pub, word32* pubSz) +{ + int rc; + mxq_err_t mxq_rc; + + WOLFSSL_ENTER("maxq10xx_create_dh_key()"); + if (!tls13active) { + return NOT_COMPILED_IN; + } + + *pubSz = pSz; + if (tls13_dh_obj_id == -1) { + tls13_dh_obj_id = alloc_temp_key_id(); + if (tls13_dh_obj_id == -1) { + WOLFSSL_MSG("MAXQ: alloc_temp_key_id() failed"); + rc = NOT_COMPILED_IN; + return rc; + } + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + mxq_rc = MXQ_TLS13_Generate_Key(pub, tls13_dh_obj_id, 0, MXQ_KEYPARAM_DHE, + pSz, p, gSz, g); + + wolfSSL_CryptHwMutexUnLock(); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_TLS13_Generate_Key() failed"); + rc = WC_HW_E; + } + + return rc; +} + +static int maxq10xx_dh_gen_key_pair(DhKey* key, WC_RNG* rng, + byte* priv, word32* privSz, + byte* pub, word32* pubSz) { + word32 p_size, g_size; + unsigned char pbuf[256], gbuf[4]; + (void)rng; + (void)priv; + (void)privSz; + + p_size = mp_unsigned_bin_size(&key->p); + mp_to_unsigned_bin(&key->p, pbuf); + + g_size = mp_unsigned_bin_size(&key->g); + mp_to_unsigned_bin(&key->g, gbuf); + + return maxq10xx_create_dh_key(pbuf, p_size, gbuf, g_size, pub, pubSz); +} + +static int maxq10xx_dh_agree(WOLFSSL* ssl, struct DhKey* key, + const unsigned char* priv, unsigned int privSz, + const unsigned char* pubKeyDer, unsigned int pubKeySz, + unsigned char* out, unsigned int* outlen, + void* ctx) +{ + int rc; + mxq_err_t mxq_rc; + (void)ctx; + (void)key; + (void)priv; + (void)privSz; + + WOLFSSL_ENTER("maxq10xx_dh_agree()"); + + mxq_u2 csid_param = ssl->options.cipherSuite | + (ssl->options.cipherSuite0 << 8); + + if (tls13_dh_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: DH key is not created before"); + rc = NOT_COMPILED_IN; + return rc; + } + + if (tls13_shared_secret_obj_id == -1) { + tls13_shared_secret_obj_id = alloc_temp_key_id(); + if (tls13_shared_secret_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + mxq_rc = MXQ_TLS13_Create_Secret((unsigned char*)pubKeyDer, pubKeySz, + tls13_dh_obj_id, 0, MXQ_KEYPARAM_DHE, + csid_param, tls13_shared_secret_obj_id, + out, outlen); + wolfSSL_CryptHwMutexUnLock(); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: wolfSSL_CryptHwMutexUnLock() failed"); + rc = WC_HW_E; + } + + *outlen = pubKeySz; + free_temp_key_id(tls13_dh_obj_id); + tls13_dh_obj_id = -1; + free_temp_key_id(tls13_ecc_obj_id); + tls13_ecc_obj_id = -1; + + return rc; +} + +static int maxq10xx_ecc_key_gen(WOLFSSL* ssl, ecc_key* key, word32 keySz, + int ecc_curve, void* ctx) +{ + int rc; + mxq_err_t mxq_rc; + unsigned char mxq_key[MAX_EC_KEY_SIZE]; + (void)ctx; + (void)ssl; + + WOLFSSL_ENTER("maxq10xx_ecc_key_gen()"); + + if (tls13_ecc_obj_id == -1) { + tls13_ecc_obj_id = alloc_temp_key_id(); + if (tls13_ecc_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + rc = NOT_COMPILED_IN; + return rc; + } + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + mxq_rc = MXQ_TLS13_Generate_Key(mxq_key, tls13_ecc_obj_id, MXQ_KEYTYPE_ECC, + getMaxqKeyParamFromCurve(key->dp->id), + keySz, NULL, 0, NULL); + + wolfSSL_CryptHwMutexUnLock(); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_TLS13_Generate_Key() failed"); + return WC_HW_E; + } + + rc = wc_ecc_import_unsigned(key, (byte*)mxq_key, (byte*)mxq_key + keySz, + NULL, ecc_curve); + if (rc) { + WOLFSSL_ERROR_MSG("MAXQ: wc_ecc_import_raw_ex() failed"); + } + + return rc; +} + +static int maxq10xx_ecc_verify(WOLFSSL* ssl, const byte* sig, + word32 sigSz, const byte* hash, + word32 hashSz, const byte* key, + word32 keySz, int* result, void* ctx) +{ + int rc; + (void)ssl; + (void)key; + (void)keySz; + (void)ctx; + + WOLFSSL_ENTER("maxq10xx_ecc_verify()"); + + if (!tls13active) { + return CRYPTOCB_UNAVAILABLE; + } + + if (tls13_server_key_algo != ECDSAk) { + return CRYPTOCB_UNAVAILABLE; + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + rc = maxq10xx_ecc_verify_local(tls13_server_cert_id, (mxq_u1*)hash, hashSz, + (mxq_u1*)sig, sigSz, + result, tls13_server_key_len); + wolfSSL_CryptHwMutexUnLock(); + + return rc; +} + +static int maxq10xx_tls13_ecc_shared_secret(WOLFSSL* ssl, ecc_key* otherKey, + unsigned char* pubKeyDer, word32* pubKeySz, + unsigned char* out, word32* outlen, + int side, void* ctx) +{ + int rc; + mxq_err_t mxq_rc; + word32 peerKeySz = otherKey->dp->size; + uint8_t peerKeyBuf[MAX_EC_KEY_SIZE]; + uint8_t* peerKey = peerKeyBuf; + uint8_t* qx = peerKey; + uint8_t* qy = &peerKey[peerKeySz]; + word32 qxLen = peerKeySz, qyLen = peerKeySz; + mxq_u2 csid_param = ssl->options.cipherSuite | + (ssl->options.cipherSuite0 << 8); + (void)ctx; + (void)pubKeyDer; + (void)side; + (void)pubKeySz; + + WOLFSSL_ENTER("maxq10xx_ecc_shared_secret()"); + + rc = wc_ecc_export_public_raw(otherKey, qx, &qxLen, qy, &qyLen); + + if (tls13_ecc_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: ECDHE key is not created before"); + rc = NOT_COMPILED_IN; + return rc; + } + + if (tls13_shared_secret_obj_id == -1) { + tls13_shared_secret_obj_id = alloc_temp_key_id(); + if (tls13_shared_secret_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + mxq_rc = MXQ_TLS13_Create_Secret(peerKey, (2*peerKeySz), tls13_ecc_obj_id, + MXQ_KEYTYPE_ECC, + getMaxqKeyParamFromCurve(otherKey->dp->id), + csid_param, tls13_shared_secret_obj_id, + out, outlen); + + wolfSSL_CryptHwMutexUnLock(); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_TLS13_Create_Secret() failed"); + rc = WC_HW_E; + } + + *outlen = otherKey->dp->size; + free_temp_key_id(tls13_dh_obj_id); + tls13_dh_obj_id = -1; + free_temp_key_id(tls13_ecc_obj_id); + tls13_ecc_obj_id = -1; + + return rc; +} + +static int maxq10xx_rsa_pss_verify_ex(WOLFSSL* ssl, + byte* hashed_msg, word32 hashed_msg_sz, + byte* pss_sign, word32 pss_signlen, + int isCertId) +{ + mxq_u2 pubkey_objectid; + int ret; + mxq_err_t mxq_rc; + (void)ssl; + + WOLFSSL_ENTER("maxq10xx_rsa_pss_verify_ex"); + + if (!tls13active) { + return NOT_COMPILED_IN; + } + + if (isCertId) { + pubkey_objectid = tls13_server_cert_id; + } + else { + pubkey_objectid = DEVICE_KEY_PAIR_OBJ_ID; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret != 0) { + return ret; + } + mxq_rc = MXQ_Verify(ALGO_RSASSAPSSPKCS1_V2_1_PLAIN, pubkey_objectid, + hashed_msg, hashed_msg_sz, pss_sign, pss_signlen); + + wolfSSL_CryptHwMutexUnLock(); + + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_Verify() failed"); + ret = WC_HW_E; + } + return ret; +} + +/* This will do all the work that is normally done in RsaVerify() and + * CheckRSASignature(). That is why at the bottom, we release the key. Because + * verification has been completed and CheckRSASignature() should be skipped. + * The same reasoning for maxq10xx_RsaSkipSignCheck() doing nothing. */ +static int maxq10xx_rsa_pss_verify(WOLFSSL* ssl, + unsigned char* in, unsigned int inSz, + unsigned char** out, int hash, int mgf, + const unsigned char* key, unsigned int keySz, + void* ctx) { + int ret = 0; + byte sigData[MAX_SIG_DATA_SZ]; + word16 sigDataSz; + word32 sigSz; + (void)out; + (void)mgf; + (void)key; + (void)keySz; + (void)ctx; + + if (hash == SHA256h) { + hash = sha256_mac; + } + else if (hash == SHA384h) { + hash = sha384_mac; + } + else if (hash == SHA512h) { + hash = sha512_mac; + } + else { + return BAD_FUNC_ARG; + } + + ret = CreateSigData(ssl, sigData, &sigDataSz, 1); + if (ret != 0) + return ret; + + /* PSS signature can be done in-place */ + ret = CreateRSAEncodedSig(sigData, sigData, sigDataSz, + rsa_pss_sa_algo, hash); + if (ret < 0) + return ret; + sigSz = ret; + + ret = maxq10xx_rsa_pss_verify_ex(ssl, sigData, sigSz, in, inSz, 1); + + if (ret == 0) { + /* This ensures call to CheckRSASignature() is skipped. */ + ssl->peerRsaKeyPresent = 0; + FreeKey(ssl, DYNAMIC_TYPE_RSA, (void**)&ssl->peerRsaKey); + ssl->options.peerAuthGood = 1; + } + + return ret; +} + +static int maxq10xx_skip_sign_check(WOLFSSL* ssl, + unsigned char* sig, unsigned int sigSz, + unsigned char** out, int hash, int mgf, + const unsigned char* key, unsigned int keySz, + void* ctx) { + (void)ssl; + (void)sig; + (void)sigSz; + (void)out; + (void)hash; + (void)mgf; + (void)key; + (void)keySz; + (void)ctx; + return 0; +} + +static int maxq10xx_rsa_pss_sign(WOLFSSL* ssl, const byte* in, word32 inSz, + byte* out, word32* outSz, int hash, int mgf, + const byte* key, word32 keySz, void* ctx) +{ + int ret; + mxq_err_t mxq_rc; + (void)ssl; + (void)hash; + (void)mgf; + (void)key; + (void)keySz; + (void)ctx; + + WOLFSSL_ENTER("maxq10xx_rsa_pss_sign"); + + if (!tls13active) { + return NOT_COMPILED_IN; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret != 0) { + return ret; + } + + mxq_rc = MXQ_Sign(ALGO_RSASSAPSSPKCS1_V2_1_PLAIN, DEVICE_KEY_PAIR_OBJ_ID, + in, inSz, out, outSz); + + wolfSSL_CryptHwMutexUnLock(); + + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_Sign() failed"); + return WC_HW_E; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret != 0) { + return ret; + } + + mxq_rc = MXQ_Verify(ALGO_RSASSAPSSPKCS1_V2_1_PLAIN, DEVICE_KEY_PAIR_OBJ_ID, + in, inSz, out, *outSz); + + wolfSSL_CryptHwMutexUnLock(); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_Verify() failed"); + return WC_HW_E; + } + + return ret; +} + +#ifdef HAVE_HKDF +static int maxq10xx_hkdf_extract(byte* prk, const byte* salt, word32 saltLen, + byte* ikm, word32 ikmLen, int digest, void* ctx) +{ + int rc; + mxq_err_t mxq_rc; + mxq_length prk_len = 0; + mxq_algo_id_t mxq_digest_id = ALGO_INVALID; + int salt_kid = -1, ikm_kid = -1, ret_kid = -1; + + (void)ctx; + + switch (digest) { + #ifndef NO_SHA256 + case WC_SHA256: + prk_len = WC_SHA256_DIGEST_SIZE; + mxq_digest_id = ALGO_MD_SHA256; + break; + #endif + + #ifdef WOLFSSL_SHA384 + case WC_SHA384: + prk_len = WC_SHA384_DIGEST_SIZE; + mxq_digest_id = ALGO_MD_SHA384; + break; + #endif + + #ifdef WOLFSSL_TLS13_SHA512 + case WC_SHA512: + prk_len = WC_SHA512_DIGEST_SIZE; + mxq_digest_id = ALGO_MD_SHA512; + break; + #endif + default: + return BAD_FUNC_ARG; + } + + /* Prepare key id parameters */ + if (saltLen != 0 && ikmLen != 0) { + /* handshake_secret = HKDF-Extract(salt: derived_secret, + * key: shared_secret) */ + if (tls13_handshake_secret_obj_id == -1) { + tls13_handshake_secret_obj_id = alloc_temp_key_id(); + if (tls13_handshake_secret_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + salt_kid = tls13_derived_secret_obj_id; + ikm_kid = tls13_shared_secret_obj_id; + ret_kid = tls13_handshake_secret_obj_id; + free_temp_key_id(tls13_derived_secret_obj_id); + tls13_derived_secret_obj_id = -1; + } + else if (saltLen != 0 && ikmLen == 0) { + /* master_secret = HKDF-Extract(salt: derived_secret, + * key: 00...) */ + if (tls13_master_secret_obj_id == -1) { + tls13_master_secret_obj_id = alloc_temp_key_id(); + if (tls13_master_secret_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + + salt_kid = tls13_derived_secret_obj_id; + ikm_kid = -1; + ret_kid = tls13_master_secret_obj_id; + free_temp_key_id(tls13_derived_secret_obj_id); + tls13_derived_secret_obj_id = -1; + } + else if (saltLen == 0 && ikmLen == 0) { + /* early_secret = HKDF-Extract(salt: 00, key: 00...) */ + if (tls13_early_secret_obj_id == -1) { + tls13_early_secret_obj_id = alloc_temp_key_id(); + if (tls13_early_secret_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + + salt_kid = -1; + ikm_kid = -1; + ret_kid = tls13_early_secret_obj_id; + + tls13early = 1; + } + else if (saltLen == 0 && ikmLen != 0) { + /* early_secret = HKDF-Extract(salt: 00, key: 00...) */ + if (tls13_hs_early_secret_obj_id == -1) { + tls13_hs_early_secret_obj_id = alloc_temp_key_id(); + if (tls13_hs_early_secret_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + + salt_kid = -1; + ikm_kid = PSK_KID; + ret_kid = tls13_hs_early_secret_obj_id; + + tls13early = 1; + } + else { + WOLFSSL_MSG("MAXQ: MXQ_TLS13_Extract_Secret() does not support"); + return NOT_COMPILED_IN; + } + + /* When length is 0 then use zeroed data of digest length. */ + if (ikmLen == 0) { + ikmLen = prk_len; + XMEMSET(ikm, 0, prk_len); + } + + if (salt_kid != -1) { + saltLen = 0; + } + + if (ikm_kid != -1) { + ikmLen = 0; + } + + if (ret_kid != -1) { + XMEMSET(prk, 0, prk_len); + prk_len = 0; + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + mxq_rc = MXQ_TLS13_Extract_Secret(mxq_digest_id, (mxq_u2)ret_kid, + prk, &prk_len, (mxq_u2)salt_kid, + salt, (mxq_u2)saltLen, + (mxq_u2)ikm_kid, ikm, (mxq_u2)ikmLen); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_TLS13_Extract_Secret() failed"); + wolfSSL_CryptHwMutexUnLock(); + return WC_HW_E; + } + + wolfSSL_CryptHwMutexUnLock(); + return 0; +} + +static char *strstr_with_size(char *str, const char *substr, size_t n) +{ + char *p = str, *pEnd = str + n; + size_t substr_len = XSTRLEN(substr); + + if (substr_len == 0) { + return str; + } + + pEnd -= (substr_len - 1); + + for (;p < pEnd; ++p) { + if (0 == XSTRNCMP(p, substr, substr_len)) + return p; + } + + return NULL; +} + +static int maxq10xx_HkdfExpand(int digest, const byte* inKey, word32 inKeySz, + const byte* info, word32 infoSz, byte* out, + word32 outSz, int side) +{ + int rc; + mxq_err_t mxq_rc; + mxq_algo_id_t mxq_digest_id = ALGO_INVALID; + mxq_keytype_id_t ret_keytype = MXQ_KEYTYPE_IKM; + int prk_kid = -1, ret_kid = -1; + int ret_isiv = 0; + + switch (digest) { + #ifndef NO_SHA256 + case WC_SHA256: + mxq_digest_id = ALGO_MD_SHA256; + break; + #endif + + #ifdef WOLFSSL_SHA384 + case WC_SHA384: + mxq_digest_id = ALGO_MD_SHA384; + break; + #endif + + #ifdef WOLFSSL_TLS13_SHA512 + case WC_SHA512: + mxq_digest_id = ALGO_MD_SHA512; + break; + #endif + default: + return BAD_FUNC_ARG; + } + + /* Prepare key id parameters */ + if (strstr_with_size((char *)info, derivedLabel, infoSz) != NULL) { + if (tls13early) { + if (local_is_psk) { + if (tls13_hs_early_secret_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: Handshake early secret is not " + "created yet"); + return NOT_COMPILED_IN; + } + + tls13_derived_secret_obj_id = alloc_temp_key_id(); + if (tls13_derived_secret_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + prk_kid = tls13_hs_early_secret_obj_id; + ret_kid = tls13_derived_secret_obj_id; + ret_keytype = MXQ_KEYTYPE_IKM; + free_temp_key_id(tls13_hs_early_secret_obj_id); + tls13_hs_early_secret_obj_id = -1; + } + else { + /* derived_secret = HKDF-Expand-Label(key: early_secret, + * label: "derived", ctx: empty_hash) */ + tls13_derived_secret_obj_id = alloc_temp_key_id(); + if (tls13_derived_secret_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + + prk_kid = tls13_early_secret_obj_id; + ret_kid = tls13_derived_secret_obj_id; + ret_keytype = MXQ_KEYTYPE_IKM; + free_temp_key_id(tls13_early_secret_obj_id); + tls13_early_secret_obj_id = -1; + } + ret_isiv = 0; + tls13early = 0; + } + else { + /* derived_secret = HKDF-Expand-Label(key: handshake_secret, + * label: "derived", ctx: empty_hash) */ + tls13_derived_secret_obj_id = alloc_temp_key_id(); + if (tls13_derived_secret_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + + prk_kid = tls13_handshake_secret_obj_id; + ret_kid = tls13_derived_secret_obj_id; + ret_keytype = MXQ_KEYTYPE_IKM; + free_temp_key_id(tls13_handshake_secret_obj_id); + tls13_handshake_secret_obj_id = -1; + ret_isiv = 0; + } + } + else if (strstr_with_size((char *)info, cHsTrafficLabel, infoSz) + != NULL) { + is_hs_key = 1; + /* client_secret = HKDF-Expand-Label(key: handshake_secret, + * label: "c hs traffic", ctx: hello_hash) */ + if (tls13_client_secret_obj_id == -1) { + tls13_client_secret_obj_id = alloc_temp_key_id(); + if (tls13_client_secret_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + + prk_kid = tls13_handshake_secret_obj_id; + ret_kid = tls13_client_secret_obj_id; + ret_keytype = MXQ_KEYTYPE_IKM; + ret_isiv = 0; + } + else if (strstr_with_size((char *)info, sHsTrafficLabel, infoSz) + != NULL) { + /* client_secret = HKDF-Expand-Label(key: handshake_secret, + * label: "s hs traffic", ctx: hello_hash) */ + if (tls13_server_secret_obj_id == -1) { + tls13_server_secret_obj_id = alloc_temp_key_id(); + if (tls13_server_secret_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + + prk_kid = tls13_handshake_secret_obj_id; + ret_kid = tls13_server_secret_obj_id; + ret_keytype = MXQ_KEYTYPE_IKM; + ret_isiv = 0; + } + else if (strstr_with_size((char *)info, cAppTrafficLabel, infoSz) + != NULL) { + is_hs_key = 0; + /* client_secret = HKDF-Expand-Label(key: master_secret, + * label: "c ap traffic", ctx: handshake_hash) */ + if (tls13_client_secret_obj_id == -1) { + tls13_client_secret_obj_id = alloc_temp_key_id(); + if (tls13_client_secret_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + + prk_kid = tls13_master_secret_obj_id; + ret_kid = tls13_client_secret_obj_id; + ret_keytype = MXQ_KEYTYPE_IKM; + ret_isiv = 0; + } + else if (strstr_with_size((char *)info, sAppTrafficLabel, infoSz) + != NULL) { + /* server_secret = HKDF-Expand-Label(key: master_secret, + * label: "s ap traffic", ctx: handshake_hash) */ + tls13_server_secret_obj_id = alloc_temp_key_id(); + if (tls13_server_secret_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + + prk_kid = tls13_master_secret_obj_id; + ret_kid = tls13_server_secret_obj_id; + ret_keytype = MXQ_KEYTYPE_IKM; + ret_isiv = 0; + } + else if (strstr_with_size((char *)info, keyLabel, infoSz) != NULL) { + /* first client key then server */ + if (side == WOLFSSL_CLIENT_END) { + /* client_handshake_key = HKDF-Expand-Label(key: client_secret, + * label: "key", ctx: "") + * client_application_key = HKDF-Expand-Label(key: client_secret, + * label: "key", ctx: "") */ + int tls13_client_key_obj_id = -1; + if (is_hs_key) { + if (tls13_client_hs_key_obj_id == -1) { + tls13_client_hs_key_obj_id = alloc_temp_key_id(); + if (tls13_client_hs_key_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + tls13_client_key_obj_id = tls13_client_hs_key_obj_id; + } + else { + if (tls13_client_app_key_obj_id == -1) { + tls13_client_app_key_obj_id = alloc_temp_key_id(); + if (tls13_client_app_key_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + tls13_client_key_obj_id = tls13_client_app_key_obj_id; + } + + prk_kid = tls13_client_secret_obj_id; + ret_kid = tls13_client_key_obj_id; + ret_keytype = MXQ_KEYTYPE_AES; + ret_isiv = 0; + } + else { + /* server_handshake_key = HKDF-Expand-Label(key: server_secret, + * label: "key", ctx: "") + * server_application_key = HKDF-Expand-Label(key: server_secret, + label: "key", ctx: "") */ + int tls13_server_key_obj_id = -1; + if (is_hs_key) { + if (tls13_server_hs_key_obj_id == -1) { + tls13_server_hs_key_obj_id = alloc_temp_key_id(); + if (tls13_server_hs_key_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + tls13_server_key_obj_id = tls13_server_hs_key_obj_id; + } + else { + if (tls13_server_app_key_obj_id == -1) { + tls13_server_app_key_obj_id = alloc_temp_key_id(); + if (tls13_server_app_key_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + tls13_server_key_obj_id = tls13_server_app_key_obj_id; + } + + prk_kid = tls13_server_secret_obj_id; + ret_kid = tls13_server_key_obj_id; + ret_keytype = MXQ_KEYTYPE_AES; + ret_isiv = 0; + } + } + else if (strstr_with_size((char *)info, ivLabel, infoSz) != NULL) { + /* first client key then server */ + if (side == WOLFSSL_CLIENT_END) { + /* client_handshake_iv = HKDF-Expand-Label(key: client_secret, + * label: "iv", ctx: "") + * cient_application_iv = HKDF-Expand-Label(key: client_secret, + * label: "iv", ctx: "") */ + int tls13_client_iv_obj_id = -1; + if (is_hs_key) { + if (tls13_client_hs_key_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + tls13_client_iv_obj_id = tls13_client_hs_key_obj_id; + } + else { + if (tls13_client_app_key_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + tls13_client_iv_obj_id = tls13_client_app_key_obj_id; + } + + prk_kid = tls13_client_secret_obj_id; + ret_kid = tls13_client_iv_obj_id; + ret_keytype = MXQ_KEYTYPE_AES; + ret_isiv = 1; + } + else { + /* server_handshake_iv = HKDF-Expand-Label(key: server_secret, + * label: "iv", ctx: "") + * server_application_iv = HKDF-Expand-Label(key: server_secret, + * label: "iv", ctx: "") */ + int tls13_server_iv_obj_id = -1; + if (is_hs_key) { + if (tls13_server_hs_key_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + tls13_server_iv_obj_id = tls13_server_hs_key_obj_id; + } + else { + if (tls13_server_app_key_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + tls13_server_iv_obj_id = tls13_server_app_key_obj_id; + } + + prk_kid = tls13_server_secret_obj_id; + ret_kid = tls13_server_iv_obj_id; + ret_keytype = MXQ_KEYTYPE_AES; + ret_isiv = 1; + local_is_psk = 0; + } + } + else if (strstr_with_size((char *)info, finishedLabel, infoSz) != NULL) { + if (local_is_psk) { + if (tls13_client_finish_obj_id == -1) { + tls13_client_finish_obj_id = alloc_temp_key_id(); + if (tls13_client_finish_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + if (tls13_binder_key_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: Binder key is not created yet"); + return NOT_COMPILED_IN; + } + prk_kid = tls13_binder_key_obj_id; + ret_kid = tls13_client_finish_obj_id; + tls13_client_key_id = &tls13_binder_key_obj_id; + ret_keytype = MXQ_KEYTYPE_HMAC; + ret_isiv = 0; + } + else { + /* first client key then server */ + if (side == WOLFSSL_CLIENT_END) { + /* finished_key = HKDF-Expand-Label(key: client_secret, + * label: "finished", ctx: "") */ + if (is_hs_key) { + tls13_client_key_id = &tls13_client_hs_key_obj_id; + } + else { + tls13_client_key_id = &tls13_client_app_key_obj_id; + } + if (tls13_client_finish_obj_id == -1) { + tls13_client_finish_obj_id = alloc_temp_key_id(); + if (tls13_client_finish_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + + prk_kid = tls13_client_secret_obj_id; + ret_kid = tls13_client_finish_obj_id; + + ret_keytype = MXQ_KEYTYPE_HMAC; + ret_isiv = 0; + free_temp_key_id(tls13_client_secret_obj_id); + tls13_client_secret_obj_id = -1; + + } + else { + /* finished_key = HKDF-Expand-Label(key: server_secret, + * label: "finished", ctx: "") */ + if (is_hs_key) { + tls13_server_key_id = &tls13_server_hs_key_obj_id; + } + else { + tls13_server_key_id = &tls13_server_app_key_obj_id; + } + if (tls13_server_finish_obj_id == -1) { + tls13_server_finish_obj_id = alloc_temp_key_id(); + if (tls13_server_finish_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + } + + prk_kid = tls13_server_secret_obj_id; + ret_kid = tls13_server_finish_obj_id; + ret_keytype = MXQ_KEYTYPE_HMAC; + ret_isiv = 0; + free_temp_key_id(tls13_server_secret_obj_id); + tls13_server_secret_obj_id = -1; + + } + } + } + else if (strstr_with_size((char *)info, extBinderLabel, infoSz) != NULL) { + + /* binder_key = HKDF-Expand-Label(key: hs_early_secret, + * label: "ext binder", ctx: empty_hash) */ + tls13_binder_key_obj_id = alloc_temp_key_id(); + if (tls13_binder_key_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + + prk_kid = tls13_hs_early_secret_obj_id; + ret_kid = tls13_binder_key_obj_id; + ret_keytype = MXQ_KEYTYPE_IKM; + ret_isiv = 0; + local_is_psk = 1; + + } + else if (strstr_with_size((char *)info, resMasterLabel, infoSz) != NULL) { + /* TODO: */ + tls13_res_master_obj_id = alloc_temp_key_id(); + if (tls13_res_master_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: alloc_temp_key_id() failed"); + return NOT_COMPILED_IN; + } + prk_kid = tls13_master_secret_obj_id; + ret_kid = tls13_res_master_obj_id; + ret_keytype = MXQ_KEYTYPE_IKM; + ret_isiv = 0; + free_temp_key_id(*tls13_client_key_id); + *tls13_client_key_id = -1; + } + else if (strstr_with_size((char *)info, appTrafUpdLabel, infoSz) != NULL) { + if (side == WOLFSSL_CLIENT_END) { + /* updated_client_secret = HKDF-Expand-Label(key: client_secret, + * label: "traffic upd", ctx: "") */ + if (tls13_client_app_key_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: Client Application Key was not set"); + return NOT_COMPILED_IN; + } + prk_kid = tls13_client_secret_obj_id; + ret_kid = tls13_client_secret_obj_id; + ret_keytype = MXQ_KEYTYPE_IKM; + ret_isiv = 0; + } + else { + /* updated_server_secret = HKDF-Expand-Label(key: server_secret, + * label: "traffic upd", ctx: "") */ + if (tls13_server_app_key_obj_id == -1) { + WOLFSSL_ERROR_MSG("MAXQ: Client Application Key was not set"); + return NOT_COMPILED_IN; + } + prk_kid = tls13_server_secret_obj_id; + ret_kid = tls13_server_secret_obj_id; + ret_keytype = MXQ_KEYTYPE_IKM; + ret_isiv = 0; + } + } + else { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_TLS13_Expand_Secret() does not support"); + return NOT_COMPILED_IN; + } + + if (prk_kid != -1) { + inKeySz = 0; + } + + if (ret_kid != -1) { + XMEMSET(out, 0, outSz); + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + mxq_rc = MXQ_TLS13_Expand_Secret(mxq_digest_id, (mxq_u2)ret_kid, + ret_keytype, ret_isiv, out, &outSz, + (mxq_u2)prk_kid, inKey, inKeySz, + info, infoSz ); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_TLS13_Expand_Secret() failed"); + wolfSSL_CryptHwMutexUnLock(); + return WC_HW_E; + } + + wolfSSL_CryptHwMutexUnLock(); + return 0; +} + +static int maxq10xx_hkdf_expand_label(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) +{ + int ret = 0; + int idx = 0; + byte data[MAX_TLS13_HKDF_LABEL_SZ]; + + /* Output length. */ + data[idx++] = (byte)(okmLen >> 8); + data[idx++] = (byte)okmLen; + /* Length of protocol | label. */ + data[idx++] = (byte)(protocolLen + labelLen); + /* Protocol */ + XMEMCPY(&data[idx], protocol, protocolLen); + idx += protocolLen; + /* Label */ + XMEMCPY(&data[idx], label, labelLen); + idx += labelLen; + /* Length of hash of messages */ + data[idx++] = (byte)infoLen; + /* Hash of messages */ + XMEMCPY(&data[idx], info, infoLen); + idx += infoLen; + +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("wc_Tls13_HKDF_Expand_Label data", data, idx); +#endif + + ret = maxq10xx_HkdfExpand(digest, prk, prkLen, data, idx, okm, okmLen, + side); + ForceZero(data, idx); + +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(data, MAX_TLS13_HKDF_LABEL_SZ); +#endif + + return ret; +} + +static int maxq10xx_perform_tls13_record_processing(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) +{ + int rc; + mxq_err_t mxq_rc; + mxq_u2 key_id; + + if (!tls13active) { + return NOT_COMPILED_IN; + } + + if ((ssl->specs.bulk_cipher_algorithm != wolfssl_aes_gcm) && + (ssl->specs.bulk_cipher_algorithm != wolfssl_aes_ccm)) { + WOLFSSL_MSG("MAXQ: tls record cipher algo not supported"); + return NOT_COMPILED_IN; + } + + if (is_encrypt) { + if (tls13_client_hs_key_obj_id != -1) { + key_id = tls13_client_hs_key_obj_id; + } + else if (tls13_client_app_key_obj_id != -1) { + key_id = tls13_client_app_key_obj_id; + } + else { + WOLFSSL_ERROR_MSG("MAXQ: tls record enc key was not selected"); + } + } + else { + if (tls13_server_hs_key_obj_id != -1) { + key_id = tls13_server_hs_key_obj_id; + } + else if (tls13_server_app_key_obj_id != -1) { + key_id = tls13_server_app_key_obj_id; + } + else { + WOLFSSL_ERROR_MSG("MAXQ: tls record dec key was not selected"); + } + } + mxq_algo_id_t algo_id = 0; + + if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) { + algo_id = ALGO_CIPHER_AES_GCM; + } + else if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm) { + algo_id = ALGO_CIPHER_AES_CCM; + } + + rc = wolfSSL_CryptHwMutexLock(); + if (rc != 0) { + return rc; + } + + WOLFSSL_MSG("MAXQ: MXQ_TLS13_Update_IV()"); + mxq_rc = MXQ_TLS13_Update_IV( key_id, (mxq_u1 *)iv, ivSz); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: MXQ_TLS13_Update_IV() failed"); + wolfSSL_CryptHwMutexUnLock(); + return WC_HW_E; + } + + mxq_rc = maxq10xx_cipher_do(algo_id, is_encrypt, key_id, (mxq_u1 *)in, out, + sz, (mxq_u1 *)iv, ivSz, (mxq_u1 *)authIn, + authInSz, authTag, authTagSz); + if (mxq_rc) { + WOLFSSL_ERROR_MSG("MAXQ: maxq10xx_cipher_do() failed"); + wolfSSL_CryptHwMutexUnLock(); + return WC_HW_E; + } + + wolfSSL_CryptHwMutexUnLock(); + return 0; +} +#endif /* HAVE_HKDF */ +#endif /* WOLFSSL_MAXQ108X */ + +void maxq10xx_SetupPkCallbacks(struct WOLFSSL_CTX* ctx, ProtocolVersion *pv) +{ + (void)pv; + + if (pv == NULL) { + return; + } + + WOLFSSL_ENTER("maxq10xx_SetupPkCallbacks"); + if (init_pk_callbacks) { + return; + } + +#ifdef WOLFSSL_MAXQ108X + #ifdef HAVE_HKDF + wolfSSL_CTX_SetHKDFExtractCb(ctx, maxq10xx_hkdf_extract); + wolfSSL_CTX_SetHKDFExpandLabelCb(ctx, maxq10xx_hkdf_expand_label); + #endif + + if ((pv->major == SSLv3_MAJOR) && (pv->minor == WOLFSSL_TLSV1_3)) { + tls13active = 1; + wolfSSL_CTX_SetEccKeyGenCb(ctx, maxq10xx_ecc_key_gen); + wolfSSL_CTX_SetEccSharedSecretCb(ctx, maxq10xx_tls13_ecc_shared_secret); + wolfSSL_CTX_SetEccVerifyCb(ctx, maxq10xx_ecc_verify); + wolfSSL_CTX_SetDhGenerateKeyPair(ctx, maxq10xx_dh_gen_key_pair); + wolfSSL_CTX_SetDhAgreeCb(ctx, maxq10xx_dh_agree); + wolfSSL_CTX_SetRsaPssSignCb(ctx, maxq10xx_rsa_pss_sign); + wolfSSL_CTX_SetRsaPssSignCheckCb(ctx, maxq10xx_skip_sign_check); + wolfSSL_CTX_SetRsaPssVerifyCb(ctx, maxq10xx_rsa_pss_verify); + + wolfSSL_CTX_SetPerformTlsRecordProcessingCb(ctx, + maxq10xx_perform_tls13_record_processing); + } + else +#endif /* WOLFSSL_MAXQ108X */ + { + wolfSSL_CTX_SetEccSharedSecretCb(ctx, maxq10xx_tls12_ecc_shared_secret); + wolfSSL_CTX_SetPerformTlsRecordProcessingCb(ctx, + maxq10xx_perform_tls12_record_processing); + } + + wolfSSL_CTX_SetProcessPeerCertCb(ctx, maxq10xx_process_server_certificate); + wolfSSL_CTX_SetProcessServerSigKexCb(ctx, maxq10xx_process_server_sig_kex); + wolfSSL_CTX_SetGenMasterSecretCb(ctx, maxq10xx_gen_tls_master_secret); + wolfSSL_CTX_SetTlsFinishedCb(ctx, maxq10xx_perform_client_finished); + + wolfSSL_CTX_SetEccSignCb(ctx, maxq10xx_ecc_sign); + + init_pk_callbacks = 1; +} + +#endif /* WOLFSSL_MAXQ1065 || WOLFSSL_MAXQ108X */ diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 53621f5f5..d7dacf09e 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -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 diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 7b8febf51..c4ef4a15b 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -50,6 +50,10 @@ #include #endif +#ifdef MAXQ10XX_MODULE_INIT + #include +#endif + #if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A) || \ defined(WOLFSSL_ATECC608A) #include @@ -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) diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 1ed41618e..40ffd7c1f 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -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 diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index c0e27b301..5c9113d04 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -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 diff --git a/wolfssl/test.h b/wolfssl/test.h index e9024d511..8697c5866 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -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"); diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 637e50644..f2f83ec81 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -122,6 +122,10 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #include #endif +#ifdef WOLFSSL_MAXQ10XX_CRYPTO + #include +#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; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 2fc65981b..a9d48ea46 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -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; diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 1a080e6b7..a5949d791 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -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]; diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index 6b841d7cd..fa6c02340 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -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 diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 62bcd1311..fff6bbec7 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -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 diff --git a/wolfssl/wolfcrypt/port/maxim/maxq10xx.h b/wolfssl/wolfcrypt/port/maxim/maxq10xx.h new file mode 100644 index 000000000..8ec372cdb --- /dev/null +++ b/wolfssl/wolfcrypt/port/maxim/maxq10xx.h @@ -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 + +#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_ */ diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 64f654d0d..bcf19aa92 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.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 #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) || \ diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index b6f131995..66165a4be 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -157,6 +157,10 @@ enum { #include "wolfssl/wolfcrypt/port/nxp/se050_port.h" #endif +#ifdef WOLFSSL_MAXQ10XX_CRYPTO + #include +#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 diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index a5461d776..79cac76e9 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -217,6 +217,12 @@ } wolfSSL_Mutex; #elif defined(USE_WINDOWS_API) typedef CRITICAL_SECTION wolfSSL_Mutex; + #elif defined(MAXQ10XX_MUTEX) + #include + #include + #include + typedef pthread_mutex_t wolfSSL_Mutex; + int maxq_CryptHwMutexTryLock(void); #elif defined(WOLFSSL_PTHREADS) typedef pthread_mutex_t wolfSSL_Mutex; #elif defined(THREADX)