diff --git a/test-refactor/README.md b/test-refactor/README.md
index 8d1a0a52..34ab5cc5 100644
--- a/test-refactor/README.md
+++ b/test-refactor/README.md
@@ -73,7 +73,7 @@ Translated tests:
|---|---|---|---|
| `wh_test_dma.c::whTest_Dma` | `misc/wh_test_dma.c::whTest_Dma` | Misc | |
| `wh_test_cert.c::whTest_CertRamSim` | `server/wh_test_cert.c::whTest_CertVerify` | Server | remove ramsim coupling and migrate to server group |
-| `wh_test_crypto.c::whTest_Crypto` | `client-server/wh_test_crypto.c::{whTest_CryptoSha256, whTest_CryptoAes, whTest_CryptoEcc256}` | Client | Subset only; remaining cases listed below |
+| `wh_test_crypto.c::whTest_Crypto` | `client-server/wh_test_aes.c::whTest_CryptoAes`, `client-server/wh_test_sha.c::{whTest_CryptoSha224/256/384/512, ...LargeInput, ...Async, ...DmaAsync}` (16 functions), `client-server/wh_test_ecc.c::{whTest_CryptoEcc, whTest_CryptoEccCacheDuplicate, whTest_CryptoEccCrossVerify, whTest_CryptoEccAsync}`, `client-server/wh_test_curve25519.c::whTest_CryptoCurve25519`, `client-server/wh_test_ed25519.c::{whTest_CryptoEd25519Inline, whTest_CryptoEd25519ServerKey, whTest_CryptoEd25519Dma}`, `client-server/wh_test_mldsa.c::{whTestCrypto_MlDsaClient, whTestCrypto_MlDsaDmaClient, whTestCrypto_MlDsaVerifyOnlyDma}`, `client-server/wh_test_cmac.c::whTest_CryptoCmac`, `client-server/wh_test_keypolicy.c::{whTest_CryptoKeyUsagePolicies, whTest_CryptoKeyRevocationAesCbc}`, `client-server/wh_test_rng.c::{whTest_CryptoRng, whTest_CryptoRngAsync, whTest_CryptoRngDmaAsync}`, `client-server/wh_test_rsa.c::whTest_CryptoRsa` | Client | Full coverage |
| `wh_test_clientserver.c` (echo and server-info paths) | `client-server/wh_test_echo.c::whTest_Echo`, `client-server/wh_test_server_info.c::whTest_ServerInfo` | Client | pthread test ported, sequential test dropped |
| `wh_test_wolfcrypt_test.c::whTest_WolfCryptTest` | `client-server/wh_test_wolfcrypt.c::whTest_WolfCryptTest` | Client | |
| `wh_test_flash_ramsim.c::whTest_Flash_RamSim` | `posix/wh_test_flash_ramsim.c::{whTest_FlashWriteLock, whTest_FlashEraseProgramVerify, whTest_FlashUnitOps}` | POSIX port-specific (`whTestGroup_RunOne`) | remove ramsim coupling and migrate to server group |
@@ -86,7 +86,6 @@ Not yet migrated (still live in `wolfHSM/test/`):
|---|---|
| `wh_test_comm.c::whTest_Comm` | |
| `wh_test_clientserver.c::whTest_ClientServer` | Pthread variant: remaining client-side coverage (NVM ops, etc.) still needs to be split out as new tests. The sequential test is dropped |
-| `wh_test_crypto.c::whTest_Crypto` | RNG, key cache, key-cache enforcement, RSA, CMAC, Curve25519, ML-DSA, key usage policies, key revocation |
| `wh_test_crypto_affinity.c::whTest_CryptoAffinity` | |
| `wh_test_keywrap.c::whTest_KeyWrapClientConfig` | |
| `wh_test_multiclient.c::whTest_MultiClient` | |
@@ -102,3 +101,4 @@ Not yet migrated (still live in `wolfHSM/test/`):
### Other improvements
- Add callback from `wh_Server_HandleRequestMessage` to allow sleep and avoid a busy loop
+- Implement `whTestPort_ResetServer/Client` and re-enable persistent-NVM-artifact tests (`WOLFHSM_CFG_TEST_ALLOW_PERSISTENT_NVM_ARTIFACTS` is intentionally not defined in `config/wolfhsm_cfg.h`)
diff --git a/test-refactor/client-server/wh_test_aes.c b/test-refactor/client-server/wh_test_aes.c
new file mode 100644
index 00000000..7d83bf8b
--- /dev/null
+++ b/test-refactor/client-server/wh_test_aes.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2026 wolfSSL Inc.
+ *
+ * This file is part of wolfHSM.
+ *
+ * wolfHSM 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfHSM 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 wolfHSM. If not, see .
+ */
+/*
+ * test-refactor/client-server/wh_test_aes.c
+ *
+ * AES round-trips routed through the server via WH_DEV_ID. Covers CBC, CTR,
+ * ECB, and GCM in both client-side-key and HSM-cached-key forms, plus the
+ * AES-CBC streaming request/response API. Under a WOLFHSM_CFG_DMA build the
+ * wc_Aes* calls dispatch to the *Dma wrappers via the cryptocb.
+ */
+
+#include "wolfhsm/wh_settings.h"
+
+#if !defined(WOLFHSM_CFG_NO_CRYPTO)
+
+#include
+#include
+
+#include "wolfssl/wolfcrypt/settings.h"
+#include "wolfssl/wolfcrypt/types.h"
+#include "wolfssl/wolfcrypt/aes.h"
+
+#include "wolfhsm/wh_error.h"
+#include "wolfhsm/wh_common.h"
+#include "wolfhsm/wh_client.h"
+#include "wolfhsm/wh_client_crypto.h"
+
+#include "wh_test_common.h"
+#include "wh_test_list.h"
+
+#if !defined(NO_AES) && \
+ (defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_COUNTER) || \
+ defined(HAVE_AES_ECB) || defined(HAVE_AESGCM))
+int whTest_CryptoAes(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ Aes aes[1];
+ whKeyId keyId = WH_KEYID_ERASED;
+ uint8_t labelIn[WH_NVM_LABEL_LEN] = "AES Key Label";
+
+ /* NIST SP 800-38A / SP 800-38B test vectors (key + 64-byte message
+ * spanning four AES blocks). Deterministic vectors keep the test
+ * self-contained, no RNG needed. */
+ const uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae,
+ 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88,
+ 0x09, 0xcf, 0x4f, 0x3c};
+ const uint8_t iv[AES_BLOCK_SIZE] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f};
+ const uint8_t plainIn[64] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e,
+ 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03,
+ 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30,
+ 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19,
+ 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b,
+ 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10};
+ uint8_t cipher[sizeof(plainIn)];
+ uint8_t plainOut[sizeof(plainIn)];
+
+#ifdef HAVE_AES_CBC
+ /* CBC with client-side key */
+ if (ret == 0) {
+ memset(cipher, 0, sizeof(cipher));
+ memset(plainOut, 0, sizeof(plainOut));
+ ret = wc_AesInit(aes, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wc_AesInit %d\n", ret);
+ }
+ if (ret == 0) {
+ ret = wc_AesSetKey(aes, key, sizeof(key), iv, AES_ENCRYPTION);
+ }
+ if (ret == 0) {
+ ret = wc_AesCbcEncrypt(aes, cipher, plainIn, sizeof(plainIn));
+ }
+ if (ret == 0) {
+ ret = wc_AesSetKey(aes, key, sizeof(key), iv, AES_DECRYPTION);
+ }
+ if (ret == 0) {
+ ret = wc_AesCbcDecrypt(aes, plainOut, cipher, sizeof(cipher));
+ }
+ if (ret == 0 && memcmp(plainIn, plainOut, sizeof(plainIn)) != 0) {
+ WH_ERROR_PRINT("AES-CBC client key failed to match\n");
+ ret = -1;
+ }
+ (void)wc_AesFree(aes);
+ }
+
+ /* CBC with HSM-cached key */
+ if (ret == 0) {
+ memset(cipher, 0, sizeof(cipher));
+ memset(plainOut, 0, sizeof(plainOut));
+ ret = wc_AesInit(aes, NULL, devId);
+ if (ret == 0) {
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_KeyCache(
+ ctx, WH_NVM_FLAGS_USAGE_ENCRYPT | WH_NVM_FLAGS_USAGE_DECRYPT,
+ labelIn, sizeof(labelIn), key, sizeof(key), &keyId);
+ }
+ if (ret == 0) {
+ ret = wh_Client_AesSetKeyId(aes, keyId);
+ }
+ if (ret == 0) {
+ ret = wc_AesSetIV(aes, iv);
+ }
+ if (ret == 0) {
+ ret = wc_AesCbcEncrypt(aes, cipher, plainIn, sizeof(plainIn));
+ }
+ if (ret == 0) {
+ ret = wc_AesSetIV(aes, iv);
+ }
+ if (ret == 0) {
+ ret = wc_AesCbcDecrypt(aes, plainOut, cipher, sizeof(plainIn));
+ }
+ if (ret == 0 && memcmp(plainIn, plainOut, sizeof(plainIn)) != 0) {
+ WH_ERROR_PRINT("AES-CBC HSM key failed to match\n");
+ ret = -1;
+ }
+ if (keyId != WH_KEYID_ERASED) {
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ keyId = WH_KEYID_ERASED;
+ }
+ (void)wc_AesFree(aes);
+ }
+ if (ret == 0) {
+ WH_TEST_PRINT("AES CBC DEVID=0x%X SUCCESS\n", devId);
+ }
+
+ /* CBC streaming via the explicit request/response API. Drives the server
+ * directly with INVALID_DEVID so the cryptocb is not invoked; covers
+ * wh_Client_AesCbcRequest / wh_Client_AesCbcResponse and IV chaining
+ * across two halves. */
+ if (ret == 0) {
+ const uint32_t halfSize = sizeof(plainIn) / 2;
+ uint32_t outSize = 0;
+
+ memset(cipher, 0, sizeof(cipher));
+ memset(plainOut, 0, sizeof(plainOut));
+
+ ret = wc_AesInit(aes, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wc_AesSetKey(aes, key, sizeof(key), iv, AES_ENCRYPTION);
+ }
+ if (ret == 0) {
+ ret = wh_Client_AesCbcRequest(ctx, aes, 1, plainIn, halfSize);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_AesCbcResponse(ctx, aes, cipher, &outSize);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = wh_Client_AesCbcRequest(ctx, aes, 1, plainIn + halfSize,
+ halfSize);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_AesCbcResponse(ctx, aes, cipher + halfSize,
+ &outSize);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+
+ if (ret == 0) {
+ ret = wc_AesSetKey(aes, key, sizeof(key), iv, AES_DECRYPTION);
+ }
+ if (ret == 0) {
+ ret = wh_Client_AesCbcRequest(ctx, aes, 0, cipher, halfSize);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_AesCbcResponse(ctx, aes, plainOut, &outSize);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = wh_Client_AesCbcRequest(ctx, aes, 0, cipher + halfSize,
+ halfSize);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_AesCbcResponse(ctx, aes, plainOut + halfSize,
+ &outSize);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0 && memcmp(plainIn, plainOut, sizeof(plainIn)) != 0) {
+ WH_ERROR_PRINT("AES-CBC streaming failed to match\n");
+ ret = -1;
+ }
+ (void)wc_AesFree(aes);
+ if (ret == 0) {
+ WH_TEST_PRINT("AES CBC ASYNC STREAMING DEVID=0x%X SUCCESS\n",
+ devId);
+ }
+ }
+#endif /* HAVE_AES_CBC */
+
+#ifdef WOLFSSL_AES_COUNTER
+ /* CTR with client-side key */
+ if (ret == 0) {
+ memset(cipher, 0, sizeof(cipher));
+ memset(plainOut, 0, sizeof(plainOut));
+ ret = wc_AesInit(aes, NULL, devId);
+ if (ret == 0) {
+ ret = wc_AesSetKeyDirect(aes, key, sizeof(key), iv, AES_ENCRYPTION);
+ }
+ if (ret == 0) {
+ ret = wc_AesCtrEncrypt(aes, cipher, plainIn, sizeof(plainIn));
+ }
+ if (ret == 0) {
+ ret = wc_AesSetKeyDirect(aes, key, sizeof(key), iv, AES_DECRYPTION);
+ }
+ if (ret == 0) {
+ ret = wc_AesCtrEncrypt(aes, plainOut, cipher, sizeof(cipher));
+ }
+ if (ret == 0 && memcmp(plainIn, plainOut, sizeof(plainIn)) != 0) {
+ WH_ERROR_PRINT("AES-CTR client key failed to match\n");
+ ret = -1;
+ }
+ (void)wc_AesFree(aes);
+ }
+
+ /* CTR with HSM-cached key */
+ if (ret == 0) {
+ memset(cipher, 0, sizeof(cipher));
+ memset(plainOut, 0, sizeof(plainOut));
+ ret = wc_AesInit(aes, NULL, devId);
+ if (ret == 0) {
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_KeyCache(
+ ctx, WH_NVM_FLAGS_USAGE_ENCRYPT | WH_NVM_FLAGS_USAGE_DECRYPT,
+ labelIn, sizeof(labelIn), key, sizeof(key), &keyId);
+ }
+ if (ret == 0) {
+ ret = wh_Client_AesSetKeyId(aes, keyId);
+ }
+ if (ret == 0) {
+ ret = wc_AesSetIV(aes, iv);
+ }
+ if (ret == 0) {
+ ret = wc_AesCtrEncrypt(aes, cipher, plainIn, sizeof(plainIn));
+ }
+ if (ret == 0) {
+ ret = wc_AesSetIV(aes, iv);
+ }
+ if (ret == 0) {
+ ret = wc_AesCtrEncrypt(aes, plainOut, cipher, sizeof(plainIn));
+ }
+ if (ret == 0 && memcmp(plainIn, plainOut, sizeof(plainIn)) != 0) {
+ WH_ERROR_PRINT("AES-CTR HSM key failed to match\n");
+ ret = -1;
+ }
+ if (keyId != WH_KEYID_ERASED) {
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ keyId = WH_KEYID_ERASED;
+ }
+ (void)wc_AesFree(aes);
+ }
+ if (ret == 0) {
+ WH_TEST_PRINT("AES CTR DEVID=0x%X SUCCESS\n", devId);
+ }
+#endif /* WOLFSSL_AES_COUNTER */
+
+#ifdef HAVE_AES_ECB
+ /* ECB with client-side key */
+ if (ret == 0) {
+ memset(cipher, 0, sizeof(cipher));
+ memset(plainOut, 0, sizeof(plainOut));
+ ret = wc_AesInit(aes, NULL, devId);
+ if (ret == 0) {
+ /* AES-ECB does not use an IV */
+ ret = wc_AesSetKey(aes, key, sizeof(key), NULL, AES_ENCRYPTION);
+ }
+ if (ret == 0) {
+ ret = wc_AesEcbEncrypt(aes, cipher, plainIn, sizeof(plainIn));
+ }
+ if (ret == 0) {
+ ret = wc_AesSetKey(aes, key, sizeof(key), NULL, AES_DECRYPTION);
+ }
+ if (ret == 0) {
+ ret = wc_AesEcbDecrypt(aes, plainOut, cipher, sizeof(cipher));
+ }
+ if (ret == 0 && memcmp(plainIn, plainOut, sizeof(plainIn)) != 0) {
+ WH_ERROR_PRINT("AES-ECB client key failed to match\n");
+ ret = -1;
+ }
+ (void)wc_AesFree(aes);
+ }
+
+ /* ECB with HSM-cached key */
+ if (ret == 0) {
+ memset(cipher, 0, sizeof(cipher));
+ memset(plainOut, 0, sizeof(plainOut));
+ ret = wc_AesInit(aes, NULL, devId);
+ if (ret == 0) {
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_KeyCache(
+ ctx, WH_NVM_FLAGS_USAGE_ENCRYPT | WH_NVM_FLAGS_USAGE_DECRYPT,
+ labelIn, sizeof(labelIn), key, sizeof(key), &keyId);
+ }
+ if (ret == 0) {
+ ret = wh_Client_AesSetKeyId(aes, keyId);
+ }
+ if (ret == 0) {
+ ret = wc_AesSetIV(aes, NULL);
+ }
+ if (ret == 0) {
+ ret = wc_AesEcbEncrypt(aes, cipher, plainIn, sizeof(plainIn));
+ }
+ if (ret == 0) {
+ ret = wc_AesSetIV(aes, NULL);
+ }
+ if (ret == 0) {
+ ret = wc_AesEcbDecrypt(aes, plainOut, cipher, sizeof(plainIn));
+ }
+ if (ret == 0 && memcmp(plainIn, plainOut, sizeof(plainIn)) != 0) {
+ WH_ERROR_PRINT("AES-ECB HSM key failed to match\n");
+ ret = -1;
+ }
+ if (keyId != WH_KEYID_ERASED) {
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ keyId = WH_KEYID_ERASED;
+ }
+ (void)wc_AesFree(aes);
+ }
+ if (ret == 0) {
+ WH_TEST_PRINT("AES ECB DEVID=0x%X SUCCESS\n", devId);
+ }
+#endif /* HAVE_AES_ECB */
+
+#ifdef HAVE_AESGCM
+ {
+ const uint8_t authIn[16] = {0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
+ 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce,
+ 0xde, 0xad, 0xbe, 0xef};
+ uint8_t authTag[16];
+
+ /* GCM with client-side key */
+ if (ret == 0) {
+ memset(cipher, 0, sizeof(cipher));
+ memset(plainOut, 0, sizeof(plainOut));
+ memset(authTag, 0, sizeof(authTag));
+ ret = wc_AesInit(aes, NULL, devId);
+ if (ret == 0) {
+ ret = wc_AesGcmSetKey(aes, key, sizeof(key));
+ }
+ if (ret == 0) {
+ ret = wc_AesGcmEncrypt(aes, cipher, plainIn, sizeof(plainIn),
+ iv, sizeof(iv), authTag, sizeof(authTag),
+ authIn, sizeof(authIn));
+ }
+ if (ret == 0) {
+ ret = wc_AesGcmDecrypt(aes, plainOut, cipher, sizeof(plainIn),
+ iv, sizeof(iv), authTag, sizeof(authTag),
+ authIn, sizeof(authIn));
+ }
+ if (ret == 0 && memcmp(plainIn, plainOut, sizeof(plainIn)) != 0) {
+ WH_ERROR_PRINT("AES-GCM client key failed to match\n");
+ ret = -1;
+ }
+ (void)wc_AesFree(aes);
+ }
+
+ /* GCM with HSM-cached key */
+ if (ret == 0) {
+ memset(cipher, 0, sizeof(cipher));
+ memset(plainOut, 0, sizeof(plainOut));
+ memset(authTag, 0, sizeof(authTag));
+ ret = wc_AesInit(aes, NULL, devId);
+ if (ret == 0) {
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_KeyCache(ctx,
+ WH_NVM_FLAGS_USAGE_ENCRYPT |
+ WH_NVM_FLAGS_USAGE_DECRYPT,
+ labelIn, sizeof(labelIn), key,
+ sizeof(key), &keyId);
+ }
+ if (ret == 0) {
+ ret = wh_Client_AesSetKeyId(aes, keyId);
+ }
+ if (ret == 0) {
+ ret = wc_AesGcmEncrypt(aes, cipher, plainIn, sizeof(plainIn),
+ iv, sizeof(iv), authTag, sizeof(authTag),
+ authIn, sizeof(authIn));
+ }
+ if (ret == 0) {
+ ret = wc_AesGcmDecrypt(aes, plainOut, cipher, sizeof(plainIn),
+ iv, sizeof(iv), authTag, sizeof(authTag),
+ authIn, sizeof(authIn));
+ }
+ if (ret == 0 && memcmp(plainIn, plainOut, sizeof(plainIn)) != 0) {
+ WH_ERROR_PRINT("AES-GCM HSM key failed to match\n");
+ ret = -1;
+ }
+ if (keyId != WH_KEYID_ERASED) {
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ keyId = WH_KEYID_ERASED;
+ }
+ (void)wc_AesFree(aes);
+ }
+ if (ret == 0) {
+ WH_TEST_PRINT("AES GCM DEVID=0x%X SUCCESS\n", devId);
+ }
+ }
+#endif /* HAVE_AESGCM */
+
+ return ret;
+}
+#endif /* !NO_AES && (HAVE_AES_CBC || WOLFSSL_AES_COUNTER || HAVE_AES_ECB || \
+ HAVE_AESGCM) */
+
+#endif /* !WOLFHSM_CFG_NO_CRYPTO */
diff --git a/test-refactor/client-server/wh_test_cmac.c b/test-refactor/client-server/wh_test_cmac.c
new file mode 100644
index 00000000..89774e57
--- /dev/null
+++ b/test-refactor/client-server/wh_test_cmac.c
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2026 wolfSSL Inc.
+ *
+ * This file is part of wolfHSM.
+ *
+ * wolfHSM 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfHSM 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 wolfHSM. If not, see .
+ */
+/*
+ * test-refactor/client-server/wh_test_cmac.c
+ *
+ * AES-CMAC tests against NIST SP 800-38B vectors. For each (key, msg, tag)
+ * triple, exercises (a) one-shot generate with a cached server key,
+ * (b) one-shot verify, and (c) incremental update/finalize. Also commits a
+ * key to NVM and verifies through the cache->NVM->cache fetch path.
+ */
+
+#include "wolfhsm/wh_settings.h"
+
+#if !defined(WOLFHSM_CFG_NO_CRYPTO)
+
+#include
+#include
+
+#include "wolfssl/wolfcrypt/settings.h"
+#include "wolfssl/wolfcrypt/types.h"
+#include "wolfssl/wolfcrypt/aes.h"
+#include "wolfssl/wolfcrypt/cmac.h"
+
+#include "wolfhsm/wh_error.h"
+#include "wolfhsm/wh_common.h"
+#include "wolfhsm/wh_client.h"
+#include "wolfhsm/wh_client_crypto.h"
+
+#include "wh_test_common.h"
+#include "wh_test_list.h"
+
+#if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT)
+int whTest_CryptoCmac(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ Cmac cmac[1];
+ uint8_t tag[AES_BLOCK_SIZE] = {0};
+ word32 tagSz;
+ whKeyId keyId;
+ uint8_t labelIn[WH_NVM_LABEL_LEN] = "CMAC Key Label";
+ word32 i;
+
+ /* NIST SP 800-38B test vectors */
+#ifdef WOLFSSL_AES_128
+ const byte k128[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
+#endif
+#ifdef WOLFSSL_AES_192
+ const byte k192[] = {0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
+ 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
+ 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b};
+#endif
+#ifdef WOLFSSL_AES_256
+ const byte k256[] = {0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
+ 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
+ 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
+ 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4};
+#endif
+
+ const byte m[] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e,
+ 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03,
+ 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30,
+ 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19,
+ 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b,
+ 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10};
+
+ enum {
+ CMAC_MLEN_0 = 0,
+ CMAC_MLEN_128 = 128 / 8,
+ CMAC_MLEN_319 = 320 / 8 - 1,
+ CMAC_MLEN_320 = 320 / 8,
+ CMAC_MLEN_512 = 512 / 8,
+ };
+
+#ifdef WOLFSSL_AES_128
+ const byte t128_0[] = {0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
+ 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46};
+ const byte t128_128[] = {0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
+ 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c};
+ const byte t128_319[] = {0x2c, 0x17, 0x84, 0x4c, 0x93, 0x1c, 0x07, 0x95,
+ 0x15, 0x92, 0x73, 0x0a, 0x34, 0xd0, 0xd9, 0xd2};
+ const byte t128_320[] = {0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
+ 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27};
+ const byte t128_512[] = {0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
+ 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe};
+#endif
+#ifdef WOLFSSL_AES_192
+ const byte t192_0[] = {0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
+ 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67};
+ const byte t192_128[] = {0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
+ 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84};
+ const byte t192_320[] = {0x8a, 0x1d, 0xe5, 0xbe, 0x2e, 0xb3, 0x1a, 0xad,
+ 0x08, 0x9a, 0x82, 0xe6, 0xee, 0x90, 0x8b, 0x0e};
+ const byte t192_512[] = {0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
+ 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11};
+#endif
+#ifdef WOLFSSL_AES_256
+ const byte t256_0[] = {0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
+ 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83};
+ const byte t256_128[] = {0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
+ 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c};
+ const byte t256_320[] = {0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2,
+ 0x32, 0xf5, 0xb1, 0x69, 0xb9, 0xc9, 0x11, 0xe6};
+ const byte t256_512[] = {0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
+ 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10};
+#endif
+
+ typedef struct {
+ const byte* k;
+ word32 kSz;
+ const byte* m;
+ word32 mSz;
+ const byte* t;
+ word32 tSz;
+ word32 partial;
+ } CmacTestCase;
+
+ const CmacTestCase testCases[] = {
+#ifdef WOLFSSL_AES_128
+ {k128, sizeof(k128), m, CMAC_MLEN_0, t128_0, AES_BLOCK_SIZE, 0},
+ {k128, sizeof(k128), m, CMAC_MLEN_128, t128_128, AES_BLOCK_SIZE, 0},
+ {k128, sizeof(k128), m, CMAC_MLEN_319, t128_319, AES_BLOCK_SIZE, 0},
+ {k128, sizeof(k128), m, CMAC_MLEN_320, t128_320, AES_BLOCK_SIZE, 0},
+ {k128, sizeof(k128), m, CMAC_MLEN_512, t128_512, AES_BLOCK_SIZE, 0},
+ {k128, sizeof(k128), m, CMAC_MLEN_512, t128_512, AES_BLOCK_SIZE, 5},
+#endif
+#ifdef WOLFSSL_AES_192
+ {k192, sizeof(k192), m, CMAC_MLEN_0, t192_0, AES_BLOCK_SIZE, 0},
+ {k192, sizeof(k192), m, CMAC_MLEN_128, t192_128, AES_BLOCK_SIZE, 0},
+ {k192, sizeof(k192), m, CMAC_MLEN_320, t192_320, AES_BLOCK_SIZE, 0},
+ {k192, sizeof(k192), m, CMAC_MLEN_512, t192_512, AES_BLOCK_SIZE, 0},
+#endif
+#ifdef WOLFSSL_AES_256
+ {k256, sizeof(k256), m, CMAC_MLEN_0, t256_0, AES_BLOCK_SIZE, 0},
+ {k256, sizeof(k256), m, CMAC_MLEN_128, t256_128, AES_BLOCK_SIZE, 0},
+ {k256, sizeof(k256), m, CMAC_MLEN_320, t256_320, AES_BLOCK_SIZE, 0},
+ {k256, sizeof(k256), m, CMAC_MLEN_512, t256_512, AES_BLOCK_SIZE, 0},
+#endif
+ };
+ const word32 numCases = sizeof(testCases) / sizeof(testCases[0]);
+
+ for (i = 0; i < numCases && ret == 0; i++) {
+ const CmacTestCase* tc = &testCases[i];
+
+ /* (a) One-shot generate with cached key */
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_USAGE_SIGN, labelIn,
+ sizeof(labelIn), (uint8_t*)tc->k, tc->kSz,
+ &keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wh_Client_KeyCache (gen) tc=%d %d\n", i,
+ ret);
+ break;
+ }
+ ret = wc_InitCmac_ex(cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wc_InitCmac_ex (gen) tc=%d %d\n", i, ret);
+ break;
+ }
+ ret = wh_Client_CmacSetKeyId(cmac, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to wh_Client_CmacSetKeyId (gen) tc=%d %d\n", i, ret);
+ break;
+ }
+ memset(tag, 0, sizeof(tag));
+ tagSz = sizeof(tag);
+ ret = wc_AesCmacGenerate_ex(cmac, tag, &tagSz, tc->m, tc->mSz, NULL, 0,
+ NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wc_AesCmacGenerate_ex tc=%d %d\n", i, ret);
+ break;
+ }
+ if (memcmp(tag, tc->t, AES_BLOCK_SIZE) != 0) {
+ WH_ERROR_PRINT("CMAC generate mismatch tc=%d\n", i);
+ ret = -1;
+ break;
+ }
+ ret = wh_Client_KeyEvict(ctx, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wh_Client_KeyEvict (gen) tc=%d %d\n", i,
+ ret);
+ break;
+ }
+
+ /* (b) One-shot verify with cached key */
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_USAGE_VERIFY, labelIn,
+ sizeof(labelIn), (uint8_t*)tc->k, tc->kSz,
+ &keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wh_Client_KeyCache (ver) tc=%d %d\n", i,
+ ret);
+ break;
+ }
+ ret = wh_Client_CmacSetKeyId(cmac, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to wh_Client_CmacSetKeyId (ver) tc=%d %d\n", i, ret);
+ break;
+ }
+ ret = wc_AesCmacVerify_ex(cmac, tc->t, tc->tSz, tc->m, tc->mSz, NULL,
+ 0, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wc_AesCmacVerify_ex tc=%d %d\n", i, ret);
+ break;
+ }
+ wc_CmacFree(cmac);
+ ret = wh_Client_KeyEvict(ctx, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wh_Client_KeyEvict (ver) tc=%d %d\n", i,
+ ret);
+ break;
+ }
+
+ /* (c) Incremental init/update/final with cached key */
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_USAGE_SIGN, labelIn,
+ sizeof(labelIn), (uint8_t*)tc->k, tc->kSz,
+ &keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wh_Client_KeyCache (inc) tc=%d %d\n", i,
+ ret);
+ break;
+ }
+ ret = wc_InitCmac_ex(cmac, NULL, 0, WC_CMAC_AES, NULL, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wc_InitCmac_ex (inc) tc=%d %d\n", i, ret);
+ break;
+ }
+ ret = wh_Client_CmacSetKeyId(cmac, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to wh_Client_CmacSetKeyId (inc) tc=%d %d\n", i, ret);
+ break;
+ }
+ if (tc->partial > 0) {
+ word32 firstSz = tc->mSz / 2 - tc->partial;
+ word32 secondSz = tc->mSz / 2 + tc->partial;
+ ret = wc_CmacUpdate(cmac, tc->m, firstSz);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wc_CmacUpdate (inc1) tc=%d %d\n", i,
+ ret);
+ break;
+ }
+ ret = wc_CmacUpdate(cmac, tc->m + firstSz, secondSz);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wc_CmacUpdate (inc2) tc=%d %d\n", i,
+ ret);
+ break;
+ }
+ }
+ else {
+ ret = wc_CmacUpdate(cmac, tc->m, tc->mSz);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wc_CmacUpdate (inc) tc=%d %d\n", i,
+ ret);
+ break;
+ }
+ }
+ memset(tag, 0, sizeof(tag));
+ tagSz = sizeof(tag);
+ ret = wc_CmacFinal(cmac, tag, &tagSz);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wc_CmacFinal (inc) tc=%d %d\n", i, ret);
+ break;
+ }
+ if (memcmp(tag, tc->t, AES_BLOCK_SIZE) != 0) {
+ WH_ERROR_PRINT("CMAC incremental mismatch tc=%d\n", i);
+ ret = -1;
+ break;
+ }
+ wc_CmacFree(cmac);
+ ret = wh_Client_KeyEvict(ctx, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wh_Client_KeyEvict (inc) tc=%d %d\n", i,
+ ret);
+ break;
+ }
+ }
+
+ /* Round-trip a key through commit / evict / re-cache, then verify a tag
+ * computed from the still-valid key material. */
+ if (ret == 0) {
+#ifdef WOLFSSL_AES_128
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_USAGE_VERIFY, labelIn,
+ sizeof(labelIn), (uint8_t*)k128,
+ sizeof(k128), &keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wh_Client_KeyCache (commit) %d\n", ret);
+ }
+ else {
+ ret = wh_Client_KeyCommit(ctx, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wh_Client_KeyCommit %d\n", ret);
+ }
+ else {
+ ret = wh_Client_KeyEvict(ctx, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wh_Client_KeyEvict %d\n", ret);
+ }
+ else {
+ ret = wc_InitCmac_ex(cmac, k128, sizeof(k128), WC_CMAC_AES,
+ NULL, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitCmac_ex %d\n", ret);
+ }
+ else {
+ ret = wh_Client_CmacSetKeyId(cmac, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to wh_Client_CmacSetKeyId %d\n", ret);
+ }
+ else {
+ tagSz = sizeof(tag);
+ ret = wc_AesCmacVerify_ex(
+ cmac, t128_512, sizeof(t128_512), m,
+ CMAC_MLEN_512, NULL, 0, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed wc_AesCmacVerify_ex (commit) "
+ "%d\n",
+ ret);
+ }
+ else {
+ ret = wh_Client_KeyErase(ctx, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to wh_Client_KeyErase %d\n",
+ ret);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif /* WOLFSSL_AES_128 */
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("CMAC DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+#endif /* WOLFSSL_CMAC && !NO_AES && WOLFSSL_AES_DIRECT */
+
+#endif /* !WOLFHSM_CFG_NO_CRYPTO */
diff --git a/test-refactor/client-server/wh_test_crypto.c b/test-refactor/client-server/wh_test_crypto.c
deleted file mode 100644
index 5319850a..00000000
--- a/test-refactor/client-server/wh_test_crypto.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2026 wolfSSL Inc.
- *
- * This file is part of wolfHSM.
- *
- * wolfHSM 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 3 of the License, or
- * (at your option) any later version.
- *
- * wolfHSM 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 wolfHSM. If not, see .
- */
-/*
- * test-refactor/wh_test_crypto.c
- *
- * Basic crypto test suite. Minimal SHA256 and AES-CBC
- * round-trips routed through the server via WH_DEV_ID.
- */
-
-#include "wolfhsm/wh_settings.h"
-
-#if !defined(WOLFHSM_CFG_NO_CRYPTO)
-
-#include
-#include
-
-#include "wolfssl/wolfcrypt/settings.h"
-#include "wolfssl/wolfcrypt/types.h"
-#include "wolfssl/wolfcrypt/aes.h"
-#include "wolfssl/wolfcrypt/ecc.h"
-#include "wolfssl/wolfcrypt/random.h"
-#include "wolfssl/wolfcrypt/sha256.h"
-
-#include "wolfhsm/wh_error.h"
-#include "wolfhsm/wh_client.h"
-
-#include "wh_test_common.h"
-#include "wh_test_list.h"
-
-#ifndef NO_SHA256
-int whTest_CryptoSha256(whClientContext* ctx)
-{
- int devId = WH_DEV_ID;
- int ret = WH_ERROR_OK;
- wc_Sha256 sha256[1];
- uint8_t out[WC_SHA256_DIGEST_SIZE];
- /* Vector exactly one block size in length */
- const char inOne[] =
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
- const uint8_t expectedOutOne[WC_SHA256_DIGEST_SIZE] = {
- 0xff, 0xe0, 0x54, 0xfe, 0x7a, 0xe0, 0xcb, 0x6d, 0xc6, 0x5c, 0x3a,
- 0xf9, 0xb6, 0x1d, 0x52, 0x09, 0xf4, 0x39, 0x85, 0x1d, 0xb4, 0x3d,
- 0x0b, 0xa5, 0x99, 0x73, 0x37, 0xdf, 0x15, 0x46, 0x68, 0xeb};
-
- (void)ctx;
-
- /* Initialize SHA256 structure */
- ret = wc_InitSha256_ex(sha256, NULL, devId);
- if (ret != 0) {
- WH_ERROR_PRINT("Failed to wc_InitSha256 on devId 0x%X: %d\n", devId,
- ret);
- } else {
- /* Single-block update should trigger a server transaction */
- ret = wc_Sha256Update(sha256,
- (const byte*)inOne,
- WC_SHA256_BLOCK_SIZE);
- if (ret != 0) {
- WH_ERROR_PRINT("Failed to wc_Sha256Update %d\n", ret);
- } else {
- /* Finalize should trigger a server transaction with empty buffer */
- ret = wc_Sha256Final(sha256, out);
- if (ret != 0) {
- WH_ERROR_PRINT("Failed to wc_Sha256Final %d\n", ret);
- } else {
- /* Compare the computed hash with the expected output */
- if (memcmp(out, expectedOutOne, WC_SHA256_DIGEST_SIZE) != 0) {
- WH_ERROR_PRINT("SHA256 hash does not match expected.\n");
- ret = -1;
- }
- }
- }
- (void)wc_Sha256Free(sha256);
- }
- if (ret == 0) {
- WH_TEST_PRINT("SHA256 DEVID=0x%X SUCCESS\n", devId);
- }
- return ret;
-}
-#endif /* !NO_SHA256 */
-
-
-#if !defined(NO_AES) && defined(HAVE_AES_CBC)
-int whTest_CryptoAes(whClientContext* ctx)
-{
- int devId = WH_DEV_ID;
- int ret = 0;
- Aes aes[1];
- uint8_t cipher[AES_BLOCK_SIZE] = {0};
- uint8_t plainOut[AES_BLOCK_SIZE] = {0};
- /* NIST SP 800-38B test vectors (same k128 / m used by the CMAC test
- * in test/wh_test_crypto.c). Using a fixed vector keeps this suite
- * self-contained, no RNG needed. */
- const uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
- 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
- const uint8_t iv[AES_BLOCK_SIZE] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
- const uint8_t plainIn[AES_BLOCK_SIZE] = {
- 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
- 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
-
- (void)ctx;
-
- /* test aes CBC with client side key */
- ret = wc_AesInit(aes, NULL, devId);
- if (ret != 0) {
- WH_ERROR_PRINT("Failed to wc_AesInit %d\n", ret);
- } else {
- ret = wc_AesSetKey(aes, key, sizeof(key), iv, AES_ENCRYPTION);
- if (ret != 0) {
- WH_ERROR_PRINT("Failed to wc_AesSetKey %d\n", ret);
- } else {
- ret = wc_AesCbcEncrypt(aes, cipher, plainIn,
- sizeof(plainIn));
- if (ret != 0) {
- WH_ERROR_PRINT("Failed to wc_AesCbcEncrypt %d\n", ret);
- } else {
- ret = wc_AesSetKey(aes, key, sizeof(key), iv,
- AES_DECRYPTION);
- if (ret != 0) {
- WH_ERROR_PRINT("Failed to wc_AesSetKey %d\n", ret);
- } else {
- ret = wc_AesCbcDecrypt(aes, plainOut, cipher,
- sizeof(cipher));
- if (ret != 0) {
- WH_ERROR_PRINT("Failed to wc_AesCbcDecrypt %d\n",
- ret);
- } else {
- if (memcmp(plainIn, plainOut, sizeof(plainIn)) !=
- 0) {
- WH_ERROR_PRINT("Failed to match AES-CBC\n");
- ret = -1;
- }
- }
- }
- }
- }
- (void)wc_AesFree(aes);
- }
- if (ret == 0) {
- WH_TEST_PRINT("AES CBC DEVID=0x%X SUCCESS\n", devId);
- }
- return ret;
-}
-#endif /* !NO_AES && HAVE_AES_CBC */
-
-
-#if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN) && defined(HAVE_ECC_VERIFY)
-int whTest_CryptoEcc256(whClientContext* ctx)
-{
- int devId = WH_DEV_ID;
- int ret = 0;
- WC_RNG rng[1];
- ecc_key key[1];
- uint8_t hash[32] = {0};
- uint8_t sig[ECC_MAX_SIG_SIZE] = {0};
- word32 sigLen = sizeof(sig);
- int verify = 0;
-
- (void)ctx;
-
- /* Minimal P-256 sign/verify round-trip routed through the server via
- * WH_DEV_ID. Key size 32 selects SECP256R1 as wolfCrypt's default. */
- ret = wc_InitRng_ex(rng, NULL, devId);
- if (ret != 0) {
- WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
- } else {
- ret = wc_ecc_init_ex(key, NULL, devId);
- if (ret != 0) {
- WH_ERROR_PRINT("Failed to wc_ecc_init_ex %d\n", ret);
- } else {
- ret = wc_ecc_make_key(rng, 32, key);
- if (ret != 0) {
- WH_ERROR_PRINT("Failed to wc_ecc_make_key %d\n", ret);
- } else {
- ret = wc_ecc_sign_hash(hash, sizeof(hash),
- sig, &sigLen, rng, key);
- if (ret != 0) {
- WH_ERROR_PRINT("Failed to wc_ecc_sign_hash %d\n",
- ret);
- } else {
- ret = wc_ecc_verify_hash(sig, sigLen,
- hash, sizeof(hash), &verify, key);
- if (ret != 0) {
- WH_ERROR_PRINT("Failed to wc_ecc_verify_hash %d\n",
- ret);
- } else if (verify != 1) {
- WH_ERROR_PRINT("ECC256 verify mismatch\n");
- ret = -1;
- }
- }
- }
- (void)wc_ecc_free(key);
- }
- (void)wc_FreeRng(rng);
- }
- if (ret == 0) {
- WH_TEST_PRINT("ECC256 DEVID=0x%X SUCCESS\n", devId);
- }
- return ret;
-}
-#endif /* HAVE_ECC && HAVE_ECC_SIGN && HAVE_ECC_VERIFY */
-
-#endif /* !WOLFHSM_CFG_NO_CRYPTO */
diff --git a/test-refactor/client-server/wh_test_curve25519.c b/test-refactor/client-server/wh_test_curve25519.c
new file mode 100644
index 00000000..a5d0742c
--- /dev/null
+++ b/test-refactor/client-server/wh_test_curve25519.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2026 wolfSSL Inc.
+ *
+ * This file is part of wolfHSM.
+ *
+ * wolfHSM 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfHSM 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 wolfHSM. If not, see .
+ */
+/*
+ * test-refactor/client-server/wh_test_curve25519.c
+ *
+ * Curve25519 ECDH round-trips routed through the server via WH_DEV_ID,
+ * across ephemeral / server-export / server-cache key paths.
+ */
+
+#include "wolfhsm/wh_settings.h"
+
+#if !defined(WOLFHSM_CFG_NO_CRYPTO)
+
+#include
+#include
+
+#include "wolfssl/wolfcrypt/settings.h"
+#include "wolfssl/wolfcrypt/types.h"
+#include "wolfssl/wolfcrypt/curve25519.h"
+#include "wolfssl/wolfcrypt/random.h"
+
+#include "wolfhsm/wh_error.h"
+#include "wolfhsm/wh_common.h"
+#include "wolfhsm/wh_client.h"
+#include "wolfhsm/wh_client_crypto.h"
+
+#include "wh_test_common.h"
+#include "wh_test_list.h"
+
+#ifdef HAVE_CURVE25519
+int whTest_CryptoCurve25519(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ WC_RNG rng[1];
+ curve25519_key key_a[1] = {0};
+ curve25519_key key_b[1] = {0};
+ uint8_t shared_ab[CURVE25519_KEYSIZE] = {0};
+ uint8_t shared_ba[CURVE25519_KEYSIZE] = {0};
+ int key_size = CURVE25519_KEYSIZE;
+ whNvmFlags flags = WH_NVM_FLAGS_USAGE_DERIVE;
+ whKeyId key_id_a = WH_KEYID_ERASED;
+ uint8_t label_a[WH_NVM_LABEL_LEN] = "Curve25519 Label A";
+ whKeyId key_id_b = 42;
+ uint8_t label_b[WH_NVM_LABEL_LEN] = "Curve25519 Label B";
+ word32 len = 0;
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+
+ /* Test 1: ephemeral wolfCrypt keys via WH_DEV_ID */
+ ret = wc_curve25519_init_ex(key_a, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_curve25519_init_ex %d\n", ret);
+ }
+ else {
+ ret = wc_curve25519_init_ex(key_b, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_curve25519_init_ex %d\n", ret);
+ }
+ else {
+ ret = wc_curve25519_make_key(rng, key_size, key_a);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_curve25519_make_key %d\n", ret);
+ }
+ if (ret == 0) {
+ ret = wc_curve25519_make_key(rng, key_size, key_b);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_curve25519_make_key %d\n",
+ ret);
+ }
+ }
+ if (ret == 0) {
+ len = sizeof(shared_ab);
+ ret =
+ wc_curve25519_shared_secret(key_a, key_b, shared_ab, &len);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to compute shared secret %d\n", ret);
+ }
+ }
+ if (ret == 0) {
+ len = sizeof(shared_ba);
+ ret =
+ wc_curve25519_shared_secret(key_b, key_a, shared_ba, &len);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to compute shared secret %d\n", ret);
+ }
+ }
+ if (ret == 0) {
+ if (memcmp(shared_ab, shared_ba, len) != 0) {
+ WH_ERROR_PRINT("CURVE25519 secrets don't match\n");
+ ret = -1;
+ }
+ }
+ wc_curve25519_free(key_b);
+ }
+ wc_curve25519_free(key_a);
+ }
+
+ /* Test 2: server creates keys and exports them to client */
+ if (ret == 0) {
+ ret = wc_curve25519_init_ex(key_a, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_curve25519_init_ex %d\n", ret);
+ }
+ else {
+ ret = wc_curve25519_init_ex(key_b, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_curve25519_init_ex %d\n", ret);
+ }
+ else {
+ ret = wh_Client_Curve25519MakeExportKey(ctx, key_size, key_a);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to make exported key %d\n", ret);
+ }
+ if (ret == 0) {
+ ret = wh_Client_Curve25519MakeExportKey(ctx, key_size,
+ key_b);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to make exported key %d\n",
+ ret);
+ }
+ }
+ if (ret == 0) {
+ len = sizeof(shared_ab);
+ ret = wc_curve25519_shared_secret(key_a, key_b, shared_ab,
+ &len);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to compute shared secret %d\n", ret);
+ }
+ }
+ if (ret == 0) {
+ len = sizeof(shared_ba);
+ ret = wc_curve25519_shared_secret(key_b, key_a, shared_ba,
+ &len);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to compute shared secret %d\n", ret);
+ }
+ }
+ if (ret == 0) {
+ if (memcmp(shared_ab, shared_ba, len) != 0) {
+ WH_ERROR_PRINT("CURVE25519 secrets don't match\n");
+ ret = -1;
+ }
+ }
+ wc_curve25519_free(key_b);
+ }
+ wc_curve25519_free(key_a);
+ }
+ }
+
+ /* Test 3: server-cached keys referenced via keyId */
+ if (ret == 0) {
+ ret = wc_curve25519_init_ex(key_a, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_curve25519_init_ex %d\n", ret);
+ }
+ else {
+ ret = wc_curve25519_init_ex(key_b, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_curve25519_init_ex %d\n", ret);
+ }
+ else {
+ ret = wh_Client_Curve25519MakeCacheKey(
+ ctx, key_size, &key_id_a, flags, label_a, sizeof(label_a));
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to make cached key %d\n", ret);
+ }
+ if (ret == 0) {
+ ret = wh_Client_Curve25519MakeCacheKey(
+ ctx, key_size, &key_id_b, flags, label_b,
+ sizeof(label_b));
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to make cached key %d\n", ret);
+ }
+ }
+ if (ret == 0) {
+ len = sizeof(shared_ab);
+ wh_Client_Curve25519SetKeyId(key_a, key_id_a);
+ wh_Client_Curve25519SetKeyId(key_b, key_id_b);
+ ret = wc_curve25519_shared_secret(key_a, key_b, shared_ab,
+ &len);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to compute shared secret %d\n", ret);
+ }
+ }
+ if (ret == 0) {
+ len = sizeof(shared_ba);
+ ret = wc_curve25519_shared_secret(key_b, key_a, shared_ba,
+ &len);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to compute shared secret %d\n", ret);
+ }
+ }
+ if (ret == 0) {
+ if (memcmp(shared_ab, shared_ba, len) != 0) {
+ WH_ERROR_PRINT("CURVE25519 secrets don't match\n");
+ ret = -1;
+ }
+ }
+ if (!WH_KEYID_ISERASED(key_id_a)) {
+ (void)wh_Client_KeyEvict(ctx, key_id_a);
+ }
+ if (!WH_KEYID_ISERASED(key_id_b)) {
+ (void)wh_Client_KeyEvict(ctx, key_id_b);
+ }
+ wc_curve25519_free(key_b);
+ }
+ wc_curve25519_free(key_a);
+ }
+ }
+
+ (void)wc_FreeRng(rng);
+
+ if (ret == 0) {
+ WH_TEST_PRINT("CURVE25519 SUCCESS\n");
+ }
+ return ret;
+}
+
+/* Cache a NONEXPORTABLE Curve25519 keypair on the server, then verify the
+ * server-side ECDH (private cached, public local) produces the same shared
+ * secret as a client-side ECDH (private local, public exported via
+ * wh_Client_Curve25519ExportPublicKey). */
+int whTest_CryptoCurve25519ExportPublicKey(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ WC_RNG rng[1];
+ curve25519_key hsmPub[1] = {0};
+ curve25519_key hsmPriv[1] = {0};
+ curve25519_key localKey[1] = {0};
+ uint8_t sharedHsm[CURVE25519_KEYSIZE] = {0};
+ uint8_t sharedLocal[CURVE25519_KEYSIZE] = {0};
+ word32 secLen = 0;
+ whKeyId keyId = WH_KEYID_ERASED;
+ uint8_t denyBuf[256];
+ uint16_t denyLen = sizeof(denyBuf);
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+
+ ret = wh_Client_Curve25519MakeCacheKey(
+ ctx, (uint16_t)CURVE25519_KEYSIZE, &keyId,
+ WH_NVM_FLAGS_USAGE_DERIVE | WH_NVM_FLAGS_NONEXPORTABLE, NULL, 0);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to make NONEXPORTABLE cached Curve25519 key %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ /* Full export must be denied by the NONEXPORTABLE policy. */
+ {
+ int denyRet = wh_Client_KeyExport(ctx, keyId, NULL, 0, denyBuf,
+ &denyLen);
+ if (denyRet != WH_ERROR_ACCESS) {
+ WH_ERROR_PRINT(
+ "NONEXPORTABLE Curve25519 full export was not denied: %d\n",
+ denyRet);
+ ret = -1;
+ }
+ }
+
+ /* Public-only export must succeed and parse into a usable key struct. */
+ if (ret == 0) {
+ ret = wc_curve25519_init_ex(hsmPub, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wh_Client_Curve25519ExportPublicKey(ctx, keyId, hsmPub, 0,
+ NULL);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "wh_Client_Curve25519ExportPublicKey failed %d\n", ret);
+ }
+ }
+ }
+
+ /* Generate a local ephemeral keypair to ECDH against the exported pub. */
+ if (ret == 0) {
+ ret = wc_curve25519_init_ex(localKey, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wc_curve25519_make_key(rng, CURVE25519_KEYSIZE, localKey);
+ }
+ }
+
+ /* Local side: localPriv * exportedHsmPub. */
+ if (ret == 0) {
+ secLen = sizeof(sharedLocal);
+ ret = wc_curve25519_shared_secret(localKey, hsmPub, sharedLocal,
+ &secLen);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Local Curve25519 shared secret failed %d\n", ret);
+ }
+ }
+
+ /* HSM side: hsmPriv-by-keyId * localPub, dispatched through cryptoCb. */
+ if (ret == 0) {
+ ret = wc_curve25519_init_ex(hsmPriv, NULL, devId);
+ if (ret == 0) {
+ ret = wh_Client_Curve25519SetKeyId(hsmPriv, keyId);
+ }
+ if (ret == 0) {
+ secLen = sizeof(sharedHsm);
+ ret = wc_curve25519_shared_secret(hsmPriv, localKey, sharedHsm,
+ &secLen);
+ if (ret != 0) {
+ WH_ERROR_PRINT("HSM Curve25519 shared secret failed %d\n", ret);
+ }
+ }
+ wc_curve25519_free(hsmPriv);
+ }
+
+ if (ret == 0 && memcmp(sharedHsm, sharedLocal, secLen) != 0) {
+ WH_ERROR_PRINT("Curve25519 shared secrets don't match\n");
+ ret = -1;
+ }
+
+ wc_curve25519_free(localKey);
+ wc_curve25519_free(hsmPub);
+ if (!WH_KEYID_ISERASED(keyId)) {
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ }
+ (void)wc_FreeRng(rng);
+
+ if (ret == 0) {
+ WH_TEST_PRINT("CURVE25519 EXPORT-PUBLIC DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+#endif /* HAVE_CURVE25519 */
+
+#endif /* !WOLFHSM_CFG_NO_CRYPTO */
diff --git a/test-refactor/client-server/wh_test_ecc.c b/test-refactor/client-server/wh_test_ecc.c
new file mode 100644
index 00000000..5abda50f
--- /dev/null
+++ b/test-refactor/client-server/wh_test_ecc.c
@@ -0,0 +1,1633 @@
+/*
+ * Copyright (C) 2026 wolfSSL Inc.
+ *
+ * This file is part of wolfHSM.
+ *
+ * wolfHSM 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfHSM 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 wolfHSM. If not, see .
+ */
+/*
+ * test-refactor/client-server/wh_test_ecc.c
+ *
+ * ECC tests routed through the server via WH_DEV_ID:
+ * whTest_CryptoEcc - ECDH + ECDSA across ephemeral / export /
+ * cache key paths
+ * whTest_CryptoEccCacheDuplicate - cache slot replacement semantics
+ * whTest_CryptoEccCrossVerify - HSM<->SW signature interop, P-256/384/521
+ * whTest_CryptoEccAsync - async sign/verify, ECDH, server keygen
+ */
+
+#include "wolfhsm/wh_settings.h"
+
+#if !defined(WOLFHSM_CFG_NO_CRYPTO)
+
+#include
+#include
+
+#include "wolfssl/wolfcrypt/settings.h"
+#include "wolfssl/wolfcrypt/types.h"
+#include "wolfssl/wolfcrypt/ecc.h"
+#include "wolfssl/wolfcrypt/random.h"
+
+#include "wolfhsm/wh_error.h"
+#include "wolfhsm/wh_common.h"
+#include "wolfhsm/wh_client.h"
+#include "wolfhsm/wh_client_crypto.h"
+
+#include "wh_test_common.h"
+#include "wh_test_list.h"
+
+#if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN) && defined(HAVE_ECC_VERIFY)
+
+/* Full coverage of ECDH + ECDSA across the three key-management paths:
+ * - ephemeral wolfCrypt keys with WH_DEV_ID
+ * - server-generated keys exported back to the client
+ * - server-cached keys referenced via keyId */
+#define TEST_ECC_KEYSIZE 32
+#define TEST_ECC_CURVE_ID ECC_SECP256R1
+
+int whTest_CryptoEcc(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = WH_ERROR_OK;
+ WC_RNG rng[1];
+ ecc_key bobKey[1];
+ ecc_key aliceKey[1];
+ uint8_t shared_ab[TEST_ECC_KEYSIZE] = {0};
+ uint8_t shared_ba[TEST_ECC_KEYSIZE] = {0};
+ uint8_t hash[TEST_ECC_KEYSIZE] = {0};
+ uint8_t sig[ECC_MAX_SIG_SIZE] = {0};
+ whKeyId keyIdPrivate = WH_KEYID_ERASED;
+ whKeyId checkKeyId = WH_KEYID_ERASED;
+ whNvmFlags flags = WH_NVM_FLAGS_USAGE_SIGN | WH_NVM_FLAGS_USAGE_VERIFY |
+ WH_NVM_FLAGS_USAGE_DERIVE;
+ uint8_t labelPrivate[WH_NVM_LABEL_LEN] = "ECC Private Key";
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+
+ /* Test Case 1: Using ephemeral key (normal wolfCrypt flow) */
+ ret = wc_ecc_init_ex(bobKey, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_ecc_init_ex %d\n", ret);
+ }
+ else {
+ ret = wc_ecc_init_ex(aliceKey, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_ecc_init_ex %d\n", ret);
+ }
+ else {
+ ret = wc_ecc_make_key(rng, TEST_ECC_KEYSIZE, bobKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_ecc_make_key %d\n", ret);
+ }
+ else {
+ ret = wc_ecc_make_key(rng, TEST_ECC_KEYSIZE, aliceKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_ecc_make_key %d\n", ret);
+ }
+ else {
+ word32 secLen = TEST_ECC_KEYSIZE;
+ ret = wc_ecc_shared_secret(
+ bobKey, aliceKey, (byte*)shared_ab, &secLen);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to compute secret %d\n", ret);
+ }
+ else {
+ ret = wc_ecc_shared_secret(aliceKey, bobKey,
+ (byte*)shared_ba, &secLen);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to compute secret %d\n",
+ ret);
+ }
+ else if (memcmp(shared_ab, shared_ba, secLen) == 0) {
+ WH_TEST_PRINT("ECC ephemeral ECDH SUCCESS\n");
+ }
+ else {
+ WH_ERROR_PRINT(
+ "ECC ephemeral ECDH FAILED TO MATCH\n");
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ word32 sigLen = sizeof(sig);
+ memcpy(hash, shared_ba, sizeof(hash));
+ ret = wc_ecc_sign_hash((void*)hash, sizeof(hash),
+ (void*)sig, &sigLen, rng,
+ bobKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_ecc_sign_hash %d\n",
+ ret);
+ }
+ else {
+ int res = 0;
+ ret = wc_ecc_verify_hash(
+ (void*)sig, sigLen, (void*)hash,
+ sizeof(hash), &res, bobKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to wc_ecc_verify_hash %d\n", ret);
+ }
+ else if (res == 1) {
+ WH_TEST_PRINT(
+ "ECC ephemeral SIGN/VERIFY SUCCESS\n");
+ }
+ else {
+ WH_ERROR_PRINT(
+ "ECC ephemeral SIGN/VERIFY FAIL\n");
+ ret = -1;
+ }
+ }
+ }
+ }
+ }
+ wc_ecc_free(aliceKey);
+ }
+ wc_ecc_free(bobKey);
+ }
+
+ /* Test Case 2: Server creates the keys and exports them to the client. */
+ if (ret == 0) {
+ memset(shared_ab, 0, sizeof(shared_ab));
+ memset(shared_ba, 0, sizeof(shared_ba));
+ memset(sig, 0, sizeof(sig));
+
+ ret = wc_ecc_init_ex(bobKey, NULL, WH_DEV_ID);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_ecc_init_ex for export key %d\n", ret);
+ }
+ else {
+ ret = wc_ecc_init_ex(aliceKey, NULL, WH_DEV_ID);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_ecc_init_ex for export key %d\n",
+ ret);
+ }
+ else {
+ ret = wh_Client_EccMakeExportKey(ctx, TEST_ECC_KEYSIZE,
+ TEST_ECC_CURVE_ID, bobKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to wh_Client_EccMakeExportKey %d\n", ret);
+ }
+ if (ret == 0) {
+ ret = wh_Client_EccMakeExportKey(
+ ctx, TEST_ECC_KEYSIZE, TEST_ECC_CURVE_ID, aliceKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to wh_Client_EccMakeExportKey %d\n", ret);
+ }
+ }
+ if (ret == 0) {
+ word32 secLen = TEST_ECC_KEYSIZE;
+ ret = wc_ecc_shared_secret(
+ bobKey, aliceKey, (byte*)shared_ab, &secLen);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to compute export key secret %d\n", ret);
+ }
+ }
+ if (ret == 0) {
+ word32 secLen = TEST_ECC_KEYSIZE;
+ ret = wc_ecc_shared_secret(
+ aliceKey, bobKey, (byte*)shared_ba, &secLen);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to compute export key secret %d\n", ret);
+ }
+ }
+ if (ret == 0) {
+ if (memcmp(shared_ab, shared_ba, TEST_ECC_KEYSIZE) != 0) {
+ WH_ERROR_PRINT(
+ "ECC export key ECDH FAILED TO MATCH\n");
+ ret = -1;
+ }
+ else {
+ WH_TEST_PRINT("ECC export key ECDH SUCCESS\n");
+ }
+ }
+ if (ret == 0) {
+ word32 sigLen = sizeof(sig);
+ memcpy(hash, shared_ba, sizeof(hash));
+ ret = wc_ecc_sign_hash((void*)hash, sizeof(hash),
+ (void*)sig, &sigLen, rng, bobKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to sign with export key %d\n",
+ ret);
+ }
+ else {
+ int res = 0;
+ ret = wc_ecc_verify_hash((void*)sig, sigLen,
+ (void*)hash, sizeof(hash),
+ &res, bobKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to verify with export key %d\n", ret);
+ }
+ else if (res != 1) {
+ WH_ERROR_PRINT(
+ "ECC export key SIGN/VERIFY FAIL\n");
+ ret = -1;
+ }
+ else {
+ WH_TEST_PRINT(
+ "ECC export key SIGN/VERIFY SUCCESS\n");
+ }
+ }
+ }
+ wc_ecc_free(aliceKey);
+ }
+ wc_ecc_free(bobKey);
+ }
+ }
+
+ /* Test Case 3: Use ONE server-cached key plus an ephemeral peer for ECDH.
+ * Limited to a single cached key so we don't blow the cache budget. */
+ if (ret == 0) {
+ memset(shared_ab, 0, sizeof(shared_ab));
+ memset(shared_ba, 0, sizeof(shared_ba));
+ memset(sig, 0, sizeof(sig));
+ keyIdPrivate = WH_KEYID_ERASED;
+
+ ret = wh_Client_EccMakeCacheKey(ctx, TEST_ECC_KEYSIZE,
+ TEST_ECC_CURVE_ID, &keyIdPrivate, flags,
+ sizeof(labelPrivate), labelPrivate);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wh_Client_EccMakeCacheKey %d\n", ret);
+ }
+ if (ret == 0) {
+ ret = wc_ecc_init_ex(bobKey, NULL, WH_DEV_ID);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_ecc_init_ex for cache key %d\n",
+ ret);
+ }
+ else {
+ ret = wh_Client_EccSetKeyId(bobKey, keyIdPrivate);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wh_Client_EccSetKeyId %d\n", ret);
+ }
+ if (ret == 0) {
+ ret = wh_Client_EccGetKeyId(bobKey, &checkKeyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wh_Client_EccGetKeyId %d\n",
+ ret);
+ }
+ else if (checkKeyId != keyIdPrivate) {
+ WH_ERROR_PRINT(
+ "ECC key ID mismatch: got %u, expected %u\n",
+ checkKeyId, keyIdPrivate);
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ /* Required: cached key has no usable curve params yet. */
+ ret = wc_ecc_set_curve(bobKey, TEST_ECC_KEYSIZE,
+ TEST_ECC_CURVE_ID);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_ecc_set_curve %d\n", ret);
+ }
+ }
+ if (ret == 0) {
+ ret = wc_ecc_init_ex(aliceKey, NULL, WH_DEV_ID);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to wc_ecc_init_ex for peer key %d\n", ret);
+ }
+ else {
+ ret = wc_ecc_make_key(rng, TEST_ECC_KEYSIZE, aliceKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to wc_ecc_make_key for peer %d\n", ret);
+ }
+ if (ret == 0) {
+ word32 secLen = TEST_ECC_KEYSIZE;
+ ret = wc_ecc_shared_secret(
+ bobKey, aliceKey, (byte*)shared_ab, &secLen);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to compute cache key secret %d\n",
+ ret);
+ }
+ }
+ if (ret == 0) {
+ word32 secLen = TEST_ECC_KEYSIZE;
+ ret = wc_ecc_shared_secret(
+ aliceKey, bobKey, (byte*)shared_ba, &secLen);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to compute peer secret %d\n", ret);
+ }
+ }
+ if (ret == 0) {
+ if (memcmp(shared_ab, shared_ba,
+ TEST_ECC_KEYSIZE) != 0) {
+ WH_ERROR_PRINT(
+ "ECC cache key ECDH FAILED TO MATCH\n");
+ ret = -1;
+ }
+ else {
+ WH_TEST_PRINT("ECC cache key ECDH SUCCESS\n");
+ }
+ }
+ wc_ecc_free(aliceKey);
+ }
+ }
+ if (ret == 0) {
+ word32 sigLen = sizeof(sig);
+ memcpy(hash, shared_ba, sizeof(hash));
+ ret = wc_ecc_sign_hash((void*)hash, sizeof(hash),
+ (void*)sig, &sigLen, rng, bobKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to sign with cache key %d\n",
+ ret);
+ }
+ else {
+ int res = 0;
+ ret = wc_ecc_verify_hash((void*)sig, sigLen,
+ (void*)hash, sizeof(hash),
+ &res, bobKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to verify with cache key %d\n", ret);
+ }
+ else if (res != 1) {
+ WH_ERROR_PRINT(
+ "ECC cache key SIGN/VERIFY FAIL\n");
+ ret = -1;
+ }
+ else {
+ WH_TEST_PRINT(
+ "ECC cache key SIGN/VERIFY SUCCESS\n");
+ }
+ }
+ }
+ wc_ecc_free(bobKey);
+ }
+ }
+ if (!WH_KEYID_ISERASED(keyIdPrivate)) {
+ (void)wh_Client_KeyEvict(ctx, keyIdPrivate);
+ }
+ }
+
+ (void)wc_FreeRng(rng);
+
+ if (ret == 0) {
+ WH_TEST_PRINT("ECC SUCCESS\n");
+ }
+ return ret;
+}
+
+/* Cache slot replacement: a second MakeCacheKey on the same keyId must
+ * return the new key on subsequent export, not the original. */
+int whTest_CryptoEccCacheDuplicate(whClientContext* ctx)
+{
+ int ret = WH_ERROR_OK;
+ whKeyId keyId = WH_KEYID_ERASED;
+ uint8_t key1[ECC_BUFSIZE];
+ uint8_t key2[ECC_BUFSIZE];
+ uint16_t key1Len = sizeof(key1);
+ uint16_t key2Len = sizeof(key2);
+
+ WH_TEST_PRINT(" Testing ECC cache duplicate returns latest key...\n");
+
+ ret = wh_Client_EccMakeCacheKey(ctx, 32, ECC_SECP256R1, &keyId,
+ WH_NVM_FLAGS_NONE, 0, NULL);
+ if (ret == WH_ERROR_OK) {
+ ret = wh_Client_KeyExport(ctx, keyId, NULL, 0, key1, &key1Len);
+ }
+
+ if (ret == WH_ERROR_OK) {
+ ret = wh_Client_EccMakeCacheKey(ctx, 32, ECC_SECP256R1, &keyId,
+ WH_NVM_FLAGS_NONE, 0, NULL);
+ }
+
+ if (ret == WH_ERROR_OK) {
+ key2Len = sizeof(key2);
+ ret = wh_Client_KeyExport(ctx, keyId, NULL, 0, key2, &key2Len);
+ }
+
+ if (ret == WH_ERROR_OK) {
+ if ((key1Len == key2Len) && (memcmp(key1, key2, key1Len) == 0)) {
+ WH_ERROR_PRINT(" FAIL: Export returned original ECC key after "
+ "duplicate insert\n");
+ ret = WH_ERROR_ABORTED;
+ }
+ else {
+ WH_TEST_PRINT(
+ " PASS: Export returned most recent cached ECC key\n");
+ }
+ }
+
+ if (!WH_KEYID_ISERASED(keyId)) {
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ }
+ return ret;
+}
+
+/* Cache a NONEXPORTABLE ECC P-256 keypair on the server, sign a hash there,
+ * then export only the public half via wh_Client_EccExportPublicKey and
+ * verify the signature client-side. */
+int whTest_CryptoEccExportPublicKey(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ WC_RNG rng[1];
+ ecc_key hsmKey[1];
+ ecc_key pubKey[1];
+ whKeyId keyId = WH_KEYID_ERASED;
+ /* Non-zero hash: wolfCrypt rejects all-zero hashes for ECDSA sign/verify
+ * (returns ECC_BAD_ARG_E) unless WC_ALLOW_ECC_ZERO_HASH is defined. */
+ uint8_t hash[TEST_ECC_KEYSIZE] = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20};
+ uint8_t sig[ECC_MAX_SIG_SIZE];
+ word32 sigLen = sizeof(sig);
+ int verify = 0;
+ uint8_t denyBuf[256];
+ uint16_t denyLen = sizeof(denyBuf);
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+
+ ret = wh_Client_EccMakeCacheKey(
+ ctx, TEST_ECC_KEYSIZE, TEST_ECC_CURVE_ID, &keyId,
+ WH_NVM_FLAGS_USAGE_SIGN | WH_NVM_FLAGS_USAGE_VERIFY |
+ WH_NVM_FLAGS_NONEXPORTABLE,
+ 0, NULL);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to make NONEXPORTABLE cached ECC key %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ /* Full export must be denied by the NONEXPORTABLE policy. */
+ {
+ int denyRet = wh_Client_KeyExport(ctx, keyId, NULL, 0, denyBuf,
+ &denyLen);
+ if (denyRet != WH_ERROR_ACCESS) {
+ WH_ERROR_PRINT(
+ "NONEXPORTABLE ECC full export was not denied: %d\n", denyRet);
+ ret = -1;
+ }
+ }
+
+ /* Sign on the server using the cached private key. */
+ if (ret == 0) {
+ ret = wc_ecc_init_ex(hsmKey, NULL, devId);
+ if (ret == 0) {
+ ret = wh_Client_EccSetKeyId(hsmKey, keyId);
+ }
+ if (ret == 0) {
+ ret = wc_ecc_sign_hash(hash, sizeof(hash), sig, &sigLen, rng,
+ hsmKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("HSM ECC sign failed %d\n", ret);
+ }
+ }
+ wc_ecc_free(hsmKey);
+ }
+
+ /* Public-only export must succeed and verify the signature client-side. */
+ if (ret == 0) {
+ ret = wc_ecc_init_ex(pubKey, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wh_Client_EccExportPublicKey(ctx, keyId, pubKey, 0, NULL);
+ if (ret != 0) {
+ WH_ERROR_PRINT("wh_Client_EccExportPublicKey failed %d\n", ret);
+ }
+ else if (pubKey->type != ECC_PUBLICKEY) {
+ WH_ERROR_PRINT(
+ "Exported ECC key is not public-only (type=%d)\n",
+ pubKey->type);
+ ret = -1;
+ }
+ else {
+ ret = wc_ecc_verify_hash(sig, sigLen, hash, sizeof(hash),
+ &verify, pubKey);
+ if (ret != 0 || verify != 1) {
+ WH_ERROR_PRINT(
+ "Client-side ECC verify failed ret=%d verify=%d\n",
+ ret, verify);
+ if (ret == 0) {
+ ret = -1;
+ }
+ }
+ }
+ wc_ecc_free(pubKey);
+ }
+ }
+
+ if (!WH_KEYID_ISERASED(keyId)) {
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ }
+ (void)wc_FreeRng(rng);
+
+ if (ret == 0) {
+ WH_TEST_PRINT("ECC EXPORT-PUBLIC DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+#if !defined(WOLF_CRYPTO_CB_ONLY_ECC)
+
+/* Curve sizes used by the cross-verify and async test families. */
+#define WH_TEST_ECC_P256_KEY_SIZE 32
+#define WH_TEST_ECC_P384_KEY_SIZE 48
+#define WH_TEST_ECC_P521_KEY_SIZE 66
+/* Use maximum digest size for all curves to test hash truncation edge cases.
+ * ECDSA implementations must properly truncate hashes larger than the curve
+ * order. */
+#define WH_TEST_ECC_HASH_SIZE WC_MAX_DIGEST_SIZE
+
+static int whTest_CryptoEccCrossVerify_OneCurve(whClientContext* ctx,
+ WC_RNG* rng, int keySize,
+ int curveId, const char* name)
+{
+ ecc_key hsmKey[1] = {0};
+ ecc_key swKey[1] = {0};
+ uint8_t hash[WH_TEST_ECC_HASH_SIZE] = {0};
+ uint8_t sig[ECC_MAX_SIG_SIZE] = {0};
+ uint8_t pubX[ECC_MAXSIZE] = {0};
+ uint8_t pubY[ECC_MAXSIZE] = {0};
+ word32 pubXLen = 0;
+ word32 pubYLen = 0;
+ word32 sigLen = 0;
+ int res = 0;
+ whKeyId keyId = WH_KEYID_ERASED;
+ int hsmKeyInit = 0;
+ int swKeyInit = 0;
+ int ret = WH_ERROR_OK;
+ int i;
+
+ /* Use non-repeating pattern to detect hash truncation bugs */
+ for (i = 0; i < WH_TEST_ECC_HASH_SIZE; i++) {
+ hash[i] = (uint8_t)i;
+ }
+
+ WH_TEST_PRINT(" Testing %s curve...\n", name);
+
+ pubXLen = keySize;
+ pubYLen = keySize;
+
+ /* Test 1: HSM sign + Software verify */
+ ret = wc_ecc_init_ex(hsmKey, NULL, WH_DEV_ID);
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: Failed to init HSM key: %d\n", name, ret);
+ }
+ else {
+ hsmKeyInit = 1;
+ }
+ if (ret == 0) {
+ ret = wc_ecc_make_key(rng, keySize, hsmKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: Failed to generate HSM key: %d\n", name, ret);
+ }
+ }
+ if (ret == 0) {
+ ret = wc_ecc_export_public_raw(hsmKey, pubX, &pubXLen, pubY, &pubYLen);
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: Failed to export HSM public key: %d\n", name,
+ ret);
+ }
+ }
+ if (ret == 0) {
+ sigLen = sizeof(sig);
+ ret = wc_ecc_sign_hash(hash, sizeof(hash), sig, &sigLen, rng, hsmKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: HSM sign failed: %d\n", name, ret);
+ }
+ }
+ if (ret == 0) {
+ ret = wc_ecc_init_ex(swKey, NULL, INVALID_DEVID);
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: Failed to init SW key: %d\n", name, ret);
+ }
+ else {
+ swKeyInit = 1;
+ }
+ }
+ if (ret == 0) {
+ ret = wc_ecc_import_unsigned(swKey, pubX, pubY, NULL, curveId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: Failed to import public to SW: %d\n", name,
+ ret);
+ }
+ }
+ if (ret == 0) {
+ res = 0;
+ ret = wc_ecc_verify_hash(sig, sigLen, hash, sizeof(hash), &res, swKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: SW verify failed: %d\n", name, ret);
+ }
+ else if (res != 1) {
+ WH_ERROR_PRINT("%s: HSM sign + SW verify: signature invalid\n",
+ name);
+ ret = -1;
+ }
+ else {
+ WH_TEST_PRINT(" HSM sign + SW verify: PASS\n");
+ }
+ }
+ if (swKeyInit) {
+ wc_ecc_free(swKey);
+ swKeyInit = 0;
+ }
+ if (hsmKeyInit) {
+ if (wh_Client_EccGetKeyId(hsmKey, &keyId) == 0 &&
+ !WH_KEYID_ISERASED(keyId)) {
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ }
+ wc_ecc_free(hsmKey);
+ hsmKeyInit = 0;
+ }
+
+ /* Test 2: Software sign + HSM verify */
+ if (ret == 0) {
+ memset(sig, 0, sizeof(sig));
+ memset(pubX, 0, sizeof(pubX));
+ memset(pubY, 0, sizeof(pubY));
+ pubXLen = keySize;
+ pubYLen = keySize;
+ keyId = WH_KEYID_ERASED;
+
+ ret = wc_ecc_init_ex(swKey, NULL, INVALID_DEVID);
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: Failed to init SW key: %d\n", name, ret);
+ }
+ else {
+ swKeyInit = 1;
+ }
+ }
+ if (ret == 0) {
+ ret = wc_ecc_make_key(rng, keySize, swKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: Failed to generate SW key: %d\n", name, ret);
+ }
+ }
+ if (ret == 0) {
+ ret = wc_ecc_export_public_raw(swKey, pubX, &pubXLen, pubY, &pubYLen);
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: Failed to export SW public key: %d\n", name,
+ ret);
+ }
+ }
+ if (ret == 0) {
+ sigLen = sizeof(sig);
+ ret = wc_ecc_sign_hash(hash, sizeof(hash), sig, &sigLen, rng, swKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: SW sign failed: %d\n", name, ret);
+ }
+ }
+ if (ret == 0) {
+ ret = wc_ecc_init_ex(hsmKey, NULL, WH_DEV_ID);
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: Failed to init HSM key: %d\n", name, ret);
+ }
+ else {
+ hsmKeyInit = 1;
+ }
+ }
+ if (ret == 0) {
+ ret = wc_ecc_import_unsigned(hsmKey, pubX, pubY, NULL, curveId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: Failed to import public to HSM: %d\n", name,
+ ret);
+ }
+ }
+ if (ret == 0) {
+ res = 0;
+ ret = wc_ecc_verify_hash(sig, sigLen, hash, sizeof(hash), &res, hsmKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: HSM verify failed: %d\n", name, ret);
+ }
+ else if (res != 1) {
+ WH_ERROR_PRINT("%s: SW sign + HSM verify: signature invalid\n",
+ name);
+ ret = -1;
+ }
+ else {
+ WH_TEST_PRINT(" SW sign + HSM verify: PASS\n");
+ }
+ }
+ if (hsmKeyInit) {
+ if (wh_Client_EccGetKeyId(hsmKey, &keyId) == 0 &&
+ !WH_KEYID_ISERASED(keyId)) {
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ }
+ wc_ecc_free(hsmKey);
+ }
+ if (swKeyInit) {
+ wc_ecc_free(swKey);
+ }
+ return ret;
+}
+
+int whTest_CryptoEccCrossVerify(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = WH_ERROR_OK;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+
+ WH_TEST_PRINT("Testing ECDSA cross-verification (HSM<->SW)...\n");
+
+#if !defined(NO_ECC256)
+ if (ret == 0) {
+ ret = whTest_CryptoEccCrossVerify_OneCurve(
+ ctx, rng, WH_TEST_ECC_P256_KEY_SIZE, ECC_SECP256R1, "P-256");
+ }
+#endif
+
+#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
+ if (ret == 0) {
+ ret = whTest_CryptoEccCrossVerify_OneCurve(
+ ctx, rng, WH_TEST_ECC_P384_KEY_SIZE, ECC_SECP384R1, "P-384");
+ }
+#endif
+
+#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
+ if (ret == 0) {
+ ret = whTest_CryptoEccCrossVerify_OneCurve(
+ ctx, rng, WH_TEST_ECC_P521_KEY_SIZE, ECC_SECP521R1, "P-521");
+ }
+#endif
+
+ (void)wc_FreeRng(rng);
+
+ if (ret == 0) {
+ WH_TEST_PRINT("ECDSA cross-verification SUCCESS\n");
+ }
+ return ret;
+}
+
+/* Async sign/verify per curve. Generates a server-cached signing key, signs
+ * via wh_Client_EccSign{Request,Response}, software-verifies, then imports
+ * the public key into a separate cache slot and async-verifies. Also covers
+ * BADARGS and stuck-ctx invariants. */
+static int whTest_CryptoEccSignVerifyAsync_OneCurve(whClientContext* ctx,
+ WC_RNG* rng, int keySize,
+ int curveId,
+ const char* name)
+{
+ ecc_key hsmKey[1] = {0};
+ ecc_key swKey[1] = {0};
+ uint8_t hash[WH_TEST_ECC_HASH_SIZE] = {0};
+ uint8_t sig[ECC_MAX_SIG_SIZE] = {0};
+ uint8_t pubX[ECC_MAXSIZE] = {0};
+ uint8_t pubY[ECC_MAXSIZE] = {0};
+ word32 pubXLen = 0;
+ word32 pubYLen = 0;
+ uint16_t sigLen = 0;
+ int res = 0;
+ whKeyId signKeyId = WH_KEYID_ERASED;
+ whKeyId verifyKeyId = WH_KEYID_ERASED;
+ int hsmKeyInit = 0;
+ int swKeyInit = 0;
+ int ret = WH_ERROR_OK;
+ int i;
+
+ for (i = 0; i < WH_TEST_ECC_HASH_SIZE; i++) {
+ hash[i] = (uint8_t)i;
+ }
+
+ WH_TEST_PRINT(" Testing async Sign/Verify %s curve...\n", name);
+
+ pubXLen = keySize;
+ pubYLen = keySize;
+
+ ret = wc_ecc_init_ex(hsmKey, NULL, WH_DEV_ID);
+ if (ret == 0) {
+ hsmKeyInit = 1;
+ ret = wc_ecc_make_key(rng, keySize, hsmKey);
+ }
+ if (ret == 0) {
+ uint8_t signLabel[] = "TestEccAsyncSign";
+ signKeyId = WH_KEYID_ERASED;
+ ret = wh_Client_EccImportKey(
+ ctx, hsmKey, &signKeyId, WH_NVM_FLAGS_USAGE_SIGN,
+ sizeof(signLabel), signLabel);
+ }
+
+ if (ret == 0) {
+ sigLen = sizeof(sig);
+ ret = wh_Client_EccSignRequest(ctx, signKeyId, hash, sizeof(hash));
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("%s: EccSignRequest failed: %d\n", name, ret);
+ }
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_EccSignResponse(ctx, sig, &sigLen);
+ } while (ret == WH_ERROR_NOTREADY);
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("%s: EccSignResponse failed: %d\n", name, ret);
+ }
+ }
+
+ if (ret == 0) {
+ int badret =
+ wh_Client_EccSignRequest(ctx, WH_KEYID_ERASED, hash, sizeof(hash));
+ if (badret != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT("%s: EccSignRequest with erased keyId returned %d "
+ "(want BADARGS)\n",
+ name, badret);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ ret = wc_ecc_export_public_raw(hsmKey, pubX, &pubXLen, pubY, &pubYLen);
+ }
+
+ if (ret == 0) {
+ ret = wc_ecc_init_ex(swKey, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ swKeyInit = 1;
+ ret = wc_ecc_import_unsigned(swKey, pubX, pubY, NULL, curveId);
+ }
+ }
+ if (ret == 0) {
+ res = 0;
+ ret = wc_ecc_verify_hash(sig, sigLen, hash, sizeof(hash), &res, swKey);
+ if (ret == 0 && res != 1) {
+ WH_ERROR_PRINT("%s: async sign produced invalid signature\n", name);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ ecc_key pubOnly[1] = {0};
+ uint8_t label[] = "TestEccAsyncVerify";
+
+ ret = wc_ecc_init_ex(pubOnly, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wc_ecc_import_unsigned(pubOnly, pubX, pubY, NULL, curveId);
+ }
+ if (ret == 0) {
+ verifyKeyId = WH_KEYID_ERASED;
+ ret = wh_Client_EccImportKey(
+ ctx, pubOnly, &verifyKeyId, WH_NVM_FLAGS_USAGE_VERIFY,
+ sizeof(label), label);
+ }
+ wc_ecc_free(pubOnly);
+ }
+ if (ret == 0) {
+ ret = wh_Client_EccVerifyRequest(ctx, verifyKeyId, sig, sigLen, hash,
+ sizeof(hash));
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("%s: EccVerifyRequest failed: %d\n", name, ret);
+ }
+ }
+ if (ret == 0) {
+ res = 0;
+ do {
+ ret = wh_Client_EccVerifyResponse(ctx, NULL, &res);
+ } while (ret == WH_ERROR_NOTREADY);
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("%s: EccVerifyResponse failed: %d\n", name, ret);
+ }
+ else if (res != 1) {
+ WH_ERROR_PRINT("%s: async verify returned res=%d (want 1)\n", name,
+ res);
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ int badret = wh_Client_EccVerifyRequest(ctx, WH_KEYID_ERASED, sig,
+ sigLen, hash, sizeof(hash));
+ if (badret != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "%s: EccVerifyRequest with erased keyId returned %d "
+ "(want BADARGS)\n",
+ name, badret);
+ ret = -1;
+ }
+ }
+
+ /* NULL ctx must be rejected by every async half. */
+ if (ret == 0) {
+ int rc1 = wh_Client_EccSignRequest(NULL, signKeyId, hash, sizeof(hash));
+ int rc2 = wh_Client_EccSignResponse(NULL, sig, &sigLen);
+ int rc3 = wh_Client_EccVerifyRequest(NULL, verifyKeyId, sig, sigLen,
+ hash, sizeof(hash));
+ int rc4 = wh_Client_EccVerifyResponse(NULL, NULL, &res);
+ if (rc1 != WH_ERROR_BADARGS || rc2 != WH_ERROR_BADARGS ||
+ rc3 != WH_ERROR_BADARGS || rc4 != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT("%s: NULL ctx async API rc=(%d,%d,%d,%d) want all "
+ "BADARGS\n",
+ name, rc1, rc2, rc3, rc4);
+ ret = -1;
+ }
+ }
+
+ /* Mismatched output-arg shape on Response must BADARGS pre-Recv. */
+ if (ret == 0) {
+ int rc1 = wh_Client_EccSignResponse(ctx, sig, NULL);
+ int rc2 = wh_Client_EccVerifyResponse(ctx, NULL, NULL);
+ if (rc1 != WH_ERROR_BADARGS || rc2 != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "%s: bad-arg Response rc=(%d,%d) want both BADARGS\n", name,
+ rc1, rc2);
+ ret = -1;
+ }
+ }
+
+ /* Wrapper-level: response-side bad args must be caught before SendRequest
+ * so the caller's ctx is not left stuck-pending. */
+ if (ret == 0) {
+ int badret = wh_Client_EccVerify(ctx, hsmKey, sig, sigLen, hash,
+ sizeof(hash), NULL);
+ if (badret != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT("%s: EccVerify with NULL out_res returned %d "
+ "(want BADARGS)\n",
+ name, badret);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ int rc;
+ sigLen = sizeof(sig);
+ rc = wh_Client_EccSignRequest(ctx, signKeyId, hash, sizeof(hash));
+ if (rc == WH_ERROR_OK) {
+ do {
+ rc = wh_Client_EccSignResponse(ctx, sig, &sigLen);
+ } while (rc == WH_ERROR_NOTREADY);
+ }
+ if (rc != WH_ERROR_OK) {
+ WH_ERROR_PRINT("%s: ctx stuck after wrapper BADARGS (rc=%d)\n",
+ name, rc);
+ ret = -1;
+ }
+ }
+
+ /* Too-small sig buffer: must return BUFFER_SIZE with required size in
+ * *inout_sig_len, and must not leak partial signature bytes. */
+ if (ret == 0) {
+ uint8_t small_buf[1] = {0xAA};
+ uint16_t small_len = sizeof(small_buf);
+ int rc;
+ rc = wh_Client_EccSignRequest(ctx, signKeyId, hash, sizeof(hash));
+ if (rc == WH_ERROR_OK) {
+ do {
+ rc = wh_Client_EccSignResponse(ctx, small_buf, &small_len);
+ } while (rc == WH_ERROR_NOTREADY);
+ }
+ if (rc != WH_ERROR_BUFFER_SIZE) {
+ WH_ERROR_PRINT(
+ "%s: too-small buffer Sign Response rc=%d (want BUFFER_SIZE)\n",
+ name, rc);
+ ret = -1;
+ }
+ else if (small_len <= 1 || small_len > ECC_MAX_SIG_SIZE) {
+ WH_ERROR_PRINT("%s: too-small buffer Sign required size=%u "
+ "(want > 1 and <= ECC_MAX_SIG_SIZE)\n",
+ name, (unsigned)small_len);
+ ret = -1;
+ }
+ else if (small_buf[0] != 0xAA) {
+ WH_ERROR_PRINT(
+ "%s: partial signature leaked into too-small buffer\n", name);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT(" async Sign/Verify %s: PASS\n", name);
+ }
+
+ if (!WH_KEYID_ISERASED(verifyKeyId)) {
+ (void)wh_Client_KeyEvict(ctx, verifyKeyId);
+ }
+ if (!WH_KEYID_ISERASED(signKeyId)) {
+ (void)wh_Client_KeyEvict(ctx, signKeyId);
+ }
+ if (swKeyInit) {
+ wc_ecc_free(swKey);
+ }
+ if (hsmKeyInit) {
+ wc_ecc_free(hsmKey);
+ }
+ return ret;
+}
+
+#ifdef HAVE_ECC_DHE
+/* Async ECDH per curve: generate two cached private keys, import each side's
+ * public into a separate cache slot, run async SharedSecret both directions,
+ * compare. Plus BUFFER_SIZE and BADARGS contracts on both wrapper and async
+ * halves. */
+static int whTest_CryptoEccSharedSecretAsync_OneCurve(whClientContext* ctx,
+ WC_RNG* rng, int keySize,
+ int curveId,
+ const char* name)
+{
+ ecc_key keyA[1] = {0};
+ ecc_key keyB[1] = {0};
+ ecc_key pubA[1] = {0};
+ ecc_key pubB[1] = {0};
+ uint8_t pubAx[ECC_MAXSIZE] = {0};
+ uint8_t pubAy[ECC_MAXSIZE] = {0};
+ uint8_t pubBx[ECC_MAXSIZE] = {0};
+ uint8_t pubBy[ECC_MAXSIZE] = {0};
+ word32 pubAxLen = 0;
+ word32 pubAyLen = 0;
+ word32 pubBxLen = 0;
+ word32 pubByLen = 0;
+ uint8_t secret_AB[ECC_MAXSIZE] = {0};
+ uint8_t secret_BA[ECC_MAXSIZE] = {0};
+ uint16_t secret_AB_len = sizeof(secret_AB);
+ uint16_t secret_BA_len = sizeof(secret_BA);
+ whKeyId privAId = WH_KEYID_ERASED;
+ whKeyId privBId = WH_KEYID_ERASED;
+ whKeyId pubAId = WH_KEYID_ERASED;
+ whKeyId pubBId = WH_KEYID_ERASED;
+ int keyAInit = 0;
+ int keyBInit = 0;
+ int pubAInit = 0;
+ int pubBInit = 0;
+ uint8_t labelA[] = "TestEccDhAsyncA";
+ uint8_t labelB[] = "TestEccDhAsyncB";
+ int ret = WH_ERROR_OK;
+
+ WH_TEST_PRINT(" Testing async ECDH %s curve...\n", name);
+
+ pubAxLen = pubAyLen = pubBxLen = pubByLen = keySize;
+
+ ret = wc_ecc_init_ex(keyA, NULL, WH_DEV_ID);
+ if (ret == 0) {
+ keyAInit = 1;
+ ret = wc_ecc_make_key(rng, keySize, keyA);
+ }
+ if (ret == 0) {
+ uint8_t privLabelA[] = "TestEccDhAsyncPrivA";
+ privAId = WH_KEYID_ERASED;
+ ret = wh_Client_EccImportKey(
+ ctx, keyA, &privAId, WH_NVM_FLAGS_USAGE_DERIVE,
+ sizeof(privLabelA), privLabelA);
+ }
+ if (ret == 0) {
+ ret = wc_ecc_init_ex(keyB, NULL, WH_DEV_ID);
+ }
+ if (ret == 0) {
+ keyBInit = 1;
+ ret = wc_ecc_make_key(rng, keySize, keyB);
+ }
+ if (ret == 0) {
+ uint8_t privLabelB[] = "TestEccDhAsyncPrivB";
+ privBId = WH_KEYID_ERASED;
+ ret = wh_Client_EccImportKey(
+ ctx, keyB, &privBId, WH_NVM_FLAGS_USAGE_DERIVE,
+ sizeof(privLabelB), privLabelB);
+ }
+
+ if (ret == 0) {
+ ret =
+ wc_ecc_export_public_raw(keyA, pubAx, &pubAxLen, pubAy, &pubAyLen);
+ }
+ if (ret == 0) {
+ ret =
+ wc_ecc_export_public_raw(keyB, pubBx, &pubBxLen, pubBy, &pubByLen);
+ }
+
+ if (ret == 0) {
+ ret = wc_ecc_init_ex(pubA, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ pubAInit = 1;
+ ret = wc_ecc_import_unsigned(pubA, pubAx, pubAy, NULL, curveId);
+ }
+ }
+ if (ret == 0) {
+ ret = wh_Client_EccImportKey(ctx, pubA, &pubAId,
+ WH_NVM_FLAGS_USAGE_DERIVE, sizeof(labelA),
+ labelA);
+ }
+ if (ret == 0) {
+ ret = wc_ecc_init_ex(pubB, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ pubBInit = 1;
+ ret = wc_ecc_import_unsigned(pubB, pubBx, pubBy, NULL, curveId);
+ }
+ }
+ if (ret == 0) {
+ ret = wh_Client_EccImportKey(ctx, pubB, &pubBId,
+ WH_NVM_FLAGS_USAGE_DERIVE, sizeof(labelB),
+ labelB);
+ }
+
+ if (ret == 0) {
+ ret = wh_Client_EccSharedSecretRequest(ctx, privAId, pubBId);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_EccSharedSecretResponse(ctx, secret_AB,
+ &secret_AB_len);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+
+ if (ret == 0) {
+ ret = wh_Client_EccSharedSecretRequest(ctx, privBId, pubAId);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_EccSharedSecretResponse(ctx, secret_BA,
+ &secret_BA_len);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+
+ if (ret == 0) {
+ if (secret_AB_len != secret_BA_len ||
+ memcmp(secret_AB, secret_BA, secret_AB_len) != 0) {
+ WH_ERROR_PRINT("%s: async ECDH secrets differ across sides\n",
+ name);
+ ret = -1;
+ }
+ }
+
+ /* Too-small output buffer: BUFFER_SIZE + required size, no leak. */
+ if (ret == 0) {
+ uint8_t small_buf[1] = {0xAA};
+ uint16_t small_len = sizeof(small_buf);
+ int rc;
+ rc = wh_Client_EccSharedSecretRequest(ctx, privAId, pubBId);
+ if (rc == WH_ERROR_OK) {
+ do {
+ rc = wh_Client_EccSharedSecretResponse(ctx, small_buf,
+ &small_len);
+ } while (rc == WH_ERROR_NOTREADY);
+ }
+ if (rc != WH_ERROR_BUFFER_SIZE) {
+ WH_ERROR_PRINT(
+ "%s: too-small buffer ECDH Response rc=%d (want BUFFER_SIZE)\n",
+ name, rc);
+ ret = -1;
+ }
+ else if (small_len != secret_AB_len) {
+ WH_ERROR_PRINT("%s: too-small buffer required size=%u (want %u)\n",
+ name, (unsigned)small_len,
+ (unsigned)secret_AB_len);
+ ret = -1;
+ }
+ else if (small_buf[0] != 0xAA) {
+ WH_ERROR_PRINT("%s: partial secret leaked into too-small buffer\n",
+ name);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ uint8_t small_buf[1] = {0xAA};
+ uint16_t small_len = sizeof(small_buf);
+ int rc =
+ wh_Client_EccSharedSecret(ctx, keyA, pubB, small_buf, &small_len);
+ if (rc != WH_ERROR_BUFFER_SIZE) {
+ WH_ERROR_PRINT(
+ "%s: too-small buffer ECDH wrapper rc=%d (want BUFFER_SIZE)\n",
+ name, rc);
+ ret = -1;
+ }
+ else if (small_len != secret_AB_len) {
+ WH_ERROR_PRINT(
+ "%s: wrapper too-small required size=%u (want %u)\n", name,
+ (unsigned)small_len, (unsigned)secret_AB_len);
+ ret = -1;
+ }
+ else if (small_buf[0] != 0xAA) {
+ WH_ERROR_PRINT(
+ "%s: wrapper leaked partial secret into too-small buffer\n",
+ name);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ int badret =
+ wh_Client_EccSharedSecretRequest(ctx, WH_KEYID_ERASED, pubBId);
+ if (badret != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "%s: ECDH Request with erased priv keyId returned %d\n", name,
+ badret);
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ int badret =
+ wh_Client_EccSharedSecretRequest(ctx, privAId, WH_KEYID_ERASED);
+ if (badret != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "%s: ECDH Request with erased pub keyId returned %d\n", name,
+ badret);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ int rc1 = wh_Client_EccSharedSecretRequest(NULL, privAId, pubBId);
+ int rc2 = wh_Client_EccSharedSecretResponse(NULL, secret_AB,
+ &secret_AB_len);
+ if (rc1 != WH_ERROR_BADARGS || rc2 != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "%s: NULL ctx async ECDH rc=(%d,%d) want BADARGS\n", name, rc1,
+ rc2);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ int rc = wh_Client_EccSharedSecretResponse(ctx, secret_AB, NULL);
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT("%s: SharedSecretResponse(out, NULL) returned %d "
+ "(want BADARGS)\n",
+ name, rc);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ int badret =
+ wh_Client_EccSharedSecret(ctx, keyA, pubB, secret_AB, NULL);
+ if (badret != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "%s: EccSharedSecret with NULL inout_size returned %d "
+ "(want BADARGS)\n",
+ name, badret);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ int rc;
+ secret_AB_len = sizeof(secret_AB);
+ rc = wh_Client_EccSharedSecretRequest(ctx, privAId, pubBId);
+ if (rc == WH_ERROR_OK) {
+ do {
+ rc = wh_Client_EccSharedSecretResponse(ctx, secret_AB,
+ &secret_AB_len);
+ } while (rc == WH_ERROR_NOTREADY);
+ }
+ if (rc != WH_ERROR_OK) {
+ WH_ERROR_PRINT(
+ "%s: ctx stuck after ECDH wrapper BADARGS (rc=%d)\n", name, rc);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT(" async ECDH %s: PASS\n", name);
+ }
+
+ if (!WH_KEYID_ISERASED(pubBId)) {
+ (void)wh_Client_KeyEvict(ctx, pubBId);
+ }
+ if (!WH_KEYID_ISERASED(pubAId)) {
+ (void)wh_Client_KeyEvict(ctx, pubAId);
+ }
+ if (!WH_KEYID_ISERASED(privBId)) {
+ (void)wh_Client_KeyEvict(ctx, privBId);
+ }
+ if (!WH_KEYID_ISERASED(privAId)) {
+ (void)wh_Client_KeyEvict(ctx, privAId);
+ }
+ if (pubBInit) {
+ wc_ecc_free(pubB);
+ }
+ if (pubAInit) {
+ wc_ecc_free(pubA);
+ }
+ if (keyBInit) {
+ wc_ecc_free(keyB);
+ }
+ if (keyAInit) {
+ wc_ecc_free(keyA);
+ }
+ return ret;
+}
+#endif /* HAVE_ECC_DHE */
+
+/* Async server-side keygen per curve: MakeCacheKey async (then sign/verify
+ * proves the cached key is usable), MakeExportKey async (then local
+ * sign/verify proves the exported struct is well-formed), plus arg-shape
+ * contracts on every async half. */
+static int whTest_CryptoEccMakeKeyAsync_OneCurve(whClientContext* ctx,
+ WC_RNG* rng, int keySize,
+ int curveId, const char* name)
+{
+ ecc_key exportKey[1] = {0};
+ ecc_key swKey[1] = {0};
+ uint8_t hash[WH_TEST_ECC_HASH_SIZE] = {0};
+ uint8_t sig[ECC_MAX_SIG_SIZE] = {0};
+ uint8_t pubX[ECC_MAXSIZE] = {0};
+ uint8_t pubY[ECC_MAXSIZE] = {0};
+ word32 pubXLen = 0;
+ word32 pubYLen = 0;
+ uint16_t sigLen = 0;
+ int res = 0;
+ whKeyId cacheKeyId = WH_KEYID_ERASED;
+ int exportKeyInit = 0;
+ int swKeyInit = 0;
+ uint8_t cacheLabel[] = "TestEccAsyncCacheGen";
+ int ret = WH_ERROR_OK;
+ int i;
+
+ for (i = 0; i < WH_TEST_ECC_HASH_SIZE; i++) {
+ hash[i] = (uint8_t)i;
+ }
+
+ pubXLen = keySize;
+ pubYLen = keySize;
+
+ WH_TEST_PRINT(" Testing async MakeKey %s curve...\n", name);
+
+ if (ret == 0) {
+ ret = wh_Client_EccMakeCacheKeyRequest(
+ ctx, keySize, curveId, WH_KEYID_ERASED, WH_NVM_FLAGS_USAGE_SIGN,
+ sizeof(cacheLabel), cacheLabel);
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("%s: EccMakeCacheKeyRequest failed: %d\n", name,
+ ret);
+ }
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_EccMakeCacheKeyResponse(ctx, &cacheKeyId);
+ } while (ret == WH_ERROR_NOTREADY);
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("%s: EccMakeCacheKeyResponse failed: %d\n", name,
+ ret);
+ }
+ else if (WH_KEYID_ISERASED(cacheKeyId)) {
+ WH_ERROR_PRINT("%s: server returned erased keyId\n", name);
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ sigLen = sizeof(sig);
+ ret = wh_Client_EccSignRequest(ctx, cacheKeyId, hash, sizeof(hash));
+ if (ret == WH_ERROR_OK) {
+ do {
+ ret = wh_Client_EccSignResponse(ctx, sig, &sigLen);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("%s: sign with cache-generated keyId failed: %d\n",
+ name, ret);
+ }
+ }
+ if (ret == 0) {
+ ecc_key pubOnly[1] = {0};
+ uint8_t labelBuf[WH_NVM_LABEL_LEN];
+ ret = wc_ecc_init_ex(pubOnly, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wh_Client_EccExportKey(ctx, cacheKeyId, pubOnly,
+ sizeof(labelBuf), labelBuf);
+ if (ret == 0) {
+ ret = wc_ecc_export_public_raw(pubOnly, pubX, &pubXLen, pubY,
+ &pubYLen);
+ }
+ wc_ecc_free(pubOnly);
+ }
+ if (ret != 0) {
+ WH_ERROR_PRINT("%s: export of cached pub failed: %d\n", name, ret);
+ }
+ }
+ if (ret == 0) {
+ ret = wc_ecc_init_ex(swKey, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ swKeyInit = 1;
+ ret = wc_ecc_import_unsigned(swKey, pubX, pubY, NULL, curveId);
+ }
+ if (ret == 0) {
+ res = 0;
+ ret = wc_ecc_verify_hash(sig, sigLen, hash, sizeof(hash), &res,
+ swKey);
+ if (ret == 0 && res != 1) {
+ WH_ERROR_PRINT(
+ "%s: software verify of cache-generated key failed\n",
+ name);
+ ret = -1;
+ }
+ }
+ }
+ if (swKeyInit) {
+ wc_ecc_free(swKey);
+ }
+
+ if (ret == 0) {
+ ret = wc_ecc_init_ex(exportKey, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ exportKeyInit = 1;
+ }
+ }
+ if (ret == 0) {
+ ret = wh_Client_EccMakeExportKeyRequest(ctx, keySize, curveId);
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("%s: EccMakeExportKeyRequest failed: %d\n", name,
+ ret);
+ }
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_EccMakeExportKeyResponse(ctx, exportKey);
+ } while (ret == WH_ERROR_NOTREADY);
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("%s: EccMakeExportKeyResponse failed: %d\n", name,
+ ret);
+ }
+ }
+ if (ret == 0) {
+ word32 swSigLen = sizeof(sig);
+ memset(sig, 0, sizeof(sig));
+ ret = wc_ecc_sign_hash(hash, sizeof(hash), sig, &swSigLen, rng,
+ exportKey);
+ if (ret == 0) {
+ res = 0;
+ ret = wc_ecc_verify_hash(sig, swSigLen, hash, sizeof(hash), &res,
+ exportKey);
+ if (ret == 0 && res != 1) {
+ WH_ERROR_PRINT(
+ "%s: local verify of exported keygen key failed\n", name);
+ ret = -1;
+ }
+ }
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "%s: local sign/verify of exported keygen key failed: %d\n",
+ name, ret);
+ }
+ }
+
+ if (ret == 0) {
+ int rc1 = wh_Client_EccMakeCacheKeyRequest(NULL, keySize, curveId,
+ WH_KEYID_ERASED,
+ WH_NVM_FLAGS_NONE, 0, NULL);
+ int rc2 = wh_Client_EccMakeCacheKeyResponse(NULL, &cacheKeyId);
+ int rc3 = wh_Client_EccMakeExportKeyRequest(NULL, keySize, curveId);
+ int rc4 = wh_Client_EccMakeExportKeyResponse(NULL, exportKey);
+ if (rc1 != WH_ERROR_BADARGS || rc2 != WH_ERROR_BADARGS ||
+ rc3 != WH_ERROR_BADARGS || rc4 != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "%s: NULL ctx async MakeKey rc=(%d,%d,%d,%d) want all "
+ "BADARGS\n",
+ name, rc1, rc2, rc3, rc4);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ int rc1 = wh_Client_EccMakeCacheKeyResponse(ctx, NULL);
+ int rc2 = wh_Client_EccMakeExportKeyResponse(ctx, NULL);
+ if (rc1 != WH_ERROR_BADARGS || rc2 != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "%s: NULL out arg Response rc=(%d,%d) want both BADARGS\n",
+ name, rc1, rc2);
+ ret = -1;
+ }
+ }
+
+ /* EPHEMERAL flag must be rejected by the cache Request so the export pair
+ * unambiguously owns ephemeral keygen. */
+ if (ret == 0) {
+ int rc = wh_Client_EccMakeCacheKeyRequest(
+ ctx, keySize, curveId, WH_KEYID_ERASED, WH_NVM_FLAGS_EPHEMERAL, 0,
+ NULL);
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT("%s: cache Request with EPHEMERAL flag returned %d "
+ "(want BADARGS)\n",
+ name, rc);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ whKeyId tmpId = WH_KEYID_ERASED;
+ int rc = wh_Client_EccMakeCacheKeyRequest(
+ ctx, keySize, curveId, WH_KEYID_ERASED, WH_NVM_FLAGS_USAGE_SIGN,
+ sizeof(cacheLabel), cacheLabel);
+ if (rc == WH_ERROR_OK) {
+ do {
+ rc = wh_Client_EccMakeCacheKeyResponse(ctx, &tmpId);
+ } while (rc == WH_ERROR_NOTREADY);
+ }
+ if (rc != WH_ERROR_OK) {
+ WH_ERROR_PRINT("%s: ctx stuck after MakeKey BADARGS (rc=%d)\n",
+ name, rc);
+ ret = -1;
+ }
+ if (!WH_KEYID_ISERASED(tmpId)) {
+ (void)wh_Client_KeyEvict(ctx, tmpId);
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT(" async MakeKey %s: PASS\n", name);
+ }
+
+ if (!WH_KEYID_ISERASED(cacheKeyId)) {
+ (void)wh_Client_KeyEvict(ctx, cacheKeyId);
+ }
+ if (exportKeyInit) {
+ wc_ecc_free(exportKey);
+ }
+ return ret;
+}
+
+int whTest_CryptoEccAsync(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = WH_ERROR_OK;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+
+ WH_TEST_PRINT("Testing ECC async API...\n");
+
+#if !defined(NO_ECC256)
+ if (ret == 0) {
+ ret = whTest_CryptoEccSignVerifyAsync_OneCurve(
+ ctx, rng, WH_TEST_ECC_P256_KEY_SIZE, ECC_SECP256R1, "P-256");
+ }
+#ifdef HAVE_ECC_DHE
+ if (ret == 0) {
+ ret = whTest_CryptoEccSharedSecretAsync_OneCurve(
+ ctx, rng, WH_TEST_ECC_P256_KEY_SIZE, ECC_SECP256R1, "P-256");
+ }
+#endif
+ if (ret == 0) {
+ ret = whTest_CryptoEccMakeKeyAsync_OneCurve(
+ ctx, rng, WH_TEST_ECC_P256_KEY_SIZE, ECC_SECP256R1, "P-256");
+ }
+#endif
+
+#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
+ if (ret == 0) {
+ ret = whTest_CryptoEccSignVerifyAsync_OneCurve(
+ ctx, rng, WH_TEST_ECC_P384_KEY_SIZE, ECC_SECP384R1, "P-384");
+ }
+#ifdef HAVE_ECC_DHE
+ if (ret == 0) {
+ ret = whTest_CryptoEccSharedSecretAsync_OneCurve(
+ ctx, rng, WH_TEST_ECC_P384_KEY_SIZE, ECC_SECP384R1, "P-384");
+ }
+#endif
+ if (ret == 0) {
+ ret = whTest_CryptoEccMakeKeyAsync_OneCurve(
+ ctx, rng, WH_TEST_ECC_P384_KEY_SIZE, ECC_SECP384R1, "P-384");
+ }
+#endif
+
+#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
+ if (ret == 0) {
+ ret = whTest_CryptoEccSignVerifyAsync_OneCurve(
+ ctx, rng, WH_TEST_ECC_P521_KEY_SIZE, ECC_SECP521R1, "P-521");
+ }
+#ifdef HAVE_ECC_DHE
+ if (ret == 0) {
+ ret = whTest_CryptoEccSharedSecretAsync_OneCurve(
+ ctx, rng, WH_TEST_ECC_P521_KEY_SIZE, ECC_SECP521R1, "P-521");
+ }
+#endif
+ if (ret == 0) {
+ ret = whTest_CryptoEccMakeKeyAsync_OneCurve(
+ ctx, rng, WH_TEST_ECC_P521_KEY_SIZE, ECC_SECP521R1, "P-521");
+ }
+#endif
+
+ (void)wc_FreeRng(rng);
+
+ if (ret == 0) {
+ WH_TEST_PRINT("ECC async API SUCCESS\n");
+ }
+ return ret;
+}
+
+#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
+
+#endif /* HAVE_ECC && HAVE_ECC_SIGN && HAVE_ECC_VERIFY */
+
+#endif /* !WOLFHSM_CFG_NO_CRYPTO */
+
diff --git a/test-refactor/client-server/wh_test_ed25519.c b/test-refactor/client-server/wh_test_ed25519.c
new file mode 100644
index 00000000..d6f467ea
--- /dev/null
+++ b/test-refactor/client-server/wh_test_ed25519.c
@@ -0,0 +1,565 @@
+/*
+ * Copyright (C) 2026 wolfSSL Inc.
+ *
+ * This file is part of wolfHSM.
+ *
+ * wolfHSM 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfHSM 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 wolfHSM. If not, see .
+ */
+/*
+ * test-refactor/client-server/wh_test_ed25519.c
+ *
+ * Ed25519 sign/verify routed through the server via WH_DEV_ID:
+ * whTest_CryptoEd25519Inline - pure wolfCrypt (sign+verify locally,
+ * plus negative case for tampered sig)
+ * whTest_CryptoEd25519ServerKey - server-cached sign and verify keyIds
+ * whTest_CryptoEd25519Dma - same, via the DMA messaging path
+ */
+
+#include "wolfhsm/wh_settings.h"
+
+#if !defined(WOLFHSM_CFG_NO_CRYPTO)
+
+#include
+#include
+
+#include "wolfssl/wolfcrypt/settings.h"
+#include "wolfssl/wolfcrypt/types.h"
+#include "wolfssl/wolfcrypt/ed25519.h"
+#include "wolfssl/wolfcrypt/random.h"
+
+#include "wolfhsm/wh_error.h"
+#include "wolfhsm/wh_common.h"
+#include "wolfhsm/wh_client.h"
+#include "wolfhsm/wh_client_crypto.h"
+
+#include "wh_test_common.h"
+#include "wh_test_list.h"
+
+#ifdef HAVE_ED25519
+
+/* Imports the supplied private key into the server cache as a sign-only
+ * keyId, and the matching public key as a verify-only keyId. Wipes the
+ * client-side key material afterward and rebinds each ed25519_key struct
+ * to its server-side keyId so the caller can use them as opaque handles.
+ *
+ * Output keyIds are written as soon as each import succeeds, even if a
+ * later step fails. Callers must evict any non-erased keyId on the error
+ * path. */
+static int whTest_Ed25519ImportToServer(whClientContext* ctx, int devId,
+ ed25519_key* key, ed25519_key* pubKey,
+ uint8_t* label, uint16_t labelLen,
+ whKeyId* outSignKeyId,
+ whKeyId* outVerifyKeyId)
+{
+ int ret = 0;
+ byte pubKeyRaw[ED25519_PUB_KEY_SIZE];
+ word32 pubKeySize = sizeof(pubKeyRaw);
+ whKeyId signKeyId = WH_KEYID_ERASED;
+ whKeyId verifyKeyId = WH_KEYID_ERASED;
+
+ ret = wc_ed25519_export_public(key, pubKeyRaw, &pubKeySize);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to export Ed25519 public key: %d\n", ret);
+ }
+ else {
+ ret = wc_ed25519_import_public(pubKeyRaw, pubKeySize, pubKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to import Ed25519 public key: %d\n", ret);
+ }
+ }
+
+ if (ret == 0) {
+ ret = wh_Client_Ed25519ImportKey(
+ ctx, key, &signKeyId, WH_NVM_FLAGS_USAGE_SIGN, labelLen, label);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to import Ed25519 key to server: %d\n",
+ ret);
+ }
+ else {
+ if (outSignKeyId != NULL) {
+ *outSignKeyId = signKeyId;
+ }
+ wc_ed25519_free(key);
+ ret = wc_ed25519_init_ex(key, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to re-initialize Ed25519 key: %d\n",
+ ret);
+ }
+ else {
+ wh_Client_Ed25519SetKeyId(key, signKeyId);
+ }
+ }
+ }
+
+ if (ret == 0) {
+ ret = wh_Client_Ed25519ImportKey(ctx, pubKey, &verifyKeyId,
+ WH_NVM_FLAGS_USAGE_VERIFY, labelLen,
+ label);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to import Ed25519 public key to server: %d\n", ret);
+ }
+ else {
+ if (outVerifyKeyId != NULL) {
+ *outVerifyKeyId = verifyKeyId;
+ }
+ wc_ed25519_free(pubKey);
+ ret = wc_ed25519_init_ex(pubKey, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to re-initialize Ed25519 public key: %d\n", ret);
+ }
+ else {
+ wh_Client_Ed25519SetKeyId(pubKey, verifyKeyId);
+ }
+ }
+ }
+
+ return ret;
+}
+
+int whTest_CryptoEd25519Inline(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ WC_RNG rng[1];
+ ed25519_key key[1] = {0};
+ ed25519_key pubKey[1] = {0};
+ byte msg[] = "Test message for Ed25519 signing";
+ byte sig[ED25519_SIG_SIZE];
+ word32 sigSz = sizeof(sig);
+ int verified = 0;
+ const word32 msgSz = (word32)sizeof(msg);
+ byte pubKeyRaw[ED25519_PUB_KEY_SIZE];
+ word32 pubKeySize = sizeof(pubKeyRaw);
+
+ (void)ctx;
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+
+ ret = wc_ed25519_init_ex(key, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to initialize Ed25519 key: %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ ret = wc_ed25519_init_ex(pubKey, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to initialize Ed25519 public key: %d\n", ret);
+ wc_ed25519_free(key);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ ret = wc_ed25519_make_key(rng, ED25519_KEY_SIZE, key);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to generate Ed25519 key: %d\n", ret);
+ }
+ else {
+ ret = wc_ed25519_export_public(key, pubKeyRaw, &pubKeySize);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to export Ed25519 public key: %d\n", ret);
+ }
+ else {
+ ret = wc_ed25519_import_public(pubKeyRaw, pubKeySize, pubKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to import Ed25519 public key: %d\n",
+ ret);
+ }
+ }
+ }
+
+ if (ret == 0) {
+ sigSz = sizeof(sig);
+ ret = wc_ed25519_sign_msg(msg, msgSz, sig, &sigSz, key);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to sign message with Ed25519: %d\n", ret);
+ }
+ else {
+ ret = wc_ed25519_verify_msg(sig, sigSz, msg, msgSz, &verified,
+ pubKey);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to verify Ed25519 signature: %d\n",
+ ret);
+ }
+ else if (verified != 1) {
+ WH_ERROR_PRINT("Ed25519 signature verification failed\n");
+ ret = -1;
+ }
+ }
+ }
+
+ if (ret == 0) {
+ /* Tampered signature must fail verification. wolfCrypt may signal
+ * rejection either as ret==0 with verified==0, or as ret==SIG_VERIFY_E
+ * (path-dependent inside wolfCrypt). Anything else is a real error. */
+ sig[0] ^= 0xFF;
+ verified = 0;
+ ret = wc_ed25519_verify_msg(sig, sigSz, msg, msgSz, &verified, pubKey);
+ if (verified != 0) {
+ WH_ERROR_PRINT(
+ "Modified Ed25519 signature unexpectedly verified\n");
+ ret = -1;
+ }
+ else if (ret == 0 || ret == SIG_VERIFY_E) {
+ ret = 0;
+ }
+ else {
+ WH_ERROR_PRINT(
+ "wc_ed25519_verify_msg of tampered sig errored: %d\n", ret);
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("Ed25519 INLINE DEVID=0x%X SUCCESS\n", devId);
+ }
+
+ wc_ed25519_free(pubKey);
+ wc_ed25519_free(key);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+
+int whTest_CryptoEd25519ServerKey(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ WC_RNG rng[1];
+ ed25519_key key[1] = {0};
+ ed25519_key pubKey[1] = {0};
+ whKeyId signKeyId = WH_KEYID_ERASED;
+ whKeyId verifyKeyId = WH_KEYID_ERASED;
+ byte msg[] = "Ed25519 server key message";
+ byte sig[ED25519_SIG_SIZE];
+ uint32_t sigSz = sizeof(sig);
+ int verified = 0;
+ uint8_t label[] = "Ed25519 Server Key";
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+
+ ret = wc_ed25519_init_ex(key, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to initialize Ed25519 key: %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ ret = wc_ed25519_init_ex(pubKey, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to initialize Ed25519 public key: %d\n", ret);
+ wc_ed25519_free(key);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ ret = wc_ed25519_make_key(rng, ED25519_KEY_SIZE, key);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to generate Ed25519 key: %d\n", ret);
+ }
+ else {
+ ret = whTest_Ed25519ImportToServer(ctx, devId, key, pubKey, label,
+ sizeof(label), &signKeyId,
+ &verifyKeyId);
+ }
+
+ if (ret == 0) {
+ ret = wh_Client_Ed25519Sign(ctx, key, msg, (uint32_t)sizeof(msg),
+ (uint8_t)Ed25519, NULL, 0, sig, &sigSz);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to sign with server Ed25519 key: %d\n",
+ ret);
+ }
+ }
+
+ if (ret == 0) {
+ ret = wh_Client_Ed25519Verify(ctx, pubKey, sig, sigSz, msg,
+ (uint32_t)sizeof(msg), (uint8_t)Ed25519,
+ NULL, 0, &verified);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to verify server Ed25519 signature: %d\n", ret);
+ }
+ else if (verified != 1) {
+ WH_ERROR_PRINT(
+ "Server Ed25519 signature verification failed\n");
+ ret = -1;
+ }
+ }
+
+ /* Sign-only keyId must be rejected by Verify with WH_ERROR_USAGE. */
+ if (ret == 0) {
+ int negVerified = 0;
+ int negRet = wh_Client_Ed25519Verify(
+ ctx, key, sig, sigSz, msg, (uint32_t)sizeof(msg),
+ (uint8_t)Ed25519, NULL, 0, &negVerified);
+ if (negRet != WH_ERROR_USAGE) {
+ WH_ERROR_PRINT(
+ "Sign-only Ed25519 key Verify expected WH_ERROR_USAGE (%d), "
+ "got %d\n",
+ WH_ERROR_USAGE, negRet);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ /* Same shape as the inline tampered-sig case above. */
+ sig[0] ^= 0xAA;
+ verified = 0;
+ ret = wh_Client_Ed25519Verify(
+ ctx, pubKey, sig, sigSz, msg, (uint32_t)sizeof(msg),
+ (uint8_t)Ed25519, NULL, 0, &verified);
+ if (verified != 0) {
+ WH_ERROR_PRINT("Modified server Ed25519 signature unexpectedly "
+ "verified\n");
+ ret = -1;
+ }
+ else if (ret == 0 || ret == SIG_VERIFY_E) {
+ ret = 0;
+ }
+ else {
+ WH_ERROR_PRINT(
+ "Server Ed25519 verify of tampered sig errored: %d\n", ret);
+ }
+ }
+
+ if (!WH_KEYID_ISERASED(signKeyId)) {
+ (void)wh_Client_KeyEvict(ctx, signKeyId);
+ }
+ if (!WH_KEYID_ISERASED(verifyKeyId)) {
+ (void)wh_Client_KeyEvict(ctx, verifyKeyId);
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("Ed25519 SERVER KEY DEVID=0x%X SUCCESS\n", devId);
+ }
+
+ wc_ed25519_free(pubKey);
+ wc_ed25519_free(key);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+
+#ifdef WOLFHSM_CFG_DMA
+int whTest_CryptoEd25519Dma(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ WC_RNG rng[1];
+ ed25519_key key[1] = {0};
+ ed25519_key pubKey[1] = {0};
+ whKeyId signKeyId = WH_KEYID_ERASED;
+ whKeyId verifyKeyId = WH_KEYID_ERASED;
+ byte msg[] = "Ed25519 DMA message";
+ byte sig[ED25519_SIG_SIZE];
+ uint32_t sigSz = sizeof(sig);
+ int verified = 0;
+ uint8_t label[] = "Ed25519 DMA Key";
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+
+ ret = wc_ed25519_init_ex(key, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to initialize Ed25519 key (DMA): %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ ret = wc_ed25519_init_ex(pubKey, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to initialize Ed25519 public key (DMA): %d\n",
+ ret);
+ wc_ed25519_free(key);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ ret = wc_ed25519_make_key(rng, ED25519_KEY_SIZE, key);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to generate Ed25519 key (DMA): %d\n", ret);
+ }
+ else {
+ ret = whTest_Ed25519ImportToServer(ctx, devId, key, pubKey, label,
+ sizeof(label), &signKeyId,
+ &verifyKeyId);
+ }
+
+ if (ret == 0) {
+ ret = wh_Client_Ed25519SignDma(ctx, key, msg, (uint32_t)sizeof(msg),
+ (uint8_t)Ed25519, NULL, 0, sig, &sigSz);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to sign via DMA Ed25519 key: %d\n", ret);
+ }
+ }
+
+ if (ret == 0) {
+ ret = wh_Client_Ed25519VerifyDma(ctx, pubKey, sig, sigSz, msg,
+ (uint32_t)sizeof(msg),
+ (uint8_t)Ed25519, NULL, 0, &verified);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to verify DMA Ed25519 signature: %d\n",
+ ret);
+ }
+ else if (verified != 1) {
+ WH_ERROR_PRINT("DMA Ed25519 signature verification failed\n");
+ ret = -1;
+ }
+ }
+
+ /* Sign-only keyId must be rejected by VerifyDma with WH_ERROR_USAGE. */
+ if (ret == 0) {
+ int negVerified = 0;
+ int negRet = wh_Client_Ed25519VerifyDma(
+ ctx, key, sig, sigSz, msg, (uint32_t)sizeof(msg),
+ (uint8_t)Ed25519, NULL, 0, &negVerified);
+ if (negRet != WH_ERROR_USAGE) {
+ WH_ERROR_PRINT(
+ "Sign-only Ed25519 key VerifyDma expected WH_ERROR_USAGE (%d), "
+ "got %d\n",
+ WH_ERROR_USAGE, negRet);
+ ret = -1;
+ }
+ }
+
+ if (!WH_KEYID_ISERASED(signKeyId)) {
+ (void)wh_Client_KeyEvict(ctx, signKeyId);
+ }
+ if (!WH_KEYID_ISERASED(verifyKeyId)) {
+ (void)wh_Client_KeyEvict(ctx, verifyKeyId);
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("Ed25519 DMA DEVID=0x%X SUCCESS\n", devId);
+ }
+
+ wc_ed25519_free(pubKey);
+ wc_ed25519_free(key);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+#endif /* WOLFHSM_CFG_DMA */
+
+/* Cache a NONEXPORTABLE Ed25519 keypair on the server, sign a message there,
+ * then export only the public half via wh_Client_Ed25519ExportPublicKey and
+ * verify the signature client-side. */
+int whTest_CryptoEd25519ExportPublicKey(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ ed25519_key hsmKey[1] = {0};
+ ed25519_key pubKey[1] = {0};
+ whKeyId keyId = WH_KEYID_ERASED;
+ byte msg[] = "Ed25519 export-public message";
+ byte sig[ED25519_SIG_SIZE];
+ uint32_t sigSz = sizeof(sig);
+ int verified = 0;
+ uint8_t denyBuf[256];
+ uint16_t denyLen = sizeof(denyBuf);
+
+ ret = wh_Client_Ed25519MakeCacheKey(ctx, &keyId,
+ WH_NVM_FLAGS_USAGE_SIGN |
+ WH_NVM_FLAGS_USAGE_VERIFY |
+ WH_NVM_FLAGS_NONEXPORTABLE,
+ 0, NULL);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to make NONEXPORTABLE cached Ed25519 key %d\n",
+ ret);
+ return ret;
+ }
+
+ /* Full export must be denied by the NONEXPORTABLE policy. */
+ {
+ int denyRet = wh_Client_KeyExport(ctx, keyId, NULL, 0, denyBuf,
+ &denyLen);
+ if (denyRet != WH_ERROR_ACCESS) {
+ WH_ERROR_PRINT(
+ "NONEXPORTABLE Ed25519 full export was not denied: %d\n",
+ denyRet);
+ ret = -1;
+ }
+ }
+
+ /* Sign on the server using the cached private key. */
+ if (ret == 0) {
+ ret = wc_ed25519_init_ex(hsmKey, NULL, devId);
+ if (ret == 0) {
+ ret = wh_Client_Ed25519SetKeyId(hsmKey, keyId);
+ }
+ if (ret == 0) {
+ ret = wh_Client_Ed25519Sign(ctx, hsmKey, msg, (uint32_t)sizeof(msg),
+ (uint8_t)Ed25519, NULL, 0, sig, &sigSz);
+ if (ret != 0) {
+ WH_ERROR_PRINT("HSM Ed25519 sign failed %d\n", ret);
+ }
+ }
+ wc_ed25519_free(hsmKey);
+ }
+
+ /* Public-only export must succeed and verify the signature client-side. */
+ if (ret == 0) {
+ ret = wc_ed25519_init_ex(pubKey, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wh_Client_Ed25519ExportPublicKey(ctx, keyId, pubKey, 0, NULL);
+ if (ret != 0) {
+ WH_ERROR_PRINT("wh_Client_Ed25519ExportPublicKey failed %d\n",
+ ret);
+ }
+ else if (pubKey->pubKeySet != 1 || pubKey->privKeySet != 0) {
+ WH_ERROR_PRINT(
+ "Exported Ed25519 key flags wrong: pub=%d priv=%d\n",
+ (int)pubKey->pubKeySet, (int)pubKey->privKeySet);
+ ret = -1;
+ }
+ else {
+ ret = wc_ed25519_verify_msg(sig, sigSz, msg,
+ (word32)sizeof(msg), &verified,
+ pubKey);
+ if (ret != 0 || verified != 1) {
+ WH_ERROR_PRINT(
+ "Client-side Ed25519 verify failed ret=%d verify=%d\n",
+ ret, verified);
+ if (ret == 0) {
+ ret = -1;
+ }
+ }
+ }
+ wc_ed25519_free(pubKey);
+ }
+ }
+
+ if (!WH_KEYID_ISERASED(keyId)) {
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("Ed25519 EXPORT-PUBLIC DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+#endif /* HAVE_ED25519 */
+
+#endif /* !WOLFHSM_CFG_NO_CRYPTO */
diff --git a/test-refactor/client-server/wh_test_kdf.c b/test-refactor/client-server/wh_test_kdf.c
new file mode 100644
index 00000000..c0258419
--- /dev/null
+++ b/test-refactor/client-server/wh_test_kdf.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2026 wolfSSL Inc.
+ *
+ * This file is part of wolfHSM.
+ *
+ * wolfHSM 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfHSM 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 wolfHSM. If not, see .
+ */
+/*
+ * test-refactor/client-server/wh_test_kdf.c
+ *
+ * HKDF (RFC 5869) and CMAC-KDF (NIST SP 800-108 / SP 800-56C two-step) routed
+ * through the server. Each test exercises three paths: the wolfCrypt API
+ * dispatched via the cryptocb, wh_Client_*MakeExportKey returning the derived
+ * key to the client, and wh_Client_*MakeCacheKey caching the derived key on
+ * the server (verified by exporting and comparing). Each KDF also has a
+ * cached-input variant where the raw key material is first cached and then
+ * referenced by key id.
+ */
+
+#include "wolfhsm/wh_settings.h"
+
+#if !defined(WOLFHSM_CFG_NO_CRYPTO)
+
+#include
+#include
+
+#include "wolfssl/wolfcrypt/settings.h"
+#include "wolfssl/wolfcrypt/types.h"
+#include "wolfssl/wolfcrypt/kdf.h"
+
+#include "wolfhsm/wh_error.h"
+#include "wolfhsm/wh_common.h"
+#include "wolfhsm/wh_client.h"
+#include "wolfhsm/wh_client_crypto.h"
+
+#include "wh_test_common.h"
+#include "wh_test_list.h"
+
+#ifdef HAVE_HKDF
+#define WH_TEST_HKDF_IKM_SIZE 22
+#define WH_TEST_HKDF_SALT_SIZE 13
+#define WH_TEST_HKDF_INFO_SIZE 10
+#define WH_TEST_HKDF_OKM_SIZE 42
+
+int whTest_CryptoHkdf(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = WH_ERROR_OK;
+ whKeyId keyId = WH_KEYID_ERASED;
+
+ /* RFC 5869 Test Case 1 */
+ const uint8_t ikm[WH_TEST_HKDF_IKM_SIZE] = {
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
+ const uint8_t salt[WH_TEST_HKDF_SALT_SIZE] = {0x00, 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08, 0x09,
+ 0x0a, 0x0b, 0x0c};
+ const uint8_t info[WH_TEST_HKDF_INFO_SIZE] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4,
+ 0xf5, 0xf6, 0xf7, 0xf8, 0xf9};
+ const uint8_t expected[WH_TEST_HKDF_OKM_SIZE] = {
+ 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f,
+ 0x64, 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a,
+ 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34,
+ 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65};
+
+ uint8_t okm[WH_TEST_HKDF_OKM_SIZE];
+ uint8_t okm2[WH_TEST_HKDF_OKM_SIZE];
+ uint8_t label[] = "HKDF Test Label";
+
+ /* 1. wc_HKDF dispatched through the cryptocb */
+ memset(okm, 0, sizeof(okm));
+ ret = wc_HKDF_ex(WC_SHA256, ikm, WH_TEST_HKDF_IKM_SIZE, salt,
+ WH_TEST_HKDF_SALT_SIZE, info, WH_TEST_HKDF_INFO_SIZE, okm,
+ WH_TEST_HKDF_OKM_SIZE, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wc_HKDF_ex: %d\n", ret);
+ return ret;
+ }
+ if (memcmp(okm, expected, WH_TEST_HKDF_OKM_SIZE) != 0) {
+ WH_ERROR_PRINT("HKDF output mismatch (wc_HKDF_ex)\n");
+ return -1;
+ }
+
+ /* 2. wc_HKDF without salt -- no expected vector, just no error */
+ memset(okm, 0, sizeof(okm));
+ ret = wc_HKDF_ex(WC_SHA256, ikm, WH_TEST_HKDF_IKM_SIZE, NULL, 0, info,
+ WH_TEST_HKDF_INFO_SIZE, okm, WH_TEST_HKDF_OKM_SIZE, NULL,
+ devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wc_HKDF_ex (no salt): %d\n", ret);
+ return ret;
+ }
+
+ /* 3. wc_HKDF without info */
+ memset(okm, 0, sizeof(okm));
+ ret = wc_HKDF_ex(WC_SHA256, ikm, WH_TEST_HKDF_IKM_SIZE, salt,
+ WH_TEST_HKDF_SALT_SIZE, NULL, 0, okm, WH_TEST_HKDF_OKM_SIZE,
+ NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wc_HKDF_ex (no info): %d\n", ret);
+ return ret;
+ }
+
+ /* 4. wh_Client_HkdfMakeExportKey */
+ memset(okm, 0, sizeof(okm));
+ ret = wh_Client_HkdfMakeExportKey(
+ ctx, WC_SHA256, WH_KEYID_ERASED, ikm, WH_TEST_HKDF_IKM_SIZE, salt,
+ WH_TEST_HKDF_SALT_SIZE, info, WH_TEST_HKDF_INFO_SIZE, okm,
+ WH_TEST_HKDF_OKM_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wh_Client_HkdfMakeExportKey: %d\n", ret);
+ return ret;
+ }
+ if (memcmp(okm, expected, WH_TEST_HKDF_OKM_SIZE) != 0) {
+ WH_ERROR_PRINT("HKDF output mismatch (MakeExportKey)\n");
+ return -1;
+ }
+
+ /* 5. wh_Client_HkdfMakeCacheKey -- derive into a cached key, then export
+ * it back to verify the server-side derivation. */
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_HkdfMakeCacheKey(
+ ctx, WC_SHA256, WH_KEYID_ERASED, ikm, WH_TEST_HKDF_IKM_SIZE, salt,
+ WH_TEST_HKDF_SALT_SIZE, info, WH_TEST_HKDF_INFO_SIZE, &keyId,
+ WH_NVM_FLAGS_NONE, label, sizeof(label), WH_TEST_HKDF_OKM_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wh_Client_HkdfMakeCacheKey: %d\n", ret);
+ return ret;
+ }
+ if (keyId == WH_KEYID_ERASED) {
+ WH_ERROR_PRINT("HKDF cache did not return a key id\n");
+ return -1;
+ }
+ {
+ uint8_t exportLabel[sizeof(label)] = {0};
+ uint16_t exportLen = WH_TEST_HKDF_OKM_SIZE;
+ memset(okm2, 0, sizeof(okm2));
+ ret = wh_Client_KeyExport(ctx, keyId, exportLabel, sizeof(exportLabel),
+ okm2, &exportLen);
+ if (ret == 0 && exportLen != WH_TEST_HKDF_OKM_SIZE) {
+ WH_ERROR_PRINT("HKDF exported length mismatch: %u != %u\n",
+ exportLen, WH_TEST_HKDF_OKM_SIZE);
+ ret = -1;
+ }
+ if (ret == 0 && memcmp(okm2, expected, WH_TEST_HKDF_OKM_SIZE) != 0) {
+ WH_ERROR_PRINT("HKDF output mismatch (MakeCacheKey)\n");
+ ret = -1;
+ }
+ }
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* 6. HKDF with a cached input key id -- derives the same OKM as direct
+ * buffers when the IKM lives in the keystore. */
+ {
+ whKeyId keyIdIn = WH_KEYID_ERASED;
+ uint8_t label_in[] = "input-key";
+ const uint8_t ikm2[] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D,
+ 0x3E, 0x3F};
+ const uint8_t salt2[] = {0xB0, 0xB1, 0xB2, 0xB3};
+ const uint8_t info2[] = {0xC0, 0xC1, 0xC2};
+ uint8_t okmCached[WH_TEST_HKDF_OKM_SIZE];
+ uint8_t okmDirect[WH_TEST_HKDF_OKM_SIZE];
+
+ ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_USAGE_DERIVE, label_in,
+ sizeof(label_in), (uint8_t*)ikm2, sizeof(ikm2),
+ &keyIdIn);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to cache HKDF input key: %d\n", ret);
+ return ret;
+ }
+
+ memset(okmCached, 0, sizeof(okmCached));
+ ret = wh_Client_HkdfMakeExportKey(
+ ctx, WC_SHA256, keyIdIn, NULL, 0, salt2, sizeof(salt2), info2,
+ sizeof(info2), okmCached, sizeof(okmCached));
+ if (ret == 0) {
+ memset(okmDirect, 0, sizeof(okmDirect));
+ ret = wh_Client_HkdfMakeExportKey(
+ ctx, WC_SHA256, WH_KEYID_ERASED, ikm2, sizeof(ikm2), salt2,
+ sizeof(salt2), info2, sizeof(info2), okmDirect,
+ sizeof(okmDirect));
+ }
+ if (ret == 0 &&
+ memcmp(okmCached, okmDirect, sizeof(okmCached)) != 0) {
+ WH_ERROR_PRINT("HKDF mismatch (cached vs direct input key)\n");
+ ret = -1;
+ }
+ (void)wh_Client_KeyEvict(ctx, keyIdIn);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ WH_TEST_PRINT("HKDF DEVID=0x%X SUCCESS\n", devId);
+ return 0;
+}
+#endif /* HAVE_HKDF */
+
+#ifdef HAVE_CMAC_KDF
+#define WH_TEST_CMAC_KDF_SALT_SIZE 24
+#define WH_TEST_CMAC_KDF_Z_SIZE 32
+#define WH_TEST_CMAC_KDF_FIXED_INFO_SIZE 60
+#define WH_TEST_CMAC_KDF_OUT_SIZE 40
+
+int whTest_CryptoCmacKdf(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = WH_ERROR_OK;
+ whKeyId keyId = WH_KEYID_ERASED;
+
+ /* NIST SP 800-108 KDF in Counter Mode using CMAC -- vectors from the
+ * wolfSSL CMAC KDF implementation tests. */
+ static const uint8_t salt[WH_TEST_CMAC_KDF_SALT_SIZE] = {
+ 0x20, 0x51, 0xaf, 0x34, 0x76, 0x2e, 0xbe, 0x55, 0x6f, 0x72, 0xa5, 0xc6,
+ 0xed, 0xc7, 0x77, 0x1e, 0xb9, 0x24, 0x5f, 0xad, 0x76, 0xf0, 0x34, 0xbe};
+ static const uint8_t z[WH_TEST_CMAC_KDF_Z_SIZE] = {
+ 0xae, 0x8e, 0x93, 0xc9, 0xc9, 0x91, 0xcf, 0x89, 0x6a, 0x49, 0x1a,
+ 0x89, 0x07, 0xdf, 0x4e, 0x4b, 0xe5, 0x18, 0x6a, 0xe4, 0x96, 0xcd,
+ 0x34, 0x0d, 0xc1, 0x9b, 0x23, 0x78, 0x21, 0xdb, 0x7b, 0x60};
+ static const uint8_t fixedInfo[WH_TEST_CMAC_KDF_FIXED_INFO_SIZE] = {
+ 0xa2, 0x59, 0xca, 0xe2, 0xc4, 0xa3, 0x6b, 0x89, 0x56, 0x3c, 0xb1, 0x48,
+ 0xc7, 0x82, 0x51, 0x34, 0x3b, 0xbf, 0xab, 0xdc, 0x13, 0xca, 0x7a, 0xc2,
+ 0x17, 0x1c, 0x2e, 0xb6, 0x02, 0x1f, 0x44, 0x77, 0xfe, 0xa3, 0x3b, 0x28,
+ 0x72, 0x4d, 0xa7, 0x21, 0xee, 0x08, 0x7b, 0xff, 0xd7, 0x94, 0xa1, 0x56,
+ 0x37, 0x54, 0xb4, 0x25, 0xa8, 0xd0, 0x9b, 0x3e, 0x0d, 0xa5, 0xff, 0xed};
+ static const uint8_t expected[WH_TEST_CMAC_KDF_OUT_SIZE] = {
+ 0xb4, 0x0c, 0x32, 0xbe, 0x01, 0x27, 0x93, 0xba, 0xfd, 0xf7,
+ 0x78, 0xc5, 0xf4, 0x54, 0x43, 0xf4, 0xc9, 0x71, 0x23, 0x93,
+ 0x17, 0x63, 0xd8, 0x3a, 0x59, 0x27, 0x07, 0xbf, 0xf2, 0xd3,
+ 0x60, 0x59, 0x50, 0x27, 0x29, 0xca, 0xb8, 0x8b, 0x29, 0x38};
+
+ uint8_t out[WH_TEST_CMAC_KDF_OUT_SIZE];
+ uint8_t exported[WH_TEST_CMAC_KDF_OUT_SIZE];
+ uint8_t exportLabel[12] = {0};
+ uint16_t exportLen;
+ uint8_t keyLabel[] = "CMAC KDF Key";
+
+ /* 1. Direct wolfCrypt API dispatched via the cryptocb */
+ memset(out, 0, sizeof(out));
+ ret = wc_KDA_KDF_twostep_cmac(salt, WH_TEST_CMAC_KDF_SALT_SIZE, z,
+ WH_TEST_CMAC_KDF_Z_SIZE, fixedInfo,
+ WH_TEST_CMAC_KDF_FIXED_INFO_SIZE, out,
+ WH_TEST_CMAC_KDF_OUT_SIZE, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wc_KDA_KDF_twostep_cmac: %d\n", ret);
+ return ret;
+ }
+ if (memcmp(out, expected, sizeof(out)) != 0) {
+ WH_ERROR_PRINT("CMAC KDF mismatch (direct wolfCrypt)\n");
+ return -1;
+ }
+
+ /* 2. Client export with direct salt and Z */
+ memset(out, 0, sizeof(out));
+ ret = wh_Client_CmacKdfMakeExportKey(
+ ctx, WH_KEYID_ERASED, salt, WH_TEST_CMAC_KDF_SALT_SIZE, WH_KEYID_ERASED,
+ z, WH_TEST_CMAC_KDF_Z_SIZE, fixedInfo, WH_TEST_CMAC_KDF_FIXED_INFO_SIZE,
+ out, sizeof(out));
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wh_Client_CmacKdfMakeExportKey: %d\n", ret);
+ return ret;
+ }
+ if (memcmp(out, expected, sizeof(out)) != 0) {
+ WH_ERROR_PRINT("CMAC KDF mismatch (export key)\n");
+ return -1;
+ }
+
+ /* 3. Client cache with direct salt and Z, then export to compare */
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_CmacKdfMakeCacheKey(
+ ctx, WH_KEYID_ERASED, salt, WH_TEST_CMAC_KDF_SALT_SIZE, WH_KEYID_ERASED,
+ z, WH_TEST_CMAC_KDF_Z_SIZE, fixedInfo, WH_TEST_CMAC_KDF_FIXED_INFO_SIZE,
+ &keyId, WH_NVM_FLAGS_NONE, keyLabel, sizeof(keyLabel),
+ WH_TEST_CMAC_KDF_OUT_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed wh_Client_CmacKdfMakeCacheKey: %d\n", ret);
+ return ret;
+ }
+ if (keyId == WH_KEYID_ERASED) {
+ WH_ERROR_PRINT("CMAC KDF cache did not return a key id\n");
+ return -1;
+ }
+ memset(exported, 0, sizeof(exported));
+ exportLen = (uint16_t)sizeof(exported);
+ ret = wh_Client_KeyExport(ctx, keyId, exportLabel, sizeof(exportLabel),
+ exported, &exportLen);
+ if (ret == 0 &&
+ (exportLen != WH_TEST_CMAC_KDF_OUT_SIZE ||
+ memcmp(exported, expected, sizeof(exported)) != 0)) {
+ WH_ERROR_PRINT("Exported CMAC KDF key mismatch\n");
+ ret = -1;
+ }
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* 4. Cached salt and cached Z. Caches both inputs first, then derives by
+ * key id with NULL/0 raw buffers. Derives via both export and cache. */
+ {
+ whKeyId saltKeyId = WH_KEYID_ERASED;
+ whKeyId zKeyId = WH_KEYID_ERASED;
+
+ ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_USAGE_DERIVE, NULL, 0,
+ (uint8_t*)salt, WH_TEST_CMAC_KDF_SALT_SIZE,
+ &saltKeyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to cache CMAC KDF salt: %d\n", ret);
+ return ret;
+ }
+ ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_USAGE_DERIVE, NULL, 0,
+ (uint8_t*)z, WH_TEST_CMAC_KDF_Z_SIZE, &zKeyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to cache CMAC KDF Z: %d\n", ret);
+ (void)wh_Client_KeyEvict(ctx, saltKeyId);
+ return ret;
+ }
+
+ memset(out, 0, sizeof(out));
+ ret = wh_Client_CmacKdfMakeExportKey(
+ ctx, saltKeyId, NULL, 0, zKeyId, NULL, 0, fixedInfo,
+ WH_TEST_CMAC_KDF_FIXED_INFO_SIZE, out, sizeof(out));
+ if (ret == 0 && memcmp(out, expected, sizeof(out)) != 0) {
+ WH_ERROR_PRINT("CMAC KDF mismatch (cached inputs export)\n");
+ ret = -1;
+ }
+
+ if (ret == 0) {
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_CmacKdfMakeCacheKey(
+ ctx, saltKeyId, NULL, 0, zKeyId, NULL, 0, fixedInfo,
+ WH_TEST_CMAC_KDF_FIXED_INFO_SIZE, &keyId, WH_NVM_FLAGS_NONE,
+ keyLabel, sizeof(keyLabel), WH_TEST_CMAC_KDF_OUT_SIZE);
+ if (ret == 0 && keyId == WH_KEYID_ERASED) {
+ WH_ERROR_PRINT("CMAC KDF cache (cached inputs) returned no "
+ "key id\n");
+ ret = -1;
+ }
+ if (ret == 0) {
+ memset(exported, 0, sizeof(exported));
+ exportLen = (uint16_t)sizeof(exported);
+ ret = wh_Client_KeyExport(ctx, keyId, exportLabel,
+ sizeof(exportLabel), exported,
+ &exportLen);
+ if (ret == 0 &&
+ (exportLen != WH_TEST_CMAC_KDF_OUT_SIZE ||
+ memcmp(exported, expected, sizeof(exported)) != 0)) {
+ WH_ERROR_PRINT("CMAC KDF mismatch (cached inputs cache)\n");
+ ret = -1;
+ }
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ }
+ }
+
+ (void)wh_Client_KeyEvict(ctx, saltKeyId);
+ (void)wh_Client_KeyEvict(ctx, zKeyId);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ WH_TEST_PRINT("CMAC KDF DEVID=0x%X SUCCESS\n", devId);
+ return 0;
+}
+#endif /* HAVE_CMAC_KDF */
+
+#endif /* !WOLFHSM_CFG_NO_CRYPTO */
diff --git a/test-refactor/client-server/wh_test_keypolicy.c b/test-refactor/client-server/wh_test_keypolicy.c
new file mode 100644
index 00000000..9d742428
--- /dev/null
+++ b/test-refactor/client-server/wh_test_keypolicy.c
@@ -0,0 +1,693 @@
+/*
+ * Copyright (C) 2026 wolfSSL Inc.
+ *
+ * This file is part of wolfHSM.
+ *
+ * wolfHSM 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfHSM 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 wolfHSM. If not, see .
+ */
+/*
+ * test-refactor/client-server/wh_test_keypolicy.c
+ *
+ * Per-cached-key usage policy enforcement and revocation lifecycle:
+ * whTest_CryptoKeyUsagePolicies - cache keys with restricted
+ * WH_NVM_FLAGS_USAGE_* bits, confirm
+ * operations outside that policy fail
+ * with WH_ERROR_USAGE
+ * whTest_CryptoKeyRevocationAesCbc - revoke a cached AES key, confirm
+ * it cannot be used or erased; commit
+ * + revoke an NVM-backed key with the
+ * same expectation
+ */
+
+#include "wolfhsm/wh_settings.h"
+
+#if !defined(WOLFHSM_CFG_NO_CRYPTO)
+
+#include
+#include
+
+#include "wolfssl/wolfcrypt/settings.h"
+#include "wolfssl/wolfcrypt/types.h"
+#include "wolfssl/wolfcrypt/aes.h"
+#include "wolfssl/wolfcrypt/cmac.h"
+#include "wolfssl/wolfcrypt/ecc.h"
+#include "wolfssl/wolfcrypt/random.h"
+#include "wolfssl/wolfcrypt/sha256.h"
+
+#include "wolfhsm/wh_error.h"
+#include "wolfhsm/wh_common.h"
+#include "wolfhsm/wh_client.h"
+#include "wolfhsm/wh_client_crypto.h"
+
+#include "wh_test_common.h"
+#include "wh_test_list.h"
+
+int whTest_CryptoKeyUsagePolicies(whClientContext* client)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ WC_RNG rng[1];
+ uint8_t plaintext[16] = {0};
+ uint8_t ciphertext[16] = {0};
+ uint8_t key[32] = {0};
+ uint32_t keyLen = sizeof(key);
+ whKeyId keyId = WH_KEYID_ERASED;
+
+ (void)ciphertext;
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+
+ WH_TEST_PRINT("Testing Key Usage Policies...\n");
+
+ ret = wc_RNG_GenerateBlock(rng, plaintext, sizeof(plaintext));
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to generate random data: %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ ret = wc_RNG_GenerateBlock(rng, key, sizeof(key));
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to generate random key: %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+#ifndef NO_AES
+#ifdef HAVE_AES_CBC
+ WH_TEST_PRINT(" Testing AES CBC encrypt without ENCRYPT flag...\n");
+ {
+ Aes aes[1];
+ uint8_t iv[AES_BLOCK_SIZE] = {0};
+
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_NONE,
+ (uint8_t*)"aes-no-enc", strlen("aes-no-enc"),
+ key, keyLen, &keyId);
+ if (ret == 0) {
+ ret = wc_AesInit(aes, NULL, WH_DEV_ID);
+ if (ret == 0) {
+ ret = wh_Client_AesSetKeyId(aes, keyId);
+ if (ret == 0) {
+ ret = wc_AesSetIV(aes, iv);
+ if (ret == 0) {
+ ret = wc_AesCbcEncrypt(aes, ciphertext, plaintext,
+ sizeof(plaintext));
+ if (ret == WH_ERROR_USAGE) {
+ WH_TEST_PRINT(
+ " PASS: Correctly denied encryption\n");
+ ret = 0;
+ }
+ else {
+ WH_ERROR_PRINT(
+ " FAIL: Expected WH_ERROR_USAGE, got %d\n",
+ ret);
+ ret = WH_ERROR_ABORTED;
+ }
+ }
+ }
+ wc_AesFree(aes);
+ }
+ wh_Client_KeyEvict(client, keyId);
+ }
+ }
+ if (ret != 0) {
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ WH_TEST_PRINT(" Testing AES CBC decrypt without DECRYPT flag...\n");
+ {
+ Aes aes[1];
+ uint8_t iv[AES_BLOCK_SIZE] = {0};
+ uint8_t decrypted[16] = {0};
+ uint8_t tempCipher[16] = {0};
+
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_USAGE_ENCRYPT,
+ (uint8_t*)"aes-enc-only",
+ strlen("aes-enc-only"), key, keyLen, &keyId);
+ if (ret == 0) {
+ ret = wc_AesInit(aes, NULL, WH_DEV_ID);
+ if (ret == 0) {
+ ret = wh_Client_AesSetKeyId(aes, keyId);
+ if (ret == 0) {
+ ret = wc_AesSetIV(aes, iv);
+ if (ret == 0) {
+ ret = wc_AesCbcEncrypt(aes, tempCipher, plaintext,
+ sizeof(plaintext));
+ }
+ }
+ wc_AesFree(aes);
+ }
+ wh_Client_KeyEvict(client, keyId);
+ }
+
+ if (ret == 0) {
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_KeyCache(
+ client, WH_NVM_FLAGS_USAGE_ENCRYPT, (uint8_t*)"aes-no-dec",
+ strlen("aes-no-dec"), key, keyLen, &keyId);
+ if (ret == 0) {
+ ret = wc_AesInit(aes, NULL, WH_DEV_ID);
+ if (ret == 0) {
+ ret = wh_Client_AesSetKeyId(aes, keyId);
+ if (ret == 0) {
+ ret = wc_AesSetIV(aes, iv);
+ if (ret == 0) {
+ ret = wc_AesCbcDecrypt(aes, decrypted, tempCipher,
+ sizeof(tempCipher));
+ if (ret == WH_ERROR_USAGE) {
+ WH_TEST_PRINT(
+ " PASS: Correctly denied decryption\n");
+ ret = 0;
+ }
+ else {
+ WH_ERROR_PRINT(" FAIL: Expected "
+ "WH_ERROR_USAGE, got %d\n",
+ ret);
+ ret = WH_ERROR_ABORTED;
+ }
+ }
+ }
+ wc_AesFree(aes);
+ }
+ wh_Client_KeyEvict(client, keyId);
+ }
+ }
+ }
+ if (ret != 0) {
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+#endif /* HAVE_AES_CBC */
+#endif /* !NO_AES */
+
+#ifdef HAVE_ECC
+#ifdef HAVE_ECC_SIGN
+ WH_TEST_PRINT(" Testing ECDSA sign without SIGN flag...\n");
+ {
+ ecc_key eccKey[1];
+ uint8_t sig[ECC_MAX_SIG_SIZE] = {0};
+ word32 sigLen = sizeof(sig);
+ uint8_t hash[WC_SHA256_DIGEST_SIZE] = {0};
+
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_EccMakeCacheKey(
+ client, 32, ECC_SECP256R1, &keyId, WH_NVM_FLAGS_NONE,
+ strlen("ecc-no-sign"), (uint8_t*)"ecc-no-sign");
+ if (ret == 0) {
+ ret = wc_ecc_init_ex(eccKey, NULL, WH_DEV_ID);
+ if (ret == 0) {
+ ret = wc_ecc_set_curve(eccKey, 32, ECC_SECP256R1);
+ if (ret == 0) {
+ ret = wh_Client_EccSetKeyId(eccKey, keyId);
+ if (ret == 0) {
+ ret = wc_RNG_GenerateBlock(rng, hash, sizeof(hash));
+ if (ret == 0) {
+ ret = wc_ecc_sign_hash(hash, sizeof(hash), sig,
+ &sigLen, rng, eccKey);
+ if (ret == WH_ERROR_USAGE) {
+ WH_TEST_PRINT(
+ " PASS: Correctly denied signing\n");
+ ret = 0;
+ }
+ else {
+ WH_ERROR_PRINT(" FAIL: Expected "
+ "WH_ERROR_USAGE, got %d\n",
+ ret);
+ ret = WH_ERROR_ABORTED;
+ }
+ }
+ }
+ }
+ wc_ecc_free(eccKey);
+ }
+ wh_Client_KeyEvict(client, keyId);
+ }
+ }
+ if (ret != 0) {
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+#endif /* HAVE_ECC_SIGN */
+
+#ifdef HAVE_ECC_DHE
+ WH_TEST_PRINT(" Testing ECDH without DERIVE flag...\n");
+ {
+ ecc_key privKey[1];
+ ecc_key pubKey[1];
+ uint8_t sharedSecret[ECC_MAXSIZE] = {0};
+ word32 secretLen = sizeof(sharedSecret);
+
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_EccMakeCacheKey(
+ client, 32, ECC_SECP256R1, &keyId, WH_NVM_FLAGS_NONE,
+ strlen("ecc-no-derive"), (uint8_t*)"ecc-no-derive");
+ if (ret == 0) {
+ ret = wc_ecc_init_ex(privKey, NULL, WH_DEV_ID);
+ if (ret == 0) {
+ ret = wc_ecc_set_curve(privKey, 32, ECC_SECP256R1);
+ if (ret == 0) {
+ ret = wh_Client_EccSetKeyId(privKey, keyId);
+ }
+ if (ret == 0) {
+ const byte qx[] = {
+ 0xbb, 0x33, 0xac, 0x4c, 0x27, 0x50, 0x4a, 0xc6,
+ 0x4a, 0xa5, 0x04, 0xc3, 0x3c, 0xde, 0x9f, 0x36,
+ 0xdb, 0x72, 0x2d, 0xce, 0x94, 0xea, 0x2b, 0xfa,
+ 0xcb, 0x20, 0x09, 0x39, 0x2c, 0x16, 0xe8, 0x61};
+ const byte qy[] = {
+ 0x02, 0xe9, 0xaf, 0x4d, 0xd3, 0x02, 0x93, 0x9a,
+ 0x31, 0x5b, 0x97, 0x92, 0x21, 0x7f, 0xf0, 0xcf,
+ 0x18, 0xda, 0x91, 0x11, 0x02, 0x34, 0x86, 0xe8,
+ 0x20, 0x58, 0x33, 0x0b, 0x80, 0x34, 0x89, 0xd8};
+ int curveId = ECC_SECP256R1;
+
+ ret = wc_ecc_init_ex(pubKey, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wc_ecc_import_unsigned(pubKey, qx, qy, NULL,
+ curveId);
+ if (ret == 0) {
+ ret = wc_ecc_shared_secret(privKey, pubKey,
+ sharedSecret,
+ &secretLen);
+ if (ret == WH_ERROR_USAGE) {
+ WH_TEST_PRINT(" PASS: Correctly denied key "
+ "derivation\n");
+ ret = 0;
+ }
+ else {
+ WH_ERROR_PRINT(" FAIL: Expected "
+ "WH_ERROR_USAGE, got %d\n",
+ ret);
+ ret = WH_ERROR_ABORTED;
+ }
+ }
+ wc_ecc_free(pubKey);
+ }
+ }
+ wc_ecc_free(privKey);
+ }
+ wh_Client_KeyEvict(client, keyId);
+ }
+ }
+ if (ret != 0) {
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+#endif /* HAVE_ECC_DHE */
+#endif /* HAVE_ECC */
+
+#ifdef HAVE_HKDF
+ WH_TEST_PRINT(" Testing HKDF without DERIVE flag...\n");
+ {
+ uint8_t ikm[32] = {0};
+ whKeyId outKeyId = WH_KEYID_ERASED;
+
+ ret = wc_RNG_GenerateBlock(rng, ikm, sizeof(ikm));
+ if (ret == 0) {
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_KeyCache(
+ client, WH_NVM_FLAGS_NONE, (uint8_t*)"hkdf-no-derive",
+ strlen("hkdf-no-derive"), ikm, sizeof(ikm), &keyId);
+ if (ret == 0) {
+ ret = wh_Client_HkdfMakeCacheKey(
+ client, WC_SHA256, keyId, NULL, 0, NULL, 0, NULL, 0,
+ &outKeyId, WH_NVM_FLAGS_EPHEMERAL, (uint8_t*)"hkdf-out",
+ strlen("hkdf-out"), 32);
+ if (ret == WH_ERROR_USAGE) {
+ WH_TEST_PRINT(
+ " PASS: Correctly denied HKDF derivation\n");
+ ret = 0;
+ }
+ else {
+ WH_ERROR_PRINT(
+ " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret);
+ ret = WH_ERROR_ABORTED;
+ }
+ wh_Client_KeyEvict(client, keyId);
+ if (!WH_KEYID_ISERASED(outKeyId)) {
+ wh_Client_KeyEvict(client, outKeyId);
+ }
+ }
+ }
+ }
+ if (ret != 0) {
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+#endif /* HAVE_HKDF */
+
+#if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT)
+ WH_TEST_PRINT(" Testing CMAC generate without SIGN flag...\n");
+ {
+ Cmac cmac;
+ whKeyId cmacKeyId = WH_KEYID_ERASED;
+ uint8_t message[64];
+ uint8_t tag[AES_BLOCK_SIZE];
+ word32 tagLen = sizeof(tag);
+
+ ret = wc_RNG_GenerateBlock(rng, message, sizeof(message));
+ if (ret == 0) {
+ ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_NONE,
+ (uint8_t*)"cmac-no-sign",
+ strlen("cmac-no-sign"), key,
+ AES_128_KEY_SIZE, &cmacKeyId);
+ }
+ if (ret == 0) {
+ ret = wc_InitCmac_ex(&cmac, NULL, 0, WC_CMAC_AES, NULL, NULL,
+ WH_DEV_ID);
+ if (ret == 0) {
+ ret = wh_Client_CmacSetKeyId(&cmac, cmacKeyId);
+ if (ret == 0) {
+ ret = wc_AesCmacGenerate_ex(&cmac, tag, &tagLen, message,
+ sizeof(message), NULL, 0, NULL,
+ WH_DEV_ID);
+ if (ret == WH_ERROR_USAGE) {
+ WH_TEST_PRINT(
+ " PASS: Correctly denied CMAC generate\n");
+ ret = 0;
+ }
+ else {
+ WH_ERROR_PRINT(
+ " FAIL: Expected WH_ERROR_USAGE, got %d\n",
+ ret);
+ ret = WH_ERROR_ABORTED;
+ }
+ }
+ wc_CmacFree(&cmac);
+ }
+ wh_Client_KeyEvict(client, cmacKeyId);
+ }
+ }
+ if (ret != 0) {
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ WH_TEST_PRINT(" Testing CMAC verify without VERIFY flag...\n");
+ {
+ Cmac cmac;
+ whKeyId cmacKeyId = WH_KEYID_ERASED;
+ uint8_t message[64];
+ uint8_t tag[AES_BLOCK_SIZE];
+ word32 tagLen = sizeof(tag);
+
+ ret = wc_RNG_GenerateBlock(rng, message, sizeof(message));
+ if (ret == 0) {
+ ret = wc_RNG_GenerateBlock(rng, tag, sizeof(tag));
+ }
+ if (ret == 0) {
+ ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_NONE,
+ (uint8_t*)"cmac-no-verify",
+ strlen("cmac-no-verify"), key,
+ AES_128_KEY_SIZE, &cmacKeyId);
+ }
+ if (ret == 0) {
+ ret = wc_InitCmac_ex(&cmac, NULL, 0, WC_CMAC_AES, NULL, NULL,
+ WH_DEV_ID);
+ if (ret == 0) {
+ ret = wh_Client_CmacSetKeyId(&cmac, cmacKeyId);
+ if (ret == 0) {
+ ret = wc_AesCmacVerify_ex(&cmac, tag, tagLen, message,
+ sizeof(message), NULL, 0, NULL,
+ WH_DEV_ID);
+ if (ret == WH_ERROR_USAGE) {
+ WH_TEST_PRINT(
+ " PASS: Correctly denied CMAC verify\n");
+ ret = 0;
+ }
+ else {
+ WH_ERROR_PRINT(
+ " FAIL: Expected WH_ERROR_USAGE, got %d\n",
+ ret);
+ ret = WH_ERROR_ABORTED;
+ }
+ }
+ wc_CmacFree(&cmac);
+ }
+ wh_Client_KeyEvict(client, cmacKeyId);
+ }
+ }
+ if (ret != 0) {
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+#endif /* WOLFSSL_CMAC && !NO_AES && WOLFSSL_AES_DIRECT */
+
+#ifdef WOLFHSM_CFG_KEYWRAP
+ WH_TEST_PRINT(" Testing key wrap without WRAP flag...\n");
+ {
+ uint8_t kek[32] = {0};
+ uint8_t dataKey[32] = {0};
+ uint8_t wrappedKey[256] = {0};
+ uint16_t wrappedKeySz = sizeof(wrappedKey);
+ whKeyId kekId = WH_KEYID_ERASED;
+ const whKeyId wrappedId = 1;
+ whNvmMetadata meta = {0};
+
+ ret = wc_RNG_GenerateBlock(rng, kek, sizeof(kek));
+ if (ret == 0) {
+ ret = wc_RNG_GenerateBlock(rng, dataKey, sizeof(dataKey));
+ }
+ if (ret == 0) {
+ ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_NONE,
+ (uint8_t*)"kek-no-wrap",
+ strlen("kek-no-wrap"), kek, sizeof(kek),
+ &kekId);
+ if (ret == 0) {
+ meta.id = WH_CLIENT_KEYID_MAKE_WRAPPED_META(
+ client->comm->client_id, wrappedId);
+ meta.flags = WH_NVM_FLAGS_NONE;
+ meta.len = sizeof(dataKey);
+
+ ret = wh_Client_KeyWrap(client, WC_CIPHER_AES_GCM, kekId,
+ dataKey, sizeof(dataKey), &meta,
+ wrappedKey, &wrappedKeySz);
+ if (ret == WH_ERROR_USAGE) {
+ WH_TEST_PRINT(" PASS: Correctly denied key wrapping\n");
+ ret = 0;
+ }
+ else {
+ WH_ERROR_PRINT(
+ " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret);
+ ret = WH_ERROR_ABORTED;
+ }
+ wh_Client_KeyEvict(client, kekId);
+ }
+ }
+ }
+ if (ret != 0) {
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+#endif /* WOLFHSM_CFG_KEYWRAP */
+
+ (void)wc_FreeRng(rng);
+ WH_TEST_PRINT("Key Usage Policy Tests PASSED\n");
+ return 0;
+}
+
+#if !defined(NO_AES) && defined(HAVE_AES_CBC) && \
+ defined(WOLFHSM_CFG_TEST_ALLOW_PERSISTENT_NVM_ARTIFACTS)
+static int whTest_RevocationTryAESEncrypt(whKeyId keyId, WC_RNG* rng,
+ int* encryptRes)
+{
+ int ret;
+ Aes aes[1];
+ uint8_t iv[AES_BLOCK_SIZE];
+ uint8_t plaintext[16];
+ uint8_t ciphertext[16] = {0};
+
+ ret = wc_RNG_GenerateBlock(rng, iv, sizeof(iv));
+ if (ret == 0) {
+ ret = wc_RNG_GenerateBlock(rng, plaintext, sizeof(plaintext));
+ }
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to generate AES revocation test inputs: %d\n",
+ ret);
+ return ret;
+ }
+ ret = wc_AesInit(aes, NULL, WH_DEV_ID);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to init AES for revoked key test: %d\n", ret);
+ return ret;
+ }
+ ret = wh_Client_AesSetKeyId(aes, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to set AES keyId for revoked key test: %d\n",
+ ret);
+ wc_AesFree(aes);
+ return ret;
+ }
+ ret = wc_AesSetIV(aes, iv);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to set AES IV for revoked key test: %d\n", ret);
+ wc_AesFree(aes);
+ return ret;
+ }
+ ret = wc_AesCbcEncrypt(aes, ciphertext, plaintext,
+ (word32)sizeof(plaintext));
+ wc_AesFree(aes);
+ *encryptRes = ret;
+ return WH_ERROR_OK;
+}
+
+int whTest_CryptoKeyRevocationAesCbc(whClientContext* client)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ WC_RNG rng[1];
+ uint8_t key[32] = {0};
+ const uint8_t label[] = "revocation-aes-cbc";
+ whKeyId keyId = WH_KEYID_ERASED;
+ const int expectedEraseErr = WH_ERROR_ACCESS;
+ int encryptRes = 0;
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+
+ WH_TEST_PRINT("Testing Key Revocation...\n");
+ WH_TEST_PRINT(" AES-CBC key revoke flow...\n");
+
+ ret = wc_RNG_GenerateBlock(rng, key, sizeof(key));
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to generate AES revocation inputs: %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_USAGE_ANY, (uint8_t*)label,
+ sizeof(label), key, sizeof(key), &keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to cache AES key: %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ ret = whTest_RevocationTryAESEncrypt(keyId, rng, &encryptRes);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to encrypt with unrevoked AES key: %d\n", ret);
+ (void)wh_Client_KeyEvict(client, keyId);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+ if (encryptRes != 0) {
+ WH_ERROR_PRINT("Encrypt with unrevoked AES key failed: %d\n",
+ encryptRes);
+ (void)wc_FreeRng(rng);
+ return encryptRes;
+ }
+
+ ret = wh_Client_KeyRevoke(client, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to revoke AES key: %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ ret = whTest_RevocationTryAESEncrypt(keyId, rng, &encryptRes);
+ if (ret != 0 || encryptRes != WH_ERROR_USAGE) {
+ WH_ERROR_PRINT(
+ "Encrypt with revoked AES key should fail (%d), got %d\n",
+ WH_ERROR_USAGE, encryptRes);
+ (void)wc_FreeRng(rng);
+ return WH_ERROR_ABORTED;
+ }
+
+ ret = wh_Client_KeyCommit(client, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to commit revoked AES key: %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+
+ ret = whTest_RevocationTryAESEncrypt(keyId, rng, &encryptRes);
+ if (ret != 0 || encryptRes != WH_ERROR_USAGE) {
+ WH_ERROR_PRINT(
+ "Encrypt with revoked AES key should fail (%d), got %d\n",
+ WH_ERROR_USAGE, encryptRes);
+ (void)wc_FreeRng(rng);
+ return WH_ERROR_ABORTED;
+ }
+
+ ret = wh_Client_KeyErase(client, keyId);
+ if (ret != expectedEraseErr) {
+ WH_ERROR_PRINT("Revoked key erase should fail (%d), got %d\n",
+ expectedEraseErr, ret);
+ (void)wc_FreeRng(rng);
+ return WH_ERROR_ABORTED;
+ }
+
+ /* Slightly different flow: cache + commit + evict + revoke */
+ keyId = WH_KEYID_ERASED;
+ ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_USAGE_ANY, (uint8_t*)label,
+ sizeof(label), key, sizeof(key), &keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to cache AES key (2nd time): %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+ ret = wh_Client_KeyCommit(client, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to commit AES key (2nd time): %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+ ret = whTest_RevocationTryAESEncrypt(keyId, rng, &encryptRes);
+ if (ret != 0 || encryptRes != 0) {
+ WH_ERROR_PRINT(
+ "Failed to encrypt with unrevoked AES key (2nd time): %d\n", ret);
+ (void)wh_Client_KeyEvict(client, keyId);
+ (void)wc_FreeRng(rng);
+ return ret != 0 ? ret : encryptRes;
+ }
+ ret = wh_Client_KeyEvict(client, keyId);
+ if (ret != 0 && ret != WH_ERROR_NOTFOUND) {
+ WH_ERROR_PRINT("Failed to evict AES key (2nd time): %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+ ret = wh_Client_KeyRevoke(client, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to revoke AES key (2nd time): %d\n", ret);
+ (void)wc_FreeRng(rng);
+ return ret;
+ }
+ ret = whTest_RevocationTryAESEncrypt(keyId, rng, &encryptRes);
+ if (ret != 0 || encryptRes != WH_ERROR_USAGE) {
+ WH_ERROR_PRINT(
+ "Encrypt with revoked AES key should fail (%d), got %d\n",
+ WH_ERROR_USAGE, encryptRes);
+ (void)wh_Client_KeyEvict(client, keyId);
+ (void)wc_FreeRng(rng);
+ return WH_ERROR_ABORTED;
+ }
+
+ WH_TEST_PRINT(" AES-CBC revocation enforcement: PASS\n");
+ (void)wc_FreeRng(rng);
+ return 0;
+}
+#endif /* !NO_AES && HAVE_AES_CBC && \
+ WOLFHSM_CFG_TEST_ALLOW_PERSISTENT_NVM_ARTIFACTS */
+
+#endif /* !WOLFHSM_CFG_NO_CRYPTO */
diff --git a/test-refactor/client-server/wh_test_mldsa.c b/test-refactor/client-server/wh_test_mldsa.c
new file mode 100644
index 00000000..a159eba2
--- /dev/null
+++ b/test-refactor/client-server/wh_test_mldsa.c
@@ -0,0 +1,967 @@
+/*
+ * Copyright (C) 2026 wolfSSL Inc.
+ *
+ * This file is part of wolfHSM.
+ *
+ * wolfHSM 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfHSM 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 wolfHSM. If not, see .
+ */
+/*
+ * test-refactor/client-server/wh_test_mldsa.c
+ *
+ * ML-DSA (Dilithium) tests routed through the server:
+ * whTestCrypto_MlDsaClient - non-DMA generate / sign / verify, with
+ * and without FIPS 204 context strings
+ * whTestCrypto_MlDsaDmaClient - DMA generate / import / export / sign /
+ * verify, with key round-trip equality
+ * whTestCrypto_MlDsaVerifyOnlyDma - import a known public key + signature,
+ * verify against fixed message vector
+ */
+
+#include "wolfhsm/wh_settings.h"
+
+#if !defined(WOLFHSM_CFG_NO_CRYPTO)
+
+#include
+#include
+
+#include "wolfssl/wolfcrypt/settings.h"
+#include "wolfssl/wolfcrypt/types.h"
+#include "wolfssl/wolfcrypt/random.h"
+#include "wolfssl/wolfcrypt/dilithium.h"
+#include "wolfssl/wolfcrypt/asn.h"
+
+#include "wolfhsm/wh_error.h"
+#include "wolfhsm/wh_common.h"
+#include "wolfhsm/wh_client.h"
+#include "wolfhsm/wh_client_crypto.h"
+
+#include "wh_test_common.h"
+#include "wh_test_list.h"
+
+#ifdef HAVE_DILITHIUM
+
+#if !defined(WOLFSSL_DILITHIUM_NO_VERIFY) && \
+ !defined(WOLFSSL_DILITHIUM_NO_SIGN) && \
+ !defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY) && !defined(WOLFSSL_NO_ML_DSA_44)
+
+int whTestCrypto_MlDsaClient(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ MlDsaKey key[1];
+
+ ret = wc_MlDsaKey_Init(key, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to initialize ML-DSA key: %d\n", ret);
+ return ret;
+ }
+
+ if (ret == 0) {
+ ret = wh_Client_MlDsaMakeExportKey(ctx, WC_ML_DSA_44, 0, key);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to generate ML-DSA key: %d\n", ret);
+ }
+ }
+
+ if (ret == 0) {
+ byte msg[] = "Test message for non-DMA ML-DSA";
+ byte sig[DILITHIUM_MAX_SIG_SIZE];
+ word32 sigLen = sizeof(sig);
+ int verified = 0;
+
+ ret = wh_Client_MlDsaSign(ctx, msg, sizeof(msg), sig, &sigLen, key,
+ NULL, 0, WC_HASH_TYPE_NONE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to sign using ML-DSA non-DMA: %d\n", ret);
+ }
+ else {
+ ret = wh_Client_MlDsaVerify(ctx, sig, sigLen, msg, sizeof(msg),
+ &verified, key, NULL, 0,
+ WC_HASH_TYPE_NONE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to verify ML-DSA non-DMA: %d\n", ret);
+ }
+ else if (!verified) {
+ WH_ERROR_PRINT("ML-DSA non-DMA verification failed\n");
+ ret = -1;
+ }
+ else {
+ int vret;
+ sig[0] ^= 0xFF;
+ vret = wh_Client_MlDsaVerify(ctx, sig, sigLen, msg, sizeof(msg),
+ &verified, key, NULL, 0,
+ WC_HASH_TYPE_NONE);
+ if (vret != 0) {
+ WH_ERROR_PRINT("Failed to call verify with modified sig: "
+ "%d\n",
+ vret);
+ ret = vret;
+ }
+ else if (verified) {
+ WH_ERROR_PRINT("ML-DSA non-DMA verified bad signature\n");
+ ret = -1;
+ }
+ }
+ }
+ }
+
+ if (ret == 0) {
+ byte msg[] = "Context test message non-DMA";
+ byte sig[DILITHIUM_MAX_SIG_SIZE];
+ word32 sigLen = sizeof(sig);
+ int verified = 0;
+ const byte ctx_str[] = "test-context";
+
+ ret = wh_Client_MlDsaSign(ctx, msg, sizeof(msg), sig, &sigLen, key,
+ ctx_str, sizeof(ctx_str), WC_HASH_TYPE_NONE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to sign with context non-DMA: %d\n", ret);
+ }
+ else {
+ ret = wh_Client_MlDsaVerify(ctx, sig, sigLen, msg, sizeof(msg),
+ &verified, key, ctx_str,
+ sizeof(ctx_str), WC_HASH_TYPE_NONE);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to verify with context non-DMA: %d\n", ret);
+ }
+ else if (!verified) {
+ WH_ERROR_PRINT("Context verification failed non-DMA\n");
+ ret = -1;
+ }
+ else {
+ const byte wrong_ctx[] = "wrong-context";
+ int wrong_verified = 0;
+ int vret = wh_Client_MlDsaVerify(
+ ctx, sig, sigLen, msg, sizeof(msg), &wrong_verified, key,
+ wrong_ctx, sizeof(wrong_ctx), WC_HASH_TYPE_NONE);
+ if (vret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to call verify with wrong context "
+ "non-DMA: %d\n",
+ vret);
+ ret = vret;
+ }
+ else if (wrong_verified) {
+ WH_ERROR_PRINT(
+ "Verification succeeded with wrong context "
+ "non-DMA\n");
+ ret = -1;
+ }
+ }
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("ML-DSA Client Non-DMA API SUCCESS\n");
+ }
+
+ wc_MlDsaKey_Free(key);
+ return ret;
+}
+
+/* Cache a NONEXPORTABLE ML-DSA-44 keypair on the server, then verify that
+ * wh_Client_MlDsaExportPublicKey returns a public-only key struct. */
+int whTestCrypto_MlDsaExportPublicKey(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ MlDsaKey pub[1] = {0};
+ whKeyId keyId = WH_KEYID_ERASED;
+ uint8_t denyBuf[DILITHIUM_MAX_BOTH_KEY_DER_SIZE];
+ uint16_t denyLen = sizeof(denyBuf);
+
+ ret = wh_Client_MlDsaMakeCacheKey(
+ ctx, 0, WC_ML_DSA_44, &keyId,
+ WH_NVM_FLAGS_USAGE_SIGN | WH_NVM_FLAGS_USAGE_VERIFY |
+ WH_NVM_FLAGS_NONEXPORTABLE,
+ 0, NULL);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to make NONEXPORTABLE cached ML-DSA key %d\n",
+ ret);
+ return ret;
+ }
+
+ /* Full export must be denied by the NONEXPORTABLE policy. */
+ {
+ int denyRet = wh_Client_KeyExport(ctx, keyId, NULL, 0, denyBuf,
+ &denyLen);
+ if (denyRet != WH_ERROR_ACCESS) {
+ WH_ERROR_PRINT(
+ "NONEXPORTABLE ML-DSA full export was not denied: %d\n",
+ denyRet);
+ ret = -1;
+ }
+ }
+
+ /* Public-only export must succeed and yield a public-only key struct. */
+ if (ret == 0) {
+ ret = wc_MlDsaKey_Init(pub, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wc_MlDsaKey_SetParams(pub, WC_ML_DSA_44);
+ }
+ if (ret == 0) {
+ ret = wh_Client_MlDsaExportPublicKey(ctx, keyId, pub, 0, NULL);
+ if (ret != 0) {
+ WH_ERROR_PRINT("wh_Client_MlDsaExportPublicKey failed %d\n",
+ ret);
+ }
+ else if (pub->pubKeySet != 1 || pub->prvKeySet != 0) {
+ WH_ERROR_PRINT(
+ "Exported ML-DSA key flags wrong: pub=%d prv=%d\n",
+ (int)pub->pubKeySet, (int)pub->prvKeySet);
+ ret = -1;
+ }
+ }
+ wc_MlDsaKey_Free(pub);
+ }
+
+ if (!WH_KEYID_ISERASED(keyId)) {
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("ML-DSA EXPORT-PUBLIC DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+#ifdef WOLFHSM_CFG_DMA
+int whTestCrypto_MlDsaDmaClient(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ MlDsaKey key[1];
+ MlDsaKey imported_key[1];
+ whKeyId keyId = WH_KEYID_ERASED;
+ uint8_t label[] = "ML-DSA Test Key";
+ int keyImported = 0;
+
+ /* Buffers for comparing serialized keys */
+ byte key_der1[DILITHIUM_MAX_PRV_KEY_SIZE];
+ byte key_der2[DILITHIUM_MAX_PRV_KEY_SIZE];
+ word32 key_der1_len = sizeof(key_der1);
+ word32 key_der2_len = sizeof(key_der2);
+
+ ret = wc_MlDsaKey_Init(key, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to initialize ML-DSA key: %d\n", ret);
+ return ret;
+ }
+
+ ret = wc_MlDsaKey_Init(imported_key, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to initialize imported ML-DSA key: %d\n", ret);
+ wc_MlDsaKey_Free(key);
+ return ret;
+ }
+
+ if (ret == 0) {
+ ret = wh_Client_MlDsaMakeExportKeyDma(ctx, WC_ML_DSA_44, key);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to generate ML-DSA key using DMA: %d\n",
+ ret);
+ }
+ }
+
+ if (ret == 0) {
+ ret = wc_Dilithium_PrivateKeyToDer(key, key_der1, key_der1_len);
+ if (ret < 0) {
+ WH_ERROR_PRINT("Failed to serialize generated key: %d\n", ret);
+ }
+ else {
+ key_der1_len = ret;
+ ret = 0;
+ }
+ }
+
+ if (ret == 0) {
+ ret = wh_Client_MlDsaImportKeyDma(ctx, key, &keyId, WH_NVM_FLAGS_NONE,
+ sizeof(label), label);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to import ML-DSA key using DMA: %d\n",
+ ret);
+ }
+ keyImported = (ret == 0);
+ }
+
+ if (ret == 0) {
+ ret = wh_Client_MlDsaExportKeyDma(ctx, keyId, imported_key,
+ sizeof(label), label);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to export ML-DSA key using DMA: %d\n",
+ ret);
+ }
+ }
+
+ if (ret == 0) {
+ ret = wc_Dilithium_PrivateKeyToDer(imported_key, key_der2,
+ key_der2_len);
+ if (ret < 0) {
+ WH_ERROR_PRINT("Failed to serialize exported key: %d\n", ret);
+ }
+ else {
+ key_der2_len = ret;
+ ret = 0;
+ }
+ }
+
+ if (ret == 0) {
+ if (key_der1_len != key_der2_len ||
+ memcmp(key_der1, key_der2, key_der1_len) != 0) {
+ WH_ERROR_PRINT("Exported key does not match generated key\n");
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ byte msg[] = "Test message to sign";
+ byte sig[DILITHIUM_MAX_SIG_SIZE];
+ word32 sigLen = sizeof(sig);
+ int verified = 0;
+
+ ret = wh_Client_MlDsaSignDma(ctx, msg, sizeof(msg), sig, &sigLen, key,
+ NULL, 0, WC_HASH_TYPE_NONE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to sign message using ML-DSA: %d\n", ret);
+ }
+ else {
+ ret = wh_Client_MlDsaVerifyDma(ctx, sig, sigLen, msg, sizeof(msg),
+ &verified, key, NULL, 0,
+ WC_HASH_TYPE_NONE);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to verify signature using ML-DSA: %d\n", ret);
+ }
+ else if (!verified) {
+ WH_ERROR_PRINT("Signature verification failed when it should "
+ "have succeeded\n");
+ ret = -1;
+ }
+ else {
+ sig[0] ^= 0xFF;
+ ret = wh_Client_MlDsaVerifyDma(ctx, sig, sigLen, msg,
+ sizeof(msg), &verified, key,
+ NULL, 0, WC_HASH_TYPE_NONE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to verify modified signature using "
+ "ML-DSA: %d\n",
+ ret);
+ }
+ else if (verified) {
+ WH_ERROR_PRINT("Signature verification succeeded when it "
+ "should have failed\n");
+ ret = -1;
+ }
+ else {
+ ret = 0;
+ }
+ }
+ }
+ }
+
+ if (ret == 0) {
+ byte msg[] = "Context test message";
+ byte sig[DILITHIUM_MAX_SIG_SIZE];
+ word32 sigLen = sizeof(sig);
+ int verified = 0;
+ const byte ctx_str[] = "test-context";
+
+ ret = wh_Client_MlDsaSignDma(ctx, msg, sizeof(msg), sig, &sigLen, key,
+ ctx_str, sizeof(ctx_str),
+ WC_HASH_TYPE_NONE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to sign with context using ML-DSA: %d\n",
+ ret);
+ }
+ else {
+ ret = wh_Client_MlDsaVerifyDma(
+ ctx, sig, sigLen, msg, sizeof(msg), &verified, key, ctx_str,
+ sizeof(ctx_str), WC_HASH_TYPE_NONE);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to verify with context using ML-DSA: %d\n", ret);
+ }
+ else if (!verified) {
+ WH_ERROR_PRINT("Context verification failed when it should "
+ "have succeeded\n");
+ ret = -1;
+ }
+ else {
+ const byte wrong_ctx[] = "wrong-context";
+ int wrong_verified = 0;
+ int vret = wh_Client_MlDsaVerifyDma(
+ ctx, sig, sigLen, msg, sizeof(msg), &wrong_verified, key,
+ wrong_ctx, sizeof(wrong_ctx), WC_HASH_TYPE_NONE);
+ if (vret != 0) {
+ WH_ERROR_PRINT("Failed to call verify with wrong context: "
+ "%d\n",
+ vret);
+ ret = vret;
+ }
+ else if (wrong_verified) {
+ WH_ERROR_PRINT("Context verification succeeded with wrong "
+ "context\n");
+ ret = -1;
+ }
+ }
+ }
+ }
+
+ if (keyImported) {
+ int evict_ret = wh_Client_KeyEvict(ctx, keyId);
+ if (evict_ret != 0) {
+ WH_ERROR_PRINT("Failed to evict ML-DSA key: %d\n", evict_ret);
+ if (ret == 0) {
+ ret = evict_ret;
+ }
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("ML-DSA Client DMA API SUCCESS\n");
+ }
+
+ wc_MlDsaKey_Free(key);
+ wc_MlDsaKey_Free(imported_key);
+ return ret;
+}
+
+/* DMA counterpart to whTestCrypto_MlDsaExportPublicKey: cache a NONEXPORTABLE
+ * ML-DSA-44 keypair, then verify wh_Client_MlDsaExportPublicKeyDma yields a
+ * public-only key. */
+int whTestCrypto_MlDsaExportPublicKeyDma(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = 0;
+ MlDsaKey pub[1] = {0};
+ whKeyId keyId = WH_KEYID_ERASED;
+ uint8_t denyBuf[DILITHIUM_MAX_BOTH_KEY_DER_SIZE];
+ uint16_t denyLen = sizeof(denyBuf);
+
+ ret = wh_Client_MlDsaMakeCacheKey(
+ ctx, 0, WC_ML_DSA_44, &keyId,
+ WH_NVM_FLAGS_USAGE_SIGN | WH_NVM_FLAGS_USAGE_VERIFY |
+ WH_NVM_FLAGS_NONEXPORTABLE,
+ 0, NULL);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "Failed to make NONEXPORTABLE cached ML-DSA key (DMA test) %d\n",
+ ret);
+ return ret;
+ }
+
+ /* Full DMA export must be denied by the NONEXPORTABLE policy. */
+ {
+ int denyRet = wh_Client_KeyExportDma(ctx, keyId, denyBuf,
+ (uint16_t)sizeof(denyBuf), NULL, 0,
+ &denyLen);
+ if (denyRet != WH_ERROR_ACCESS) {
+ WH_ERROR_PRINT(
+ "NONEXPORTABLE ML-DSA full DMA export was not denied: %d\n",
+ denyRet);
+ ret = -1;
+ }
+ }
+
+ /* Public-only DMA export must succeed and yield a public-only key. */
+ if (ret == 0) {
+ ret = wc_MlDsaKey_Init(pub, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wc_MlDsaKey_SetParams(pub, WC_ML_DSA_44);
+ }
+ if (ret == 0) {
+ ret = wh_Client_MlDsaExportPublicKeyDma(ctx, keyId, pub, 0, NULL);
+ if (ret != 0) {
+ WH_ERROR_PRINT(
+ "wh_Client_MlDsaExportPublicKeyDma failed %d\n", ret);
+ }
+ else if (pub->pubKeySet != 1 || pub->prvKeySet != 0) {
+ WH_ERROR_PRINT(
+ "Exported ML-DSA key (DMA) flags wrong: pub=%d prv=%d\n",
+ (int)pub->pubKeySet, (int)pub->prvKeySet);
+ ret = -1;
+ }
+ }
+ wc_MlDsaKey_Free(pub);
+ }
+
+ if (!WH_KEYID_ISERASED(keyId)) {
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("ML-DSA EXPORT-PUBLIC DMA DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+#endif /* WOLFHSM_CFG_DMA */
+
+#endif /* !WOLFSSL_DILITHIUM_NO_VERIFY && !WOLFSSL_DILITHIUM_NO_SIGN && \
+ !WOLFSSL_DILITHIUM_NO_MAKE_KEY && !WOLFSSL_NO_ML_DSA_44 */
+
+#if !defined(WOLFSSL_DILITHIUM_NO_VERIFY) && \
+ !defined(WOLFSSL_NO_ML_DSA_44) && \
+ defined(WOLFHSM_CFG_DMA)
+int whTestCrypto_MlDsaVerifyOnlyDma(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID_DMA;
+
+ /* Vectors from wolfCrypt test vectors, but decoupled for isolated usage */
+ const byte ml_dsa_44_pub_key[] = {
+ 0xd8, 0xac, 0xaf, 0xd8, 0x2e, 0x14, 0x23, 0x78, 0xf7, 0x0d, 0x9a, 0x04,
+ 0x2b, 0x92, 0x48, 0x67, 0x60, 0x55, 0x34, 0xd9, 0xac, 0x0b, 0xc4, 0x1f,
+ 0x46, 0xe8, 0x85, 0xb9, 0x2e, 0x1b, 0x10, 0x3a, 0x75, 0x7a, 0xc2, 0xbc,
+ 0x76, 0xf0, 0x6d, 0x05, 0xa4, 0x78, 0x48, 0x84, 0x26, 0x69, 0xbd, 0x26,
+ 0x1d, 0x73, 0x60, 0xaa, 0x57, 0x9d, 0x8c, 0x66, 0xb1, 0x19, 0xea, 0x11,
+ 0xff, 0xbb, 0xf6, 0xeb, 0x26, 0x26, 0xac, 0x78, 0x74, 0x46, 0x6d, 0x51,
+ 0x6e, 0x92, 0xdf, 0x6a, 0x98, 0x41, 0xe9, 0x10, 0xf2, 0xcc, 0xa8, 0x7a,
+ 0x50, 0xdb, 0x1f, 0x4c, 0x42, 0x19, 0xd5, 0xbc, 0x76, 0x20, 0x6f, 0x2f,
+ 0xbf, 0xc2, 0xc9, 0x1b, 0x02, 0xb5, 0xb1, 0x09, 0x46, 0x06, 0x87, 0x02,
+ 0xac, 0x3d, 0xcf, 0xc3, 0xa5, 0x1b, 0xf0, 0xce, 0xd4, 0x9e, 0x84, 0x34,
+ 0x3c, 0x24, 0x7d, 0x89, 0xf3, 0xbf, 0x9c, 0x18, 0x9d, 0x1b, 0x1d, 0xd4,
+ 0xf6, 0xda, 0xc9, 0xa4, 0x14, 0xc4, 0x6b, 0xd7, 0x05, 0x6d, 0xed, 0x54,
+ 0x42, 0x6b, 0x5f, 0x6d, 0x1e, 0xda, 0x6b, 0x47, 0x70, 0xe5, 0x4e, 0xe7,
+ 0x25, 0x06, 0xf8, 0x28, 0x24, 0x34, 0xd6, 0xe5, 0xbe, 0xc5, 0x4f, 0x9e,
+ 0x5d, 0x33, 0xfc, 0xef, 0xe4, 0xe9, 0x55, 0x67, 0x93, 0x1f, 0x2e, 0x11,
+ 0x3a, 0x2e, 0xf2, 0xbb, 0x82, 0x09, 0x8d, 0xb2, 0x09, 0xf3, 0x2f, 0xef,
+ 0x6f, 0x38, 0xc6, 0x56, 0xf2, 0x23, 0x08, 0x63, 0x99, 0x7f, 0x4e, 0xc0,
+ 0x9d, 0x08, 0x9d, 0xa1, 0x59, 0x6e, 0xe1, 0x00, 0x2c, 0x99, 0xec, 0x83,
+ 0x2f, 0x12, 0x97, 0x2f, 0x75, 0x04, 0x67, 0x44, 0xb5, 0x95, 0xce, 0xc6,
+ 0x3e, 0x7a, 0x10, 0x77, 0x5e, 0xbe, 0x9c, 0x0f, 0xb3, 0xc7, 0x38, 0xbf,
+ 0x9e, 0x35, 0x8f, 0xe4, 0x8d, 0x19, 0xc3, 0x41, 0xb1, 0x0b, 0x8c, 0x10,
+ 0x9a, 0x58, 0xec, 0x4f, 0xb3, 0xe9, 0x5b, 0x72, 0x4b, 0xb8, 0x99, 0x34,
+ 0x9a, 0xcd, 0xb0, 0x69, 0xd0, 0x67, 0xef, 0x96, 0xb9, 0xe5, 0x54, 0x92,
+ 0xb7, 0x1a, 0x52, 0xf6, 0x0a, 0xc2, 0x23, 0x8d, 0x4f, 0xad, 0x00, 0xae,
+ 0x0f, 0x97, 0xfa, 0xce, 0x96, 0xba, 0xe7, 0x74, 0x55, 0xd4, 0xaf, 0xbf,
+ 0xa1, 0x32, 0x91, 0x2d, 0x03, 0x9f, 0xe3, 0x10, 0x8c, 0x77, 0x5d, 0x26,
+ 0x76, 0xf1, 0x87, 0x90, 0xf0, 0x20, 0xd1, 0xea, 0xf7, 0xa4, 0xe8, 0x2c,
+ 0x32, 0x1c, 0x55, 0xc0, 0x5d, 0xc9, 0xcd, 0x4e, 0x8f, 0x0d, 0xef, 0x0a,
+ 0x27, 0xb6, 0x4f, 0xa4, 0xd3, 0xa4, 0xed, 0x33, 0x22, 0xa1, 0xd3, 0x15,
+ 0xac, 0x1a, 0x20, 0x4e, 0x28, 0x8c, 0x8c, 0xd0, 0x71, 0xd1, 0xf2, 0xdb,
+ 0x33, 0x63, 0xb6, 0xa4, 0xf2, 0x17, 0x3c, 0x12, 0xb0, 0xad, 0xef, 0x31,
+ 0x91, 0xfe, 0xe5, 0x53, 0x99, 0xb6, 0x85, 0x63, 0xfa, 0xe6, 0xcd, 0xf6,
+ 0xb9, 0xce, 0x4a, 0x7d, 0x4a, 0x49, 0x29, 0xd2, 0xd9, 0xc9, 0x47, 0x4a,
+ 0x8a, 0x5c, 0x14, 0x5e, 0x0f, 0x7c, 0xc3, 0x91, 0xb0, 0xab, 0x37, 0xf5,
+ 0x26, 0x8d, 0x46, 0x74, 0x49, 0xad, 0x51, 0xc3, 0x11, 0xfa, 0x85, 0x15,
+ 0xa5, 0x84, 0xc1, 0xe0, 0x3c, 0x13, 0x6d, 0x13, 0xa3, 0xe6, 0xa8, 0x3c,
+ 0x22, 0xac, 0x17, 0x48, 0x57, 0x7c, 0x81, 0xe2, 0x4e, 0xd8, 0x33, 0x5d,
+ 0x4d, 0x65, 0xf7, 0xe1, 0xb8, 0x00, 0x78, 0x09, 0x16, 0xb0, 0x0b, 0xca,
+ 0x15, 0x0d, 0xcd, 0x9a, 0xd8, 0x47, 0x4c, 0x9b, 0x69, 0xb2, 0xa0, 0x9d,
+ 0x96, 0x96, 0x52, 0x6d, 0x89, 0xad, 0xff, 0x55, 0xde, 0x7b, 0xd6, 0x3d,
+ 0x1d, 0x5e, 0x8d, 0xf1, 0xfc, 0x48, 0x1c, 0x50, 0x59, 0x55, 0xb9, 0x07,
+ 0xfd, 0x6b, 0xcb, 0x95, 0xa6, 0x14, 0x73, 0xdb, 0x40, 0x40, 0x1c, 0x44,
+ 0xe6, 0x79, 0x30, 0x88, 0xbd, 0xa0, 0xde, 0x9b, 0xb8, 0x76, 0xf8, 0x98,
+ 0x56, 0x4b, 0xb9, 0x7a, 0xf6, 0xd4, 0x73, 0x89, 0x6b, 0xf7, 0x7d, 0x05,
+ 0x33, 0xbe, 0xb6, 0x1c, 0x4d, 0xa7, 0x12, 0x3b, 0x3f, 0xed, 0x4a, 0x0f,
+ 0xae, 0xa7, 0x6a, 0x26, 0x0d, 0x01, 0x84, 0x84, 0xa8, 0x0e, 0xc1, 0xc1,
+ 0xfd, 0xe4, 0xa9, 0xe2, 0x3f, 0xab, 0xce, 0x20, 0x90, 0x86, 0x79, 0xa2,
+ 0x40, 0xd0, 0xef, 0x79, 0x34, 0x2b, 0xe8, 0xc9, 0x54, 0xa7, 0x19, 0x62,
+ 0xcc, 0x20, 0x79, 0x3f, 0x5b, 0x9c, 0x61, 0xc2, 0xc1, 0xd2, 0x36, 0x7c,
+ 0x8e, 0xe3, 0x01, 0xbe, 0xc4, 0xb2, 0xb8, 0x07, 0x51, 0x23, 0x5b, 0x5d,
+ 0x00, 0xe6, 0x7f, 0xd6, 0xbb, 0x32, 0xa9, 0x7e, 0xb4, 0x30, 0xeb, 0x5e,
+ 0x6d, 0xed, 0xb2, 0xc3, 0x88, 0x81, 0xa3, 0x3b, 0x1f, 0x1e, 0xf9, 0x48,
+ 0x10, 0xd6, 0x01, 0x65, 0x5f, 0x6d, 0xc5, 0xeb, 0x76, 0x5f, 0x10, 0x79,
+ 0xaa, 0xc0, 0x86, 0xe7, 0x44, 0x95, 0x44, 0x4b, 0x54, 0x0c, 0x46, 0x2a,
+ 0x98, 0x01, 0x6e, 0xc0, 0xb9, 0x59, 0x2a, 0xff, 0x8f, 0xb3, 0x80, 0x15,
+ 0xec, 0xcd, 0x39, 0x36, 0xd7, 0x2f, 0x20, 0x9e, 0x3a, 0xc1, 0x90, 0xe5,
+ 0x99, 0x27, 0x16, 0xd7, 0x6c, 0x30, 0x10, 0x12, 0x03, 0x3e, 0xdc, 0xb9,
+ 0x03, 0x25, 0xb0, 0x8a, 0x27, 0x4d, 0x1a, 0x32, 0x36, 0x54, 0xc0, 0xba,
+ 0x22, 0xb2, 0xe2, 0xf6, 0x39, 0x23, 0x03, 0xc4, 0xc9, 0xe4, 0x0d, 0x99,
+ 0xfb, 0x98, 0xa5, 0x9b, 0x12, 0x9b, 0x58, 0x44, 0x74, 0x9f, 0x65, 0x61,
+ 0x51, 0xba, 0x31, 0x60, 0x9c, 0xec, 0xf8, 0x4d, 0x36, 0x61, 0xd1, 0x33,
+ 0x6d, 0xa6, 0x28, 0x75, 0xba, 0x7c, 0x82, 0xcb, 0x7e, 0xbe, 0x8f, 0x2d,
+ 0x21, 0x84, 0xb9, 0xf2, 0x4e, 0x7b, 0x95, 0x99, 0x11, 0xf3, 0xe1, 0xc0,
+ 0x6a, 0x44, 0xae, 0x11, 0xcb, 0x04, 0xa0, 0xf2, 0x3e, 0x17, 0xdf, 0xb2,
+ 0x6a, 0xdf, 0x5c, 0xf3, 0x8a, 0xf8, 0x90, 0x86, 0x64, 0xea, 0x0a, 0x32,
+ 0x7f, 0x9f, 0x90, 0xa8, 0x9d, 0x33, 0x12, 0xa6, 0xa4, 0xe7, 0x74, 0xa0,
+ 0x75, 0xa9, 0x65, 0xf8, 0x39, 0xae, 0x14, 0x32, 0x79, 0xcc, 0xaa, 0x34,
+ 0x86, 0x55, 0xcc, 0x99, 0xb7, 0x00, 0x05, 0x8b, 0xe3, 0x76, 0x28, 0x12,
+ 0xb6, 0x2a, 0x3e, 0x44, 0x8d, 0xf4, 0xba, 0xef, 0xf6, 0xdc, 0x29, 0x08,
+ 0x29, 0x7d, 0xd1, 0x1d, 0x17, 0x15, 0xb6, 0xb6, 0x58, 0x67, 0xd5, 0xd3,
+ 0x12, 0x05, 0x4e, 0xb0, 0xc3, 0x83, 0xe0, 0x35, 0x30, 0x60, 0x59, 0xa0,
+ 0xc5, 0x97, 0x5b, 0x81, 0xd3, 0x68, 0x6c, 0x8c, 0x17, 0x28, 0xa9, 0x24,
+ 0x4f, 0x80, 0x20, 0xa5, 0x21, 0x9f, 0x8f, 0x15, 0x89, 0x2d, 0x87, 0xae,
+ 0x2e, 0xcc, 0x73, 0x3e, 0x06, 0x43, 0xbc, 0xb3, 0x1b, 0xa6, 0x72, 0xaa,
+ 0xa3, 0xaa, 0xbb, 0x6f, 0x2d, 0x68, 0x60, 0xcf, 0x05, 0x94, 0x25, 0x3e,
+ 0x59, 0xf3, 0x64, 0x61, 0x5e, 0x78, 0x9a, 0x7e, 0x0d, 0x50, 0x45, 0x78,
+ 0x51, 0xab, 0x11, 0xb1, 0xc6, 0x95, 0xfc, 0x29, 0x28, 0x10, 0x9c, 0x1a,
+ 0x8c, 0x37, 0xb5, 0x4f, 0x0e, 0xed, 0x4a, 0x28, 0x6c, 0xaa, 0xb7, 0x0d,
+ 0x12, 0xfa, 0x87, 0x5d, 0xd4, 0x9a, 0xb7, 0x2b, 0x46, 0x90, 0x58, 0x4e,
+ 0xd7, 0x8b, 0x41, 0x1b, 0xf8, 0xc4, 0xc2, 0xde, 0xda, 0xec, 0x61, 0xe7,
+ 0xbf, 0x11, 0xdd, 0x6e, 0x4e, 0x6a, 0xd4, 0x87, 0x01, 0xe4, 0xac, 0xe8,
+ 0xaf, 0x2b, 0x01, 0xe1, 0x09, 0x20, 0xe0, 0xbd, 0x7d, 0x03, 0x73, 0x23,
+ 0xdf, 0x77, 0x71, 0xa4, 0x25, 0x8b, 0x0a, 0x93, 0x49, 0x32, 0x45, 0x1a,
+ 0xa4, 0x94, 0x31, 0x61, 0x2e, 0x17, 0x39, 0x8a, 0x66, 0xc9, 0xf9, 0x20,
+ 0x2d, 0x6a, 0x97, 0x2f, 0xe7, 0x26, 0xd8, 0x01, 0x42, 0x65, 0xcf, 0xce,
+ 0xd4, 0x24, 0x41, 0xfb, 0x9b, 0x6f, 0xf1, 0xc2, 0x9e, 0xd5, 0x08, 0x0c,
+ 0xdc, 0x4d, 0x8e, 0xae, 0xcb, 0x5f, 0xd4, 0xcd, 0x7c, 0xf6, 0x82, 0xc6,
+ 0xee, 0xf9, 0x88, 0x3a, 0x34, 0x07, 0x04, 0xb4, 0x84, 0x69, 0xb3, 0xa4,
+ 0x67, 0xab, 0x09, 0xc0, 0x83, 0xfe, 0x59, 0xaf, 0x18, 0x2c, 0xc8, 0x09,
+ 0xc1, 0xbb, 0x13, 0x7c, 0xce, 0x01, 0x5d, 0x85, 0xaa, 0x10, 0x28, 0xa2,
+ 0x96, 0x98, 0x69, 0x23, 0xa3, 0xe7, 0x67, 0xbc, 0x7c, 0x7e, 0xde, 0x4b,
+ 0x36, 0xab, 0x94, 0xd2, 0xb8, 0xf9, 0xdf, 0xee, 0xa1, 0x69, 0xa1, 0xc8,
+ 0xe9, 0x83, 0x21, 0xac, 0x1b, 0x39, 0xf7, 0x6d, 0xbf, 0x8c, 0xdb, 0xd6,
+ 0x2f, 0xc9, 0x3c, 0x3d, 0x50, 0xcf, 0x7f, 0xbe, 0x4a, 0x8d, 0xd8, 0x14,
+ 0xad, 0x69, 0xb0, 0x3e, 0x8a, 0xaf, 0xeb, 0xd9, 0x1a, 0x15, 0x4a, 0xe4,
+ 0xdd, 0xd9, 0xb2, 0xf8, 0x6b, 0xe2, 0x42, 0x9e, 0x29, 0x16, 0xfc, 0x85,
+ 0x9c, 0x47, 0x4b, 0x1f, 0x3d, 0x7b, 0x8c, 0xe1, 0x6d, 0xa3, 0xb8, 0x0a,
+ 0xe6, 0xfa, 0x27, 0xfe, 0x52, 0x72, 0xab, 0x3a, 0xa6, 0x58, 0xd7, 0x53,
+ 0xaf, 0x9f, 0xee, 0x03, 0x85, 0xfc, 0xa4, 0x7a, 0x72, 0x29, 0x7e, 0x62,
+ 0x28, 0x08, 0x79, 0xa8, 0xb8, 0xc7, 0x51, 0x8d, 0xaa, 0x40, 0x2d, 0x4a,
+ 0xd9, 0x47, 0xb4, 0xa8, 0xa2, 0x0a, 0x43, 0xd0, 0xe0, 0x4a, 0x39, 0xa3,
+ 0x06, 0x08, 0x9a, 0xe2, 0xf3, 0xf2, 0xf8, 0xb9, 0x9f, 0x63, 0x32, 0xa0,
+ 0x65, 0x0b, 0xb0, 0x50, 0x96, 0xa6, 0xa8, 0x7a, 0x18, 0xdd, 0x6c, 0xd1,
+ 0x9b, 0xd9, 0x4e, 0x76, 0x8f, 0xfb, 0x22, 0xa6, 0x1d, 0x29, 0xfc, 0xb8,
+ 0x47, 0x29, 0xb6, 0xd1, 0xb1, 0x63, 0x4a, 0x36, 0x1b, 0x10, 0xe6, 0x4c,
+ 0x65, 0x68, 0x1f, 0xad, 0x4f, 0x7d, 0x6b, 0x01, 0x41, 0x18, 0x5f, 0xba,
+ 0x3d, 0xa6, 0x54, 0x28, 0x58, 0xd5, 0x81, 0x60, 0xdf, 0x84, 0x76, 0x00,
+ 0x21, 0x53, 0xeb, 0xd3, 0xa6, 0xec, 0x7d, 0x3c, 0xb8, 0xcd, 0x91, 0x4c,
+ 0x2f, 0x4b, 0x2e, 0x23, 0x4c, 0x0f, 0x0f, 0xe0, 0x14, 0xa5, 0xe7, 0xe5,
+ 0x70, 0x8d, 0x8b, 0x9c};
+ const byte ml_dsa_44_sig[] = {
+ 0x27, 0x3b, 0x58, 0xa0, 0xcf, 0x00, 0x29, 0x5e, 0x1a, 0x63, 0xbf, 0xb4,
+ 0x97, 0x16, 0xa1, 0x9c, 0x78, 0xd1, 0x33, 0xdc, 0x72, 0xde, 0xa3, 0xfc,
+ 0xf4, 0x09, 0xb1, 0x09, 0x16, 0x3f, 0x80, 0x72, 0x22, 0x68, 0x65, 0x68,
+ 0xb9, 0x80, 0x5a, 0x4a, 0x0d, 0x73, 0x49, 0xe1, 0xc6, 0xde, 0xca, 0x08,
+ 0x4f, 0xca, 0xf8, 0xb2, 0xf8, 0x45, 0x3b, 0x6b, 0x8c, 0x6c, 0xfd, 0x3a,
+ 0xf4, 0xde, 0xde, 0x82, 0xd8, 0x04, 0xbe, 0x4f, 0x4a, 0xdb, 0x92, 0x47,
+ 0x83, 0x2d, 0xc4, 0x55, 0xed, 0x20, 0x4f, 0x71, 0xb1, 0x58, 0xd9, 0x70,
+ 0x73, 0xbd, 0xb0, 0x3a, 0xb4, 0x8f, 0xd6, 0x9e, 0x32, 0x98, 0x2b, 0x9e,
+ 0xff, 0x2a, 0x7c, 0xcb, 0x05, 0x1b, 0x8e, 0xe6, 0x3a, 0x45, 0xc6, 0x7a,
+ 0xc8, 0xaf, 0x62, 0xd3, 0x04, 0xfa, 0x69, 0x4f, 0xda, 0x1b, 0x74, 0x16,
+ 0x0d, 0xb3, 0x1a, 0xee, 0x71, 0xd7, 0xb0, 0xef, 0x69, 0xf5, 0xe2, 0xe9,
+ 0xc2, 0xcc, 0x15, 0x66, 0x28, 0x0a, 0xac, 0xe2, 0x63, 0x06, 0xb7, 0x21,
+ 0x0d, 0xd8, 0x5c, 0x94, 0x63, 0xfd, 0x51, 0x18, 0x9f, 0x07, 0x19, 0x3d,
+ 0xa2, 0x50, 0x40, 0xd3, 0xe9, 0x05, 0xd4, 0x11, 0x13, 0x15, 0xaa, 0x46,
+ 0xda, 0x3e, 0x5f, 0xcd, 0x3c, 0xfa, 0x42, 0xba, 0x79, 0x4a, 0xb7, 0x43,
+ 0x91, 0xa5, 0xcb, 0xbc, 0xeb, 0x37, 0x94, 0xf1, 0x9c, 0xb9, 0xdb, 0x41,
+ 0x06, 0xd8, 0x7b, 0x5e, 0x90, 0xe3, 0x3c, 0x8a, 0x10, 0x62, 0x9a, 0x15,
+ 0x27, 0x78, 0xed, 0x69, 0x11, 0x2c, 0xb5, 0xb4, 0xdb, 0xc8, 0x70, 0x50,
+ 0x62, 0x47, 0x96, 0xcb, 0xd9, 0xb2, 0x3e, 0x59, 0x2f, 0x1c, 0xac, 0xcb,
+ 0xcf, 0x22, 0xc2, 0x9b, 0xc7, 0x92, 0xe9, 0x4d, 0x8d, 0x5d, 0xcf, 0x06,
+ 0x53, 0x7e, 0xf4, 0x4e, 0xfe, 0x9e, 0x41, 0x5d, 0x00, 0x8c, 0x08, 0xf4,
+ 0x02, 0x79, 0x33, 0x1c, 0x27, 0x1d, 0xe3, 0x94, 0xac, 0xe6, 0x87, 0xa0,
+ 0x08, 0xb4, 0x60, 0x0c, 0xff, 0x47, 0xdc, 0x16, 0x3a, 0x1d, 0x89, 0xc0,
+ 0x6a, 0xa4, 0x3d, 0x71, 0x33, 0xdd, 0x1e, 0x70, 0xfe, 0xd4, 0x8b, 0xed,
+ 0x7c, 0x91, 0xe4, 0xe2, 0x15, 0x06, 0xc1, 0x83, 0x24, 0x55, 0xa7, 0x2a,
+ 0x9f, 0x4e, 0xd9, 0x56, 0x7a, 0x95, 0xa8, 0xdd, 0xc4, 0xf0, 0x71, 0x3a,
+ 0x99, 0x65, 0x31, 0x4b, 0xb7, 0x96, 0x2c, 0x53, 0x54, 0x83, 0xec, 0xc9,
+ 0x97, 0x2f, 0x0c, 0xa4, 0x8f, 0xbb, 0x93, 0x9d, 0xea, 0xae, 0xf9, 0xcb,
+ 0xb2, 0xb9, 0xa3, 0x61, 0x5f, 0x77, 0x8c, 0xb6, 0x5a, 0x56, 0xbe, 0x5f,
+ 0x85, 0xd1, 0xb5, 0x0a, 0x53, 0xe2, 0xc7, 0xbf, 0x76, 0x8b, 0x97, 0x6f,
+ 0x10, 0xdd, 0x1f, 0x44, 0x69, 0x66, 0x03, 0xc4, 0x6b, 0x59, 0xf7, 0xb4,
+ 0xc1, 0x12, 0xcc, 0x00, 0x70, 0xe8, 0xbd, 0x44, 0x28, 0xf5, 0xfa, 0x96,
+ 0xf3, 0x59, 0xed, 0x81, 0x67, 0xe0, 0xbe, 0x47, 0x75, 0xb3, 0xa8, 0x9f,
+ 0x21, 0x70, 0x2e, 0x6f, 0xef, 0x54, 0x11, 0x3f, 0x34, 0xaf, 0x0d, 0x73,
+ 0x5b, 0x9e, 0x6d, 0x86, 0x58, 0xb7, 0x34, 0xc2, 0xc2, 0xb3, 0x64, 0xd5,
+ 0x9b, 0x6e, 0xb9, 0x99, 0x6a, 0xe4, 0xfd, 0xc3, 0x17, 0xf3, 0x10, 0xfc,
+ 0x6e, 0xf5, 0x65, 0xe1, 0x9c, 0x59, 0x15, 0x11, 0x00, 0xea, 0x96, 0x81,
+ 0x69, 0x9b, 0x05, 0x4d, 0xf3, 0xce, 0xf3, 0xf0, 0xa9, 0x01, 0x3f, 0x13,
+ 0xbb, 0xb0, 0xac, 0xc3, 0x92, 0x1c, 0x2b, 0x61, 0xe3, 0x01, 0x22, 0x45,
+ 0x4a, 0x23, 0x19, 0x80, 0xca, 0xb9, 0xef, 0x4e, 0x76, 0x52, 0xc5, 0x9d,
+ 0x91, 0x33, 0x17, 0xc4, 0x28, 0x83, 0x55, 0x61, 0x49, 0x72, 0x04, 0xaa,
+ 0xf8, 0xe3, 0x4b, 0x20, 0xf7, 0x6a, 0x74, 0x56, 0x64, 0xf9, 0xb3, 0xc9,
+ 0x67, 0x5b, 0x55, 0x29, 0x9a, 0x89, 0xa5, 0x14, 0x67, 0xea, 0x6d, 0x6a,
+ 0xde, 0x98, 0x58, 0x73, 0x25, 0xa3, 0xdb, 0xed, 0x3d, 0x62, 0xaa, 0xe0,
+ 0x79, 0x7f, 0xa3, 0xd9, 0xb5, 0x4c, 0xe9, 0xa8, 0xdf, 0xfd, 0x59, 0x31,
+ 0x42, 0x81, 0x9e, 0xb7, 0x81, 0x3f, 0x0e, 0xfb, 0xef, 0x80, 0x71, 0x9d,
+ 0xb7, 0xa5, 0xfc, 0xb1, 0x80, 0xc9, 0x7e, 0x31, 0xd9, 0x47, 0xe2, 0xca,
+ 0x10, 0x7b, 0xd1, 0xa1, 0x1c, 0x28, 0xc7, 0x7f, 0x51, 0x26, 0xb1, 0x4e,
+ 0x57, 0xdd, 0x7d, 0x76, 0x5c, 0x5a, 0x85, 0xa7, 0x7b, 0x8c, 0xc5, 0x6e,
+ 0xac, 0x20, 0xf8, 0x49, 0x16, 0xd6, 0x64, 0xf5, 0xf4, 0x2c, 0x32, 0xa1,
+ 0x5d, 0xfb, 0x87, 0xb6, 0x14, 0xfe, 0x68, 0x7c, 0x4d, 0xce, 0xd7, 0x94,
+ 0xf9, 0x8b, 0xf0, 0x61, 0xfd, 0xe0, 0x83, 0x7f, 0x13, 0xec, 0x7a, 0xb7,
+ 0x41, 0x04, 0x51, 0x6e, 0x30, 0xa2, 0x01, 0xf7, 0x30, 0x12, 0xec, 0xd2,
+ 0x8f, 0x73, 0xe7, 0x8e, 0x12, 0xb4, 0xe5, 0xc1, 0xff, 0xdf, 0x67, 0x14,
+ 0xb1, 0xe9, 0xba, 0x36, 0x19, 0x18, 0xf4, 0xaa, 0xe0, 0xe4, 0x9d, 0xcd,
+ 0xe8, 0xe7, 0x2b, 0x33, 0xb3, 0xdc, 0xb9, 0x19, 0xd7, 0xad, 0xa4, 0x68,
+ 0xcd, 0x83, 0x77, 0x98, 0x36, 0x49, 0xd9, 0x32, 0x20, 0xfd, 0xfc, 0x34,
+ 0xe7, 0x54, 0xd9, 0xb5, 0x05, 0xab, 0x0e, 0x08, 0x0e, 0x16, 0x8a, 0x7d,
+ 0x91, 0x4c, 0xaa, 0x19, 0x04, 0x37, 0x35, 0xa5, 0xab, 0x6c, 0xee, 0xc4,
+ 0x90, 0xf0, 0x5f, 0xc7, 0xae, 0x82, 0xfd, 0x59, 0x53, 0xe5, 0x36, 0x5a,
+ 0x56, 0x37, 0x61, 0x69, 0xda, 0xe5, 0x8f, 0xfd, 0x2e, 0xd4, 0x9c, 0x7f,
+ 0xb6, 0x39, 0xa4, 0x8d, 0x0a, 0xab, 0x82, 0x0f, 0xfe, 0x84, 0x69, 0x44,
+ 0x8a, 0xa6, 0xd0, 0x39, 0xf9, 0x72, 0x68, 0xe7, 0x97, 0xd8, 0x6c, 0x7b,
+ 0xec, 0x85, 0x8c, 0x52, 0xc9, 0x97, 0xbb, 0xc4, 0x7a, 0x67, 0x22, 0x60,
+ 0x46, 0x9f, 0x16, 0xf1, 0x67, 0x0e, 0x1b, 0x50, 0x7c, 0xc4, 0x29, 0x15,
+ 0xbc, 0x55, 0x6a, 0x67, 0xf6, 0xa8, 0x85, 0x66, 0x89, 0x9f, 0xff, 0x38,
+ 0x28, 0xaa, 0x87, 0x91, 0xce, 0xde, 0x8d, 0x45, 0x5c, 0xa1, 0x25, 0x95,
+ 0xe2, 0x86, 0xdd, 0xa1, 0x87, 0x6a, 0x0a, 0xa8, 0x3e, 0x63, 0x0e, 0x21,
+ 0xa5, 0x6e, 0x08, 0x4d, 0x07, 0xb6, 0x26, 0xa8, 0x92, 0xdb, 0xed, 0x13,
+ 0x01, 0xc3, 0xba, 0xcf, 0xad, 0x01, 0xbc, 0xe5, 0xc0, 0xba, 0xbe, 0x7c,
+ 0x75, 0xf1, 0xb9, 0xfe, 0xd3, 0xf0, 0xa5, 0x2c, 0x8e, 0x10, 0xff, 0x99,
+ 0xcb, 0xe2, 0x2d, 0xdc, 0x2f, 0x76, 0x00, 0xf8, 0x51, 0x7c, 0xcc, 0x52,
+ 0x16, 0x0f, 0x18, 0x98, 0xea, 0x34, 0x06, 0x7f, 0xb7, 0x2e, 0xe9, 0x40,
+ 0xf0, 0x2d, 0x30, 0x3d, 0xc0, 0x67, 0x4c, 0xe6, 0x63, 0x40, 0x41, 0x42,
+ 0x96, 0xbb, 0x0b, 0xd6, 0xc9, 0x1c, 0x22, 0x7a, 0xa9, 0x4d, 0xcc, 0x5b,
+ 0xaa, 0x03, 0xc6, 0x3b, 0x1e, 0x2f, 0x11, 0xae, 0x34, 0x6f, 0x0c, 0xe9,
+ 0x16, 0x9c, 0x82, 0x3b, 0x90, 0x4c, 0x0e, 0xf0, 0xf9, 0x7f, 0x02, 0xca,
+ 0xb9, 0xa9, 0x49, 0x6d, 0x27, 0x73, 0xd0, 0xbf, 0x15, 0x61, 0x52, 0xbc,
+ 0xd6, 0x31, 0x59, 0x2b, 0x52, 0x5b, 0xaf, 0x3c, 0xc0, 0x8f, 0xdc, 0xd5,
+ 0x2c, 0x1d, 0xe4, 0xe9, 0x41, 0xe8, 0xd3, 0x35, 0xd6, 0xb1, 0xf3, 0x32,
+ 0xe0, 0x52, 0x08, 0x73, 0x99, 0xb6, 0x6b, 0xbc, 0x26, 0xfb, 0x2e, 0xa7,
+ 0xb7, 0xcd, 0x14, 0xf0, 0xf9, 0xe5, 0x3a, 0xd0, 0x05, 0x5b, 0x2b, 0x38,
+ 0xbd, 0x7c, 0xda, 0xd4, 0x15, 0x45, 0xfa, 0x3b, 0x6f, 0x94, 0x8e, 0x22,
+ 0xce, 0xfa, 0x53, 0xe0, 0x5f, 0xa6, 0x9d, 0x1c, 0x26, 0x91, 0x8a, 0xab,
+ 0x72, 0x5b, 0x18, 0x78, 0x69, 0x98, 0x3f, 0x8d, 0x33, 0x7c, 0x21, 0x93,
+ 0x9e, 0xf0, 0xaf, 0xb7, 0x30, 0xc8, 0xac, 0xbc, 0xdb, 0x9c, 0x29, 0x17,
+ 0x6b, 0x9d, 0x0f, 0x16, 0xd6, 0xc0, 0xcc, 0x3b, 0xce, 0x11, 0xe9, 0x64,
+ 0xc8, 0xd4, 0x4c, 0x98, 0x7c, 0x8f, 0xf1, 0x5e, 0x84, 0xe4, 0x72, 0xf9,
+ 0x69, 0xf5, 0x9d, 0xad, 0x95, 0x3b, 0xfb, 0x6d, 0x30, 0x7e, 0x0a, 0x47,
+ 0x5b, 0x26, 0xb2, 0x4e, 0xeb, 0x1a, 0xc3, 0x37, 0x16, 0x28, 0x79, 0x62,
+ 0xb4, 0x36, 0x85, 0x4a, 0x15, 0x5a, 0xc3, 0x6e, 0xbe, 0x7e, 0x00, 0xe9,
+ 0x4a, 0xa5, 0xd7, 0x90, 0xcf, 0x59, 0x63, 0x2d, 0x2b, 0xc2, 0xc6, 0x47,
+ 0xe6, 0x77, 0xb7, 0x6e, 0x9b, 0xc8, 0x0d, 0x18, 0x2b, 0x45, 0x2b, 0xc9,
+ 0x5a, 0x6e, 0xb4, 0x50, 0xa5, 0x23, 0x7d, 0x17, 0xcc, 0x49, 0xe2, 0xb3,
+ 0xf4, 0x6d, 0xb4, 0xb7, 0xbb, 0x9e, 0xdd, 0x20, 0x99, 0x19, 0xf5, 0x53,
+ 0x1f, 0xd0, 0xff, 0x67, 0xf3, 0x8e, 0x6a, 0xcd, 0x2a, 0x6e, 0x2b, 0x0a,
+ 0x90, 0xd7, 0xdb, 0xe1, 0xff, 0x1c, 0x40, 0xa1, 0xb0, 0x5d, 0x94, 0x4d,
+ 0x20, 0x14, 0x01, 0xa1, 0xa8, 0xd1, 0x15, 0xd2, 0xd9, 0x1b, 0xbf, 0xc2,
+ 0x8a, 0xd0, 0x02, 0xf6, 0x16, 0xa1, 0xb7, 0x40, 0xe0, 0x36, 0x88, 0xc8,
+ 0x17, 0x0a, 0xf0, 0xb6, 0x0d, 0x3c, 0x53, 0xb9, 0x51, 0xed, 0xef, 0x20,
+ 0x6f, 0xf3, 0x0c, 0xb5, 0xce, 0x0e, 0x9e, 0xfd, 0x0f, 0x5e, 0x3f, 0x8f,
+ 0x3c, 0xb7, 0x2a, 0xdb, 0xc6, 0xa7, 0xf2, 0x11, 0x6e, 0xdc, 0x05, 0x33,
+ 0xd4, 0xd8, 0xb0, 0x2d, 0x8a, 0xe5, 0x39, 0x82, 0x00, 0x49, 0x7d, 0xfd,
+ 0x32, 0x29, 0xbb, 0x79, 0x5d, 0xcb, 0x21, 0x7b, 0x2d, 0x36, 0x58, 0x73,
+ 0x52, 0x57, 0x52, 0x96, 0x4d, 0x89, 0x61, 0xf4, 0xad, 0x1f, 0x48, 0xd5,
+ 0x7a, 0x4a, 0xaa, 0x1c, 0xa1, 0xf4, 0xb4, 0x9c, 0x43, 0x3b, 0x95, 0x72,
+ 0xd0, 0x0e, 0x35, 0x82, 0x26, 0xd4, 0x2e, 0xe3, 0x83, 0x96, 0x97, 0x5a,
+ 0x7b, 0xfc, 0x48, 0x17, 0x3c, 0xba, 0x9e, 0x5f, 0x46, 0x1a, 0x53, 0xe3,
+ 0x2e, 0x78, 0x79, 0x80, 0xf6, 0x2d, 0x24, 0xcf, 0x62, 0xb6, 0x86, 0xeb,
+ 0xee, 0xec, 0xf2, 0x1d, 0x00, 0xc8, 0x28, 0x9d, 0x93, 0x16, 0xa7, 0xd9,
+ 0x11, 0x47, 0xe3, 0xc4, 0xb6, 0xc4, 0xa0, 0x99, 0x83, 0xc1, 0x17, 0xd8,
+ 0x8e, 0xde, 0x69, 0x1d, 0xcb, 0xdd, 0xe7, 0x86, 0x6f, 0xf2, 0x36, 0x07,
+ 0x23, 0x86, 0x0d, 0xe9, 0xad, 0x87, 0xae, 0x76, 0x98, 0x95, 0x51, 0xf2,
+ 0xb3, 0x11, 0xc5, 0x34, 0xf0, 0x0c, 0xf8, 0x29, 0x9c, 0x84, 0x4f, 0x81,
+ 0x49, 0x85, 0x63, 0x25, 0x16, 0xb0, 0xc3, 0xaa, 0xd7, 0x8a, 0x2e, 0x4b,
+ 0x97, 0x60, 0x74, 0xf8, 0xa7, 0x39, 0xec, 0x6c, 0x2c, 0x9b, 0x33, 0x3a,
+ 0x11, 0xbd, 0xa6, 0x90, 0x48, 0x65, 0xb1, 0xe7, 0x38, 0x53, 0x47, 0x1b,
+ 0x62, 0xd5, 0xb7, 0xa8, 0xd4, 0xae, 0xf5, 0x12, 0x06, 0x12, 0x54, 0xa2,
+ 0xce, 0xf1, 0x6b, 0x3a, 0xda, 0x63, 0x2e, 0x37, 0x2a, 0x25, 0x89, 0x30,
+ 0x98, 0x77, 0x1d, 0x4b, 0x5a, 0x1e, 0xb7, 0x3d, 0xed, 0x19, 0xec, 0x9f,
+ 0x64, 0x46, 0xa8, 0x2a, 0x79, 0xf3, 0x70, 0x39, 0x9f, 0x8c, 0xc3, 0x28,
+ 0xcc, 0x2a, 0xc0, 0xd0, 0xe6, 0x80, 0xf5, 0x01, 0x78, 0x72, 0x7f, 0xe7,
+ 0x2e, 0x7b, 0x5f, 0x05, 0xc3, 0x41, 0x33, 0x07, 0xdb, 0x9c, 0xa8, 0x96,
+ 0xa7, 0x21, 0x20, 0x23, 0xd0, 0x59, 0x39, 0x06, 0x19, 0xa4, 0x29, 0xe5,
+ 0x72, 0x39, 0x69, 0x23, 0xe3, 0xfa, 0x28, 0x63, 0xf5, 0x42, 0x3b, 0xca,
+ 0x88, 0x5d, 0x7e, 0x47, 0x93, 0xa8, 0x8c, 0x75, 0xf2, 0x19, 0x44, 0x43,
+ 0x15, 0x39, 0x03, 0x42, 0xd8, 0x1d, 0x81, 0x30, 0x8e, 0x84, 0x31, 0x24,
+ 0x75, 0x67, 0x4e, 0xbe, 0xfe, 0x0a, 0xd8, 0xc3, 0xe7, 0x5b, 0xe1, 0xd5,
+ 0x12, 0x6a, 0x69, 0x99, 0xcd, 0x35, 0xca, 0x22, 0x02, 0x65, 0xb3, 0x0f,
+ 0x50, 0xb6, 0xaa, 0xc6, 0x91, 0x5c, 0x4d, 0xd4, 0x07, 0x93, 0x46, 0xf0,
+ 0xcc, 0xe1, 0x92, 0x14, 0x91, 0x21, 0x43, 0xc4, 0xba, 0x45, 0x1c, 0x47,
+ 0x29, 0xdf, 0xff, 0x89, 0x60, 0xee, 0x89, 0x1e, 0xc3, 0xb4, 0xb9, 0x0b,
+ 0xc9, 0x7e, 0xd9, 0x15, 0xb0, 0x80, 0x91, 0xbe, 0xb9, 0x43, 0x48, 0x12,
+ 0x86, 0x8e, 0x79, 0x38, 0x4d, 0xce, 0x36, 0x7f, 0xc3, 0xe8, 0xb7, 0xb9,
+ 0x92, 0xbf, 0x27, 0x20, 0x54, 0xc8, 0x05, 0x63, 0x3b, 0xf5, 0x48, 0x1a,
+ 0xa9, 0x04, 0x6c, 0xb6, 0x0e, 0x11, 0xea, 0xf3, 0x59, 0xb9, 0xa6, 0xf6,
+ 0xf8, 0x0b, 0x15, 0xed, 0x30, 0xf9, 0xe4, 0xe5, 0x26, 0x2d, 0xbb, 0xc6,
+ 0x5b, 0x36, 0xbb, 0x73, 0xa6, 0x4f, 0xf5, 0x43, 0x9f, 0xd7, 0xb9, 0x0f,
+ 0xbc, 0x4f, 0x8d, 0xb8, 0xec, 0x1d, 0x42, 0x19, 0x56, 0x37, 0xc4, 0xcb,
+ 0xd0, 0x16, 0x85, 0xff, 0xd3, 0x9b, 0xef, 0xc8, 0x75, 0x37, 0xd1, 0x92,
+ 0xad, 0x21, 0x94, 0x1e, 0x9a, 0xf6, 0x2f, 0x6d, 0x30, 0xba, 0x37, 0xc3,
+ 0xdc, 0x11, 0xe0, 0x79, 0xa4, 0x92, 0x1f, 0xe4, 0xaa, 0x7a, 0x6b, 0x2a,
+ 0xe4, 0x04, 0xb7, 0xf9, 0x86, 0x95, 0xdb, 0xa8, 0xfc, 0x8a, 0x53, 0x21,
+ 0x31, 0x14, 0xf7, 0x40, 0x01, 0x78, 0x4e, 0x73, 0x18, 0xb3, 0x54, 0xd7,
+ 0xa6, 0x93, 0xf0, 0x70, 0x04, 0x1c, 0xe0, 0x2b, 0xef, 0xee, 0xd4, 0x64,
+ 0xa7, 0xd9, 0x9f, 0x81, 0x4f, 0xe5, 0x1e, 0xbe, 0x6e, 0xd2, 0xf6, 0x3a,
+ 0xba, 0xcf, 0x8c, 0x96, 0x2a, 0x3d, 0xf7, 0xe5, 0x5c, 0x59, 0x40, 0x9c,
+ 0xe3, 0xf9, 0x2b, 0x6d, 0x3d, 0xf2, 0x6f, 0x81, 0xd6, 0xab, 0x9c, 0xab,
+ 0xc6, 0xf7, 0x8f, 0xaa, 0xe5, 0x71, 0xe3, 0xc9, 0x8c, 0x1a, 0xeb, 0xc5,
+ 0x87, 0xe7, 0xb0, 0xde, 0x18, 0xba, 0xaa, 0x1e, 0xda, 0x12, 0x32, 0x16,
+ 0x94, 0x3a, 0x6e, 0x4f, 0x84, 0x06, 0x8e, 0x33, 0xf7, 0xfa, 0x35, 0xb8,
+ 0x45, 0xe4, 0x5e, 0x9e, 0x46, 0x05, 0x7a, 0xf7, 0xf4, 0x99, 0xad, 0xb9,
+ 0xdd, 0x55, 0xd9, 0x52, 0x3b, 0x93, 0xe3, 0x9b, 0x54, 0x1b, 0xe6, 0xa9,
+ 0x70, 0xd3, 0x48, 0xf9, 0x3d, 0xdb, 0x88, 0x63, 0x66, 0xa0, 0xab, 0x72,
+ 0x83, 0x6e, 0x8f, 0x78, 0x9d, 0x55, 0x46, 0x21, 0xca, 0x7c, 0xb7, 0x5d,
+ 0x16, 0xe8, 0x66, 0x3b, 0x7b, 0xaa, 0xfe, 0x9c, 0x9c, 0x33, 0xc9, 0xc2,
+ 0xa4, 0x3c, 0x78, 0x97, 0xf3, 0x5b, 0xc2, 0x29, 0x36, 0x98, 0x68, 0x28,
+ 0xfe, 0x0a, 0xae, 0x6f, 0xe5, 0xf7, 0xfb, 0x9d, 0xf8, 0x8c, 0xd9, 0xd0,
+ 0x4d, 0xfe, 0xc7, 0xd0, 0xb0, 0xe3, 0x9c, 0xdb, 0xac, 0x9e, 0x1b, 0x55,
+ 0x7e, 0x24, 0xfe, 0xc4, 0x12, 0xcb, 0xc2, 0xdd, 0x0a, 0xda, 0x31, 0x40,
+ 0x41, 0xb7, 0xfc, 0x3f, 0x6d, 0xe2, 0xd3, 0x8a, 0x0f, 0x21, 0x33, 0x3a,
+ 0xbc, 0xa7, 0x62, 0x18, 0xb3, 0xaf, 0x48, 0xc6, 0xe2, 0xa3, 0xdd, 0x1d,
+ 0x20, 0x62, 0xe4, 0x4b, 0x81, 0x6b, 0x3a, 0xc5, 0xb1, 0x07, 0xe1, 0xf1,
+ 0xe1, 0xba, 0xf6, 0x01, 0xc6, 0xf2, 0xea, 0xc0, 0x97, 0x73, 0x79, 0x19,
+ 0x06, 0xaa, 0x62, 0x42, 0xcb, 0x21, 0x5f, 0x08, 0x97, 0x7d, 0x72, 0xb5,
+ 0x39, 0x4d, 0x99, 0xe3, 0xa2, 0x3f, 0xb9, 0xb4, 0xed, 0xf4, 0x61, 0x35,
+ 0xe1, 0x50, 0xfb, 0x56, 0x7c, 0x35, 0xfd, 0x44, 0x8a, 0x57, 0x22, 0xed,
+ 0x30, 0x33, 0xc3, 0x0b, 0xf1, 0x88, 0xe4, 0x44, 0x46, 0xf5, 0x73, 0x6d,
+ 0x9b, 0x98, 0x88, 0x92, 0xf5, 0x34, 0x85, 0x18, 0x66, 0xef, 0x70, 0xbe,
+ 0x7b, 0xc1, 0x0f, 0x1c, 0x78, 0x2d, 0x42, 0x13, 0x2d, 0x2f, 0x4d, 0x40,
+ 0x8e, 0xe2, 0x6f, 0xe0, 0x04, 0xdb, 0x58, 0xbc, 0x65, 0x80, 0xba, 0xfc,
+ 0x89, 0xee, 0xf3, 0x78, 0xb2, 0xd9, 0x78, 0x93, 0x6d, 0xbf, 0xd4, 0x74,
+ 0x24, 0xf4, 0x5c, 0x37, 0x89, 0x0c, 0x14, 0xd5, 0xbd, 0xc5, 0xfc, 0x37,
+ 0xe8, 0x8b, 0xe0, 0xc5, 0x89, 0xc9, 0x70, 0xb3, 0x76, 0x46, 0xce, 0x0d,
+ 0x7c, 0x3d, 0xa4, 0x5d, 0x02, 0x95, 0x03, 0xba, 0x24, 0xaa, 0xf7, 0xd0,
+ 0x75, 0x35, 0x78, 0x27, 0x9c, 0x6d, 0x2a, 0xef, 0xaa, 0xac, 0x85, 0xef,
+ 0x8d, 0xfc, 0xc0, 0xfc, 0x72, 0x02, 0xf4, 0xa3, 0xd3, 0x87, 0xfc, 0x4d,
+ 0xce, 0x3d, 0xcb, 0xc2, 0x74, 0x5b, 0xb0, 0x83, 0xc5, 0x72, 0x72, 0xd6,
+ 0xa1, 0x67, 0x4d, 0xa1, 0xd6, 0xaa, 0xe7, 0x9b, 0xe7, 0xc0, 0xfd, 0x86,
+ 0x91, 0x08, 0xfa, 0x48, 0x2f, 0x50, 0xce, 0x17, 0xea, 0x1c, 0xe3, 0x90,
+ 0x35, 0xe6, 0x6c, 0xc9, 0x66, 0x7d, 0x51, 0x32, 0x20, 0x0c, 0x2d, 0x4b,
+ 0xa1, 0xbf, 0x78, 0x87, 0xe1, 0x5a, 0x28, 0x0e, 0x9a, 0x85, 0xf6, 0x7e,
+ 0x39, 0x60, 0xbc, 0x64, 0x42, 0x5d, 0xf0, 0x0a, 0xd7, 0x3e, 0xbb, 0xa0,
+ 0x6d, 0x7c, 0xfa, 0x75, 0xee, 0x34, 0x39, 0x23, 0x0e, 0xbd, 0x50, 0x19,
+ 0x7a, 0x2a, 0xb7, 0x17, 0x3a, 0x8b, 0xb7, 0xb6, 0xf4, 0xd8, 0x47, 0x71,
+ 0x6b, 0x21, 0x1b, 0x56, 0xcc, 0xfb, 0x7b, 0x81, 0x99, 0x46, 0x88, 0x23,
+ 0x40, 0x49, 0x66, 0x8b, 0xac, 0x84, 0x16, 0x8a, 0x86, 0xae, 0x38, 0xc4,
+ 0x5b, 0x1f, 0x2b, 0xfa, 0xf2, 0x8b, 0x81, 0xc1, 0x22, 0x61, 0x61, 0x6c,
+ 0x43, 0x16, 0x8c, 0x1d, 0x37, 0xb2, 0xaf, 0x3c, 0x3a, 0x90, 0x33, 0xed,
+ 0xf5, 0x08, 0x78, 0xfd, 0x5a, 0xde, 0xd3, 0x38, 0x6d, 0xd7, 0x1c, 0x23,
+ 0xeb, 0xb4, 0x9b, 0x8e, 0xc2, 0x48, 0x47, 0x8e, 0x84, 0xbb, 0xc4, 0xd0,
+ 0xcc, 0xf9, 0x55, 0x5a, 0x57, 0xb9, 0x99, 0x52, 0x82, 0x21, 0x3b, 0x83,
+ 0xda, 0x8f, 0xa3, 0x88, 0x9c, 0x57, 0xe0, 0x4b, 0xc1, 0xce, 0xbe, 0xd3,
+ 0xea, 0xdd, 0xf2, 0x07, 0xc1, 0x73, 0x6f, 0xc0, 0x5e, 0x8e, 0x85, 0x72,
+ 0xab, 0x2f, 0xa9, 0xac, 0x39, 0xee, 0x05, 0x34, 0x13, 0x16, 0x1b, 0x1c,
+ 0x21, 0x24, 0x41, 0x49, 0x78, 0x87, 0x8b, 0x97, 0x9c, 0x9f, 0xa3, 0xa8,
+ 0xb9, 0xbc, 0xc6, 0xcc, 0xf2, 0xfd, 0x18, 0x2a, 0x46, 0x58, 0x5a, 0x88,
+ 0xa2, 0xb5, 0xcc, 0xd2, 0xda, 0xe1, 0xe3, 0x0d, 0x20, 0x23, 0x2b, 0x2f,
+ 0x47, 0x57, 0x5e, 0x64, 0x87, 0x97, 0x9c, 0xa7, 0xaa, 0xbc, 0xc1, 0xe4,
+ 0xe5, 0xea, 0x0b, 0x16, 0x3b, 0x3c, 0x3e, 0x45, 0x58, 0x63, 0x6a, 0x6f,
+ 0x7c, 0x8c, 0x8d, 0x92, 0x99, 0x9c, 0xad, 0xb5, 0xb7, 0xce, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x16, 0x23, 0x36, 0x4a};
+ static byte test_msg[512] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
+ 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53,
+ 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
+ 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
+ 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
+ 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
+ 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
+ 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
+ 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
+ 0xfc, 0xfd, 0xfe, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
+ 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b,
+ 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
+ 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b,
+ 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3,
+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb,
+ 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,
+ 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
+ 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
+
+ int ret;
+ MlDsaKey key[1];
+ whNvmId keyId = WH_KEYID_ERASED;
+ int evictKey = 0;
+
+ /* Initialize keys */
+ ret = wc_MlDsaKey_Init(key, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to initialize ML-DSA key: %d\n", ret);
+ return ret;
+ }
+ else {
+ ret = wc_dilithium_set_level(key, WC_ML_DSA_44);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to set ML-DSA level: %d\n", ret);
+ }
+ }
+
+ /* make dummy msg */
+ int i = 0;
+ for (i = 0; i < (int)sizeof(test_msg); i++) {
+ test_msg[i] = (byte)i;
+ }
+
+ /* Import the raw public key into the wolfCrypt structure */
+ if (ret == 0) {
+ ret = wc_MlDsaKey_ImportPubRaw(key, ml_dsa_44_pub_key,
+ sizeof(ml_dsa_44_pub_key));
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to import ML-DSA public key: %d\n", ret);
+ }
+ }
+ /* Import the key into wolfHSM via the wolfCrypt structure */
+ if (ret == 0) {
+ if (devId == WH_DEV_ID_DMA) {
+ ret = wh_Client_MlDsaImportKeyDma(ctx, key, &keyId, 0, 0, NULL);
+ }
+ else {
+ ret = wh_Client_MlDsaImportKey(ctx, key, &keyId, 0, 0, NULL);
+ }
+ if (ret == WH_ERROR_OK) {
+ evictKey = 1;
+ }
+ else {
+ WH_ERROR_PRINT("Failed to import ML-DSA key: %d\n", ret);
+ }
+ }
+
+ /* Cache the key using DMA and set the key ID */
+ if (ret == 0) {
+ ret = wh_Client_MlDsaSetKeyId(key, keyId);
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("Failed to set key ID: %d\n", ret);
+ }
+ }
+
+ /* Verify the message signature */
+ if (ret == 0) {
+ int verifyResult;
+ ret = wc_MlDsaKey_VerifyCtx(key, ml_dsa_44_sig, sizeof(ml_dsa_44_sig),
+ NULL, 0, test_msg, sizeof(test_msg),
+ &verifyResult);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Signature did not verify\n");
+ }
+ }
+
+ if (evictKey) {
+ if (WH_ERROR_OK != wh_Client_KeyEvict(ctx, keyId)) {
+ WH_ERROR_PRINT("Failed to evict key\n");
+ }
+ }
+ wc_MlDsaKey_Free(key);
+
+ if (ret == WH_ERROR_OK) {
+ WH_TEST_PRINT("ML-DSA VERIFY ONLY: SUCCESS\n");
+ }
+
+ return ret;
+}
+#endif /* !defined(WOLFSSL_DILITHIUM_NO_VERIFY) && \
+ !defined(WOLFSSL_NO_ML_DSA_44) && \
+ defined(WOLFHSM_CFG_DMA) */
+
+#endif /* HAVE_DILITHIUM */
+
+#endif /* !WOLFHSM_CFG_NO_CRYPTO */
diff --git a/test-refactor/client-server/wh_test_rng.c b/test-refactor/client-server/wh_test_rng.c
new file mode 100644
index 00000000..1e69b2a5
--- /dev/null
+++ b/test-refactor/client-server/wh_test_rng.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2026 wolfSSL Inc.
+ *
+ * This file is part of wolfHSM.
+ *
+ * wolfHSM 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfHSM 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 wolfHSM. If not, see .
+ */
+/*
+ * test-refactor/client-server/wh_test_rng.c
+ *
+ * RNG round-trips: synchronous (wolfCrypt API), async non-DMA, and async DMA.
+ */
+
+#include "wolfhsm/wh_settings.h"
+
+#if !defined(WOLFHSM_CFG_NO_CRYPTO)
+
+#include
+#include
+
+#include "wolfssl/wolfcrypt/settings.h"
+#include "wolfssl/wolfcrypt/types.h"
+#include "wolfssl/wolfcrypt/random.h"
+
+#include "wolfhsm/wh_error.h"
+#include "wolfhsm/wh_client.h"
+#include "wolfhsm/wh_client_crypto.h"
+#include "wolfhsm/wh_message_crypto.h"
+
+#include "wh_test_common.h"
+#include "wh_test_list.h"
+
+#define WH_TEST_RNG_LIL 7
+#define WH_TEST_RNG_MED 1024
+#define WH_TEST_RNG_BIG (WOLFHSM_CFG_COMM_DATA_LEN * 2)
+
+/* Returns 0 if buf appears to contain non-trivial data (not all zero), -1 on
+ * the all-zero case which would suggest the response was never written. */
+static int whTest_RngBufNonZero(const uint8_t* buf, uint32_t len)
+{
+ uint32_t i;
+ for (i = 0; i < len; i++) {
+ if (buf[i] != 0) {
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int whTest_CryptoRng(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+ uint8_t lil[WH_TEST_RNG_LIL];
+ uint8_t med[WH_TEST_RNG_MED];
+ uint8_t big[WH_TEST_RNG_BIG];
+
+ (void)ctx;
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ }
+ else {
+ int freeRet;
+ ret = wc_RNG_GenerateBlock(rng, lil, sizeof(lil));
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_RNG_GenerateBlock %d\n", ret);
+ }
+ else {
+ ret = wc_RNG_GenerateBlock(rng, med, sizeof(med));
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_RNG_GenerateBlock %d\n", ret);
+ }
+ else {
+ ret = wc_RNG_GenerateBlock(rng, big, sizeof(big));
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_RNG_GenerateBlock %d\n", ret);
+ }
+ else if (memcmp(lil, med, sizeof(lil)) == 0) {
+ /* The prefixes of two successive independent RNG calls
+ * must not match. A collision here indicates a stuck RNG */
+ WH_ERROR_PRINT("RNG: successive calls produced identical "
+ "prefix\n");
+ ret = -1;
+ }
+ }
+ }
+ /* Always free the RNG if InitRng succeeded, regardless of which (if
+ * any) GenerateBlock call failed. */
+ freeRet = wc_FreeRng(rng);
+ if (freeRet != 0) {
+ WH_ERROR_PRINT("Failed to wc_FreeRng %d\n", freeRet);
+ if (ret == 0) {
+ ret = freeRet;
+ }
+ }
+ }
+ if (ret == 0) {
+ WH_TEST_PRINT("RNG DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+/* Direct exercise of the async non-DMA RNG primitives. */
+int whTest_CryptoRngAsync(whClientContext* ctx)
+{
+ int ret = WH_ERROR_OK;
+ uint8_t small[64];
+ uint8_t big[WOLFHSM_CFG_COMM_DATA_LEN * 2];
+ uint32_t got;
+
+ /* Case A: small Request -> poll Response */
+ if (ret == 0) {
+ memset(small, 0, sizeof(small));
+ ret = wh_Client_RngGenerateRequest(ctx, sizeof(small));
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("Async RNG: Request(small) failed %d\n", ret);
+ }
+ }
+ if (ret == 0) {
+ got = sizeof(small);
+ do {
+ ret = wh_Client_RngGenerateResponse(ctx, small, &got);
+ } while (ret == WH_ERROR_NOTREADY);
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("Async RNG: Response(small) failed %d\n", ret);
+ }
+ else if (got != sizeof(small)) {
+ WH_ERROR_PRINT("Async RNG: short read got=%u want=%u\n",
+ (unsigned)got, (unsigned)sizeof(small));
+ ret = -1;
+ }
+ else if (whTest_RngBufNonZero(small, sizeof(small)) != 0) {
+ WH_ERROR_PRINT("Async RNG: small buffer all zeros\n");
+ ret = -1;
+ }
+ }
+
+ /* Case B: max-inline-size Request -> Response in a single round trip */
+ if (ret == 0) {
+ uint32_t cap = (uint32_t)WH_MESSAGE_CRYPTO_RNG_MAX_INLINE_SZ;
+ memset(big, 0, cap);
+ ret = wh_Client_RngGenerateRequest(ctx, cap);
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("Async RNG: Request(max) failed %d\n", ret);
+ }
+ if (ret == 0) {
+ got = cap;
+ do {
+ ret = wh_Client_RngGenerateResponse(ctx, big, &got);
+ } while (ret == WH_ERROR_NOTREADY);
+ if (ret == 0 && got != cap) {
+ WH_ERROR_PRINT("Async RNG: max read short got=%u want=%u\n",
+ (unsigned)got, (unsigned)cap);
+ ret = -1;
+ }
+ else if (ret == 0 && whTest_RngBufNonZero(big, cap) != 0) {
+ WH_ERROR_PRINT("Async RNG: max buffer all zeros\n");
+ ret = -1;
+ }
+ }
+ }
+
+ /* Case C: caller-driven chunking to fill a buffer larger than the per-call
+ * inline capacity. */
+ if (ret == 0) {
+ uint32_t cap = (uint32_t)WH_MESSAGE_CRYPTO_RNG_MAX_INLINE_SZ;
+ uint32_t total = (uint32_t)sizeof(big);
+ uint32_t consumed = 0;
+
+ memset(big, 0, total);
+ while (ret == 0 && consumed < total) {
+ uint32_t want = total - consumed;
+ if (want > cap) {
+ want = cap;
+ }
+ ret = wh_Client_RngGenerateRequest(ctx, want);
+ if (ret == 0) {
+ got = want;
+ do {
+ ret = wh_Client_RngGenerateResponse(ctx, big + consumed,
+ &got);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ if (got == 0 || got > want) {
+ WH_ERROR_PRINT(
+ "Async RNG: bad chunk reply got=%u want=%u\n",
+ (unsigned)got, (unsigned)want);
+ ret = -1;
+ }
+ else {
+ consumed += got;
+ }
+ }
+ }
+ if (ret == 0 && whTest_RngBufNonZero(big, total) != 0) {
+ WH_ERROR_PRINT("Async RNG: chunked buffer all zeros\n");
+ ret = -1;
+ }
+ }
+
+ /* Case D: oversize request must be rejected without sending. */
+ if (ret == 0) {
+ int rc = wh_Client_RngGenerateRequest(
+ ctx, (uint32_t)WH_MESSAGE_CRYPTO_RNG_MAX_INLINE_SZ + 1u);
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "Async RNG: oversize Request returned %d (want BADARGS)\n", rc);
+ ret = -1;
+ }
+ }
+
+ /* Case E: zero-size request must be rejected. */
+ if (ret == 0) {
+ int rc = wh_Client_RngGenerateRequest(ctx, 0);
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "Async RNG: zero-size Request returned %d (want BADARGS)\n",
+ rc);
+ ret = -1;
+ }
+ }
+
+ /* Case F: NULL ctx rejection on both halves. */
+ if (ret == 0) {
+ int rc = wh_Client_RngGenerateRequest(NULL, 16);
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "Async RNG: NULL ctx Request returned %d (want BADARGS)\n", rc);
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ int rc;
+ got = 16;
+ rc = wh_Client_RngGenerateResponse(NULL, small, &got);
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "Async RNG: NULL ctx Response returned %d (want BADARGS)\n",
+ rc);
+ ret = -1;
+ }
+ }
+
+ /* Case G: NULL inout_size rejection. */
+ if (ret == 0) {
+ int rc = wh_Client_RngGenerateResponse(ctx, small, NULL);
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT("Async RNG: NULL inout_size Response returned %d "
+ "(want BADARGS)\n",
+ rc);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("RNG ASYNC SUCCESS\n");
+ }
+ return ret;
+}
+
+#ifdef WOLFHSM_CFG_DMA
+/* Direct exercise of the async DMA RNG primitives. */
+int whTest_CryptoRngDmaAsync(whClientContext* ctx)
+{
+ int ret = WH_ERROR_OK;
+ /* DMA bypasses the comm buffer so we can request more than COMM_DATA_LEN
+ * in a single round trip. */
+ uint8_t big[WOLFHSM_CFG_COMM_DATA_LEN * 2];
+
+ /* Case A: basic DMA Request -> Response */
+ if (ret == 0) {
+ memset(big, 0, sizeof(big));
+ ret = wh_Client_RngGenerateDmaRequest(ctx, big, sizeof(big));
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("Async RNG DMA: Request failed %d\n", ret);
+ }
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_RngGenerateDmaResponse(ctx);
+ } while (ret == WH_ERROR_NOTREADY);
+ if (ret != WH_ERROR_OK) {
+ WH_ERROR_PRINT("Async RNG DMA: Response failed %d\n", ret);
+ }
+ else if (whTest_RngBufNonZero(big, sizeof(big)) != 0) {
+ WH_ERROR_PRINT("Async RNG DMA: buffer all zeros\n");
+ ret = -1;
+ }
+ }
+
+ /* Case B: small DMA request still works (no chunking semantics). */
+ if (ret == 0) {
+ uint8_t small[32];
+ memset(small, 0, sizeof(small));
+ ret = wh_Client_RngGenerateDmaRequest(ctx, small, sizeof(small));
+ if (ret == 0) {
+ do {
+ ret = wh_Client_RngGenerateDmaResponse(ctx);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0 && whTest_RngBufNonZero(small, sizeof(small)) != 0) {
+ WH_ERROR_PRINT("Async RNG DMA: small buffer all zeros\n");
+ ret = -1;
+ }
+ }
+
+ /* Case C: input validation. */
+ if (ret == 0) {
+ int rc = wh_Client_RngGenerateDmaRequest(NULL, big, sizeof(big));
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "Async RNG DMA: NULL ctx returned %d (want BADARGS)\n", rc);
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ int rc = wh_Client_RngGenerateDmaRequest(ctx, NULL, sizeof(big));
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "Async RNG DMA: NULL out returned %d (want BADARGS)\n", rc);
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ int rc = wh_Client_RngGenerateDmaRequest(ctx, big, 0);
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "Async RNG DMA: zero size returned %d (want BADARGS)\n", rc);
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ int rc = wh_Client_RngGenerateDmaResponse(NULL);
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT(
+ "Async RNG DMA: Response NULL ctx returned %d (want BADARGS)\n",
+ rc);
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("RNG DMA ASYNC SUCCESS\n");
+ }
+ return ret;
+}
+#endif /* WOLFHSM_CFG_DMA */
+
+#endif /* !WOLFHSM_CFG_NO_CRYPTO */
diff --git a/test-refactor/client-server/wh_test_rsa.c b/test-refactor/client-server/wh_test_rsa.c
new file mode 100644
index 00000000..999a23fc
--- /dev/null
+++ b/test-refactor/client-server/wh_test_rsa.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2026 wolfSSL Inc.
+ *
+ * This file is part of wolfHSM.
+ *
+ * wolfHSM 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfHSM 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 wolfHSM. If not, see .
+ */
+/*
+ * test-refactor/client-server/wh_test_rsa.c
+ *
+ * RSA encrypt/decrypt round-trips routed through the server via WH_DEV_ID:
+ * ephemeral key, server-exported key, and server-cached key paths.
+ */
+
+#include "wolfhsm/wh_settings.h"
+
+#if !defined(WOLFHSM_CFG_NO_CRYPTO)
+
+#include
+#include
+
+#include "wolfssl/wolfcrypt/settings.h"
+#include "wolfssl/wolfcrypt/types.h"
+#include "wolfssl/wolfcrypt/rsa.h"
+#include "wolfssl/wolfcrypt/random.h"
+
+#include "wolfhsm/wh_error.h"
+#include "wolfhsm/wh_common.h"
+#include "wolfhsm/wh_client.h"
+#include "wolfhsm/wh_client_crypto.h"
+
+#include "wh_test_common.h"
+#include "wh_test_list.h"
+
+#ifndef NO_RSA
+
+#define RSA_KEY_BITS 2048
+#define RSA_KEY_BYTES (RSA_KEY_BITS / 8)
+#define RSA_EXPONENT WC_RSA_EXPONENT
+#define WH_TEST_RSA_PLAINTEXT "mytextisbigplain"
+
+int whTest_CryptoRsa(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = WH_ERROR_OK;
+ WC_RNG rng[1];
+ RsaKey rsa[1];
+ char plainText[sizeof(WH_TEST_RSA_PLAINTEXT)] = WH_TEST_RSA_PLAINTEXT;
+ char cipherText[RSA_KEY_BYTES];
+ char finalText[RSA_KEY_BYTES];
+ whKeyId keyId = WH_KEYID_ERASED;
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+
+ /* Using ephemeral key */
+ memset(cipherText, 0, sizeof(cipherText));
+ memset(finalText, 0, sizeof(finalText));
+ ret = wc_InitRsaKey_ex(rsa, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRsaKey_ex %d\n", ret);
+ }
+ else {
+ ret = wc_MakeRsaKey(rsa, RSA_KEY_BITS, RSA_EXPONENT, rng);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_MakeRsaKey %d\n", ret);
+ }
+ else {
+ ret = wc_RsaPublicEncrypt((byte*)plainText, sizeof(plainText),
+ (byte*)cipherText, sizeof(cipherText),
+ rsa, rng);
+ if (ret < 0) {
+ WH_ERROR_PRINT("Failed to wc_RsaPublicEncrypt %d\n", ret);
+ }
+ else {
+ ret = wc_RsaPrivateDecrypt((byte*)cipherText, ret,
+ (byte*)finalText, sizeof(finalText),
+ rsa);
+ if (ret < 0) {
+ WH_ERROR_PRINT("Failed to wc_RsaPrivateDecrypt %d\n", ret);
+ }
+ else {
+ ret = 0;
+ if (memcmp(plainText, finalText, sizeof(plainText)) != 0) {
+ WH_ERROR_PRINT("Failed to match\n");
+ ret = -1;
+ }
+ }
+ }
+ }
+ (void)wc_FreeRsaKey(rsa);
+ }
+
+ if (ret == 0) {
+ /* Using client export key */
+ memset(cipherText, 0, sizeof(cipherText));
+ memset(finalText, 0, sizeof(finalText));
+ ret = wc_InitRsaKey_ex(rsa, NULL, WH_DEV_ID);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRsaKey_ex %d\n", ret);
+ }
+ else {
+ ret = wh_Client_RsaMakeExportKey(ctx, RSA_KEY_BITS, RSA_EXPONENT,
+ rsa);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to make exported key %d\n", ret);
+ }
+ else {
+ ret = wc_RsaPublicEncrypt((byte*)plainText, sizeof(plainText),
+ (byte*)cipherText, sizeof(cipherText),
+ rsa, rng);
+ if (ret < 0) {
+ WH_ERROR_PRINT("Failed to encrypt %d\n", ret);
+ }
+ else {
+ ret = wc_RsaPrivateDecrypt((byte*)cipherText, ret,
+ (byte*)finalText,
+ sizeof(finalText), rsa);
+ if (ret < 0) {
+ WH_ERROR_PRINT("Failed to decrypt %d\n", ret);
+ }
+ else {
+ ret = 0;
+ if (memcmp(plainText, finalText, sizeof(plainText)) !=
+ 0) {
+ WH_ERROR_PRINT("Failed to match\n");
+ ret = -1;
+ }
+ }
+ }
+ }
+ (void)wc_FreeRsaKey(rsa);
+ }
+ }
+
+ if (ret == 0) {
+ /* Using keyCache key */
+ memset(cipherText, 0, sizeof(cipherText));
+ memset(finalText, 0, sizeof(finalText));
+ ret = wh_Client_RsaMakeCacheKey(
+ ctx, RSA_KEY_BITS, RSA_EXPONENT, &keyId,
+ WH_NVM_FLAGS_USAGE_ENCRYPT | WH_NVM_FLAGS_USAGE_DECRYPT, 0, NULL);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to make cached key %d\n", ret);
+ }
+ else {
+ ret = wc_InitRsaKey_ex(rsa, NULL, WH_DEV_ID);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRsaKey_ex %d\n", ret);
+ }
+ else {
+ ret = wh_Client_RsaSetKeyId(rsa, keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wh_Client_SetKeyIdRsa %d\n", ret);
+ }
+ else {
+ ret = wh_Client_RsaGetKeyId(rsa, &keyId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_GetKeyIdRsa %d\n", ret);
+ }
+ else {
+ ret = wc_RsaPublicEncrypt(
+ (byte*)plainText, sizeof(plainText),
+ (byte*)cipherText, sizeof(cipherText), rsa, rng);
+ if (ret < 0) {
+ WH_ERROR_PRINT("Failed to encrypt %d\n", ret);
+ }
+ else {
+ ret = wc_RsaPrivateDecrypt(
+ (byte*)cipherText, ret, (byte*)finalText,
+ sizeof(finalText), rsa);
+ if (ret < 0) {
+ WH_ERROR_PRINT("Failed to decrypt %d\n", ret);
+ }
+ else {
+ ret = 0;
+ if (memcmp(plainText, finalText,
+ sizeof(plainText)) != 0) {
+ WH_ERROR_PRINT("Failed to match\n");
+ ret = -1;
+ }
+ }
+ }
+ }
+ }
+ (void)wc_FreeRsaKey(rsa);
+ }
+ }
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ }
+
+ (void)wc_FreeRng(rng);
+
+ if (ret == 0) {
+ WH_TEST_PRINT("RSA DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+/* Cache a NONEXPORTABLE RSA keypair, export only the public half via
+ * wh_Client_RsaExportPublicKey, then encrypt client-side with the exported
+ * pub and decrypt server-side using the cached private. A successful round
+ * trip proves the exported public key matches the cached private. */
+int whTest_CryptoRsaExportPublicKey(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret = WH_ERROR_OK;
+ WC_RNG rng[1];
+ RsaKey rsaPub[1];
+ RsaKey rsaFull[1];
+ char plainText[sizeof(WH_TEST_RSA_PLAINTEXT)] = WH_TEST_RSA_PLAINTEXT;
+ char cipherText[RSA_KEY_BYTES];
+ char finalText[RSA_KEY_BYTES];
+ whKeyId keyId = WH_KEYID_ERASED;
+ uint8_t denyBuf[2048];
+ uint16_t denyLen = sizeof(denyBuf);
+ int encLen;
+ int decLen;
+
+ memset(cipherText, 0, sizeof(cipherText));
+ memset(finalText, 0, sizeof(finalText));
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+
+ ret = wh_Client_RsaMakeCacheKey(
+ ctx, RSA_KEY_BITS, RSA_EXPONENT, &keyId,
+ WH_NVM_FLAGS_USAGE_ENCRYPT | WH_NVM_FLAGS_USAGE_DECRYPT |
+ WH_NVM_FLAGS_NONEXPORTABLE,
+ 0, NULL);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to make NONEXPORTABLE cached RSA key %d\n", ret);
+ }
+
+ /* Full export must be denied by the NONEXPORTABLE policy. */
+ if (ret == 0) {
+ int denyRet =
+ wh_Client_KeyExport(ctx, keyId, NULL, 0, denyBuf, &denyLen);
+ if (denyRet != WH_ERROR_ACCESS) {
+ WH_ERROR_PRINT(
+ "NONEXPORTABLE RSA full export was not denied: %d\n", denyRet);
+ ret = -1;
+ }
+ }
+
+ /* Public-only export must succeed and yield a usable public key. */
+ if (ret == 0) {
+ ret = wc_InitRsaKey_ex(rsaPub, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wh_Client_RsaExportPublicKey(ctx, keyId, rsaPub, 0, NULL);
+ if (ret != 0) {
+ WH_ERROR_PRINT("wh_Client_RsaExportPublicKey failed %d\n", ret);
+ }
+ else if (rsaPub->type != RSA_PUBLIC) {
+ WH_ERROR_PRINT(
+ "Exported RSA key is not public-only (type=%d)\n",
+ rsaPub->type);
+ ret = -1;
+ }
+ else {
+ encLen = wc_RsaPublicEncrypt(
+ (byte*)plainText, sizeof(plainText), (byte*)cipherText,
+ sizeof(cipherText), rsaPub, rng);
+ if (encLen < 0) {
+ WH_ERROR_PRINT("PublicEncrypt with exported pub failed %d\n",
+ encLen);
+ ret = encLen;
+ }
+ }
+ (void)wc_FreeRsaKey(rsaPub);
+ }
+ }
+
+ /* Server-side decrypt with the cached private completes the round-trip. */
+ if (ret == 0) {
+ ret = wc_InitRsaKey_ex(rsaFull, NULL, devId);
+ if (ret == 0) {
+ ret = wh_Client_RsaSetKeyId(rsaFull, keyId);
+ }
+ if (ret == 0) {
+ decLen = wc_RsaPrivateDecrypt((byte*)cipherText, encLen,
+ (byte*)finalText, sizeof(finalText),
+ rsaFull);
+ if (decLen < 0) {
+ WH_ERROR_PRINT("HSM PrivateDecrypt failed %d\n", decLen);
+ ret = decLen;
+ }
+ else if (memcmp(plainText, finalText, sizeof(plainText)) != 0) {
+ WH_ERROR_PRINT("RSA round-trip plaintext mismatch\n");
+ ret = -1;
+ }
+ }
+ (void)wc_FreeRsaKey(rsaFull);
+ }
+
+ if (!WH_KEYID_ISERASED(keyId)) {
+ (void)wh_Client_KeyEvict(ctx, keyId);
+ }
+ (void)wc_FreeRng(rng);
+
+ if (ret == 0) {
+ WH_TEST_PRINT("RSA EXPORT-PUBLIC DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+#endif /* !NO_RSA */
+
+#endif /* !WOLFHSM_CFG_NO_CRYPTO */
diff --git a/test-refactor/client-server/wh_test_sha.c b/test-refactor/client-server/wh_test_sha.c
new file mode 100644
index 00000000..5bb2f8be
--- /dev/null
+++ b/test-refactor/client-server/wh_test_sha.c
@@ -0,0 +1,2400 @@
+/*
+ * Copyright (C) 2026 wolfSSL Inc.
+ *
+ * This file is part of wolfHSM.
+ *
+ * wolfHSM 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfHSM 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 wolfHSM. If not, see .
+ */
+/*
+ * test-refactor/client-server/wh_test_sha.c
+ *
+ * SHA-224 / 256 / 384 / 512 routed through the server via WH_DEV_ID.
+ * Each hash size has four variants:
+ * whTest_CryptoSha sync wolfCrypt API single+multi block
+ * whTest_CryptoShaLargeInput sync test with input larger than the
+ * server transport buffer (chunked send)
+ * whTest_CryptoShaAsync direct exercise of wh_Client_Sha*Request
+ * / Response primitives
+ * whTest_CryptoShaDmaAsync same, via the DMA messaging path
+ *
+ * The legacy implementations are preserved verbatim as static *Impl
+ * helpers; thin public wrappers above each family own the WC_RNG lifecycle
+ * so the public API matches the rest of the test-refactor suite.
+ */
+
+#include "wolfhsm/wh_settings.h"
+
+#if !defined(WOLFHSM_CFG_NO_CRYPTO)
+
+#include
+#include
+
+#include "wolfssl/wolfcrypt/settings.h"
+#include "wolfssl/wolfcrypt/types.h"
+#include "wolfssl/wolfcrypt/sha256.h"
+#include "wolfssl/wolfcrypt/sha512.h"
+#include "wolfssl/wolfcrypt/random.h"
+
+#include "wolfhsm/wh_error.h"
+#include "wolfhsm/wh_common.h"
+#include "wolfhsm/wh_client.h"
+#include "wolfhsm/wh_client_crypto.h"
+#include "wolfhsm/wh_message_crypto.h"
+
+#include "wh_test_common.h"
+#include "wh_test_list.h"
+
+#ifndef NO_SHA256
+static int whTest_CryptoSha256Impl(whClientContext* ctx, int devId, WC_RNG* rng)
+{
+ (void)ctx; (void)rng; /* Not currently used */
+ int ret = WH_ERROR_OK;
+ wc_Sha256 sha256[1];
+ uint8_t out[WC_SHA256_DIGEST_SIZE];
+ /* Vector exactly one block size in length */
+ const char inOne[] =
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ const uint8_t expectedOutOne[WC_SHA256_DIGEST_SIZE] = {
+ 0xff, 0xe0, 0x54, 0xfe, 0x7a, 0xe0, 0xcb, 0x6d, 0xc6, 0x5c, 0x3a,
+ 0xf9, 0xb6, 0x1d, 0x52, 0x09, 0xf4, 0x39, 0x85, 0x1d, 0xb4, 0x3d,
+ 0x0b, 0xa5, 0x99, 0x73, 0x37, 0xdf, 0x15, 0x46, 0x68, 0xeb};
+ /* Vector long enough to span a SHA256 block */
+ const char inMulti[] =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX"
+ "YZ1234567890abcdefghi";
+ const uint8_t expectedOutMulti[WC_SHA256_DIGEST_SIZE] = {
+ 0x7b, 0x54, 0x45, 0x86, 0xb3, 0x51, 0x43, 0x4e, 0xf6, 0x83, 0xdb,
+ 0x78, 0x1d, 0x94, 0xd6, 0xb0, 0x36, 0x9b, 0x36, 0x56, 0x93, 0x0e,
+ 0xf4, 0x47, 0x9b, 0xae, 0xff, 0xfa, 0x1f, 0x36, 0x38, 0x64};
+
+ /* Initialize SHA256 structure */
+ ret = wc_InitSha256_ex(sha256, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitSha256 on devId 0x%X: %d\n", devId,
+ ret);
+ } else {
+ /* Test SHA256 on a single block worth of data. Should trigger a server
+ * transaction */
+ ret = wc_Sha256Update(sha256,
+ (const byte*)inOne,
+ WC_SHA256_BLOCK_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha256Update %d\n", ret);
+ } else {
+ /* Finalize should trigger a server transaction with empty buffer */
+ ret = wc_Sha256Final(sha256, out);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha256Final %d\n", ret);
+ } else {
+ /* Compare the computed hash with the expected output */
+ if (memcmp(out, expectedOutOne, WC_SHA256_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA256 hash does not match expected.\n");
+ ret = -1;
+ }
+ memset(out, 0, WC_SHA256_DIGEST_SIZE);
+ }
+ }
+ /* Reset state for multi block test */
+ (void)wc_Sha256Free(sha256);
+ }
+ if (ret == 0) {
+ /* Multiblock test */
+ ret = wc_InitSha256_ex(sha256, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitSha256 for devId 0x%X: %d\n",
+ devId, ret);
+ } else {
+ /* Update with a non-block aligned length. Will not trigger server
+ * transaction */
+ ret = wc_Sha256Update(sha256,
+ (const byte*)inMulti,
+ 1);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha256Update (first) %d\n", ret);
+ } else {
+ /* Update with a full block, will trigger block to be sent to
+ * server and one additional byte to be buffered */
+ ret = wc_Sha256Update(sha256,
+ (const byte*)inMulti + 1,
+ WC_SHA256_BLOCK_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha256Update (mid) %d\n", ret);
+ } else {
+ /* Update with the remaining data, should not trigger server
+ * transaction */
+ ret = wc_Sha256Update(sha256,
+ (const byte*)inMulti + 1 + WC_SHA256_BLOCK_SIZE,
+ strlen(inMulti) - 1 - WC_SHA256_BLOCK_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha256Update (last) %d\n",
+ ret);
+ } else {
+ /* Finalize should trigger a server transaction on the
+ * remaining partial buffer */
+ ret = wc_Sha256Final(sha256, out);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha256Final %d\n",
+ ret);
+ } else {
+ /* Compare the computed hash with the expected
+ * output */
+ if (memcmp(out, expectedOutMulti,
+ WC_SHA256_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA256 hash does not match the "
+ "expected output.\n");
+ ret = -1;
+ }
+ }
+ }
+ }
+ }
+ (void)wc_Sha256Free(sha256);
+ }
+ }
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA256 DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+/* Hash a buffer with a pure-software SHA256 (no devId) so we can compare. */
+static int whTest_Sha256Reference(const uint8_t* in, uint32_t inLen,
+ uint8_t out[WC_SHA256_DIGEST_SIZE])
+{
+ wc_Sha256 sw[1];
+ int ret = wc_InitSha256_ex(sw, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wc_Sha256Update(sw, in, inLen);
+ }
+ if (ret == 0) {
+ ret = wc_Sha256Final(sw, out);
+ }
+ (void)wc_Sha256Free(sw);
+ return ret;
+}
+
+/* Drive the new multi-block wire format through the blocking wrapper. Tests:
+ * - large multi-request input,
+ * - exact per-call inline capacity boundary,
+ * - one-byte-over-capacity boundary (forces a tail in the client buffer),
+ * - non-aligned chunked update sequence.
+ *
+ * Buffer is sized to comfortably exceed the per-call inline capacity at any
+ * reasonable comm-buffer size. We use a static buffer to keep stack pressure
+ * low under ASAN. */
+static uint8_t
+ whTest_Sha256BigBuf[2 *
+ (WH_MESSAGE_CRYPTO_SHA256_MAX_INLINE_UPDATE_SZ + 64u)];
+
+static int whTest_CryptoSha256LargeInputImpl(whClientContext* ctx, int devId,
+ WC_RNG* rng)
+{
+ int ret = WH_ERROR_OK;
+ wc_Sha256 sha256[1];
+ uint8_t out[WC_SHA256_DIGEST_SIZE];
+ uint8_t ref[WC_SHA256_DIGEST_SIZE];
+ uint8_t* buf = whTest_Sha256BigBuf;
+ uint32_t BUFSZ = (uint32_t)sizeof(whTest_Sha256BigBuf);
+ uint32_t i;
+
+ (void)ctx;
+ (void)rng;
+
+ for (i = 0; i < BUFSZ; i++) {
+ buf[i] = (uint8_t)(i & 0xff);
+ }
+
+ /* Test 1: large single-update */
+ ret = wc_InitSha256_ex(sha256, NULL, devId);
+ if (ret == 0) {
+ ret = wc_Sha256Update(sha256, buf, BUFSZ);
+ }
+ if (ret == 0) {
+ ret = wc_Sha256Final(sha256, out);
+ }
+ (void)wc_Sha256Free(sha256);
+ if (ret == 0) {
+ ret = whTest_Sha256Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA256_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA256 large input mismatch\n");
+ ret = -1;
+ }
+
+ /* Test 2: exactly the per-call inline capacity in one shot */
+ if (ret == 0) {
+ const uint32_t cap = WH_MESSAGE_CRYPTO_SHA256_MAX_INLINE_UPDATE_SZ;
+ ret = wc_InitSha256_ex(sha256, NULL, devId);
+ if (ret == 0) {
+ ret = wc_Sha256Update(sha256, buf, cap);
+ }
+ if (ret == 0) {
+ ret = wc_Sha256Final(sha256, out);
+ }
+ (void)wc_Sha256Free(sha256);
+ if (ret == 0) {
+ ret = whTest_Sha256Reference(buf, cap, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA256_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA256 capacity-boundary mismatch\n");
+ ret = -1;
+ }
+ }
+
+ /* Test 3: capacity + 1 byte (one full request, then a tail buffered) */
+ if (ret == 0) {
+ const uint32_t cap1 =
+ WH_MESSAGE_CRYPTO_SHA256_MAX_INLINE_UPDATE_SZ + 1u;
+ ret = wc_InitSha256_ex(sha256, NULL, devId);
+ if (ret == 0) {
+ ret = wc_Sha256Update(sha256, buf, cap1);
+ }
+ if (ret == 0) {
+ ret = wc_Sha256Final(sha256, out);
+ }
+ (void)wc_Sha256Free(sha256);
+ if (ret == 0) {
+ ret = whTest_Sha256Reference(buf, cap1, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA256_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA256 capacity+1 mismatch\n");
+ ret = -1;
+ }
+ }
+
+ /* Test 4: non-aligned chunk stress test */
+ if (ret == 0) {
+ const uint32_t chunks[] = {13, 17, 1280, 41, 1};
+ const size_t nChunks = sizeof(chunks) / sizeof(chunks[0]);
+ uint32_t total = 0;
+ size_t k;
+ for (k = 0; k < nChunks; k++) {
+ total += chunks[k];
+ }
+ if (total > BUFSZ) {
+ WH_ERROR_PRINT("test buffer too small for chunked stress test\n");
+ ret = -1;
+ }
+ if (ret == 0) {
+ uint32_t off = 0;
+ ret = wc_InitSha256_ex(sha256, NULL, devId);
+ for (k = 0; ret == 0 && k < nChunks; k++) {
+ ret = wc_Sha256Update(sha256, buf + off, chunks[k]);
+ off += chunks[k];
+ }
+ if (ret == 0) {
+ ret = wc_Sha256Final(sha256, out);
+ }
+ (void)wc_Sha256Free(sha256);
+ if (ret == 0) {
+ ret = whTest_Sha256Reference(buf, total, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA256_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA256 chunked stress mismatch\n");
+ ret = -1;
+ }
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA256 LARGE-INPUT DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+/* Direct exercise of the new async non-DMA SHA256 primitives. */
+static int whTest_CryptoSha256AsyncImpl(whClientContext* ctx, int devId,
+ WC_RNG* rng)
+{
+ int ret = WH_ERROR_OK;
+ wc_Sha256 sha256[1];
+ uint8_t out[WC_SHA256_DIGEST_SIZE];
+ uint8_t ref[WC_SHA256_DIGEST_SIZE];
+ /* Use the same large static buffer as the LargeInput test. */
+ uint8_t* buf = whTest_Sha256BigBuf;
+ uint32_t BUFSZ = (uint32_t)sizeof(whTest_Sha256BigBuf);
+ uint32_t i;
+ bool sent;
+
+ (void)rng;
+
+ for (i = 0; i < BUFSZ; i++) {
+ buf[i] = (uint8_t)((i * 31u + 7u) & 0xff);
+ }
+
+ /* Case A: basic UpdateRequest -> UpdateResponse -> Final */
+ ret = wc_InitSha256_ex(sha256, NULL, devId);
+ if (ret == 0) {
+ sent = false;
+ ret = wh_Client_Sha256UpdateRequest(ctx, sha256, buf, 256, &sent);
+ }
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha256UpdateResponse(ctx, sha256);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha256FinalRequest(ctx, sha256);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha256FinalResponse(ctx, sha256, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = whTest_Sha256Reference(buf, 256, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA256_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async SHA256 case A mismatch\n");
+ ret = -1;
+ }
+
+ /* Case B: pure-buffer-fill update (sent must be false), then finalize */
+ if (ret == 0) {
+ (void)wc_Sha256Free(sha256);
+ ret = wc_InitSha256_ex(sha256, NULL, devId);
+ }
+ if (ret == 0) {
+ sent = true; /* expect to be cleared to false */
+ ret = wh_Client_Sha256UpdateRequest(ctx, sha256, buf, 10, &sent);
+ if (ret == 0 && sent != false) {
+ WH_ERROR_PRINT(
+ "Async SHA256: expected sent==false on small update\n");
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha256FinalRequest(ctx, sha256);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha256FinalResponse(ctx, sha256, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = whTest_Sha256Reference(buf, 10, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA256_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async SHA256 case B mismatch\n");
+ ret = -1;
+ }
+
+ /* Case C: multi-round async updates that span more than the per-call
+ * inline capacity (forces multiple Request/Response pairs). */
+ if (ret == 0) {
+ uint32_t consumed = 0;
+ (void)wc_Sha256Free(sha256);
+ ret = wc_InitSha256_ex(sha256, NULL, devId);
+ while (ret == 0 && consumed < BUFSZ) {
+ /* arbitrary, 70% of max inline */
+ uint32_t chunk =
+ (WH_MESSAGE_CRYPTO_SHA256_MAX_INLINE_UPDATE_SZ * 7 / 10);
+ if (consumed + chunk > BUFSZ) {
+ chunk = BUFSZ - consumed;
+ }
+ sent = false;
+ ret = wh_Client_Sha256UpdateRequest(ctx, sha256, buf + consumed,
+ chunk, &sent);
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha256UpdateResponse(ctx, sha256);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ consumed += chunk;
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha256FinalRequest(ctx, sha256);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha256FinalResponse(ctx, sha256, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = whTest_Sha256Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA256_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async SHA256 case C mismatch\n");
+ ret = -1;
+ }
+ }
+
+ /* Case D: oversized-input rejection. UpdateRequest with inLen > capacity
+ * must return BADARGS without mutating sha. */
+ if (ret == 0) {
+ uint8_t savedDigest[WC_SHA256_DIGEST_SIZE];
+ word32 savedBuffLen;
+ uint32_t cap;
+ int rc;
+ (void)wc_Sha256Free(sha256);
+ ret = wc_InitSha256_ex(sha256, NULL, devId);
+ if (ret == 0) {
+ memcpy(savedDigest, sha256->digest, WC_SHA256_DIGEST_SIZE);
+ savedBuffLen = sha256->buffLen;
+ cap = WH_MESSAGE_CRYPTO_SHA256_MAX_INLINE_UPDATE_SZ +
+ (uint32_t)(WC_SHA256_BLOCK_SIZE - 1u - sha256->buffLen);
+ sent = true;
+ rc = wh_Client_Sha256UpdateRequest(ctx, sha256, buf, cap + 1u,
+ &sent);
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT("Async SHA256: expected BADARGS, got %d\n", rc);
+ ret = -1;
+ }
+ else if (sent != false) {
+ WH_ERROR_PRINT(
+ "Async SHA256: sent should remain false on err\n");
+ ret = -1;
+ }
+ else if (sha256->buffLen != savedBuffLen ||
+ memcmp(sha256->digest, savedDigest,
+ WC_SHA256_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT(
+ "Async SHA256: state mutated on rejected call\n");
+ ret = -1;
+ }
+ }
+ (void)wc_Sha256Free(sha256);
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA256 ASYNC DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+#ifdef WOLFHSM_CFG_DMA
+/* Direct exercise of the new async DMA SHA256 primitives. */
+static int whTest_CryptoSha256DmaAsyncImpl(whClientContext* ctx, int devId,
+ WC_RNG* rng)
+{
+ int ret = WH_ERROR_OK;
+ wc_Sha256 sha256[1];
+ uint8_t out[WC_SHA256_DIGEST_SIZE];
+ uint8_t ref[WC_SHA256_DIGEST_SIZE];
+ /* DMA bypasses the comm buffer, so any size goes; reuse the shared
+ * static buffer to keep stack pressure low. */
+ uint8_t* buf = whTest_Sha256BigBuf;
+ uint32_t BUFSZ = (uint32_t)sizeof(whTest_Sha256BigBuf);
+ uint32_t i;
+
+ (void)rng;
+
+ for (i = 0; i < BUFSZ; i++) {
+ buf[i] = (uint8_t)((i * 17u + 3u) & 0xff);
+ }
+
+ /* Case A: single large DMA Update + Final */
+ ret = wc_InitSha256_ex(sha256, NULL, devId);
+ if (ret == 0) {
+ bool sent = false;
+ ret = wh_Client_Sha256DmaUpdateRequest(ctx, sha256, buf, BUFSZ, &sent);
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha256DmaUpdateResponse(ctx, sha256);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha256DmaFinalRequest(ctx, sha256);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha256DmaFinalResponse(ctx, sha256, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ (void)wc_Sha256Free(sha256);
+ if (ret == 0) {
+ ret = whTest_Sha256Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA256_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async DMA SHA256 case A mismatch\n");
+ ret = -1;
+ }
+
+ /* Case B: multiple DMA Update round-trips, then Final */
+ if (ret == 0) {
+ uint32_t consumed = 0;
+ ret = wc_InitSha256_ex(sha256, NULL, devId);
+ while (ret == 0 && consumed < BUFSZ) {
+ uint32_t chunk = 1024;
+ bool sent = false;
+ if (consumed + chunk > BUFSZ) {
+ chunk = BUFSZ - consumed;
+ }
+ ret = wh_Client_Sha256DmaUpdateRequest(ctx, sha256, buf + consumed,
+ chunk, &sent);
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha256DmaUpdateResponse(ctx, sha256);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ consumed += chunk;
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha256DmaFinalRequest(ctx, sha256);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha256DmaFinalResponse(ctx, sha256, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ (void)wc_Sha256Free(sha256);
+ if (ret == 0) {
+ ret = whTest_Sha256Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA256_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async DMA SHA256 case B mismatch\n");
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA256 DMA ASYNC DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+#endif /* WOLFHSM_CFG_DMA */
+
+int whTest_CryptoSha256(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha256Impl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+
+int whTest_CryptoSha256LargeInput(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha256LargeInputImpl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+
+int whTest_CryptoSha256Async(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha256AsyncImpl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+
+#ifdef WOLFHSM_CFG_DMA
+int whTest_CryptoSha256DmaAsync(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha256DmaAsyncImpl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+#endif /* WOLFHSM_CFG_DMA */
+
+#endif /* !NO_SHA256 */
+
+#ifdef WOLFSSL_SHA224
+static int whTest_CryptoSha224Impl(whClientContext* ctx, int devId, WC_RNG* rng)
+{
+ (void)ctx;
+ (void)rng; /* Not currently used */
+ int ret = WH_ERROR_OK;
+ wc_Sha224 sha224[1];
+ uint8_t out[WC_SHA224_DIGEST_SIZE];
+ /* Vector exactly one block size in length */
+ const char inOne[] =
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ const uint8_t expectedOutOne[WC_SHA224_DIGEST_SIZE] = {
+ 0xa8, 0x8c, 0xd5, 0xcd, 0xe6, 0xd6, 0xfe, 0x91, 0x36, 0xa4,
+ 0xe5, 0x8b, 0x49, 0x16, 0x74, 0x61, 0xea, 0x95, 0xd3, 0x88,
+ 0xca, 0x2b, 0xdb, 0x7a, 0xfd, 0xc3, 0xcb, 0xf4};
+ /* Vector long enough to span a SHA224 block */
+ const char inMulti[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX"
+ "YZ1234567890abcdefghi";
+ const uint8_t expectedOutMulti[WC_SHA224_DIGEST_SIZE] = {
+ 0xb4, 0x22, 0xdc, 0xe8, 0xf9, 0x48, 0x8c, 0x4b, 0xc3, 0xef,
+ 0x8e, 0x7d, 0xbe, 0x11, 0xc7, 0x21, 0xba, 0x38, 0xcb, 0x61,
+ 0xf5, 0x6b, 0x7d, 0xc5, 0x30, 0xa7, 0x9c, 0xfd};
+ /* Initialize SHA224 structure */
+ ret = wc_InitSha224_ex(sha224, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitSha224 on devId 0x%X: %d\n", devId,
+ ret);
+ }
+ else {
+ /* Test SHA224 on a single block worth of data. Should trigger a server
+ * transaction */
+ ret = wc_Sha224Update(sha224, (const byte*)inOne, WC_SHA224_BLOCK_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha224Update %d\n", ret);
+ }
+ else {
+ /* Finalize should trigger a server transaction with empty buffer */
+ ret = wc_Sha224Final(sha224, out);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha224Final %d\n", ret);
+ }
+ else {
+ /* Compare the computed hash with the expected output */
+ if (memcmp(out, expectedOutOne, WC_SHA224_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA224 hash does not match expected.\n");
+ ret = -1;
+ }
+ memset(out, 0, WC_SHA224_DIGEST_SIZE);
+ }
+ }
+ /* Reset state for multi block test */
+ (void)wc_Sha224Free(sha224);
+ }
+ if (ret == 0) {
+ /* Multiblock test */
+ ret = wc_InitSha224_ex(sha224, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitSha224 for devId 0x%X: %d\n",
+ devId, ret);
+ }
+ else {
+ /* Update with a non-block aligned length. Will not trigger server
+ * transaction */
+ ret = wc_Sha224Update(sha224, (const byte*)inMulti, 1);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha224Update (first) %d\n", ret);
+ }
+ else {
+ /* Update with a full block, will trigger block to be sent to
+ * server and one additional byte to be buffered */
+ ret = wc_Sha224Update(sha224, (const byte*)inMulti + 1,
+ WC_SHA224_BLOCK_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha224Update (mid) %d\n", ret);
+ }
+ else {
+ /* Update with the remaining data, should not trigger server
+ * transaction */
+ ret = wc_Sha224Update(
+ sha224, (const byte*)inMulti + 1 + WC_SHA224_BLOCK_SIZE,
+ strlen(inMulti) - 1 - WC_SHA224_BLOCK_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha224Update (last) %d\n",
+ ret);
+ }
+ else {
+ /* Finalize should trigger a server transaction on the
+ * remaining partial buffer */
+ ret = wc_Sha224Final(sha224, out);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha224Final %d\n",
+ ret);
+ }
+ else {
+ /* Compare the computed hash with the expected
+ * output */
+ if (memcmp(out, expectedOutMulti,
+ WC_SHA224_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA224 hash does not match the "
+ "expected output.\n");
+ ret = -1;
+ }
+ }
+ }
+ }
+ }
+ (void)wc_Sha224Free(sha224);
+ }
+ }
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA224 DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+/* Hash a buffer with a pure-software SHA224 (no devId) so we can compare. */
+static int whTest_Sha224Reference(const uint8_t* in, uint32_t inLen,
+ uint8_t out[WC_SHA224_DIGEST_SIZE])
+{
+ wc_Sha224 sw[1];
+ int ret = wc_InitSha224_ex(sw, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wc_Sha224Update(sw, in, inLen);
+ }
+ if (ret == 0) {
+ ret = wc_Sha224Final(sw, out);
+ }
+ (void)wc_Sha224Free(sw);
+ return ret;
+}
+
+/* Drive the new multi-block wire format through the blocking wrapper. Tests:
+ * - large multi-request input,
+ * - exact per-call inline capacity boundary,
+ * - one-byte-over-capacity boundary (forces a tail in the client buffer),
+ * - non-aligned chunked update sequence.
+ *
+ * Buffer is sized to comfortably exceed the per-call inline capacity at any
+ * reasonable comm-buffer size. We use a static buffer to keep stack pressure
+ * low under ASAN. */
+static uint8_t
+ whTest_Sha224BigBuf[2 *
+ (WH_MESSAGE_CRYPTO_SHA224_MAX_INLINE_UPDATE_SZ + 64u)];
+
+static int whTest_CryptoSha224LargeInputImpl(whClientContext* ctx, int devId,
+ WC_RNG* rng)
+{
+ int ret = WH_ERROR_OK;
+ wc_Sha224 sha224[1];
+ uint8_t out[WC_SHA224_DIGEST_SIZE];
+ uint8_t ref[WC_SHA224_DIGEST_SIZE];
+ uint8_t* buf = whTest_Sha224BigBuf;
+ uint32_t BUFSZ = (uint32_t)sizeof(whTest_Sha224BigBuf);
+ uint32_t i;
+
+ (void)ctx;
+ (void)rng;
+
+ for (i = 0; i < BUFSZ; i++) {
+ buf[i] = (uint8_t)(i & 0xff);
+ }
+
+ /* Test 1: large single-update */
+ ret = wc_InitSha224_ex(sha224, NULL, devId);
+ if (ret == 0) {
+ ret = wc_Sha224Update(sha224, buf, BUFSZ);
+ }
+ if (ret == 0) {
+ ret = wc_Sha224Final(sha224, out);
+ }
+ (void)wc_Sha224Free(sha224);
+ if (ret == 0) {
+ ret = whTest_Sha224Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA224_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA224 large input mismatch\n");
+ ret = -1;
+ }
+
+ /* Test 2: exactly the per-call inline capacity in one shot */
+ if (ret == 0) {
+ const uint32_t cap = WH_MESSAGE_CRYPTO_SHA224_MAX_INLINE_UPDATE_SZ;
+ ret = wc_InitSha224_ex(sha224, NULL, devId);
+ if (ret == 0) {
+ ret = wc_Sha224Update(sha224, buf, cap);
+ }
+ if (ret == 0) {
+ ret = wc_Sha224Final(sha224, out);
+ }
+ (void)wc_Sha224Free(sha224);
+ if (ret == 0) {
+ ret = whTest_Sha224Reference(buf, cap, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA224_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA224 capacity-boundary mismatch\n");
+ ret = -1;
+ }
+ }
+
+ /* Test 3: capacity + 1 byte (one full request, then a tail buffered) */
+ if (ret == 0) {
+ const uint32_t cap1 =
+ WH_MESSAGE_CRYPTO_SHA224_MAX_INLINE_UPDATE_SZ + 1u;
+ ret = wc_InitSha224_ex(sha224, NULL, devId);
+ if (ret == 0) {
+ ret = wc_Sha224Update(sha224, buf, cap1);
+ }
+ if (ret == 0) {
+ ret = wc_Sha224Final(sha224, out);
+ }
+ (void)wc_Sha224Free(sha224);
+ if (ret == 0) {
+ ret = whTest_Sha224Reference(buf, cap1, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA224_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA224 capacity+1 mismatch\n");
+ ret = -1;
+ }
+ }
+
+ /* Test 4: non-aligned chunk stress test */
+ if (ret == 0) {
+ const uint32_t chunks[] = {13, 17, 1280, 41, 1};
+ const size_t nChunks = sizeof(chunks) / sizeof(chunks[0]);
+ uint32_t total = 0;
+ size_t k;
+ for (k = 0; k < nChunks; k++) {
+ total += chunks[k];
+ }
+ if (total > BUFSZ) {
+ WH_ERROR_PRINT("test buffer too small for chunked stress test\n");
+ ret = -1;
+ }
+ if (ret == 0) {
+ uint32_t off = 0;
+ ret = wc_InitSha224_ex(sha224, NULL, devId);
+ for (k = 0; ret == 0 && k < nChunks; k++) {
+ ret = wc_Sha224Update(sha224, buf + off, chunks[k]);
+ off += chunks[k];
+ }
+ if (ret == 0) {
+ ret = wc_Sha224Final(sha224, out);
+ }
+ (void)wc_Sha224Free(sha224);
+ if (ret == 0) {
+ ret = whTest_Sha224Reference(buf, total, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA224_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA224 chunked stress mismatch\n");
+ ret = -1;
+ }
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA224 LARGE-INPUT DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+/* Direct exercise of the new async non-DMA SHA224 primitives. */
+static int whTest_CryptoSha224AsyncImpl(whClientContext* ctx, int devId,
+ WC_RNG* rng)
+{
+ int ret = WH_ERROR_OK;
+ wc_Sha224 sha224[1];
+ uint8_t out[WC_SHA224_DIGEST_SIZE];
+ uint8_t ref[WC_SHA224_DIGEST_SIZE];
+ /* Use the same large static buffer as the LargeInput test. */
+ uint8_t* buf = whTest_Sha224BigBuf;
+ uint32_t BUFSZ = (uint32_t)sizeof(whTest_Sha224BigBuf);
+ uint32_t i;
+ bool sent;
+
+ (void)rng;
+
+ for (i = 0; i < BUFSZ; i++) {
+ buf[i] = (uint8_t)((i * 31u + 7u) & 0xff);
+ }
+
+ /* Case A: basic UpdateRequest -> UpdateResponse -> Final */
+ ret = wc_InitSha224_ex(sha224, NULL, devId);
+ if (ret == 0) {
+ sent = false;
+ ret = wh_Client_Sha224UpdateRequest(ctx, sha224, buf, 256, &sent);
+ }
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha224UpdateResponse(ctx, sha224);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha224FinalRequest(ctx, sha224);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha224FinalResponse(ctx, sha224, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = whTest_Sha224Reference(buf, 256, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA224_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async SHA224 case A mismatch\n");
+ ret = -1;
+ }
+
+ /* Case B: pure-buffer-fill update (sent must be false), then finalize */
+ if (ret == 0) {
+ (void)wc_Sha224Free(sha224);
+ ret = wc_InitSha224_ex(sha224, NULL, devId);
+ }
+ if (ret == 0) {
+ sent = true; /* expect to be cleared to false */
+ ret = wh_Client_Sha224UpdateRequest(ctx, sha224, buf, 10, &sent);
+ if (ret == 0 && sent != false) {
+ WH_ERROR_PRINT(
+ "Async SHA224: expected sent==false on small update\n");
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha224FinalRequest(ctx, sha224);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha224FinalResponse(ctx, sha224, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = whTest_Sha224Reference(buf, 10, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA224_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async SHA224 case B mismatch\n");
+ ret = -1;
+ }
+
+ /* Case C: multi-round async updates that span more than the per-call
+ * inline capacity (forces multiple Request/Response pairs). */
+ if (ret == 0) {
+ uint32_t consumed = 0;
+ (void)wc_Sha224Free(sha224);
+ ret = wc_InitSha224_ex(sha224, NULL, devId);
+ while (ret == 0 && consumed < BUFSZ) {
+ /* arbitrary, 70% of max inline */
+ uint32_t chunk =
+ (WH_MESSAGE_CRYPTO_SHA224_MAX_INLINE_UPDATE_SZ * 7 / 10);
+ if (consumed + chunk > BUFSZ) {
+ chunk = BUFSZ - consumed;
+ }
+ sent = false;
+ ret = wh_Client_Sha224UpdateRequest(ctx, sha224, buf + consumed,
+ chunk, &sent);
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha224UpdateResponse(ctx, sha224);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ consumed += chunk;
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha224FinalRequest(ctx, sha224);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha224FinalResponse(ctx, sha224, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = whTest_Sha224Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA224_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async SHA224 case C mismatch\n");
+ ret = -1;
+ }
+ }
+
+ /* Case D: oversized-input rejection. UpdateRequest with inLen > capacity
+ * must return BADARGS without mutating sha. */
+ if (ret == 0) {
+ uint8_t savedDigest[WC_SHA256_DIGEST_SIZE];
+ word32 savedBuffLen;
+ uint32_t cap;
+ int rc;
+ (void)wc_Sha224Free(sha224);
+ ret = wc_InitSha224_ex(sha224, NULL, devId);
+ if (ret == 0) {
+ memcpy(savedDigest, sha224->digest, WC_SHA256_DIGEST_SIZE);
+ savedBuffLen = sha224->buffLen;
+ cap = WH_MESSAGE_CRYPTO_SHA224_MAX_INLINE_UPDATE_SZ +
+ (uint32_t)(WC_SHA224_BLOCK_SIZE - 1u - sha224->buffLen);
+ sent = true;
+ rc = wh_Client_Sha224UpdateRequest(ctx, sha224, buf, cap + 1u,
+ &sent);
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT("Async SHA224: expected BADARGS, got %d\n", rc);
+ ret = -1;
+ }
+ else if (sent != false) {
+ WH_ERROR_PRINT(
+ "Async SHA224: sent should remain false on err\n");
+ ret = -1;
+ }
+ else if (sha224->buffLen != savedBuffLen ||
+ memcmp(sha224->digest, savedDigest,
+ WC_SHA256_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT(
+ "Async SHA224: state mutated on rejected call\n");
+ ret = -1;
+ }
+ }
+ (void)wc_Sha224Free(sha224);
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA224 ASYNC DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+#ifdef WOLFHSM_CFG_DMA
+/* Direct exercise of the new async DMA SHA224 primitives. */
+static int whTest_CryptoSha224DmaAsyncImpl(whClientContext* ctx, int devId,
+ WC_RNG* rng)
+{
+ int ret = WH_ERROR_OK;
+ wc_Sha224 sha224[1];
+ uint8_t out[WC_SHA224_DIGEST_SIZE];
+ uint8_t ref[WC_SHA224_DIGEST_SIZE];
+ /* DMA bypasses the comm buffer, so any size goes; reuse the shared
+ * static buffer to keep stack pressure low. */
+ uint8_t* buf = whTest_Sha224BigBuf;
+ uint32_t BUFSZ = (uint32_t)sizeof(whTest_Sha224BigBuf);
+ uint32_t i;
+
+ (void)rng;
+
+ for (i = 0; i < BUFSZ; i++) {
+ buf[i] = (uint8_t)((i * 17u + 3u) & 0xff);
+ }
+
+ /* Case A: single large DMA Update + Final */
+ ret = wc_InitSha224_ex(sha224, NULL, devId);
+ if (ret == 0) {
+ bool sent = false;
+ ret = wh_Client_Sha224DmaUpdateRequest(ctx, sha224, buf, BUFSZ, &sent);
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha224DmaUpdateResponse(ctx, sha224);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha224DmaFinalRequest(ctx, sha224);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha224DmaFinalResponse(ctx, sha224, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ (void)wc_Sha224Free(sha224);
+ if (ret == 0) {
+ ret = whTest_Sha224Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA224_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async DMA SHA224 case A mismatch\n");
+ ret = -1;
+ }
+
+ /* Case B: multiple DMA Update round-trips, then Final */
+ if (ret == 0) {
+ uint32_t consumed = 0;
+ ret = wc_InitSha224_ex(sha224, NULL, devId);
+ while (ret == 0 && consumed < BUFSZ) {
+ uint32_t chunk = 1024;
+ if (consumed + chunk > BUFSZ) {
+ chunk = BUFSZ - consumed;
+ }
+ {
+ bool sent = false;
+ ret = wh_Client_Sha224DmaUpdateRequest(
+ ctx, sha224, buf + consumed, chunk, &sent);
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha224DmaUpdateResponse(ctx, sha224);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ }
+ consumed += chunk;
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha224DmaFinalRequest(ctx, sha224);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha224DmaFinalResponse(ctx, sha224, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ (void)wc_Sha224Free(sha224);
+ if (ret == 0) {
+ ret = whTest_Sha224Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA224_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async DMA SHA224 case B mismatch\n");
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA224 DMA ASYNC DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+#endif /* WOLFHSM_CFG_DMA */
+
+int whTest_CryptoSha224(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha224Impl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+
+int whTest_CryptoSha224LargeInput(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha224LargeInputImpl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+
+int whTest_CryptoSha224Async(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha224AsyncImpl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+
+#ifdef WOLFHSM_CFG_DMA
+int whTest_CryptoSha224DmaAsync(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha224DmaAsyncImpl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+#endif /* WOLFHSM_CFG_DMA */
+
+#endif /* WOLFSSL_SHA224 */
+
+#ifdef WOLFSSL_SHA384
+static int whTest_CryptoSha384Impl(whClientContext* ctx, int devId, WC_RNG* rng)
+{
+ (void)ctx;
+ (void)rng; /* Not currently used */
+ int ret = WH_ERROR_OK;
+ wc_Sha384 sha384[1];
+ uint8_t out[WC_SHA384_DIGEST_SIZE];
+ /* Vector exactly one block size in length */
+ const char inOne[] =
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ const uint8_t expectedOutOne[WC_SHA384_DIGEST_SIZE] = {
+ 0xed, 0xb1, 0x27, 0x30, 0xa3, 0x66, 0x09, 0x8b, 0x3b, 0x2b, 0xea, 0xc7,
+ 0x5a, 0x3b, 0xef, 0x1b, 0x09, 0x69, 0xb1, 0x5c, 0x48, 0xe2, 0x16, 0x3c,
+ 0x23, 0xd9, 0x69, 0x94, 0xf8, 0xd1, 0xbe, 0xf7, 0x60, 0xc7, 0xe2, 0x7f,
+ 0x3c, 0x46, 0x4d, 0x38, 0x29, 0xf5, 0x6c, 0x0d, 0x53, 0x80, 0x8b, 0x0b};
+ /* Vector long enough to span a SHA384 block */
+ const char inMulti[] =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX"
+ "YZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX"
+ "YZ1234567890abcdefghi";
+ const uint8_t expectedOutMulti[WC_SHA384_DIGEST_SIZE] = {
+ 0xe2, 0x56, 0x2a, 0x4b, 0xe2, 0x0a, 0x40, 0x34, 0xc1, 0x23, 0x8b, 0x1d,
+ 0x68, 0x49, 0x17, 0xdb, 0x8d, 0x3a, 0x78, 0xab, 0x22, 0xf3, 0xa1, 0x51,
+ 0x70, 0xae, 0x26, 0x80, 0x06, 0x25, 0x99, 0xa5, 0x3d, 0x0f, 0xc3, 0x7a,
+ 0xbd, 0xe1, 0xe2, 0xc6, 0x07, 0xdf, 0xd9, 0x6a, 0x89, 0xa8, 0x2b, 0x99};
+ /* Initialize SHA384 structure */
+ ret = wc_InitSha384_ex(sha384, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitSha384 on devId 0x%X: %d\n", devId,
+ ret);
+ }
+ else {
+ /* Test SHA384on a single block worth of data. Should trigger a server
+ * transaction */
+ ret = wc_Sha384Update(sha384, (const byte*)inOne, WC_SHA384_BLOCK_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha384Update %d\n", ret);
+ }
+ else {
+ /* Finalize should trigger a server transaction with empty buffer */
+ ret = wc_Sha384Final(sha384, out);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha384Final %d\n", ret);
+ }
+ else {
+ /* Compare the computed hash with the expected output */
+ if (memcmp(out, expectedOutOne, WC_SHA384_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA384 hash does not match expected.\n");
+ ret = -1;
+ }
+ memset(out, 0, WC_SHA384_DIGEST_SIZE);
+ }
+ }
+ /* Reset state for multi block test */
+ (void)wc_Sha384Free(sha384);
+ }
+ if (ret == 0) {
+ /* Multiblock test */
+ ret = wc_InitSha384_ex(sha384, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitSha384 for devId 0x%X: %d\n",
+ devId, ret);
+ }
+ else {
+ /* Update with a non-block aligned length. Will not trigger server
+ * transaction */
+ ret = wc_Sha384Update(sha384, (const byte*)inMulti, 1);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha384Update (first) %d\n", ret);
+ }
+ else {
+ /* Update with a full block, will trigger block to be sent to
+ * server and one additional byte to be buffered */
+ ret = wc_Sha384Update(sha384, (const byte*)inMulti + 1,
+ WC_SHA384_BLOCK_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha384Update (mid) %d\n", ret);
+ }
+ else {
+ /* Update with the remaining data, should not trigger server
+ * transaction */
+ ret = wc_Sha384Update(
+ sha384, (const byte*)inMulti + 1 + WC_SHA384_BLOCK_SIZE,
+ strlen(inMulti) - 1 - WC_SHA384_BLOCK_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha384Update (last) %d\n",
+ ret);
+ }
+ else {
+ /* Finalize should trigger a server transaction on the
+ * remaining partial buffer */
+ ret = wc_Sha384Final(sha384, out);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha384Final %d\n",
+ ret);
+ }
+ else {
+ /* Compare the computed hash with the expected
+ * output */
+ if (memcmp(out, expectedOutMulti,
+ WC_SHA384_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA384 hash does not match the "
+ "expected output.\n");
+ ret = -1;
+ }
+ }
+ }
+ }
+ }
+ (void)wc_Sha384Free(sha384);
+ }
+ }
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA384 DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+/* Hash a buffer with a pure-software SHA384 (no devId) so we can compare. */
+static int whTest_Sha384Reference(const uint8_t* in, uint32_t inLen,
+ uint8_t out[WC_SHA384_DIGEST_SIZE])
+{
+ wc_Sha384 sw[1];
+ int ret = wc_InitSha384_ex(sw, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wc_Sha384Update(sw, in, inLen);
+ }
+ if (ret == 0) {
+ ret = wc_Sha384Final(sw, out);
+ }
+ (void)wc_Sha384Free(sw);
+ return ret;
+}
+
+/* Drive the new multi-block wire format through the blocking wrapper. Tests:
+ * - large multi-request input,
+ * - exact per-call inline capacity boundary,
+ * - one-byte-over-capacity boundary (forces a tail in the client buffer),
+ * - non-aligned chunked update sequence.
+ *
+ * Buffer is sized to comfortably exceed the per-call inline capacity at any
+ * reasonable comm-buffer size. We use a static buffer to keep stack pressure
+ * low under ASAN. */
+static uint8_t
+ whTest_Sha384BigBuf[2 *
+ (WH_MESSAGE_CRYPTO_SHA384_MAX_INLINE_UPDATE_SZ + 128u)];
+
+static int whTest_CryptoSha384LargeInputImpl(whClientContext* ctx, int devId,
+ WC_RNG* rng)
+{
+ int ret = WH_ERROR_OK;
+ wc_Sha384 sha384[1];
+ uint8_t out[WC_SHA384_DIGEST_SIZE];
+ uint8_t ref[WC_SHA384_DIGEST_SIZE];
+ uint8_t* buf = whTest_Sha384BigBuf;
+ uint32_t BUFSZ = (uint32_t)sizeof(whTest_Sha384BigBuf);
+ uint32_t i;
+
+ (void)ctx;
+ (void)rng;
+
+ for (i = 0; i < BUFSZ; i++) {
+ buf[i] = (uint8_t)(i & 0xff);
+ }
+
+ /* Test 1: large single-update */
+ ret = wc_InitSha384_ex(sha384, NULL, devId);
+ if (ret == 0) {
+ ret = wc_Sha384Update(sha384, buf, BUFSZ);
+ }
+ if (ret == 0) {
+ ret = wc_Sha384Final(sha384, out);
+ }
+ (void)wc_Sha384Free(sha384);
+ if (ret == 0) {
+ ret = whTest_Sha384Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA384_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA384 large input mismatch\n");
+ ret = -1;
+ }
+
+ /* Test 2: exactly the per-call inline capacity in one shot */
+ if (ret == 0) {
+ const uint32_t cap = WH_MESSAGE_CRYPTO_SHA384_MAX_INLINE_UPDATE_SZ;
+ ret = wc_InitSha384_ex(sha384, NULL, devId);
+ if (ret == 0) {
+ ret = wc_Sha384Update(sha384, buf, cap);
+ }
+ if (ret == 0) {
+ ret = wc_Sha384Final(sha384, out);
+ }
+ (void)wc_Sha384Free(sha384);
+ if (ret == 0) {
+ ret = whTest_Sha384Reference(buf, cap, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA384_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA384 capacity-boundary mismatch\n");
+ ret = -1;
+ }
+ }
+
+ /* Test 3: capacity + 1 byte (one full request, then a tail buffered) */
+ if (ret == 0) {
+ const uint32_t cap1 =
+ WH_MESSAGE_CRYPTO_SHA384_MAX_INLINE_UPDATE_SZ + 1u;
+ ret = wc_InitSha384_ex(sha384, NULL, devId);
+ if (ret == 0) {
+ ret = wc_Sha384Update(sha384, buf, cap1);
+ }
+ if (ret == 0) {
+ ret = wc_Sha384Final(sha384, out);
+ }
+ (void)wc_Sha384Free(sha384);
+ if (ret == 0) {
+ ret = whTest_Sha384Reference(buf, cap1, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA384_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA384 capacity+1 mismatch\n");
+ ret = -1;
+ }
+ }
+
+ /* Test 4: non-aligned chunk stress test */
+ if (ret == 0) {
+ const uint32_t chunks[] = {13, 17, 1280, 41, 1};
+ const size_t nChunks = sizeof(chunks) / sizeof(chunks[0]);
+ uint32_t total = 0;
+ size_t k;
+ for (k = 0; k < nChunks; k++) {
+ total += chunks[k];
+ }
+ if (total > BUFSZ) {
+ WH_ERROR_PRINT("test buffer too small for chunked stress test\n");
+ ret = -1;
+ }
+ if (ret == 0) {
+ uint32_t off = 0;
+ ret = wc_InitSha384_ex(sha384, NULL, devId);
+ for (k = 0; ret == 0 && k < nChunks; k++) {
+ ret = wc_Sha384Update(sha384, buf + off, chunks[k]);
+ off += chunks[k];
+ }
+ if (ret == 0) {
+ ret = wc_Sha384Final(sha384, out);
+ }
+ (void)wc_Sha384Free(sha384);
+ if (ret == 0) {
+ ret = whTest_Sha384Reference(buf, total, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA384_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA384 chunked stress mismatch\n");
+ ret = -1;
+ }
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA384 LARGE-INPUT DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+/* Direct exercise of the new async non-DMA SHA384 primitives. */
+static int whTest_CryptoSha384AsyncImpl(whClientContext* ctx, int devId,
+ WC_RNG* rng)
+{
+ int ret = WH_ERROR_OK;
+ wc_Sha384 sha384[1];
+ uint8_t out[WC_SHA384_DIGEST_SIZE];
+ uint8_t ref[WC_SHA384_DIGEST_SIZE];
+ /* Use the same large static buffer as the LargeInput test. */
+ uint8_t* buf = whTest_Sha384BigBuf;
+ uint32_t BUFSZ = (uint32_t)sizeof(whTest_Sha384BigBuf);
+ uint32_t i;
+ bool sent;
+
+ (void)rng;
+
+ for (i = 0; i < BUFSZ; i++) {
+ buf[i] = (uint8_t)((i * 31u + 7u) & 0xff);
+ }
+
+ /* Case A: basic UpdateRequest -> UpdateResponse -> Final */
+ ret = wc_InitSha384_ex(sha384, NULL, devId);
+ if (ret == 0) {
+ sent = false;
+ ret = wh_Client_Sha384UpdateRequest(ctx, sha384, buf, 256, &sent);
+ }
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha384UpdateResponse(ctx, sha384);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha384FinalRequest(ctx, sha384);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha384FinalResponse(ctx, sha384, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = whTest_Sha384Reference(buf, 256, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA384_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async SHA384 case A mismatch\n");
+ ret = -1;
+ }
+
+ /* Case B: pure-buffer-fill update (sent must be false), then finalize */
+ if (ret == 0) {
+ (void)wc_Sha384Free(sha384);
+ ret = wc_InitSha384_ex(sha384, NULL, devId);
+ }
+ if (ret == 0) {
+ sent = true; /* expect to be cleared to false */
+ ret = wh_Client_Sha384UpdateRequest(ctx, sha384, buf, 10, &sent);
+ if (ret == 0 && sent != false) {
+ WH_ERROR_PRINT(
+ "Async SHA384: expected sent==false on small update\n");
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha384FinalRequest(ctx, sha384);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha384FinalResponse(ctx, sha384, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = whTest_Sha384Reference(buf, 10, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA384_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async SHA384 case B mismatch\n");
+ ret = -1;
+ }
+
+ /* Case C: multi-round async updates that span more than the per-call
+ * inline capacity (forces multiple Request/Response pairs). */
+ if (ret == 0) {
+ uint32_t consumed = 0;
+ (void)wc_Sha384Free(sha384);
+ ret = wc_InitSha384_ex(sha384, NULL, devId);
+ while (ret == 0 && consumed < BUFSZ) {
+ /* arbitrary, 70% of max inline */
+ uint32_t chunk =
+ (WH_MESSAGE_CRYPTO_SHA384_MAX_INLINE_UPDATE_SZ * 7 / 10);
+ if (consumed + chunk > BUFSZ) {
+ chunk = BUFSZ - consumed;
+ }
+ sent = false;
+ ret = wh_Client_Sha384UpdateRequest(ctx, sha384, buf + consumed,
+ chunk, &sent);
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha384UpdateResponse(ctx, sha384);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ consumed += chunk;
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha384FinalRequest(ctx, sha384);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha384FinalResponse(ctx, sha384, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = whTest_Sha384Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA384_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async SHA384 case C mismatch\n");
+ ret = -1;
+ }
+ }
+
+ /* Case D: oversized-input rejection. UpdateRequest with inLen > capacity
+ * must return BADARGS without mutating sha. */
+ if (ret == 0) {
+ uint8_t savedDigest[WC_SHA512_DIGEST_SIZE];
+ word32 savedBuffLen;
+ uint32_t cap;
+ int rc;
+ (void)wc_Sha384Free(sha384);
+ ret = wc_InitSha384_ex(sha384, NULL, devId);
+ if (ret == 0) {
+ memcpy(savedDigest, sha384->digest, WC_SHA512_DIGEST_SIZE);
+ savedBuffLen = sha384->buffLen;
+ cap = WH_MESSAGE_CRYPTO_SHA384_MAX_INLINE_UPDATE_SZ +
+ (uint32_t)(WC_SHA384_BLOCK_SIZE - 1u - sha384->buffLen);
+ sent = true;
+ rc = wh_Client_Sha384UpdateRequest(ctx, sha384, buf, cap + 1u,
+ &sent);
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT("Async SHA384: expected BADARGS, got %d\n", rc);
+ ret = -1;
+ }
+ else if (sent != false) {
+ WH_ERROR_PRINT(
+ "Async SHA384: sent should remain false on err\n");
+ ret = -1;
+ }
+ else if (sha384->buffLen != savedBuffLen ||
+ memcmp(sha384->digest, savedDigest,
+ WC_SHA512_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT(
+ "Async SHA384: state mutated on rejected call\n");
+ ret = -1;
+ }
+ }
+ (void)wc_Sha384Free(sha384);
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA384 ASYNC DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+#ifdef WOLFHSM_CFG_DMA
+/* Direct exercise of the new async DMA SHA384 primitives. */
+static int whTest_CryptoSha384DmaAsyncImpl(whClientContext* ctx, int devId,
+ WC_RNG* rng)
+{
+ int ret = WH_ERROR_OK;
+ wc_Sha384 sha384[1];
+ uint8_t out[WC_SHA384_DIGEST_SIZE];
+ uint8_t ref[WC_SHA384_DIGEST_SIZE];
+ /* DMA bypasses the comm buffer, so any size goes; reuse the shared
+ * static buffer to keep stack pressure low. */
+ uint8_t* buf = whTest_Sha384BigBuf;
+ uint32_t BUFSZ = (uint32_t)sizeof(whTest_Sha384BigBuf);
+ uint32_t i;
+
+ (void)rng;
+
+ for (i = 0; i < BUFSZ; i++) {
+ buf[i] = (uint8_t)((i * 17u + 3u) & 0xff);
+ }
+
+ /* Case A: single large DMA Update + Final */
+ ret = wc_InitSha384_ex(sha384, NULL, devId);
+ if (ret == 0) {
+ bool sent = false;
+ ret = wh_Client_Sha384DmaUpdateRequest(ctx, sha384, buf, BUFSZ, &sent);
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha384DmaUpdateResponse(ctx, sha384);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha384DmaFinalRequest(ctx, sha384);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha384DmaFinalResponse(ctx, sha384, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ (void)wc_Sha384Free(sha384);
+ if (ret == 0) {
+ ret = whTest_Sha384Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA384_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async DMA SHA384 case A mismatch\n");
+ ret = -1;
+ }
+
+ /* Case B: multiple DMA Update round-trips, then Final */
+ if (ret == 0) {
+ uint32_t consumed = 0;
+ ret = wc_InitSha384_ex(sha384, NULL, devId);
+ while (ret == 0 && consumed < BUFSZ) {
+ uint32_t chunk = 1024;
+ if (consumed + chunk > BUFSZ) {
+ chunk = BUFSZ - consumed;
+ }
+ {
+ bool sent = false;
+ ret = wh_Client_Sha384DmaUpdateRequest(
+ ctx, sha384, buf + consumed, chunk, &sent);
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha384DmaUpdateResponse(ctx, sha384);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ }
+ consumed += chunk;
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha384DmaFinalRequest(ctx, sha384);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha384DmaFinalResponse(ctx, sha384, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ (void)wc_Sha384Free(sha384);
+ if (ret == 0) {
+ ret = whTest_Sha384Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA384_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async DMA SHA384 case B mismatch\n");
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA384 DMA ASYNC DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+#endif /* WOLFHSM_CFG_DMA */
+
+int whTest_CryptoSha384(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha384Impl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+
+int whTest_CryptoSha384LargeInput(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha384LargeInputImpl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+
+int whTest_CryptoSha384Async(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha384AsyncImpl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+
+#ifdef WOLFHSM_CFG_DMA
+int whTest_CryptoSha384DmaAsync(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha384DmaAsyncImpl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+#endif /* WOLFHSM_CFG_DMA */
+
+#endif /* WOLFSSL_SHA384 */
+
+#ifdef WOLFSSL_SHA512
+static int whTest_CryptoSha512Impl(whClientContext* ctx, int devId, WC_RNG* rng)
+{
+ (void)ctx;
+ (void)rng; /* Not currently used */
+ int ret = WH_ERROR_OK;
+ wc_Sha512 sha512[1];
+ uint8_t out[WC_SHA512_DIGEST_SIZE];
+ /* Vector exactly one block size in length */
+ const char inOne[] =
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ const uint8_t expectedOutOne[WC_SHA512_DIGEST_SIZE] = {
+ 0xb7, 0x3d, 0x19, 0x29, 0xaa, 0x61, 0x59, 0x34, 0xe6, 0x1a, 0x87,
+ 0x15, 0x96, 0xb3, 0xf3, 0xb3, 0x33, 0x59, 0xf4, 0x2b, 0x81, 0x75,
+ 0x60, 0x2e, 0x89, 0xf7, 0xe0, 0x6e, 0x5f, 0x65, 0x8a, 0x24, 0x36,
+ 0x67, 0x80, 0x7e, 0xd3, 0x00, 0x31, 0x4b, 0x95, 0xca, 0xcd, 0xd5,
+ 0x79, 0xf3, 0xe3, 0x3a, 0xbd, 0xfb, 0xe3, 0x51, 0x90, 0x95, 0x19,
+ 0xa8, 0x46, 0xd4, 0x65, 0xc5, 0x95, 0x82, 0xf3, 0x21};
+ /* Vector long enough to span a SHA512 block */
+ const char inMulti[] =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX"
+ "YZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX"
+ "YZ1234567890abcdefghi";
+ const uint8_t expectedOutMulti[WC_SHA512_DIGEST_SIZE] = {
+ 0xf9, 0x09, 0xb7, 0xb7, 0x7d, 0xa2, 0x32, 0xc8, 0xcf, 0xa8, 0xcc,
+ 0xde, 0xc4, 0x36, 0x44, 0x74, 0x29, 0x4f, 0xc4, 0x9a, 0xcb, 0x60,
+ 0x13, 0x6b, 0xdb, 0x10, 0xd6, 0xa6, 0x9d, 0x1b, 0x45, 0xb2, 0x70,
+ 0xf5, 0x27, 0x9c, 0xe7, 0x80, 0x99, 0x19, 0x9b, 0x91, 0xb3, 0x83,
+ 0x7f, 0x70, 0xaf, 0x8e, 0x02, 0xd9, 0x6d, 0x20, 0xab, 0x1e, 0x72,
+ 0xde, 0x7a, 0x25, 0xa3, 0xe5, 0x60, 0x9e, 0xb0, 0x43};
+ /* Initialize SHA512 structure */
+ ret = wc_InitSha512_ex(sha512, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitSha512 on devId 0x%X: %d\n", devId,
+ ret);
+ }
+ else {
+ /* Test SHA512 on a single block worth of data. Should trigger a server
+ * transaction */
+ ret = wc_Sha512Update(sha512, (const byte*)inOne, WC_SHA512_BLOCK_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha512Update %d\n", ret);
+ }
+ else {
+ /* Finalize should trigger a server transaction with empty buffer */
+ ret = wc_Sha512Final(sha512, out);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha512Final %d\n", ret);
+ }
+ else {
+ /* Compare the computed hash with the expected output */
+ if (memcmp(out, expectedOutOne, WC_SHA512_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA512 hash does not match expected.\n");
+ ret = -1;
+ }
+ memset(out, 0, WC_SHA512_DIGEST_SIZE);
+ }
+ }
+ /* Reset state for multi block test */
+ (void)wc_Sha512Free(sha512);
+ }
+ if (ret == 0) {
+ /* Multiblock test */
+ ret = wc_InitSha512_ex(sha512, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitSha512 for devId 0x%X: %d\n",
+ devId, ret);
+ }
+ else {
+ /* Update with a non-block aligned length. Will not trigger server
+ * transaction */
+ ret = wc_Sha512Update(sha512, (const byte*)inMulti, 1);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha512Update (first) %d\n", ret);
+ }
+ else {
+ /* Update with a full block, will trigger block to be sent to
+ * server and one additional byte to be buffered */
+ ret = wc_Sha512Update(sha512, (const byte*)inMulti + 1,
+ WC_SHA512_BLOCK_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha512Update (mid) %d\n", ret);
+ }
+ else {
+ /* Update with the remaining data, should not trigger server
+ * transaction */
+ ret = wc_Sha512Update(
+ sha512, (const byte*)inMulti + 1 + WC_SHA512_BLOCK_SIZE,
+ strlen(inMulti) - 1 - WC_SHA512_BLOCK_SIZE);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha512Update (last) %d\n",
+ ret);
+ }
+ else {
+ /* Finalize should trigger a server transaction on the
+ * remaining partial buffer */
+ ret = wc_Sha512Final(sha512, out);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_Sha512Final %d\n",
+ ret);
+ }
+ else {
+ /* Compare the computed hash with the expected
+ * output */
+ if (memcmp(out, expectedOutMulti,
+ WC_SHA512_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA512 hash does not match the "
+ "expected output.\n");
+ ret = -1;
+ }
+ }
+ }
+ }
+ }
+ (void)wc_Sha512Free(sha512);
+ }
+ }
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA512 DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+/* Hash a buffer with a pure-software SHA512 (no devId) so we can compare. */
+static int whTest_Sha512Reference(const uint8_t* in, uint32_t inLen,
+ uint8_t out[WC_SHA512_DIGEST_SIZE])
+{
+ wc_Sha512 sw[1];
+ int ret = wc_InitSha512_ex(sw, NULL, INVALID_DEVID);
+ if (ret == 0) {
+ ret = wc_Sha512Update(sw, in, inLen);
+ }
+ if (ret == 0) {
+ ret = wc_Sha512Final(sw, out);
+ }
+ (void)wc_Sha512Free(sw);
+ return ret;
+}
+
+/* Drive the new multi-block wire format through the blocking wrapper. Tests:
+ * - large multi-request input,
+ * - exact per-call inline capacity boundary,
+ * - one-byte-over-capacity boundary (forces a tail in the client buffer),
+ * - non-aligned chunked update sequence.
+ *
+ * Buffer is sized to comfortably exceed the per-call inline capacity at any
+ * reasonable comm-buffer size. We use a static buffer to keep stack pressure
+ * low under ASAN. */
+static uint8_t
+ whTest_Sha512BigBuf[2 *
+ (WH_MESSAGE_CRYPTO_SHA512_MAX_INLINE_UPDATE_SZ + 128u)];
+
+static int whTest_CryptoSha512LargeInputImpl(whClientContext* ctx, int devId,
+ WC_RNG* rng)
+{
+ int ret = WH_ERROR_OK;
+ wc_Sha512 sha512[1];
+ uint8_t out[WC_SHA512_DIGEST_SIZE];
+ uint8_t ref[WC_SHA512_DIGEST_SIZE];
+ uint8_t* buf = whTest_Sha512BigBuf;
+ uint32_t BUFSZ = (uint32_t)sizeof(whTest_Sha512BigBuf);
+ uint32_t i;
+
+ (void)ctx;
+ (void)rng;
+
+ for (i = 0; i < BUFSZ; i++) {
+ buf[i] = (uint8_t)(i & 0xff);
+ }
+
+ /* Test 1: large single-update */
+ ret = wc_InitSha512_ex(sha512, NULL, devId);
+ if (ret == 0) {
+ ret = wc_Sha512Update(sha512, buf, BUFSZ);
+ }
+ if (ret == 0) {
+ ret = wc_Sha512Final(sha512, out);
+ }
+ (void)wc_Sha512Free(sha512);
+ if (ret == 0) {
+ ret = whTest_Sha512Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA512_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA512 large input mismatch\n");
+ ret = -1;
+ }
+
+ /* Test 2: exactly the per-call inline capacity in one shot */
+ if (ret == 0) {
+ const uint32_t cap = WH_MESSAGE_CRYPTO_SHA512_MAX_INLINE_UPDATE_SZ;
+ ret = wc_InitSha512_ex(sha512, NULL, devId);
+ if (ret == 0) {
+ ret = wc_Sha512Update(sha512, buf, cap);
+ }
+ if (ret == 0) {
+ ret = wc_Sha512Final(sha512, out);
+ }
+ (void)wc_Sha512Free(sha512);
+ if (ret == 0) {
+ ret = whTest_Sha512Reference(buf, cap, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA512_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA512 capacity-boundary mismatch\n");
+ ret = -1;
+ }
+ }
+
+ /* Test 3: capacity + 1 byte (one full request, then a tail buffered) */
+ if (ret == 0) {
+ const uint32_t cap1 =
+ WH_MESSAGE_CRYPTO_SHA512_MAX_INLINE_UPDATE_SZ + 1u;
+ ret = wc_InitSha512_ex(sha512, NULL, devId);
+ if (ret == 0) {
+ ret = wc_Sha512Update(sha512, buf, cap1);
+ }
+ if (ret == 0) {
+ ret = wc_Sha512Final(sha512, out);
+ }
+ (void)wc_Sha512Free(sha512);
+ if (ret == 0) {
+ ret = whTest_Sha512Reference(buf, cap1, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA512_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA512 capacity+1 mismatch\n");
+ ret = -1;
+ }
+ }
+
+ /* Test 4: non-aligned chunk stress test */
+ if (ret == 0) {
+ const uint32_t chunks[] = {13, 17, 1280, 41, 1};
+ const size_t nChunks = sizeof(chunks) / sizeof(chunks[0]);
+ uint32_t total = 0;
+ size_t k;
+ for (k = 0; k < nChunks; k++) {
+ total += chunks[k];
+ }
+ if (total > BUFSZ) {
+ WH_ERROR_PRINT("test buffer too small for chunked stress test\n");
+ ret = -1;
+ }
+ if (ret == 0) {
+ uint32_t off = 0;
+ ret = wc_InitSha512_ex(sha512, NULL, devId);
+ for (k = 0; ret == 0 && k < nChunks; k++) {
+ ret = wc_Sha512Update(sha512, buf + off, chunks[k]);
+ off += chunks[k];
+ }
+ if (ret == 0) {
+ ret = wc_Sha512Final(sha512, out);
+ }
+ (void)wc_Sha512Free(sha512);
+ if (ret == 0) {
+ ret = whTest_Sha512Reference(buf, total, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA512_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("SHA512 chunked stress mismatch\n");
+ ret = -1;
+ }
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA512 LARGE-INPUT DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+/* Direct exercise of the new async non-DMA SHA512 primitives. */
+static int whTest_CryptoSha512AsyncImpl(whClientContext* ctx, int devId,
+ WC_RNG* rng)
+{
+ int ret = WH_ERROR_OK;
+ wc_Sha512 sha512[1];
+ uint8_t out[WC_SHA512_DIGEST_SIZE];
+ uint8_t ref[WC_SHA512_DIGEST_SIZE];
+ /* Use the same large static buffer as the LargeInput test. */
+ uint8_t* buf = whTest_Sha512BigBuf;
+ uint32_t BUFSZ = (uint32_t)sizeof(whTest_Sha512BigBuf);
+ uint32_t i;
+ bool sent;
+
+ (void)rng;
+
+ for (i = 0; i < BUFSZ; i++) {
+ buf[i] = (uint8_t)((i * 31u + 7u) & 0xff);
+ }
+
+ /* Case A: basic UpdateRequest -> UpdateResponse -> Final */
+ ret = wc_InitSha512_ex(sha512, NULL, devId);
+ if (ret == 0) {
+ sent = false;
+ ret = wh_Client_Sha512UpdateRequest(ctx, sha512, buf, 256, &sent);
+ }
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha512UpdateResponse(ctx, sha512);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha512FinalRequest(ctx, sha512);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha512FinalResponse(ctx, sha512, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = whTest_Sha512Reference(buf, 256, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA512_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async SHA512 case A mismatch\n");
+ ret = -1;
+ }
+
+ /* Case B: pure-buffer-fill update (sent must be false), then finalize */
+ if (ret == 0) {
+ (void)wc_Sha512Free(sha512);
+ ret = wc_InitSha512_ex(sha512, NULL, devId);
+ }
+ if (ret == 0) {
+ sent = true; /* expect to be cleared to false */
+ ret = wh_Client_Sha512UpdateRequest(ctx, sha512, buf, 10, &sent);
+ if (ret == 0 && sent != false) {
+ WH_ERROR_PRINT(
+ "Async SHA512: expected sent==false on small update\n");
+ ret = -1;
+ }
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha512FinalRequest(ctx, sha512);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha512FinalResponse(ctx, sha512, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = whTest_Sha512Reference(buf, 10, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA512_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async SHA512 case B mismatch\n");
+ ret = -1;
+ }
+
+ /* Case C: multi-round async updates that span more than the per-call
+ * inline capacity (forces multiple Request/Response pairs). */
+ if (ret == 0) {
+ uint32_t consumed = 0;
+ (void)wc_Sha512Free(sha512);
+ ret = wc_InitSha512_ex(sha512, NULL, devId);
+ while (ret == 0 && consumed < BUFSZ) {
+ /* arbitrary, 70% of max inline */
+ uint32_t chunk =
+ (WH_MESSAGE_CRYPTO_SHA512_MAX_INLINE_UPDATE_SZ * 7 / 10);
+ if (consumed + chunk > BUFSZ) {
+ chunk = BUFSZ - consumed;
+ }
+ sent = false;
+ ret = wh_Client_Sha512UpdateRequest(ctx, sha512, buf + consumed,
+ chunk, &sent);
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha512UpdateResponse(ctx, sha512);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ consumed += chunk;
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha512FinalRequest(ctx, sha512);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha512FinalResponse(ctx, sha512, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ if (ret == 0) {
+ ret = whTest_Sha512Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA512_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async SHA512 case C mismatch\n");
+ ret = -1;
+ }
+ }
+
+ /* Case D: oversized-input rejection. UpdateRequest with inLen > capacity
+ * must return BADARGS without mutating sha. */
+ if (ret == 0) {
+ uint8_t savedDigest[WC_SHA512_DIGEST_SIZE];
+ word32 savedBuffLen;
+ uint32_t cap;
+ int rc;
+ (void)wc_Sha512Free(sha512);
+ ret = wc_InitSha512_ex(sha512, NULL, devId);
+ if (ret == 0) {
+ memcpy(savedDigest, sha512->digest, WC_SHA512_DIGEST_SIZE);
+ savedBuffLen = sha512->buffLen;
+ cap = WH_MESSAGE_CRYPTO_SHA512_MAX_INLINE_UPDATE_SZ +
+ (uint32_t)(WC_SHA512_BLOCK_SIZE - 1u - sha512->buffLen);
+ sent = true;
+ rc = wh_Client_Sha512UpdateRequest(ctx, sha512, buf, cap + 1u,
+ &sent);
+ if (rc != WH_ERROR_BADARGS) {
+ WH_ERROR_PRINT("Async SHA512: expected BADARGS, got %d\n", rc);
+ ret = -1;
+ }
+ else if (sent != false) {
+ WH_ERROR_PRINT(
+ "Async SHA512: sent should remain false on err\n");
+ ret = -1;
+ }
+ else if (sha512->buffLen != savedBuffLen ||
+ memcmp(sha512->digest, savedDigest,
+ WC_SHA512_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT(
+ "Async SHA512: state mutated on rejected call\n");
+ ret = -1;
+ }
+ }
+ (void)wc_Sha512Free(sha512);
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA512 ASYNC DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+
+#ifdef WOLFHSM_CFG_DMA
+/* Direct exercise of the new async DMA SHA512 primitives. */
+static int whTest_CryptoSha512DmaAsyncImpl(whClientContext* ctx, int devId,
+ WC_RNG* rng)
+{
+ int ret = WH_ERROR_OK;
+ wc_Sha512 sha512[1];
+ uint8_t out[WC_SHA512_DIGEST_SIZE];
+ uint8_t ref[WC_SHA512_DIGEST_SIZE];
+ /* DMA bypasses the comm buffer, so any size goes; reuse the shared
+ * static buffer to keep stack pressure low. */
+ uint8_t* buf = whTest_Sha512BigBuf;
+ uint32_t BUFSZ = (uint32_t)sizeof(whTest_Sha512BigBuf);
+ uint32_t i;
+
+ (void)rng;
+
+ for (i = 0; i < BUFSZ; i++) {
+ buf[i] = (uint8_t)((i * 17u + 3u) & 0xff);
+ }
+
+ /* Case A: single large DMA Update + Final */
+ ret = wc_InitSha512_ex(sha512, NULL, devId);
+ if (ret == 0) {
+ bool sent = false;
+ ret = wh_Client_Sha512DmaUpdateRequest(ctx, sha512, buf, BUFSZ, &sent);
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha512DmaUpdateResponse(ctx, sha512);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha512DmaFinalRequest(ctx, sha512);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha512DmaFinalResponse(ctx, sha512, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ (void)wc_Sha512Free(sha512);
+ if (ret == 0) {
+ ret = whTest_Sha512Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA512_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async DMA SHA512 case A mismatch\n");
+ ret = -1;
+ }
+
+ /* Case B: multiple DMA Update round-trips, then Final */
+ if (ret == 0) {
+ uint32_t consumed = 0;
+ ret = wc_InitSha512_ex(sha512, NULL, devId);
+ while (ret == 0 && consumed < BUFSZ) {
+ uint32_t chunk = 1024;
+ if (consumed + chunk > BUFSZ) {
+ chunk = BUFSZ - consumed;
+ }
+ {
+ bool sent = false;
+ ret = wh_Client_Sha512DmaUpdateRequest(
+ ctx, sha512, buf + consumed, chunk, &sent);
+ if (ret == 0 && sent) {
+ do {
+ ret = wh_Client_Sha512DmaUpdateResponse(ctx, sha512);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ }
+ consumed += chunk;
+ }
+ if (ret == 0) {
+ ret = wh_Client_Sha512DmaFinalRequest(ctx, sha512);
+ }
+ if (ret == 0) {
+ do {
+ ret = wh_Client_Sha512DmaFinalResponse(ctx, sha512, out);
+ } while (ret == WH_ERROR_NOTREADY);
+ }
+ (void)wc_Sha512Free(sha512);
+ if (ret == 0) {
+ ret = whTest_Sha512Reference(buf, BUFSZ, ref);
+ }
+ if (ret == 0 && memcmp(out, ref, WC_SHA512_DIGEST_SIZE) != 0) {
+ WH_ERROR_PRINT("Async DMA SHA512 case B mismatch\n");
+ ret = -1;
+ }
+ }
+
+ if (ret == 0) {
+ WH_TEST_PRINT("SHA512 DMA ASYNC DEVID=0x%X SUCCESS\n", devId);
+ }
+ return ret;
+}
+#endif /* WOLFHSM_CFG_DMA */
+
+int whTest_CryptoSha512(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha512Impl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+
+int whTest_CryptoSha512LargeInput(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha512LargeInputImpl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+
+int whTest_CryptoSha512Async(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha512AsyncImpl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+
+#ifdef WOLFHSM_CFG_DMA
+int whTest_CryptoSha512DmaAsync(whClientContext* ctx)
+{
+ int devId = WH_DEV_ID;
+ int ret;
+ WC_RNG rng[1];
+
+ ret = wc_InitRng_ex(rng, NULL, devId);
+ if (ret != 0) {
+ WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret);
+ return ret;
+ }
+ ret = whTest_CryptoSha512DmaAsyncImpl(ctx, devId, rng);
+ (void)wc_FreeRng(rng);
+ return ret;
+}
+#endif /* WOLFHSM_CFG_DMA */
+
+#endif /* WOLFSSL_SHA512 */
+
+#endif /* !WOLFHSM_CFG_NO_CRYPTO */
diff --git a/test-refactor/config/wolfhsm_cfg.h b/test-refactor/config/wolfhsm_cfg.h
new file mode 100644
index 00000000..ea8402ce
--- /dev/null
+++ b/test-refactor/config/wolfhsm_cfg.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2024 wolfSSL Inc.
+ *
+ * This file is part of wolfHSM.
+ *
+ * wolfHSM 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfHSM 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 wolfHSM. If not, see .
+ */
+/*
+ * wolfhsm_cfg.h
+ *
+ * wolfHSM compile-time options for the test-refactor suite. Sibling of
+ * test/config/wolfhsm_cfg.h; the two are intentionally allowed to diverge
+ * as the refactor matures.
+ */
+
+#ifndef WOLFHSM_CFG_H_
+#define WOLFHSM_CFG_H_
+
+#include "port/posix/posix_time.h"
+#define WOLFHSM_CFG_PORT_GETTIME posixGetTime
+
+
+/** wolfHSM settings. Simple overrides to show they work */
+/* #define WOLFHSM_CFG_NO_CRYPTO */
+/* #define WOLFHSM_CFG_SHE_EXTENSION */
+
+#define WOLFHSM_CFG_COMM_DATA_LEN (1024 * 8)
+
+/* Enable global keys feature for testing */
+#define WOLFHSM_CFG_GLOBAL_KEYS
+
+/* Enable logging feature for testing */
+#define WOLFHSM_CFG_LOGGING
+
+#define WOLFHSM_CFG_NVM_OBJECT_COUNT 30
+#define WOLFHSM_CFG_SERVER_KEYCACHE_COUNT 9
+#define WOLFHSM_CFG_SERVER_KEYCACHE_BUFSIZE 300
+#define WOLFHSM_CFG_SERVER_KEYCACHE_BIG_COUNT 3
+#define WOLFHSM_CFG_SERVER_KEYCACHE_BIG_BUFSIZE WOLFHSM_CFG_COMM_DATA_LEN
+#define WOLFHSM_CFG_DMAADDR_COUNT 8
+#define WOLFHSM_CFG_SERVER_CUSTOMCB_COUNT 6
+
+#define WOLFHSM_CFG_CERTIFICATE_MANAGER
+#define WOLFHSM_CFG_CERTIFICATE_MANAGER_ACERT
+
+/* Enable Image Manager feature */
+#define WOLFHSM_CFG_SERVER_IMG_MGR
+
+#ifndef WOLFHSM_CFG_NO_CRYPTO
+#define WOLFHSM_CFG_KEYWRAP
+#endif
+
+/* Test log-based NVM flash backend */
+#define WOLFHSM_CFG_SERVER_NVM_FLASH_LOG
+
+/* WOLFHSM_CFG_TEST_ALLOW_PERSISTENT_NVM_ARTIFACTS is intentionally NOT
+ * defined here. Persistent-artifact tests require working reset hooks
+ * (whTestPort_ResetServer/Client) which are no-ops today. */
+
+#define WOLFHSM_CFG_ENABLE_TIMEOUT
+
+#endif /* WOLFHSM_CFG_H_ */
diff --git a/test-refactor/posix/Makefile b/test-refactor/posix/Makefile
index c19267fd..760adb3e 100644
--- a/test-refactor/posix/Makefile
+++ b/test-refactor/posix/Makefile
@@ -12,6 +12,7 @@ BIN = wh_test_refactor
PROJECT_DIR ?= .
REFACTOR_DIR ?= $(PROJECT_DIR)/..
CONFIG_DIR ?= $(REFACTOR_DIR)/../test/config
+REFACTOR_CFG_DIR ?= $(REFACTOR_DIR)/config
WOLFSSL_DIR ?= ../../../wolfssl
WOLFHSM_DIR ?= $(REFACTOR_DIR)/..
WOLFHSM_PORT_DIR ?= $(WOLFHSM_DIR)/port/posix
@@ -25,6 +26,7 @@ INC = -I$(PROJECT_DIR) \
-I$(REFACTOR_DIR)/server \
-I$(REFACTOR_DIR)/client-server \
-I$(REFACTOR_DIR)/misc \
+ -I$(REFACTOR_CFG_DIR) \
-I$(CONFIG_DIR) \
-I$(TEST_DIR) \
-I$(WOLFSSL_DIR) \
diff --git a/test-refactor/wh_test_list.c b/test-refactor/wh_test_list.c
index 2867e82e..2fcdf87a 100644
--- a/test-refactor/wh_test_list.c
+++ b/test-refactor/wh_test_list.c
@@ -35,8 +35,48 @@
WH_TEST_DECL(whTest_Dma);
WH_TEST_DECL(whTest_CertVerify);
WH_TEST_DECL(whTest_CryptoAes);
-WH_TEST_DECL(whTest_CryptoEcc256);
+WH_TEST_DECL(whTest_CryptoCmac);
+WH_TEST_DECL(whTest_CryptoCmacKdf);
+WH_TEST_DECL(whTest_CryptoEcc);
+WH_TEST_DECL(whTest_CryptoEccAsync);
+WH_TEST_DECL(whTest_CryptoEccCacheDuplicate);
+WH_TEST_DECL(whTest_CryptoEccCrossVerify);
+WH_TEST_DECL(whTest_CryptoCurve25519);
+WH_TEST_DECL(whTest_CryptoCurve25519ExportPublicKey);
+WH_TEST_DECL(whTest_CryptoEccExportPublicKey);
+WH_TEST_DECL(whTest_CryptoEd25519Dma);
+WH_TEST_DECL(whTest_CryptoEd25519Inline);
+WH_TEST_DECL(whTest_CryptoEd25519ExportPublicKey);
+WH_TEST_DECL(whTest_CryptoEd25519ServerKey);
+WH_TEST_DECL(whTest_CryptoHkdf);
+WH_TEST_DECL(whTestCrypto_MlDsaClient);
+WH_TEST_DECL(whTestCrypto_MlDsaDmaClient);
+WH_TEST_DECL(whTestCrypto_MlDsaExportPublicKey);
+WH_TEST_DECL(whTestCrypto_MlDsaExportPublicKeyDma);
+WH_TEST_DECL(whTestCrypto_MlDsaVerifyOnlyDma);
+WH_TEST_DECL(whTest_CryptoKeyRevocationAesCbc);
+WH_TEST_DECL(whTest_CryptoKeyUsagePolicies);
+WH_TEST_DECL(whTest_CryptoRng);
+WH_TEST_DECL(whTest_CryptoRngAsync);
+WH_TEST_DECL(whTest_CryptoRngDmaAsync);
+WH_TEST_DECL(whTest_CryptoRsa);
+WH_TEST_DECL(whTest_CryptoRsaExportPublicKey);
+WH_TEST_DECL(whTest_CryptoSha224);
+WH_TEST_DECL(whTest_CryptoSha224Async);
+WH_TEST_DECL(whTest_CryptoSha224DmaAsync);
+WH_TEST_DECL(whTest_CryptoSha224LargeInput);
WH_TEST_DECL(whTest_CryptoSha256);
+WH_TEST_DECL(whTest_CryptoSha256Async);
+WH_TEST_DECL(whTest_CryptoSha256DmaAsync);
+WH_TEST_DECL(whTest_CryptoSha256LargeInput);
+WH_TEST_DECL(whTest_CryptoSha384);
+WH_TEST_DECL(whTest_CryptoSha384Async);
+WH_TEST_DECL(whTest_CryptoSha384DmaAsync);
+WH_TEST_DECL(whTest_CryptoSha384LargeInput);
+WH_TEST_DECL(whTest_CryptoSha512);
+WH_TEST_DECL(whTest_CryptoSha512Async);
+WH_TEST_DECL(whTest_CryptoSha512DmaAsync);
+WH_TEST_DECL(whTest_CryptoSha512LargeInput);
WH_TEST_DECL(whTest_Echo);
WH_TEST_DECL(whTest_ServerInfo);
WH_TEST_DECL(whTest_WolfCryptTest);
@@ -53,8 +93,52 @@ const size_t whTestsServerCount = sizeof(whTestsServer) / sizeof(whTestsServer[0
const whTestCase whTestsClient[] = {
{ "whTest_CryptoAes", whTest_CryptoAes },
- { "whTest_CryptoEcc256", whTest_CryptoEcc256 },
+ { "whTest_CryptoCmac", whTest_CryptoCmac },
+ { "whTest_CryptoCmacKdf", whTest_CryptoCmacKdf },
+ { "whTest_CryptoEcc", whTest_CryptoEcc },
+ { "whTest_CryptoEccAsync", whTest_CryptoEccAsync },
+ { "whTest_CryptoEccCacheDuplicate", whTest_CryptoEccCacheDuplicate },
+ { "whTest_CryptoEccCrossVerify", whTest_CryptoEccCrossVerify },
+ { "whTest_CryptoCurve25519", whTest_CryptoCurve25519 },
+ { "whTest_CryptoCurve25519ExportPublicKey",
+ whTest_CryptoCurve25519ExportPublicKey },
+ { "whTest_CryptoEccExportPublicKey", whTest_CryptoEccExportPublicKey },
+ { "whTest_CryptoEd25519Dma", whTest_CryptoEd25519Dma },
+ { "whTest_CryptoEd25519Inline", whTest_CryptoEd25519Inline },
+ { "whTest_CryptoEd25519ExportPublicKey",
+ whTest_CryptoEd25519ExportPublicKey },
+ { "whTest_CryptoEd25519ServerKey", whTest_CryptoEd25519ServerKey },
+ { "whTest_CryptoHkdf", whTest_CryptoHkdf },
+ { "whTestCrypto_MlDsaClient", whTestCrypto_MlDsaClient },
+ { "whTestCrypto_MlDsaDmaClient", whTestCrypto_MlDsaDmaClient },
+ { "whTestCrypto_MlDsaExportPublicKey",
+ whTestCrypto_MlDsaExportPublicKey },
+ { "whTestCrypto_MlDsaExportPublicKeyDma",
+ whTestCrypto_MlDsaExportPublicKeyDma },
+ { "whTestCrypto_MlDsaVerifyOnlyDma", whTestCrypto_MlDsaVerifyOnlyDma },
+ { "whTest_CryptoKeyRevocationAesCbc", whTest_CryptoKeyRevocationAesCbc },
+ { "whTest_CryptoKeyUsagePolicies", whTest_CryptoKeyUsagePolicies },
+ { "whTest_CryptoRng", whTest_CryptoRng },
+ { "whTest_CryptoRngAsync", whTest_CryptoRngAsync },
+ { "whTest_CryptoRngDmaAsync", whTest_CryptoRngDmaAsync },
+ { "whTest_CryptoRsa", whTest_CryptoRsa },
+ { "whTest_CryptoRsaExportPublicKey", whTest_CryptoRsaExportPublicKey },
+ { "whTest_CryptoSha224", whTest_CryptoSha224 },
+ { "whTest_CryptoSha224Async", whTest_CryptoSha224Async },
+ { "whTest_CryptoSha224DmaAsync", whTest_CryptoSha224DmaAsync },
+ { "whTest_CryptoSha224LargeInput", whTest_CryptoSha224LargeInput },
{ "whTest_CryptoSha256", whTest_CryptoSha256 },
+ { "whTest_CryptoSha256Async", whTest_CryptoSha256Async },
+ { "whTest_CryptoSha256DmaAsync", whTest_CryptoSha256DmaAsync },
+ { "whTest_CryptoSha256LargeInput", whTest_CryptoSha256LargeInput },
+ { "whTest_CryptoSha384", whTest_CryptoSha384 },
+ { "whTest_CryptoSha384Async", whTest_CryptoSha384Async },
+ { "whTest_CryptoSha384DmaAsync", whTest_CryptoSha384DmaAsync },
+ { "whTest_CryptoSha384LargeInput", whTest_CryptoSha384LargeInput },
+ { "whTest_CryptoSha512", whTest_CryptoSha512 },
+ { "whTest_CryptoSha512Async", whTest_CryptoSha512Async },
+ { "whTest_CryptoSha512DmaAsync", whTest_CryptoSha512DmaAsync },
+ { "whTest_CryptoSha512LargeInput", whTest_CryptoSha512LargeInput },
{ "whTest_Echo", whTest_Echo },
{ "whTest_ServerInfo", whTest_ServerInfo },
{ "whTest_WolfCryptTest", whTest_WolfCryptTest },
diff --git a/test/wh_test_cert_data.h b/test/wh_test_cert_data.h
index 78a794dd..5377375f 100644
--- a/test/wh_test_cert_data.h
+++ b/test/wh_test_cert_data.h
@@ -12,8 +12,8 @@
/* Chain A - Root CA Certificate (DER format) */
const unsigned char ROOT_A_CERT[] = {
0x30, 0x82, 0x05, 0xf9, 0x30, 0x82, 0x03, 0xe1, 0xa0, 0x03, 0x02, 0x01,
-0x02, 0x02, 0x14, 0x20, 0xf5, 0xb8, 0x5c, 0x10, 0x22, 0x90, 0xb1, 0x0b,
-0x12, 0x75, 0xf5, 0x4c, 0x5a, 0x9e, 0x45, 0x10, 0xf5, 0x4a, 0x1e, 0x30,
+0x02, 0x02, 0x14, 0x31, 0x22, 0xa6, 0xfd, 0x62, 0x99, 0xa2, 0x64, 0x72,
+0x27, 0x5c, 0xbf, 0xac, 0x29, 0x1c, 0x34, 0xe8, 0x2a, 0x02, 0x35, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x30, 0x81, 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
@@ -26,9 +26,9 @@ const unsigned char ROOT_A_CERT[] = {
0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x52, 0x6f, 0x6f, 0x74,
0x20, 0x43, 0x41, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03,
0x0c, 0x0e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x20, 0x52, 0x6f, 0x6f,
-0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x35,
-0x30, 0x38, 0x32, 0x32, 0x30, 0x37, 0x30, 0x39, 0x5a, 0x17, 0x0d, 0x33,
-0x35, 0x30, 0x35, 0x30, 0x36, 0x32, 0x32, 0x30, 0x37, 0x30, 0x39, 0x5a,
+0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x35,
+0x30, 0x39, 0x32, 0x31, 0x33, 0x35, 0x35, 0x30, 0x5a, 0x17, 0x0d, 0x33,
+0x36, 0x30, 0x35, 0x30, 0x36, 0x32, 0x31, 0x33, 0x35, 0x35, 0x30, 0x5a,
0x30, 0x81, 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69,
@@ -42,111 +42,111 @@ const unsigned char ROOT_A_CERT[] = {
0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
0x43, 0x41, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02,
-0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xcc,
-0x90, 0x43, 0xc0, 0x35, 0x2d, 0x51, 0x57, 0x06, 0xb7, 0x69, 0xfe, 0xb6,
-0xc0, 0x8f, 0xce, 0x47, 0xe1, 0x9e, 0x2c, 0x3c, 0x24, 0xea, 0x91, 0x55,
-0x16, 0x3a, 0x8c, 0x88, 0xc9, 0xd4, 0xa0, 0xac, 0x38, 0xc2, 0x03, 0x41,
-0x99, 0xb2, 0x9b, 0x7a, 0x0c, 0xdf, 0xbe, 0x78, 0x03, 0x85, 0x57, 0x5c,
-0xb5, 0xb1, 0xef, 0xf3, 0xff, 0xeb, 0xdd, 0xd8, 0x23, 0x6b, 0xee, 0xb2,
-0xa5, 0x3c, 0xcf, 0xcf, 0xf5, 0x58, 0xaa, 0x90, 0xa0, 0x18, 0x07, 0x29,
-0x84, 0xde, 0xb3, 0x48, 0x8a, 0xa9, 0x76, 0x61, 0xd1, 0xd8, 0xc1, 0x4c,
-0xb9, 0xc9, 0x68, 0x4a, 0x9a, 0x23, 0x4f, 0xcc, 0xa7, 0xd7, 0x33, 0xa0,
-0x6e, 0x8c, 0x8e, 0x85, 0x6e, 0x29, 0x4a, 0x72, 0xa2, 0xc1, 0x5e, 0x59,
-0x42, 0x43, 0x75, 0x5d, 0x8e, 0x5a, 0x55, 0x39, 0x28, 0x93, 0x5f, 0x85,
-0x44, 0x1c, 0xa7, 0x37, 0x85, 0xa7, 0xc1, 0xf6, 0xf8, 0xde, 0x2f, 0x8e,
-0x02, 0xd7, 0xff, 0x77, 0xd6, 0xc9, 0xc0, 0x2a, 0xea, 0xc0, 0x1b, 0xb0,
-0xf7, 0x17, 0x58, 0x8f, 0x0b, 0x77, 0x2b, 0x35, 0x07, 0xb0, 0x07, 0x8f,
-0xec, 0x49, 0x24, 0x59, 0x7d, 0xe7, 0xb0, 0x11, 0x2b, 0x03, 0x1b, 0x62,
-0xec, 0x3c, 0x4f, 0xd3, 0xcc, 0x22, 0x54, 0xe0, 0x75, 0xe6, 0x3e, 0x3e,
-0x88, 0x28, 0x85, 0x94, 0xc4, 0xf7, 0x5f, 0x6b, 0xef, 0x55, 0xc5, 0x00,
-0x37, 0xd3, 0xcb, 0x9d, 0x6b, 0xc8, 0x70, 0xd7, 0x91, 0x57, 0xf8, 0xb0,
-0x40, 0x4b, 0x54, 0x9a, 0x14, 0xcc, 0x0e, 0x06, 0x0c, 0x49, 0x40, 0x54,
-0x58, 0x1b, 0xee, 0xea, 0x55, 0xfd, 0x20, 0xf5, 0x49, 0x07, 0xb1, 0xe4,
-0x0a, 0xa1, 0xbc, 0x5b, 0x02, 0x7b, 0xab, 0x0d, 0xed, 0x47, 0xda, 0xa7,
-0x52, 0xe4, 0xb3, 0xab, 0x25, 0x3d, 0x02, 0x38, 0x21, 0xc9, 0x86, 0xe9,
-0x7c, 0xc1, 0x2e, 0xd5, 0xf6, 0x5a, 0xfe, 0x57, 0x88, 0xe4, 0xd5, 0xef,
-0xf3, 0x7f, 0xf5, 0xf0, 0xd4, 0x9a, 0xda, 0xaa, 0xac, 0xfd, 0xd2, 0x91,
-0x40, 0xc4, 0xd8, 0xb4, 0xa8, 0xd2, 0x48, 0x34, 0x9a, 0xb2, 0x44, 0xf2,
-0x3c, 0x9b, 0x24, 0xc3, 0x5d, 0x2c, 0xb9, 0x75, 0x5b, 0xd0, 0x5d, 0x1c,
-0x4f, 0x74, 0x9b, 0xd2, 0x9c, 0xcf, 0x69, 0x17, 0x00, 0x49, 0x4b, 0x90,
-0x82, 0x04, 0xa3, 0x94, 0xe3, 0x1c, 0x28, 0x5d, 0xb1, 0x33, 0x3a, 0xf5,
-0xff, 0x20, 0xa9, 0xb6, 0x80, 0x04, 0xaa, 0x10, 0x57, 0x32, 0x0b, 0x4f,
-0x2b, 0x8c, 0xe8, 0xac, 0xeb, 0x98, 0xf7, 0x25, 0x9f, 0x99, 0xc0, 0x4d,
-0xcc, 0xa3, 0x50, 0xcc, 0xad, 0x19, 0x74, 0xf8, 0x64, 0x16, 0x94, 0xcd,
-0x1d, 0x04, 0x13, 0x9f, 0x93, 0x04, 0x58, 0x75, 0x24, 0x34, 0x31, 0x31,
-0xa0, 0x41, 0xc5, 0xb6, 0xf2, 0xae, 0x77, 0xa5, 0x19, 0xb8, 0x34, 0xbe,
-0x64, 0xef, 0x7b, 0x94, 0x65, 0x8b, 0x60, 0x93, 0x07, 0x22, 0x31, 0x91,
-0x56, 0x11, 0x35, 0xa0, 0x7c, 0x40, 0x90, 0x18, 0x6d, 0xd0, 0xee, 0xed,
-0x5c, 0x1a, 0x69, 0x29, 0x80, 0x80, 0xa5, 0x44, 0x84, 0x9c, 0x83, 0x4c,
-0x33, 0xca, 0x29, 0xc5, 0x65, 0xb5, 0xc4, 0x16, 0xa2, 0xf1, 0xc4, 0xe3,
-0x20, 0x10, 0x66, 0x06, 0xff, 0x6e, 0x8c, 0x1e, 0x6a, 0x10, 0x60, 0x00,
-0x2b, 0x85, 0x22, 0x74, 0x92, 0x0f, 0xe7, 0x74, 0x97, 0x7f, 0x1c, 0xed,
-0x90, 0xa1, 0x3c, 0xbf, 0x95, 0xe9, 0x76, 0x55, 0x70, 0x07, 0xd6, 0xcc,
-0x17, 0x09, 0x00, 0x06, 0x75, 0x90, 0xf0, 0x84, 0x71, 0x33, 0x1b, 0xa7,
-0xa0, 0x31, 0xb3, 0x47, 0x66, 0xba, 0x70, 0xa9, 0xaf, 0xd6, 0x5e, 0x24,
-0x16, 0x48, 0xd0, 0x0c, 0x99, 0x48, 0xec, 0x9c, 0x49, 0x1a, 0xaf, 0xc7,
-0x2b, 0x4c, 0xd9, 0xfc, 0xee, 0xd1, 0x4b, 0x02, 0x03, 0x01, 0x00, 0x01,
+0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0x97,
+0x4e, 0xe6, 0xde, 0x52, 0x53, 0xab, 0xb4, 0x2e, 0xbc, 0x48, 0x45, 0xec,
+0x6a, 0xd3, 0xa5, 0x6b, 0x72, 0x4c, 0xf0, 0x8d, 0xe2, 0xbc, 0x50, 0x52,
+0xa6, 0xbb, 0xb9, 0xa3, 0xf8, 0x2c, 0x65, 0x05, 0x02, 0xa8, 0xb9, 0xeb,
+0xd9, 0x46, 0x21, 0xc7, 0x5a, 0xc9, 0x2c, 0x5a, 0x85, 0xea, 0xf9, 0xa5,
+0x80, 0xc0, 0xfd, 0xd3, 0x22, 0xe4, 0x8c, 0x2b, 0x56, 0x03, 0x7a, 0xde,
+0x07, 0xf3, 0x83, 0xff, 0x08, 0x14, 0xb2, 0xd3, 0xad, 0xfe, 0x04, 0x4c,
+0xee, 0x17, 0xf0, 0x36, 0x19, 0x6f, 0xc0, 0x7d, 0x70, 0x51, 0x0e, 0x14,
+0x1f, 0x49, 0xf6, 0xb7, 0x34, 0x4d, 0x61, 0x1d, 0x4e, 0xa8, 0x03, 0x0e,
+0x4c, 0x17, 0xd4, 0xc7, 0x7b, 0xd0, 0x37, 0x2a, 0x65, 0x7c, 0x7c, 0xed,
+0x04, 0x31, 0x93, 0x3d, 0x6f, 0x4d, 0x28, 0xcd, 0xf6, 0xfb, 0x9e, 0xdb,
+0xb1, 0x24, 0xf6, 0xe7, 0xa3, 0x80, 0x5b, 0x7b, 0x13, 0xad, 0x33, 0x50,
+0xe5, 0xbe, 0x95, 0x2f, 0xd0, 0xfe, 0xf7, 0xa5, 0xf2, 0xae, 0xa2, 0x9f,
+0x1a, 0x21, 0xfd, 0x81, 0xc2, 0xb5, 0xaa, 0x3d, 0x78, 0x4a, 0xc6, 0x54,
+0x4b, 0x12, 0x25, 0x40, 0x48, 0xc8, 0xa6, 0x9f, 0xa5, 0x46, 0xc6, 0x9b,
+0x7f, 0x56, 0xb6, 0x73, 0x22, 0xc4, 0x08, 0x15, 0x64, 0xda, 0xab, 0xf8,
+0x48, 0x0f, 0xfd, 0x18, 0xa1, 0x33, 0x03, 0xd3, 0xd5, 0xfb, 0x41, 0x8a,
+0x00, 0x63, 0x22, 0x55, 0x43, 0xba, 0x04, 0x46, 0x2d, 0x6e, 0x24, 0xec,
+0x64, 0x0a, 0xcc, 0x8c, 0x70, 0x3d, 0x2f, 0x32, 0x65, 0xa4, 0xa5, 0x71,
+0x73, 0x3e, 0xca, 0x0e, 0xd0, 0xf2, 0xfe, 0xa5, 0x9e, 0x6d, 0x73, 0xa4,
+0xec, 0x76, 0x30, 0x1f, 0xe6, 0xb4, 0xf7, 0x0f, 0x5b, 0xf1, 0xad, 0x64,
+0x22, 0xfe, 0x7f, 0xc8, 0x7b, 0xdd, 0xd1, 0x9b, 0xbe, 0x6b, 0x4e, 0xa5,
+0xd2, 0xce, 0x9b, 0x0c, 0x2f, 0x4e, 0x64, 0xc4, 0xd7, 0x16, 0x14, 0xbc,
+0xd2, 0x75, 0xf5, 0x32, 0x36, 0x24, 0x45, 0xd8, 0xe1, 0x9c, 0x13, 0x3d,
+0x6b, 0xd6, 0x6e, 0x70, 0x4b, 0x35, 0x3d, 0xdb, 0xa1, 0x47, 0x3a, 0x76,
+0x58, 0x9f, 0x5d, 0x1c, 0xfc, 0xc4, 0x44, 0xf3, 0xa5, 0xd9, 0xc4, 0x0c,
+0xb2, 0xc9, 0x63, 0x9e, 0xa0, 0x1a, 0x35, 0x2f, 0x2b, 0xd5, 0x88, 0x4d,
+0x01, 0x2b, 0xa0, 0x8f, 0x96, 0x2a, 0xf4, 0xe3, 0x66, 0x24, 0x27, 0xd4,
+0x25, 0xe1, 0x95, 0x6f, 0x9c, 0xb8, 0x80, 0xd0, 0x34, 0xa1, 0xc7, 0x8c,
+0x53, 0x1f, 0xba, 0x3c, 0x0e, 0x15, 0x7d, 0x4c, 0x0e, 0xec, 0xa2, 0x3a,
+0xcf, 0x90, 0x98, 0x05, 0x7b, 0xef, 0x88, 0x44, 0xdb, 0xd0, 0x46, 0x26,
+0x02, 0x32, 0xaf, 0xee, 0x9f, 0x71, 0x76, 0x4c, 0x10, 0x79, 0xd0, 0xab,
+0xe1, 0xa8, 0xea, 0xf6, 0xd9, 0x82, 0xa9, 0x75, 0x3f, 0x1d, 0x4e, 0x72,
+0xec, 0xa0, 0xdf, 0xcb, 0xf7, 0x14, 0xb5, 0xd2, 0x9a, 0x36, 0x52, 0xcd,
+0x1c, 0x02, 0xda, 0xa4, 0x22, 0x0e, 0x08, 0x62, 0x29, 0xcc, 0xa3, 0x78,
+0x2a, 0xbd, 0xa4, 0xd3, 0x46, 0x56, 0xed, 0x24, 0x32, 0xfa, 0x56, 0xad,
+0x6a, 0x4a, 0xc1, 0xde, 0xc5, 0x28, 0x21, 0xb5, 0x49, 0x70, 0x0c, 0x60,
+0x7b, 0xbf, 0x4d, 0x5a, 0xf1, 0x9d, 0x32, 0xc3, 0x79, 0x2e, 0x4f, 0xea,
+0x58, 0x33, 0x62, 0xbf, 0xd7, 0x61, 0xc4, 0xd3, 0x01, 0x3e, 0x8b, 0xd2,
+0xa0, 0x47, 0xfe, 0x2a, 0x97, 0xd9, 0x77, 0x10, 0x9f, 0x06, 0xee, 0x34,
+0xc6, 0xd9, 0xc9, 0x71, 0xf1, 0x45, 0x25, 0x02, 0xda, 0xe5, 0x1f, 0x4c,
+0x00, 0x77, 0x71, 0xd1, 0x25, 0xcf, 0xf7, 0x7c, 0xc2, 0xf2, 0xc0, 0xe8,
+0x5e, 0x10, 0xea, 0xed, 0xf9, 0xf9, 0x52, 0x3e, 0xec, 0xe5, 0x27, 0x0c,
+0x2c, 0x2d, 0x4e, 0xa0, 0x78, 0x62, 0x31, 0x02, 0x03, 0x01, 0x00, 0x01,
0xa3, 0x63, 0x30, 0x61, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
-0x16, 0x04, 0x14, 0xb6, 0x3c, 0x52, 0x3c, 0x43, 0x68, 0x11, 0x95, 0x13,
-0x8c, 0x57, 0x2e, 0x17, 0x0f, 0xc3, 0x96, 0x13, 0x86, 0x01, 0x59, 0x30,
+0x16, 0x04, 0x14, 0xeb, 0x5c, 0xc9, 0x3a, 0x7e, 0x10, 0x39, 0xd4, 0xf9,
+0xd1, 0xac, 0x31, 0xac, 0xf5, 0xb1, 0xd8, 0xd1, 0xdc, 0x65, 0xb6, 0x30,
0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
-0xb6, 0x3c, 0x52, 0x3c, 0x43, 0x68, 0x11, 0x95, 0x13, 0x8c, 0x57, 0x2e,
-0x17, 0x0f, 0xc3, 0x96, 0x13, 0x86, 0x01, 0x59, 0x30, 0x0f, 0x06, 0x03,
+0xeb, 0x5c, 0xc9, 0x3a, 0x7e, 0x10, 0x39, 0xd4, 0xf9, 0xd1, 0xac, 0x31,
+0xac, 0xf5, 0xb1, 0xd8, 0xd1, 0xdc, 0x65, 0xb6, 0x30, 0x0f, 0x06, 0x03,
0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01,
-0x00, 0x28, 0x38, 0xdb, 0x4a, 0x3f, 0xd3, 0x47, 0x3e, 0x17, 0x17, 0x6c,
-0xc1, 0xa0, 0x64, 0x78, 0x08, 0x90, 0x11, 0xe7, 0x48, 0x06, 0x64, 0x39,
-0x80, 0x0a, 0x48, 0x6a, 0x83, 0xdc, 0x06, 0x4b, 0x03, 0xb5, 0xfa, 0xff,
-0xd4, 0x2e, 0xd3, 0xb8, 0x0b, 0x11, 0x4e, 0x88, 0x33, 0x15, 0xac, 0xee,
-0x7a, 0x15, 0x0c, 0xfb, 0x2a, 0xc1, 0x49, 0xde, 0x04, 0xea, 0xed, 0x7a,
-0x5c, 0x35, 0x2e, 0x72, 0x34, 0x0d, 0x07, 0x96, 0xa1, 0x42, 0x9e, 0xd0,
-0x3f, 0xec, 0xc4, 0x6c, 0xf3, 0xef, 0x76, 0x76, 0xe5, 0x57, 0xb4, 0xcf,
-0xad, 0xd8, 0x77, 0xa1, 0x56, 0xb6, 0x8d, 0x51, 0xf0, 0x4a, 0xb6, 0x59,
-0xcc, 0x22, 0xd8, 0x75, 0xaf, 0x25, 0x0c, 0xb8, 0xe8, 0x98, 0xba, 0x08,
-0x3b, 0x3e, 0x62, 0xf2, 0xcb, 0x25, 0xd7, 0x1a, 0x94, 0x19, 0x5b, 0x51,
-0x15, 0xdd, 0x18, 0x83, 0x5b, 0x69, 0x76, 0x07, 0xf1, 0xcf, 0x1f, 0x2c,
-0x76, 0x7b, 0x7b, 0xe3, 0xac, 0x41, 0x52, 0xbe, 0x3b, 0xee, 0x80, 0x1e,
-0xa5, 0xa4, 0xe3, 0x71, 0x60, 0x17, 0xdd, 0x7b, 0x60, 0xd6, 0x43, 0x9b,
-0x20, 0x25, 0x24, 0x75, 0x63, 0xa7, 0xa4, 0xe9, 0x97, 0x1a, 0xb0, 0x78,
-0x36, 0x36, 0x6d, 0x77, 0x02, 0xaf, 0x4b, 0xcf, 0xdd, 0x28, 0x74, 0xdd,
-0x9e, 0xe5, 0xd8, 0x04, 0xaa, 0xe6, 0x66, 0x5b, 0x4b, 0x1a, 0xe2, 0x52,
-0x93, 0xc5, 0x59, 0x01, 0x37, 0x40, 0xc7, 0xe2, 0x14, 0x13, 0xb1, 0x03,
-0xa9, 0x54, 0xf9, 0xfc, 0x2c, 0x09, 0xee, 0x1e, 0xb2, 0xe0, 0x7e, 0xd8,
-0x30, 0x12, 0x2c, 0xf3, 0xb7, 0x01, 0x9a, 0x97, 0xb6, 0x5b, 0x9c, 0xfa,
-0x44, 0x22, 0x17, 0x47, 0x52, 0xc1, 0xd9, 0xb7, 0x02, 0x7f, 0xc1, 0x95,
-0xbd, 0xc7, 0xed, 0x92, 0x38, 0x2d, 0xa6, 0xae, 0xb0, 0x4e, 0x32, 0xca,
-0x70, 0x5c, 0x4a, 0x6e, 0x18, 0xb3, 0x8d, 0x83, 0xc4, 0x35, 0x26, 0x43,
-0x84, 0x80, 0x1d, 0xe0, 0xd0, 0x8d, 0x66, 0xdf, 0x29, 0xf4, 0x31, 0xca,
-0x10, 0x38, 0x1a, 0x74, 0x29, 0xce, 0xfa, 0xbb, 0xa8, 0x6d, 0x38, 0xb0,
-0x18, 0xaf, 0x6a, 0x43, 0x56, 0x63, 0x51, 0x92, 0x3b, 0x80, 0x76, 0x07,
-0x7d, 0x76, 0xa0, 0x90, 0xf5, 0x74, 0x58, 0x87, 0xd3, 0x25, 0xf0, 0x34,
-0x9a, 0xcc, 0x30, 0x61, 0xf5, 0xd1, 0xa6, 0x87, 0x7e, 0x90, 0x8c, 0x23,
-0x31, 0xfe, 0x8b, 0xc5, 0x43, 0xf1, 0x2e, 0x4a, 0x67, 0x19, 0x4a, 0x09,
-0x1a, 0xa7, 0xe2, 0x4c, 0xef, 0x46, 0xef, 0xe9, 0x32, 0xb7, 0x8d, 0xcc,
-0x75, 0x11, 0x60, 0xf7, 0x99, 0x1a, 0x43, 0xed, 0xf2, 0xa1, 0xe2, 0x9e,
-0xe6, 0xab, 0x6c, 0x58, 0xf3, 0xff, 0x62, 0xb2, 0x72, 0x29, 0x48, 0x73,
-0x68, 0x84, 0x43, 0x6e, 0x90, 0x58, 0x4a, 0x93, 0x8d, 0xe7, 0x37, 0xb8,
-0x73, 0xed, 0x19, 0x89, 0x6b, 0x0d, 0x43, 0x3f, 0x0e, 0xa9, 0xbe, 0xc8,
-0x17, 0x1a, 0x90, 0x47, 0x33, 0x03, 0xed, 0x73, 0x8a, 0xa4, 0x42, 0x3b,
-0x70, 0xd1, 0xc6, 0xd8, 0x61, 0x32, 0x83, 0x77, 0x68, 0xb5, 0x41, 0x83,
-0x70, 0xc3, 0x33, 0xd6, 0x4e, 0x0e, 0x6b, 0x94, 0x29, 0xd4, 0x5a, 0x39,
-0xc2, 0xd1, 0x7a, 0x71, 0x5e, 0x4e, 0xd4, 0x7c, 0x45, 0x94, 0xcf, 0x57,
-0xb5, 0x51, 0x49, 0xed, 0x0d, 0x44, 0xc0, 0xb0, 0x47, 0xdb, 0x07, 0x4e,
-0x66, 0x47, 0x41, 0xb0, 0xd9, 0x69, 0x1f, 0x6b, 0x5a, 0x24, 0xda, 0x2a,
-0x40, 0x33, 0x14, 0x6c, 0x83, 0x14, 0xc7, 0x16, 0xe3, 0x42, 0x60, 0xea,
-0xab, 0x3a, 0x3e, 0xa9, 0x19, 0x6f, 0xcb, 0xc5, 0x85, 0x51, 0x38, 0x91,
-0x77, 0x08, 0x91, 0x5a, 0x0b, 0xe4, 0xa3, 0x31, 0x41, 0xa0, 0xda, 0x6f,
-0xc3, 0x6d, 0x63, 0x22, 0x4f, 0x43, 0x70, 0x97, 0xe1
+0x00, 0x23, 0xa8, 0x94, 0x76, 0x7c, 0x50, 0x76, 0x36, 0xe3, 0xa5, 0x08,
+0x04, 0x8a, 0xbf, 0x2e, 0x44, 0x74, 0xc5, 0x18, 0xeb, 0x89, 0xef, 0x15,
+0xae, 0x5c, 0x95, 0xda, 0x5e, 0x24, 0x06, 0x75, 0x78, 0x10, 0xb7, 0xeb,
+0xf5, 0xd8, 0x94, 0x47, 0x6d, 0x55, 0x60, 0x10, 0x0a, 0x47, 0x56, 0x26,
+0xf0, 0xce, 0x58, 0x16, 0xed, 0x3f, 0x8a, 0x58, 0x0e, 0xfb, 0x18, 0xe9,
+0x65, 0x11, 0x7b, 0x66, 0x07, 0x15, 0x16, 0xa2, 0xcc, 0x65, 0xea, 0xf7,
+0x2c, 0x1d, 0xe6, 0xdd, 0xb3, 0x47, 0x17, 0x26, 0x66, 0x28, 0xcc, 0xcc,
+0x73, 0x5e, 0x25, 0x0c, 0x4e, 0x16, 0x5c, 0x62, 0x5f, 0xd9, 0xf4, 0x8c,
+0x2a, 0x97, 0xc5, 0xbc, 0xb0, 0xd0, 0xf1, 0x1f, 0x6e, 0x9e, 0xcb, 0x84,
+0xad, 0xce, 0xd3, 0xa4, 0x19, 0xb4, 0x03, 0x3a, 0x17, 0xd8, 0x3c, 0x50,
+0x5a, 0x38, 0x94, 0x8a, 0x31, 0xf1, 0xd7, 0xbb, 0x3e, 0xcb, 0x27, 0x54,
+0x02, 0x90, 0xb7, 0x9e, 0xc1, 0x9f, 0x35, 0xdd, 0x0c, 0x6f, 0xb4, 0x18,
+0x46, 0x13, 0x87, 0x52, 0x9a, 0xfa, 0x7a, 0xbf, 0x63, 0xbc, 0x29, 0xe0,
+0xbb, 0x22, 0x1c, 0xf5, 0x82, 0xeb, 0xa3, 0x94, 0x37, 0xb2, 0xdb, 0x32,
+0xab, 0x34, 0xef, 0x5d, 0xd1, 0x16, 0x3b, 0x97, 0x20, 0x7d, 0x98, 0x7c,
+0x8e, 0x14, 0xb3, 0x9e, 0xa2, 0x90, 0x1a, 0x93, 0xbb, 0x43, 0x35, 0xdb,
+0xcc, 0x79, 0xb5, 0x54, 0x94, 0x02, 0xa3, 0xa1, 0xf4, 0xd5, 0xc5, 0x89,
+0xef, 0x59, 0xce, 0x4f, 0x3c, 0x5f, 0xe2, 0xa8, 0xa1, 0xff, 0x01, 0x7e,
+0x15, 0x93, 0x0d, 0x2e, 0xb9, 0x29, 0xe4, 0x09, 0x25, 0x61, 0x2a, 0x99,
+0x5c, 0xfb, 0xd1, 0x8f, 0xc9, 0x2c, 0x97, 0x0a, 0xfd, 0xbc, 0x83, 0x31,
+0x34, 0x90, 0x30, 0x1e, 0xf5, 0xe9, 0x05, 0x10, 0x69, 0xe8, 0x9f, 0xfa,
+0xf8, 0xc9, 0x0c, 0xea, 0x0b, 0xb7, 0x9b, 0xfb, 0x7c, 0x26, 0x6c, 0x4e,
+0xc3, 0xf3, 0x36, 0x5a, 0xe2, 0xd4, 0x5e, 0xb8, 0xe3, 0x45, 0xb0, 0x05,
+0x74, 0xdc, 0x7c, 0xac, 0x9e, 0x9b, 0x0d, 0xb5, 0xd4, 0x4b, 0x35, 0xca,
+0x85, 0x66, 0xe7, 0x65, 0x38, 0x31, 0x5d, 0x25, 0x9a, 0x94, 0x77, 0x41,
+0x35, 0x71, 0x9b, 0xa8, 0xa2, 0xd0, 0x87, 0x40, 0x90, 0x8b, 0xcd, 0x9e,
+0xa3, 0x87, 0x1a, 0xa0, 0x8e, 0x70, 0x3b, 0x67, 0x01, 0xb9, 0x81, 0xed,
+0x3e, 0x7e, 0x00, 0xf0, 0xbe, 0x3e, 0x67, 0x12, 0x46, 0x6e, 0xa7, 0xad,
+0xc0, 0xcc, 0xd6, 0x60, 0x50, 0x5d, 0x4b, 0xfa, 0xf3, 0x3e, 0x52, 0xf5,
+0xbb, 0xf1, 0x27, 0xb7, 0x78, 0xaa, 0x38, 0x2d, 0x33, 0xe4, 0x73, 0x90,
+0x73, 0x86, 0xe5, 0xb5, 0x52, 0x74, 0x06, 0xc5, 0x0b, 0x0b, 0xd3, 0xed,
+0x3b, 0x27, 0xed, 0x6a, 0xf0, 0xd4, 0xbd, 0x13, 0x75, 0xf4, 0x36, 0x1d,
+0x86, 0xa3, 0x22, 0x5f, 0xa1, 0xdb, 0x4f, 0x13, 0x92, 0x56, 0xbb, 0xb8,
+0xba, 0x47, 0x65, 0x59, 0xe5, 0xd9, 0x0d, 0xb0, 0xfd, 0x9c, 0xb5, 0x00,
+0xb9, 0x72, 0xae, 0x07, 0x35, 0x4d, 0xe9, 0x34, 0xd0, 0xf6, 0x4d, 0x6a,
+0xe1, 0x50, 0x21, 0x8b, 0x8b, 0x43, 0x9d, 0x81, 0xf8, 0x95, 0x68, 0xe3,
+0x4a, 0xe7, 0x37, 0x3b, 0x65, 0x8e, 0x71, 0xf5, 0xc3, 0x9d, 0xe5, 0x47,
+0xa6, 0xd7, 0x3f, 0x8a, 0x00, 0xcd, 0x6d, 0x97, 0x83, 0x04, 0xd0, 0x40,
+0x9b, 0x14, 0xf9, 0x64, 0x2b, 0x11, 0x0a, 0xe6, 0x9c, 0xde, 0x94, 0x49,
+0x85, 0xd3, 0xa9, 0x08, 0x18, 0x4b, 0x6f, 0x71, 0x97, 0x2e, 0xed, 0xdb,
+0x64, 0xb2, 0x74, 0x4d, 0xef, 0x88, 0x76, 0x27, 0xe9, 0x7f, 0xdb, 0x8e,
+0xb2, 0xc1, 0x44, 0x30, 0x6a, 0x39, 0x7e, 0x98, 0x44, 0xee, 0xfe, 0x55,
+0x52, 0x6d, 0x04, 0x63, 0x41, 0xe0, 0x4f, 0xb0, 0xc2
};
const size_t ROOT_A_CERT_len = sizeof(ROOT_A_CERT);
/* Chain A - Intermediate CA Certificate (DER format) */
const unsigned char INTERMEDIATE_A_CERT[] = {
0x30, 0x82, 0x05, 0x0c, 0x30, 0x82, 0x02, 0xf4, 0xa0, 0x03, 0x02, 0x01,
-0x02, 0x02, 0x14, 0x36, 0x1c, 0xce, 0x27, 0xef, 0xbb, 0xb2, 0x64, 0xa5,
-0xcf, 0x7a, 0xfd, 0x78, 0x3c, 0xf1, 0xbc, 0xe7, 0x95, 0x58, 0xf4, 0x30,
+0x02, 0x02, 0x14, 0x55, 0x35, 0x79, 0x1c, 0xb8, 0x76, 0xdf, 0x38, 0x63,
+0x54, 0xc5, 0x6f, 0xe6, 0xd8, 0xc2, 0xaf, 0x32, 0xac, 0xaa, 0xe1, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x30, 0x81, 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
@@ -159,9 +159,9 @@ const unsigned char INTERMEDIATE_A_CERT[] = {
0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x52, 0x6f, 0x6f, 0x74,
0x20, 0x43, 0x41, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03,
0x0c, 0x0e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x20, 0x52, 0x6f, 0x6f,
-0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x35,
-0x30, 0x38, 0x32, 0x32, 0x30, 0x37, 0x31, 0x30, 0x5a, 0x17, 0x0d, 0x33,
-0x30, 0x30, 0x35, 0x30, 0x37, 0x32, 0x32, 0x30, 0x37, 0x31, 0x30, 0x5a,
+0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x35,
+0x30, 0x39, 0x32, 0x31, 0x33, 0x35, 0x35, 0x31, 0x5a, 0x17, 0x0d, 0x33,
+0x31, 0x30, 0x35, 0x30, 0x38, 0x32, 0x31, 0x33, 0x35, 0x35, 0x31, 0x5a,
0x30, 0x81, 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69,
@@ -177,89 +177,89 @@ const unsigned char INTERMEDIATE_A_CERT[] = {
0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
-0x01, 0x01, 0x00, 0xb7, 0x48, 0xf5, 0x71, 0x92, 0x7b, 0xd3, 0x68, 0xe0,
-0x31, 0xd2, 0x43, 0x03, 0xe2, 0x41, 0x7b, 0x48, 0xc7, 0x32, 0xef, 0x35,
-0x4c, 0xa0, 0x8e, 0x92, 0xf2, 0x40, 0x6e, 0x90, 0x7a, 0xbf, 0x57, 0x2c,
-0x1e, 0x66, 0x8c, 0x2b, 0x19, 0xca, 0xde, 0x78, 0x40, 0x23, 0x90, 0xbd,
-0xf4, 0xcf, 0x4e, 0x84, 0xf1, 0xf2, 0x3d, 0xd6, 0xd0, 0xbf, 0xfa, 0x94,
-0x37, 0xda, 0x93, 0x2f, 0x29, 0xea, 0x62, 0xb7, 0x04, 0xb8, 0x45, 0x6a,
-0x2f, 0xbe, 0x76, 0x13, 0x48, 0x02, 0x12, 0x84, 0x6e, 0x5b, 0x1e, 0x2f,
-0x44, 0x80, 0x19, 0x75, 0x44, 0x81, 0x02, 0xc0, 0x55, 0x79, 0x9c, 0x20,
-0x59, 0x35, 0xcc, 0x1e, 0x27, 0x9b, 0xcb, 0x3e, 0xfb, 0x71, 0x65, 0x27,
-0xbd, 0xb9, 0x32, 0x04, 0xd0, 0xa0, 0x5c, 0x60, 0xfc, 0xf0, 0xc3, 0xf2,
-0xf8, 0x9f, 0xad, 0x7a, 0x15, 0xcc, 0x41, 0xdd, 0x16, 0x39, 0x1e, 0xff,
-0x7d, 0xe1, 0xc8, 0xc5, 0x91, 0xde, 0x95, 0x2b, 0xc8, 0x29, 0xb2, 0x74,
-0xf3, 0xea, 0x7b, 0x3d, 0xaf, 0x70, 0x97, 0xd1, 0x48, 0x4d, 0x6d, 0x09,
-0xd2, 0xb9, 0xe0, 0xb4, 0x52, 0xa1, 0xe2, 0xf5, 0x7c, 0x07, 0xe2, 0xc1,
-0x51, 0x90, 0xb2, 0xe2, 0x6e, 0xf4, 0xaa, 0x2f, 0xda, 0x59, 0x0a, 0xd0,
-0x17, 0xb9, 0xc4, 0xf7, 0xed, 0x6f, 0xf1, 0x75, 0x5f, 0x37, 0xa6, 0x08,
-0x86, 0xa0, 0x36, 0x30, 0xa3, 0xad, 0x06, 0xcc, 0xa3, 0xe7, 0x2e, 0x5f,
-0xc0, 0x74, 0xb5, 0x59, 0xc8, 0x03, 0x31, 0xd6, 0x71, 0x8c, 0xa0, 0x19,
-0xcc, 0x34, 0x40, 0x88, 0x86, 0xb9, 0x57, 0xa5, 0x6c, 0xf4, 0x21, 0x3d,
-0x6d, 0x55, 0x53, 0x5f, 0x25, 0x4b, 0x8b, 0xad, 0xd4, 0x65, 0xd8, 0xca,
-0xc1, 0xc9, 0xe7, 0x44, 0x52, 0x6f, 0x4b, 0x2f, 0x81, 0xc3, 0x8c, 0xf5,
-0xf4, 0x09, 0x64, 0x0b, 0xe6, 0xad, 0x2d, 0x02, 0x03, 0x01, 0x00, 0x01,
+0x01, 0x01, 0x00, 0xb4, 0x63, 0xe7, 0xd5, 0xd8, 0x91, 0xa3, 0x70, 0xb0,
+0xfb, 0xbf, 0x95, 0xed, 0xbb, 0x50, 0xa3, 0xff, 0x74, 0x34, 0x45, 0x20,
+0xfc, 0xe8, 0xf3, 0x11, 0xa9, 0x01, 0x4b, 0x14, 0x61, 0x0b, 0xf8, 0x73,
+0x71, 0xc0, 0x5c, 0x58, 0x8c, 0x89, 0xf0, 0x2c, 0x87, 0xbb, 0x16, 0x69,
+0xc4, 0xd7, 0xa6, 0x67, 0x78, 0x5f, 0xac, 0xce, 0xbd, 0x74, 0xe3, 0x87,
+0x41, 0x71, 0x8e, 0xb6, 0x8e, 0x19, 0xe7, 0x72, 0xa4, 0xf0, 0x44, 0xfd,
+0x4d, 0x24, 0xf4, 0x3d, 0x31, 0xae, 0x1c, 0x86, 0x4e, 0xeb, 0xcc, 0x24,
+0xa9, 0xe9, 0x9e, 0x42, 0x7c, 0x08, 0x4f, 0xd6, 0x02, 0x7e, 0x4a, 0xb0,
+0x61, 0xef, 0x93, 0xd1, 0x89, 0x4c, 0x19, 0x67, 0xe2, 0x1d, 0x48, 0xc6,
+0x19, 0xad, 0x0e, 0xe6, 0x00, 0x27, 0x6a, 0x4c, 0xcf, 0x0d, 0x29, 0x3e,
+0xba, 0x4c, 0x4d, 0x34, 0xa9, 0x34, 0x52, 0xf5, 0x8a, 0x72, 0xd9, 0xcd,
+0x9d, 0x5a, 0x0b, 0xff, 0xce, 0x7e, 0x0a, 0x1b, 0x64, 0x7f, 0x60, 0x2d,
+0x08, 0x56, 0xcf, 0x25, 0xda, 0xbe, 0x02, 0x89, 0xce, 0x54, 0x20, 0x4f,
+0xf8, 0x45, 0x72, 0x5c, 0x98, 0xad, 0xb4, 0x19, 0x9d, 0xe2, 0xa1, 0x04,
+0xe4, 0xe3, 0x2a, 0xc9, 0x92, 0x34, 0x61, 0xfc, 0x08, 0x77, 0x7b, 0x3d,
+0x41, 0x06, 0x74, 0xd9, 0x08, 0x0d, 0xbd, 0x5a, 0x2c, 0xa3, 0x5e, 0x57,
+0xb9, 0xc0, 0xa3, 0xcf, 0x1f, 0xa6, 0xe5, 0x62, 0xe8, 0x75, 0x17, 0x98,
+0x0a, 0xda, 0xd7, 0x2b, 0x5a, 0x57, 0x8d, 0xfc, 0xd7, 0x5f, 0x61, 0xa6,
+0xb3, 0x10, 0x46, 0x8a, 0xa6, 0x36, 0xe1, 0xaa, 0xf9, 0x8b, 0xc0, 0xc2,
+0x77, 0x89, 0x2b, 0x59, 0x9c, 0xa5, 0xd7, 0xea, 0x17, 0x37, 0x47, 0x55,
+0xb9, 0x23, 0x89, 0x46, 0xee, 0x97, 0x13, 0x44, 0xd3, 0x92, 0x75, 0xdb,
+0x28, 0xf6, 0xc5, 0xfc, 0x08, 0x6f, 0xbf, 0x02, 0x03, 0x01, 0x00, 0x01,
0xa3, 0x66, 0x30, 0x64, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00,
0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
-0x16, 0x04, 0x14, 0x6d, 0x76, 0xf6, 0xca, 0xd3, 0xa1, 0x4e, 0xff, 0xa2,
-0x4d, 0x59, 0x8a, 0x53, 0x28, 0x15, 0x5c, 0x5a, 0xfa, 0x69, 0x4c, 0x30,
+0x16, 0x04, 0x14, 0x3e, 0x55, 0xb6, 0xa0, 0x53, 0x80, 0xf0, 0x03, 0xc8,
+0x9d, 0xcd, 0x87, 0x80, 0x7f, 0x62, 0x6d, 0xae, 0x36, 0x93, 0xf2, 0x30,
0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
-0xb6, 0x3c, 0x52, 0x3c, 0x43, 0x68, 0x11, 0x95, 0x13, 0x8c, 0x57, 0x2e,
-0x17, 0x0f, 0xc3, 0x96, 0x13, 0x86, 0x01, 0x59, 0x30, 0x0d, 0x06, 0x09,
+0xeb, 0x5c, 0xc9, 0x3a, 0x7e, 0x10, 0x39, 0xd4, 0xf9, 0xd1, 0xac, 0x31,
+0xac, 0xf5, 0xb1, 0xd8, 0xd1, 0xdc, 0x65, 0xb6, 0x30, 0x0d, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
-0x82, 0x02, 0x01, 0x00, 0x93, 0x46, 0xb9, 0xdc, 0x7e, 0x64, 0x3d, 0x69,
-0x03, 0x33, 0xba, 0x2a, 0xd2, 0xae, 0x9f, 0xdb, 0x90, 0x97, 0x69, 0xfc,
-0x28, 0xff, 0x66, 0x9a, 0xe1, 0x30, 0xb2, 0x3a, 0xce, 0x6d, 0x5f, 0x8a,
-0x06, 0x97, 0x01, 0x61, 0x07, 0x1c, 0x4b, 0x91, 0x62, 0xd6, 0x8f, 0x97,
-0x67, 0xcf, 0x0a, 0x7b, 0x5c, 0x50, 0x80, 0x5c, 0x26, 0x74, 0xdd, 0x53,
-0x70, 0xa6, 0xfe, 0x41, 0xe3, 0x8a, 0xd2, 0x6a, 0x66, 0xd7, 0x8f, 0x33,
-0xec, 0x84, 0xc2, 0xeb, 0xc4, 0x60, 0xdf, 0x38, 0xb6, 0xbf, 0x52, 0x39,
-0x82, 0x37, 0x3e, 0xda, 0xb5, 0xa9, 0x61, 0x08, 0x52, 0xf1, 0xbf, 0x9b,
-0x2a, 0x72, 0x3e, 0xf5, 0xba, 0xc1, 0x69, 0x97, 0xd7, 0xa4, 0x33, 0xa9,
-0xb7, 0x26, 0xb6, 0x53, 0x17, 0xdf, 0x7e, 0x80, 0xc2, 0xcd, 0xc3, 0xda,
-0x91, 0x54, 0x84, 0x1b, 0xce, 0xa3, 0xf9, 0x3e, 0xf6, 0x38, 0x16, 0x34,
-0xd9, 0x82, 0x06, 0x85, 0x8e, 0xda, 0x4d, 0x30, 0x84, 0x50, 0x59, 0x94,
-0xc1, 0xf7, 0xa2, 0xc7, 0xf7, 0xdd, 0x09, 0xe4, 0x03, 0x8b, 0xc9, 0x6f,
-0x6d, 0x3e, 0x1a, 0x6a, 0x78, 0x62, 0xe4, 0x3a, 0xa8, 0xac, 0x67, 0x7a,
-0x9c, 0x42, 0x96, 0x79, 0x5c, 0x25, 0xb0, 0x71, 0x3b, 0xd7, 0xdf, 0x67,
-0x46, 0x08, 0x70, 0x5f, 0xec, 0xd8, 0x29, 0x38, 0xf7, 0xac, 0xe3, 0x74,
-0x17, 0xc2, 0x1f, 0x1f, 0xe6, 0x6e, 0x89, 0x0a, 0x48, 0xf9, 0x19, 0x6c,
-0x65, 0xf0, 0x90, 0x85, 0x0d, 0xa4, 0xa0, 0x44, 0xc5, 0xf7, 0x3e, 0x59,
-0xd1, 0x2d, 0xf0, 0x1f, 0x53, 0x6f, 0xbb, 0x3a, 0xf9, 0x3e, 0x77, 0xb2,
-0x23, 0x5b, 0x13, 0x09, 0x07, 0xbe, 0xcc, 0xba, 0xf9, 0xdd, 0x0f, 0x1d,
-0x1b, 0x8e, 0x03, 0xfc, 0xc2, 0x28, 0xe2, 0xbe, 0xb7, 0x08, 0x42, 0x64,
-0x32, 0xee, 0x74, 0x52, 0x28, 0x8b, 0xcb, 0x8f, 0x6b, 0x86, 0xbc, 0x4d,
-0xbd, 0x9c, 0x83, 0x49, 0xc8, 0xdc, 0xa1, 0x97, 0x12, 0xe6, 0xe7, 0x06,
-0x6e, 0xc7, 0x60, 0xe9, 0x59, 0xbb, 0xfe, 0xac, 0x15, 0x11, 0x11, 0x58,
-0x2b, 0x7e, 0xf5, 0x5a, 0x4d, 0xac, 0xc3, 0x11, 0x94, 0x0e, 0xf9, 0x40,
-0x82, 0x3f, 0x73, 0x87, 0x40, 0x98, 0x51, 0xcf, 0x68, 0xfa, 0x9f, 0x89,
-0xe5, 0xbe, 0xfc, 0x8c, 0xd5, 0x41, 0x8f, 0x50, 0x45, 0xb0, 0x97, 0x7a,
-0x1a, 0x72, 0xfb, 0x67, 0xe9, 0x5b, 0x5b, 0xba, 0x38, 0x51, 0xb1, 0xa4,
-0x70, 0x4d, 0xaf, 0xfb, 0xe2, 0x91, 0xfd, 0xcc, 0xf5, 0x5a, 0x90, 0x09,
-0xea, 0x92, 0x72, 0x7f, 0x03, 0x3a, 0x4c, 0xa5, 0x36, 0x89, 0xd5, 0x15,
-0x20, 0xa8, 0xbb, 0x10, 0xf9, 0xad, 0xdf, 0x03, 0xfe, 0x8a, 0xbd, 0x8c,
-0xe1, 0x68, 0x91, 0x5d, 0x5f, 0xc9, 0xb0, 0x6f, 0x24, 0xe6, 0x2e, 0x28,
-0x7e, 0xf0, 0x05, 0xf9, 0xe3, 0xbb, 0xa1, 0xdb, 0x87, 0xa0, 0x51, 0xe9,
-0x04, 0x8e, 0x5b, 0x4f, 0xf1, 0x06, 0x62, 0xf3, 0x1c, 0x2e, 0x6a, 0x5f,
-0x4c, 0xce, 0x41, 0x6b, 0x3a, 0x46, 0x70, 0xff, 0x0d, 0x49, 0x65, 0x46,
-0xa2, 0x74, 0xac, 0x27, 0x12, 0x8f, 0xc3, 0x16, 0x9d, 0x5f, 0x0a, 0x74,
-0x8e, 0x7b, 0x3e, 0x2c, 0xa3, 0x68, 0x92, 0xca, 0x11, 0xe1, 0xad, 0x9f,
-0x1f, 0x36, 0x8f, 0x6e, 0xb5, 0x88, 0x3e, 0x76, 0x36, 0x0b, 0x0a, 0xf1,
-0x35, 0xa1, 0xad, 0x94, 0x27, 0xbd, 0xd5, 0xba, 0x77, 0x34, 0xcd, 0xb8,
-0x9e, 0xf5, 0x45, 0xe6, 0x19, 0x6b, 0xb3, 0x29, 0x9a, 0x9f, 0xf4, 0x7a,
-0x50, 0x75, 0x6e, 0x5a, 0x80, 0x36, 0x74, 0xed, 0x9a, 0x12, 0xbe, 0xed,
-0x9b, 0xbc, 0xb1, 0xed, 0x9a, 0x24, 0xb7, 0x76, 0x1b, 0x39, 0x36, 0x1a,
-0x59, 0xa9, 0xd1, 0xdc, 0xc8, 0xd7, 0xc7, 0x33, 0xd5, 0xf2, 0x61, 0x31
+0x82, 0x02, 0x01, 0x00, 0x78, 0x8f, 0x3e, 0xba, 0x86, 0x02, 0x71, 0xd8,
+0x16, 0x0d, 0x16, 0x80, 0x4a, 0x0c, 0xa0, 0x82, 0xb9, 0xbf, 0x63, 0xcc,
+0x65, 0x85, 0xdd, 0xef, 0x47, 0x9e, 0xb6, 0xf8, 0x3a, 0x52, 0xa7, 0x85,
+0x22, 0x1c, 0xc4, 0xd6, 0x12, 0x0c, 0xa4, 0x79, 0xd4, 0x00, 0xb7, 0xac,
+0xba, 0x60, 0xba, 0xd3, 0xf6, 0x86, 0x30, 0xa0, 0xf5, 0x16, 0xe3, 0x36,
+0x53, 0x88, 0x39, 0xab, 0xcb, 0xde, 0x8f, 0xc0, 0xbc, 0x68, 0xec, 0x05,
+0x8a, 0xca, 0x40, 0x65, 0x26, 0xbf, 0x9a, 0x29, 0x8a, 0x50, 0x04, 0xf9,
+0x89, 0x19, 0x0d, 0x38, 0xf8, 0x36, 0x41, 0x97, 0x34, 0xf3, 0xcb, 0x34,
+0x0d, 0x97, 0xa0, 0xb7, 0x9b, 0xaa, 0x6e, 0x37, 0x66, 0xc6, 0x17, 0x9c,
+0x58, 0xf1, 0x7c, 0x2c, 0x7b, 0x03, 0x7b, 0xd0, 0x58, 0x15, 0x11, 0xe9,
+0xc7, 0x95, 0x09, 0x0e, 0x2b, 0xeb, 0x2a, 0x68, 0x5b, 0x78, 0xe7, 0x25,
+0x73, 0xfb, 0x6e, 0x28, 0x63, 0x66, 0x3d, 0xe2, 0x84, 0x99, 0xa9, 0x11,
+0x0b, 0xea, 0x41, 0x27, 0x16, 0x24, 0x31, 0xed, 0x2e, 0xba, 0x3a, 0xfc,
+0xb6, 0x61, 0x6c, 0xc8, 0xf2, 0xff, 0x96, 0x3f, 0x27, 0x57, 0x44, 0x70,
+0x36, 0x87, 0x87, 0x97, 0xc1, 0x9e, 0x38, 0x00, 0x40, 0xe9, 0x0f, 0x76,
+0x94, 0x37, 0x9d, 0x9b, 0x7b, 0xe8, 0x11, 0x0d, 0x07, 0x2b, 0x3c, 0xee,
+0x21, 0x76, 0x7f, 0x76, 0xf5, 0x9e, 0x49, 0x34, 0x84, 0xcc, 0x8b, 0x8e,
+0x00, 0xa4, 0x72, 0x3d, 0x80, 0x9e, 0x7f, 0x21, 0x0d, 0x72, 0x07, 0x0d,
+0xd4, 0xbc, 0x0d, 0xb2, 0x1c, 0xb2, 0x5a, 0xf4, 0x62, 0xc9, 0xf7, 0x1d,
+0x65, 0xb8, 0x74, 0xc2, 0xea, 0x12, 0xa9, 0x18, 0x7b, 0xb1, 0xea, 0x3f,
+0x4a, 0x16, 0x91, 0xe1, 0x2d, 0xe3, 0x15, 0x3f, 0x3e, 0x16, 0x4a, 0x7b,
+0x41, 0x2c, 0xf5, 0xb9, 0xad, 0xcc, 0x94, 0xd3, 0x39, 0xaa, 0x6d, 0x43,
+0x79, 0x78, 0x76, 0x5b, 0x1d, 0x0c, 0x17, 0xc3, 0x15, 0x0f, 0x09, 0xc5,
+0xcd, 0xed, 0x51, 0xba, 0xd3, 0x73, 0x64, 0x8c, 0x95, 0xd0, 0x6e, 0xdf,
+0x85, 0x57, 0x82, 0x46, 0x00, 0xf6, 0x65, 0x48, 0x11, 0x89, 0xa2, 0x58,
+0xcc, 0xd3, 0xa4, 0x6f, 0x9c, 0x2e, 0x02, 0x75, 0x78, 0xb1, 0xd7, 0x3c,
+0xfc, 0xf9, 0x8c, 0xc5, 0x0b, 0x74, 0xee, 0xd2, 0xe0, 0x72, 0xff, 0xb3,
+0x75, 0xe6, 0x8b, 0x8d, 0x1e, 0x60, 0x78, 0xcf, 0x5f, 0x30, 0x89, 0xc2,
+0xfd, 0x3f, 0x90, 0xaf, 0x2b, 0xdd, 0x19, 0x7c, 0x7b, 0x66, 0x82, 0x38,
+0x3f, 0x1d, 0x06, 0x5a, 0x2c, 0x10, 0x30, 0x36, 0x4c, 0x4f, 0x7d, 0x68,
+0xcb, 0x87, 0x31, 0x4d, 0xbd, 0x9b, 0x04, 0x82, 0x46, 0x0d, 0xd8, 0x4d,
+0x59, 0xe6, 0x3d, 0x03, 0xce, 0xea, 0x2f, 0xc2, 0x5e, 0x7b, 0xd1, 0xe0,
+0x2b, 0x8d, 0x9e, 0x0e, 0xdb, 0xcd, 0xd2, 0xa8, 0x98, 0xa6, 0x00, 0xd8,
+0xa6, 0x35, 0x81, 0xec, 0xdc, 0xee, 0xcb, 0x65, 0x1e, 0x41, 0xb4, 0xab,
+0xe0, 0x77, 0x63, 0xc1, 0x95, 0x82, 0x29, 0x54, 0xe3, 0xb7, 0x74, 0xee,
+0x6c, 0xe5, 0x86, 0x90, 0x4b, 0xfa, 0xf0, 0x18, 0x1a, 0xd7, 0x38, 0x73,
+0xc1, 0x5f, 0x32, 0x94, 0xd6, 0xd7, 0xaa, 0xf4, 0xb6, 0xd7, 0x65, 0xbc,
+0xa3, 0x0b, 0x6d, 0xe3, 0xd2, 0xd1, 0xa3, 0x11, 0x24, 0x6b, 0x12, 0x01,
+0xcc, 0xee, 0x66, 0xd3, 0x9c, 0x3b, 0xb7, 0xe6, 0x42, 0x54, 0x96, 0xec,
+0x86, 0x55, 0x3a, 0x81, 0x00, 0x51, 0x93, 0x7a, 0x8f, 0xe8, 0xe4, 0x5f,
+0x4b, 0x90, 0x1c, 0xa9, 0x75, 0x2d, 0x8a, 0x68, 0xec, 0x32, 0x26, 0xe6,
+0xdb, 0x65, 0xbf, 0x3f, 0x04, 0x60, 0xc1, 0xa5, 0xa6, 0xbd, 0x3d, 0xfe,
+0x1a, 0x55, 0x8f, 0x76, 0x31, 0x6d, 0xfb, 0x6f, 0xbf, 0x4d, 0xbc, 0xe6
};
const size_t INTERMEDIATE_A_CERT_len = sizeof(INTERMEDIATE_A_CERT);
/* Chain A - Leaf/Server Certificate (DER format) */
const unsigned char LEAF_A_CERT[] = {
0x30, 0x82, 0x04, 0x20, 0x30, 0x82, 0x03, 0x08, 0xa0, 0x03, 0x02, 0x01,
-0x02, 0x02, 0x14, 0x15, 0x6c, 0x2a, 0xad, 0x3a, 0x2d, 0xb5, 0xb4, 0x2e,
-0x81, 0x9d, 0x0c, 0xd9, 0x2f, 0x26, 0x2c, 0x1e, 0xac, 0x21, 0x14, 0x30,
+0x02, 0x02, 0x14, 0x74, 0x98, 0x82, 0x8b, 0x39, 0xcf, 0x41, 0xe8, 0xac,
+0xff, 0x24, 0x6e, 0xb2, 0x8a, 0xc6, 0x6c, 0x72, 0x25, 0x90, 0x09, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x30, 0x81, 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
@@ -274,9 +274,9 @@ const unsigned char LEAF_A_CERT[] = {
0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x43, 0x68,
0x61, 0x69, 0x6e, 0x41, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65,
0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d,
-0x32, 0x35, 0x30, 0x35, 0x30, 0x38, 0x32, 0x32, 0x30, 0x37, 0x31, 0x30,
-0x5a, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x35, 0x30, 0x38, 0x32, 0x32, 0x30,
-0x37, 0x31, 0x30, 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06,
+0x32, 0x36, 0x30, 0x35, 0x30, 0x39, 0x32, 0x31, 0x33, 0x35, 0x35, 0x31,
+0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x35, 0x30, 0x39, 0x32, 0x31, 0x33,
+0x35, 0x35, 0x31, 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06,
0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11,
0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66,
0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55,
@@ -290,70 +290,70 @@ const unsigned char LEAF_A_CERT[] = {
0x2d, 0x61, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63,
0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
-0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x95,
-0xc0, 0xd1, 0xf3, 0x6a, 0xbd, 0xc9, 0xe0, 0xee, 0x14, 0x0a, 0x09, 0xca,
-0x18, 0xe7, 0x0a, 0x9f, 0x9e, 0x34, 0x22, 0xa2, 0x06, 0x9c, 0xb4, 0xc8,
-0xdd, 0x0c, 0xa9, 0x20, 0x48, 0x9d, 0xd6, 0xa9, 0xf9, 0x61, 0xe1, 0xce,
-0x39, 0x42, 0x41, 0x5c, 0xb4, 0xb1, 0xba, 0xe9, 0xf0, 0x5f, 0xb6, 0xab,
-0x53, 0x2b, 0x4c, 0x74, 0x9c, 0x26, 0xaa, 0x33, 0x5d, 0xd6, 0x50, 0x67,
-0xbd, 0x9f, 0x52, 0x21, 0xe0, 0xf6, 0x2d, 0x92, 0x1f, 0x42, 0x90, 0x13,
-0x1d, 0xed, 0x62, 0x83, 0x51, 0xfa, 0xa0, 0x3b, 0xac, 0x32, 0x71, 0x3d,
-0x4f, 0x21, 0x11, 0x33, 0xf9, 0x00, 0xf7, 0xd4, 0x9b, 0xdc, 0x65, 0xff,
-0x71, 0x3c, 0x0f, 0x7f, 0x94, 0x7b, 0xbc, 0xe5, 0x08, 0xec, 0xda, 0xc8,
-0x4f, 0x45, 0xb5, 0xd1, 0x34, 0xde, 0x24, 0x4b, 0xf9, 0xfe, 0x75, 0x3d,
-0x99, 0x97, 0x63, 0xf6, 0x0f, 0x2f, 0xb1, 0x77, 0xfd, 0xf8, 0xc2, 0xb3,
-0xed, 0xd5, 0xbb, 0x68, 0xf5, 0x6e, 0x57, 0x7e, 0x5b, 0xd0, 0xe4, 0x41,
-0x67, 0x21, 0x55, 0x62, 0x92, 0x0c, 0x12, 0x3c, 0xf0, 0xf4, 0x3a, 0xe4,
-0xc2, 0x66, 0x04, 0x44, 0xf4, 0xaf, 0xc5, 0x86, 0xa1, 0xff, 0xb9, 0x03,
-0x9d, 0x4c, 0xe4, 0xc5, 0xe3, 0xf8, 0xb9, 0x35, 0xf6, 0x1a, 0x65, 0x20,
-0x93, 0xf6, 0x0e, 0xfc, 0xac, 0xdc, 0x5b, 0x97, 0x87, 0xe4, 0xad, 0x1c,
-0x4a, 0xfc, 0x5f, 0xb0, 0xbb, 0xd6, 0x94, 0x72, 0x3b, 0x4f, 0xbe, 0x3f,
-0xfe, 0x76, 0xea, 0xa1, 0xdf, 0x12, 0xc0, 0xd8, 0x88, 0x8b, 0xbd, 0x30,
-0xa9, 0x87, 0x6c, 0xaf, 0x72, 0xab, 0x20, 0xa8, 0x2e, 0x4d, 0x01, 0x80,
-0xb5, 0xcd, 0x32, 0x90, 0x6c, 0x35, 0x6f, 0xbd, 0x1f, 0xf7, 0x6a, 0xb1,
-0xb1, 0xdc, 0x18, 0x24, 0x15, 0xff, 0xd1, 0xef, 0xb5, 0xe8, 0xef, 0x94,
-0x45, 0xf3, 0xa1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x72, 0x30, 0x70,
+0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf,
+0xfb, 0xa0, 0xf1, 0x89, 0x70, 0x45, 0xf8, 0xe9, 0xc5, 0xc0, 0xde, 0x49,
+0xb9, 0x22, 0x8a, 0x0a, 0x16, 0xbc, 0xf0, 0x4d, 0xf9, 0x70, 0xa2, 0x4c,
+0xab, 0x3d, 0x4e, 0x22, 0x04, 0xf8, 0xa6, 0xb9, 0xb8, 0x78, 0x33, 0x63,
+0x7f, 0x4b, 0xb9, 0x9f, 0xef, 0xc3, 0xda, 0xce, 0xea, 0x6b, 0x8f, 0x5e,
+0x7b, 0x96, 0x94, 0x97, 0x34, 0xde, 0xb9, 0x15, 0x86, 0x79, 0xcf, 0x61,
+0x9e, 0x21, 0x6d, 0x84, 0x88, 0xc4, 0x01, 0x5d, 0xc9, 0x2a, 0xc8, 0x7c,
+0x0b, 0xed, 0x5c, 0x76, 0x95, 0x57, 0xb5, 0x0d, 0x80, 0x25, 0x67, 0x5a,
+0xd2, 0x9f, 0x25, 0x64, 0x48, 0xa8, 0xbd, 0x89, 0x4d, 0x93, 0x06, 0x2e,
+0xc5, 0x27, 0xe7, 0xfa, 0x49, 0x59, 0x22, 0x4e, 0xe4, 0x82, 0xa0, 0xdc,
+0x10, 0x7e, 0xf7, 0x2f, 0xb4, 0xc5, 0x01, 0x4f, 0xf2, 0x8b, 0x62, 0xc2,
+0xcd, 0x70, 0x06, 0x70, 0xa4, 0x8c, 0x05, 0x7a, 0x8a, 0x82, 0x82, 0x57,
+0x02, 0x37, 0x04, 0x24, 0xa6, 0x3d, 0x56, 0xcf, 0x2f, 0x6e, 0x95, 0x52,
+0xc1, 0x08, 0xd6, 0x8e, 0x07, 0x47, 0x23, 0xfd, 0xc5, 0xf3, 0x86, 0x29,
+0x7a, 0xaa, 0x46, 0x1d, 0xba, 0x9f, 0xd5, 0x8d, 0xc3, 0x4d, 0x20, 0xd9,
+0x31, 0xf0, 0x53, 0x4b, 0x92, 0xb4, 0x82, 0x85, 0x06, 0x3b, 0xd9, 0xde,
+0x43, 0x86, 0x66, 0xfc, 0x29, 0x15, 0xc4, 0xa9, 0x6c, 0xb1, 0x70, 0xb4,
+0x0d, 0xe1, 0x37, 0x1e, 0x92, 0x4a, 0xc3, 0x51, 0x4b, 0xbd, 0x59, 0xd4,
+0xa7, 0x3e, 0x64, 0x55, 0x50, 0xb0, 0x7a, 0x28, 0xf9, 0xea, 0x77, 0x66,
+0xd3, 0x2f, 0x97, 0xc6, 0xf8, 0xe9, 0x80, 0x1a, 0x22, 0xc8, 0x29, 0x47,
+0xfa, 0x24, 0xf7, 0x9a, 0x71, 0xd7, 0xed, 0x16, 0x2c, 0x32, 0x7e, 0x6d,
+0xc6, 0x47, 0x06, 0x9e, 0xdd, 0xf2, 0xee, 0xbc, 0xfe, 0x01, 0xc9, 0x3c,
+0xaf, 0xf3, 0xcd, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x72, 0x30, 0x70,
0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30,
0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
0x02, 0x05, 0xa0, 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c,
0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
-0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x33,
-0x09, 0x98, 0xae, 0xd4, 0xa7, 0x25, 0x93, 0x32, 0xe3, 0xcd, 0x77, 0xf9,
-0xfb, 0x9a, 0x04, 0x3c, 0x53, 0x13, 0x39, 0x30, 0x1f, 0x06, 0x03, 0x55,
-0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x6d, 0x76, 0xf6, 0xca,
-0xd3, 0xa1, 0x4e, 0xff, 0xa2, 0x4d, 0x59, 0x8a, 0x53, 0x28, 0x15, 0x5c,
-0x5a, 0xfa, 0x69, 0x4c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf9,
+0x20, 0x9b, 0xe2, 0x69, 0x11, 0xcb, 0xf7, 0x01, 0x4e, 0xd4, 0x93, 0xa5,
+0xbf, 0xe3, 0x99, 0x99, 0x0e, 0xb1, 0x92, 0x30, 0x1f, 0x06, 0x03, 0x55,
+0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x3e, 0x55, 0xb6, 0xa0,
+0x53, 0x80, 0xf0, 0x03, 0xc8, 0x9d, 0xcd, 0x87, 0x80, 0x7f, 0x62, 0x6d,
+0xae, 0x36, 0x93, 0xf2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
-0x38, 0xb4, 0xc7, 0xe8, 0x42, 0x3a, 0x9c, 0xc7, 0x7c, 0xb5, 0x1c, 0xe1,
-0x1b, 0x99, 0x06, 0x00, 0x9e, 0x0f, 0x60, 0xb2, 0x99, 0x6b, 0xc1, 0xc2,
-0x0e, 0x9a, 0x7b, 0x89, 0x5f, 0xd5, 0xa0, 0x16, 0x49, 0x38, 0x8c, 0xa1,
-0x51, 0x8b, 0xfd, 0xaf, 0xd4, 0x2a, 0x0e, 0xa0, 0x10, 0x36, 0x4a, 0x20,
-0xab, 0x1c, 0xa6, 0x0e, 0xe0, 0xda, 0x48, 0xc3, 0x29, 0xbb, 0x79, 0x0a,
-0x05, 0xf0, 0x5a, 0x7d, 0xc8, 0x59, 0x85, 0x2b, 0xe2, 0xcc, 0xba, 0xac,
-0x84, 0x45, 0x68, 0xc7, 0xf1, 0xe9, 0xfb, 0xa6, 0xbf, 0x40, 0xa8, 0x67,
-0xf6, 0xc4, 0xf6, 0xb8, 0x06, 0x3f, 0xcd, 0x16, 0x13, 0x52, 0x68, 0x78,
-0x06, 0xd2, 0xd3, 0x33, 0xd5, 0x03, 0x6b, 0x4f, 0xa7, 0x72, 0xd1, 0xf8,
-0x4e, 0xed, 0x78, 0x65, 0x3d, 0x60, 0x64, 0xcb, 0x5f, 0x1d, 0x6e, 0x31,
-0x92, 0x74, 0x50, 0x40, 0x7c, 0x78, 0x3e, 0xf4, 0x23, 0xf7, 0x37, 0x24,
-0x73, 0x60, 0x0f, 0x9a, 0x16, 0xe5, 0xf1, 0xc7, 0x6b, 0xec, 0x8f, 0xee,
-0x38, 0xba, 0x65, 0xe4, 0xcf, 0x5f, 0x4c, 0x0c, 0x2b, 0xdc, 0x9a, 0x17,
-0x3e, 0xa9, 0xcc, 0xd1, 0xc1, 0x2e, 0x92, 0x7e, 0xb3, 0x1d, 0x5f, 0xde,
-0xed, 0x63, 0xbb, 0xb3, 0xff, 0x71, 0xb8, 0x8b, 0x6e, 0x27, 0x86, 0x1e,
-0xb1, 0xf2, 0x8b, 0xdd, 0xf0, 0xdb, 0xaa, 0x66, 0xc7, 0x31, 0x23, 0x69,
-0xa9, 0xa8, 0x0c, 0x73, 0x5d, 0x96, 0x57, 0x39, 0xaa, 0x5c, 0xf3, 0x88,
-0x46, 0x71, 0x46, 0x13, 0xd5, 0x88, 0x3e, 0x37, 0xf4, 0xd5, 0xf8, 0xf8,
-0x11, 0xe5, 0x50, 0x4a, 0x66, 0x5a, 0x08, 0xfc, 0xcc, 0x37, 0xd3, 0x78,
-0x5b, 0xd1, 0x4b, 0xc2, 0x3c, 0xaa, 0xe0, 0x82, 0x3b, 0x08, 0xec, 0x1f,
-0x34, 0xd2, 0xec, 0xa2, 0x12, 0x8d, 0x71, 0x85, 0x1d, 0xb9, 0x24, 0x8a,
-0xc9, 0xfa, 0xde, 0xe3
+0x3c, 0x77, 0x6d, 0xae, 0xa6, 0x5f, 0x50, 0x5b, 0xf0, 0x19, 0xd4, 0x47,
+0xef, 0xdb, 0xb5, 0xd9, 0x62, 0x8e, 0xc1, 0x6e, 0xae, 0x55, 0x6d, 0x48,
+0xab, 0x16, 0xe7, 0xc9, 0xad, 0x26, 0x89, 0x0f, 0x44, 0x9e, 0xfa, 0x9a,
+0x5b, 0x87, 0x55, 0x17, 0x5b, 0xac, 0x00, 0x35, 0x77, 0x88, 0x82, 0x41,
+0xe2, 0x71, 0x0c, 0x43, 0x5f, 0x2f, 0x71, 0xf0, 0xfa, 0xdd, 0x67, 0xa8,
+0x52, 0x95, 0xe7, 0xab, 0x86, 0x37, 0x6c, 0x6e, 0xcc, 0x26, 0x18, 0xf0,
+0xa5, 0x5d, 0x59, 0xf0, 0xe2, 0x7e, 0xeb, 0x1e, 0x6f, 0x16, 0x35, 0xa4,
+0x89, 0xda, 0xce, 0x48, 0xab, 0xe4, 0x06, 0x67, 0x87, 0x38, 0x71, 0x69,
+0xf0, 0xb3, 0x11, 0xd9, 0x31, 0xac, 0xda, 0x75, 0x92, 0x5f, 0x35, 0xe1,
+0xf9, 0x7f, 0x25, 0x3a, 0x08, 0x5e, 0x67, 0x2f, 0xdf, 0x0b, 0x2e, 0x32,
+0xda, 0x26, 0xe1, 0x25, 0x01, 0xae, 0x33, 0x65, 0x7f, 0xd4, 0x5b, 0xaf,
+0x08, 0xe6, 0xb3, 0x7f, 0xe5, 0x67, 0xd7, 0x88, 0x00, 0xeb, 0x0d, 0x18,
+0x59, 0x99, 0xa1, 0xec, 0xaa, 0x3f, 0xd6, 0x82, 0x28, 0xa0, 0x3a, 0x52,
+0x71, 0x9e, 0x76, 0x64, 0xe5, 0xa8, 0x53, 0x40, 0x2e, 0xc8, 0xbb, 0x4a,
+0x4a, 0x09, 0xf4, 0x33, 0x89, 0x0a, 0x5b, 0xf3, 0x08, 0xc0, 0xc0, 0xf7,
+0x1b, 0xbe, 0x6d, 0x76, 0x30, 0x33, 0x8a, 0x35, 0x77, 0x8a, 0xb5, 0x1a,
+0xa9, 0xc0, 0xc3, 0x18, 0xdb, 0x90, 0x6d, 0x2e, 0xd0, 0x99, 0xbb, 0xfd,
+0x9d, 0x06, 0xbc, 0x24, 0x68, 0x84, 0xd2, 0x58, 0xb0, 0xf6, 0xbd, 0x06,
+0x51, 0x8e, 0x02, 0x66, 0xec, 0xcd, 0xad, 0xd2, 0xde, 0xbd, 0x9d, 0xc5,
+0xe1, 0x35, 0x4a, 0x58, 0x87, 0xed, 0x5c, 0x8e, 0x58, 0x5a, 0x2b, 0x39,
+0x9d, 0xd5, 0xfd, 0xc4, 0xa0, 0xf2, 0xbe, 0xa1, 0x5f, 0xb6, 0x20, 0xf4,
+0xf3, 0xd9, 0xc7, 0xa8
};
const size_t LEAF_A_CERT_len = sizeof(LEAF_A_CERT);
/* Chain A - Raw Certificate Chain (Intermediate+Leaf) (DER format) */
const unsigned char RAW_CERT_CHAIN_A[] = {
0x30, 0x82, 0x05, 0x0c, 0x30, 0x82, 0x02, 0xf4, 0xa0, 0x03, 0x02, 0x01,
-0x02, 0x02, 0x14, 0x36, 0x1c, 0xce, 0x27, 0xef, 0xbb, 0xb2, 0x64, 0xa5,
-0xcf, 0x7a, 0xfd, 0x78, 0x3c, 0xf1, 0xbc, 0xe7, 0x95, 0x58, 0xf4, 0x30,
+0x02, 0x02, 0x14, 0x55, 0x35, 0x79, 0x1c, 0xb8, 0x76, 0xdf, 0x38, 0x63,
+0x54, 0xc5, 0x6f, 0xe6, 0xd8, 0xc2, 0xaf, 0x32, 0xac, 0xaa, 0xe1, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x30, 0x81, 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
@@ -366,9 +366,9 @@ const unsigned char RAW_CERT_CHAIN_A[] = {
0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x52, 0x6f, 0x6f, 0x74,
0x20, 0x43, 0x41, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03,
0x0c, 0x0e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x20, 0x52, 0x6f, 0x6f,
-0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x35,
-0x30, 0x38, 0x32, 0x32, 0x30, 0x37, 0x31, 0x30, 0x5a, 0x17, 0x0d, 0x33,
-0x30, 0x30, 0x35, 0x30, 0x37, 0x32, 0x32, 0x30, 0x37, 0x31, 0x30, 0x5a,
+0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x35,
+0x30, 0x39, 0x32, 0x31, 0x33, 0x35, 0x35, 0x31, 0x5a, 0x17, 0x0d, 0x33,
+0x31, 0x30, 0x35, 0x30, 0x38, 0x32, 0x31, 0x33, 0x35, 0x35, 0x31, 0x5a,
0x30, 0x81, 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69,
@@ -384,84 +384,84 @@ const unsigned char RAW_CERT_CHAIN_A[] = {
0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
-0x01, 0x01, 0x00, 0xb7, 0x48, 0xf5, 0x71, 0x92, 0x7b, 0xd3, 0x68, 0xe0,
-0x31, 0xd2, 0x43, 0x03, 0xe2, 0x41, 0x7b, 0x48, 0xc7, 0x32, 0xef, 0x35,
-0x4c, 0xa0, 0x8e, 0x92, 0xf2, 0x40, 0x6e, 0x90, 0x7a, 0xbf, 0x57, 0x2c,
-0x1e, 0x66, 0x8c, 0x2b, 0x19, 0xca, 0xde, 0x78, 0x40, 0x23, 0x90, 0xbd,
-0xf4, 0xcf, 0x4e, 0x84, 0xf1, 0xf2, 0x3d, 0xd6, 0xd0, 0xbf, 0xfa, 0x94,
-0x37, 0xda, 0x93, 0x2f, 0x29, 0xea, 0x62, 0xb7, 0x04, 0xb8, 0x45, 0x6a,
-0x2f, 0xbe, 0x76, 0x13, 0x48, 0x02, 0x12, 0x84, 0x6e, 0x5b, 0x1e, 0x2f,
-0x44, 0x80, 0x19, 0x75, 0x44, 0x81, 0x02, 0xc0, 0x55, 0x79, 0x9c, 0x20,
-0x59, 0x35, 0xcc, 0x1e, 0x27, 0x9b, 0xcb, 0x3e, 0xfb, 0x71, 0x65, 0x27,
-0xbd, 0xb9, 0x32, 0x04, 0xd0, 0xa0, 0x5c, 0x60, 0xfc, 0xf0, 0xc3, 0xf2,
-0xf8, 0x9f, 0xad, 0x7a, 0x15, 0xcc, 0x41, 0xdd, 0x16, 0x39, 0x1e, 0xff,
-0x7d, 0xe1, 0xc8, 0xc5, 0x91, 0xde, 0x95, 0x2b, 0xc8, 0x29, 0xb2, 0x74,
-0xf3, 0xea, 0x7b, 0x3d, 0xaf, 0x70, 0x97, 0xd1, 0x48, 0x4d, 0x6d, 0x09,
-0xd2, 0xb9, 0xe0, 0xb4, 0x52, 0xa1, 0xe2, 0xf5, 0x7c, 0x07, 0xe2, 0xc1,
-0x51, 0x90, 0xb2, 0xe2, 0x6e, 0xf4, 0xaa, 0x2f, 0xda, 0x59, 0x0a, 0xd0,
-0x17, 0xb9, 0xc4, 0xf7, 0xed, 0x6f, 0xf1, 0x75, 0x5f, 0x37, 0xa6, 0x08,
-0x86, 0xa0, 0x36, 0x30, 0xa3, 0xad, 0x06, 0xcc, 0xa3, 0xe7, 0x2e, 0x5f,
-0xc0, 0x74, 0xb5, 0x59, 0xc8, 0x03, 0x31, 0xd6, 0x71, 0x8c, 0xa0, 0x19,
-0xcc, 0x34, 0x40, 0x88, 0x86, 0xb9, 0x57, 0xa5, 0x6c, 0xf4, 0x21, 0x3d,
-0x6d, 0x55, 0x53, 0x5f, 0x25, 0x4b, 0x8b, 0xad, 0xd4, 0x65, 0xd8, 0xca,
-0xc1, 0xc9, 0xe7, 0x44, 0x52, 0x6f, 0x4b, 0x2f, 0x81, 0xc3, 0x8c, 0xf5,
-0xf4, 0x09, 0x64, 0x0b, 0xe6, 0xad, 0x2d, 0x02, 0x03, 0x01, 0x00, 0x01,
+0x01, 0x01, 0x00, 0xb4, 0x63, 0xe7, 0xd5, 0xd8, 0x91, 0xa3, 0x70, 0xb0,
+0xfb, 0xbf, 0x95, 0xed, 0xbb, 0x50, 0xa3, 0xff, 0x74, 0x34, 0x45, 0x20,
+0xfc, 0xe8, 0xf3, 0x11, 0xa9, 0x01, 0x4b, 0x14, 0x61, 0x0b, 0xf8, 0x73,
+0x71, 0xc0, 0x5c, 0x58, 0x8c, 0x89, 0xf0, 0x2c, 0x87, 0xbb, 0x16, 0x69,
+0xc4, 0xd7, 0xa6, 0x67, 0x78, 0x5f, 0xac, 0xce, 0xbd, 0x74, 0xe3, 0x87,
+0x41, 0x71, 0x8e, 0xb6, 0x8e, 0x19, 0xe7, 0x72, 0xa4, 0xf0, 0x44, 0xfd,
+0x4d, 0x24, 0xf4, 0x3d, 0x31, 0xae, 0x1c, 0x86, 0x4e, 0xeb, 0xcc, 0x24,
+0xa9, 0xe9, 0x9e, 0x42, 0x7c, 0x08, 0x4f, 0xd6, 0x02, 0x7e, 0x4a, 0xb0,
+0x61, 0xef, 0x93, 0xd1, 0x89, 0x4c, 0x19, 0x67, 0xe2, 0x1d, 0x48, 0xc6,
+0x19, 0xad, 0x0e, 0xe6, 0x00, 0x27, 0x6a, 0x4c, 0xcf, 0x0d, 0x29, 0x3e,
+0xba, 0x4c, 0x4d, 0x34, 0xa9, 0x34, 0x52, 0xf5, 0x8a, 0x72, 0xd9, 0xcd,
+0x9d, 0x5a, 0x0b, 0xff, 0xce, 0x7e, 0x0a, 0x1b, 0x64, 0x7f, 0x60, 0x2d,
+0x08, 0x56, 0xcf, 0x25, 0xda, 0xbe, 0x02, 0x89, 0xce, 0x54, 0x20, 0x4f,
+0xf8, 0x45, 0x72, 0x5c, 0x98, 0xad, 0xb4, 0x19, 0x9d, 0xe2, 0xa1, 0x04,
+0xe4, 0xe3, 0x2a, 0xc9, 0x92, 0x34, 0x61, 0xfc, 0x08, 0x77, 0x7b, 0x3d,
+0x41, 0x06, 0x74, 0xd9, 0x08, 0x0d, 0xbd, 0x5a, 0x2c, 0xa3, 0x5e, 0x57,
+0xb9, 0xc0, 0xa3, 0xcf, 0x1f, 0xa6, 0xe5, 0x62, 0xe8, 0x75, 0x17, 0x98,
+0x0a, 0xda, 0xd7, 0x2b, 0x5a, 0x57, 0x8d, 0xfc, 0xd7, 0x5f, 0x61, 0xa6,
+0xb3, 0x10, 0x46, 0x8a, 0xa6, 0x36, 0xe1, 0xaa, 0xf9, 0x8b, 0xc0, 0xc2,
+0x77, 0x89, 0x2b, 0x59, 0x9c, 0xa5, 0xd7, 0xea, 0x17, 0x37, 0x47, 0x55,
+0xb9, 0x23, 0x89, 0x46, 0xee, 0x97, 0x13, 0x44, 0xd3, 0x92, 0x75, 0xdb,
+0x28, 0xf6, 0xc5, 0xfc, 0x08, 0x6f, 0xbf, 0x02, 0x03, 0x01, 0x00, 0x01,
0xa3, 0x66, 0x30, 0x64, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00,
0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
-0x16, 0x04, 0x14, 0x6d, 0x76, 0xf6, 0xca, 0xd3, 0xa1, 0x4e, 0xff, 0xa2,
-0x4d, 0x59, 0x8a, 0x53, 0x28, 0x15, 0x5c, 0x5a, 0xfa, 0x69, 0x4c, 0x30,
+0x16, 0x04, 0x14, 0x3e, 0x55, 0xb6, 0xa0, 0x53, 0x80, 0xf0, 0x03, 0xc8,
+0x9d, 0xcd, 0x87, 0x80, 0x7f, 0x62, 0x6d, 0xae, 0x36, 0x93, 0xf2, 0x30,
0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
-0xb6, 0x3c, 0x52, 0x3c, 0x43, 0x68, 0x11, 0x95, 0x13, 0x8c, 0x57, 0x2e,
-0x17, 0x0f, 0xc3, 0x96, 0x13, 0x86, 0x01, 0x59, 0x30, 0x0d, 0x06, 0x09,
+0xeb, 0x5c, 0xc9, 0x3a, 0x7e, 0x10, 0x39, 0xd4, 0xf9, 0xd1, 0xac, 0x31,
+0xac, 0xf5, 0xb1, 0xd8, 0xd1, 0xdc, 0x65, 0xb6, 0x30, 0x0d, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
-0x82, 0x02, 0x01, 0x00, 0x93, 0x46, 0xb9, 0xdc, 0x7e, 0x64, 0x3d, 0x69,
-0x03, 0x33, 0xba, 0x2a, 0xd2, 0xae, 0x9f, 0xdb, 0x90, 0x97, 0x69, 0xfc,
-0x28, 0xff, 0x66, 0x9a, 0xe1, 0x30, 0xb2, 0x3a, 0xce, 0x6d, 0x5f, 0x8a,
-0x06, 0x97, 0x01, 0x61, 0x07, 0x1c, 0x4b, 0x91, 0x62, 0xd6, 0x8f, 0x97,
-0x67, 0xcf, 0x0a, 0x7b, 0x5c, 0x50, 0x80, 0x5c, 0x26, 0x74, 0xdd, 0x53,
-0x70, 0xa6, 0xfe, 0x41, 0xe3, 0x8a, 0xd2, 0x6a, 0x66, 0xd7, 0x8f, 0x33,
-0xec, 0x84, 0xc2, 0xeb, 0xc4, 0x60, 0xdf, 0x38, 0xb6, 0xbf, 0x52, 0x39,
-0x82, 0x37, 0x3e, 0xda, 0xb5, 0xa9, 0x61, 0x08, 0x52, 0xf1, 0xbf, 0x9b,
-0x2a, 0x72, 0x3e, 0xf5, 0xba, 0xc1, 0x69, 0x97, 0xd7, 0xa4, 0x33, 0xa9,
-0xb7, 0x26, 0xb6, 0x53, 0x17, 0xdf, 0x7e, 0x80, 0xc2, 0xcd, 0xc3, 0xda,
-0x91, 0x54, 0x84, 0x1b, 0xce, 0xa3, 0xf9, 0x3e, 0xf6, 0x38, 0x16, 0x34,
-0xd9, 0x82, 0x06, 0x85, 0x8e, 0xda, 0x4d, 0x30, 0x84, 0x50, 0x59, 0x94,
-0xc1, 0xf7, 0xa2, 0xc7, 0xf7, 0xdd, 0x09, 0xe4, 0x03, 0x8b, 0xc9, 0x6f,
-0x6d, 0x3e, 0x1a, 0x6a, 0x78, 0x62, 0xe4, 0x3a, 0xa8, 0xac, 0x67, 0x7a,
-0x9c, 0x42, 0x96, 0x79, 0x5c, 0x25, 0xb0, 0x71, 0x3b, 0xd7, 0xdf, 0x67,
-0x46, 0x08, 0x70, 0x5f, 0xec, 0xd8, 0x29, 0x38, 0xf7, 0xac, 0xe3, 0x74,
-0x17, 0xc2, 0x1f, 0x1f, 0xe6, 0x6e, 0x89, 0x0a, 0x48, 0xf9, 0x19, 0x6c,
-0x65, 0xf0, 0x90, 0x85, 0x0d, 0xa4, 0xa0, 0x44, 0xc5, 0xf7, 0x3e, 0x59,
-0xd1, 0x2d, 0xf0, 0x1f, 0x53, 0x6f, 0xbb, 0x3a, 0xf9, 0x3e, 0x77, 0xb2,
-0x23, 0x5b, 0x13, 0x09, 0x07, 0xbe, 0xcc, 0xba, 0xf9, 0xdd, 0x0f, 0x1d,
-0x1b, 0x8e, 0x03, 0xfc, 0xc2, 0x28, 0xe2, 0xbe, 0xb7, 0x08, 0x42, 0x64,
-0x32, 0xee, 0x74, 0x52, 0x28, 0x8b, 0xcb, 0x8f, 0x6b, 0x86, 0xbc, 0x4d,
-0xbd, 0x9c, 0x83, 0x49, 0xc8, 0xdc, 0xa1, 0x97, 0x12, 0xe6, 0xe7, 0x06,
-0x6e, 0xc7, 0x60, 0xe9, 0x59, 0xbb, 0xfe, 0xac, 0x15, 0x11, 0x11, 0x58,
-0x2b, 0x7e, 0xf5, 0x5a, 0x4d, 0xac, 0xc3, 0x11, 0x94, 0x0e, 0xf9, 0x40,
-0x82, 0x3f, 0x73, 0x87, 0x40, 0x98, 0x51, 0xcf, 0x68, 0xfa, 0x9f, 0x89,
-0xe5, 0xbe, 0xfc, 0x8c, 0xd5, 0x41, 0x8f, 0x50, 0x45, 0xb0, 0x97, 0x7a,
-0x1a, 0x72, 0xfb, 0x67, 0xe9, 0x5b, 0x5b, 0xba, 0x38, 0x51, 0xb1, 0xa4,
-0x70, 0x4d, 0xaf, 0xfb, 0xe2, 0x91, 0xfd, 0xcc, 0xf5, 0x5a, 0x90, 0x09,
-0xea, 0x92, 0x72, 0x7f, 0x03, 0x3a, 0x4c, 0xa5, 0x36, 0x89, 0xd5, 0x15,
-0x20, 0xa8, 0xbb, 0x10, 0xf9, 0xad, 0xdf, 0x03, 0xfe, 0x8a, 0xbd, 0x8c,
-0xe1, 0x68, 0x91, 0x5d, 0x5f, 0xc9, 0xb0, 0x6f, 0x24, 0xe6, 0x2e, 0x28,
-0x7e, 0xf0, 0x05, 0xf9, 0xe3, 0xbb, 0xa1, 0xdb, 0x87, 0xa0, 0x51, 0xe9,
-0x04, 0x8e, 0x5b, 0x4f, 0xf1, 0x06, 0x62, 0xf3, 0x1c, 0x2e, 0x6a, 0x5f,
-0x4c, 0xce, 0x41, 0x6b, 0x3a, 0x46, 0x70, 0xff, 0x0d, 0x49, 0x65, 0x46,
-0xa2, 0x74, 0xac, 0x27, 0x12, 0x8f, 0xc3, 0x16, 0x9d, 0x5f, 0x0a, 0x74,
-0x8e, 0x7b, 0x3e, 0x2c, 0xa3, 0x68, 0x92, 0xca, 0x11, 0xe1, 0xad, 0x9f,
-0x1f, 0x36, 0x8f, 0x6e, 0xb5, 0x88, 0x3e, 0x76, 0x36, 0x0b, 0x0a, 0xf1,
-0x35, 0xa1, 0xad, 0x94, 0x27, 0xbd, 0xd5, 0xba, 0x77, 0x34, 0xcd, 0xb8,
-0x9e, 0xf5, 0x45, 0xe6, 0x19, 0x6b, 0xb3, 0x29, 0x9a, 0x9f, 0xf4, 0x7a,
-0x50, 0x75, 0x6e, 0x5a, 0x80, 0x36, 0x74, 0xed, 0x9a, 0x12, 0xbe, 0xed,
-0x9b, 0xbc, 0xb1, 0xed, 0x9a, 0x24, 0xb7, 0x76, 0x1b, 0x39, 0x36, 0x1a,
-0x59, 0xa9, 0xd1, 0xdc, 0xc8, 0xd7, 0xc7, 0x33, 0xd5, 0xf2, 0x61, 0x31,
+0x82, 0x02, 0x01, 0x00, 0x78, 0x8f, 0x3e, 0xba, 0x86, 0x02, 0x71, 0xd8,
+0x16, 0x0d, 0x16, 0x80, 0x4a, 0x0c, 0xa0, 0x82, 0xb9, 0xbf, 0x63, 0xcc,
+0x65, 0x85, 0xdd, 0xef, 0x47, 0x9e, 0xb6, 0xf8, 0x3a, 0x52, 0xa7, 0x85,
+0x22, 0x1c, 0xc4, 0xd6, 0x12, 0x0c, 0xa4, 0x79, 0xd4, 0x00, 0xb7, 0xac,
+0xba, 0x60, 0xba, 0xd3, 0xf6, 0x86, 0x30, 0xa0, 0xf5, 0x16, 0xe3, 0x36,
+0x53, 0x88, 0x39, 0xab, 0xcb, 0xde, 0x8f, 0xc0, 0xbc, 0x68, 0xec, 0x05,
+0x8a, 0xca, 0x40, 0x65, 0x26, 0xbf, 0x9a, 0x29, 0x8a, 0x50, 0x04, 0xf9,
+0x89, 0x19, 0x0d, 0x38, 0xf8, 0x36, 0x41, 0x97, 0x34, 0xf3, 0xcb, 0x34,
+0x0d, 0x97, 0xa0, 0xb7, 0x9b, 0xaa, 0x6e, 0x37, 0x66, 0xc6, 0x17, 0x9c,
+0x58, 0xf1, 0x7c, 0x2c, 0x7b, 0x03, 0x7b, 0xd0, 0x58, 0x15, 0x11, 0xe9,
+0xc7, 0x95, 0x09, 0x0e, 0x2b, 0xeb, 0x2a, 0x68, 0x5b, 0x78, 0xe7, 0x25,
+0x73, 0xfb, 0x6e, 0x28, 0x63, 0x66, 0x3d, 0xe2, 0x84, 0x99, 0xa9, 0x11,
+0x0b, 0xea, 0x41, 0x27, 0x16, 0x24, 0x31, 0xed, 0x2e, 0xba, 0x3a, 0xfc,
+0xb6, 0x61, 0x6c, 0xc8, 0xf2, 0xff, 0x96, 0x3f, 0x27, 0x57, 0x44, 0x70,
+0x36, 0x87, 0x87, 0x97, 0xc1, 0x9e, 0x38, 0x00, 0x40, 0xe9, 0x0f, 0x76,
+0x94, 0x37, 0x9d, 0x9b, 0x7b, 0xe8, 0x11, 0x0d, 0x07, 0x2b, 0x3c, 0xee,
+0x21, 0x76, 0x7f, 0x76, 0xf5, 0x9e, 0x49, 0x34, 0x84, 0xcc, 0x8b, 0x8e,
+0x00, 0xa4, 0x72, 0x3d, 0x80, 0x9e, 0x7f, 0x21, 0x0d, 0x72, 0x07, 0x0d,
+0xd4, 0xbc, 0x0d, 0xb2, 0x1c, 0xb2, 0x5a, 0xf4, 0x62, 0xc9, 0xf7, 0x1d,
+0x65, 0xb8, 0x74, 0xc2, 0xea, 0x12, 0xa9, 0x18, 0x7b, 0xb1, 0xea, 0x3f,
+0x4a, 0x16, 0x91, 0xe1, 0x2d, 0xe3, 0x15, 0x3f, 0x3e, 0x16, 0x4a, 0x7b,
+0x41, 0x2c, 0xf5, 0xb9, 0xad, 0xcc, 0x94, 0xd3, 0x39, 0xaa, 0x6d, 0x43,
+0x79, 0x78, 0x76, 0x5b, 0x1d, 0x0c, 0x17, 0xc3, 0x15, 0x0f, 0x09, 0xc5,
+0xcd, 0xed, 0x51, 0xba, 0xd3, 0x73, 0x64, 0x8c, 0x95, 0xd0, 0x6e, 0xdf,
+0x85, 0x57, 0x82, 0x46, 0x00, 0xf6, 0x65, 0x48, 0x11, 0x89, 0xa2, 0x58,
+0xcc, 0xd3, 0xa4, 0x6f, 0x9c, 0x2e, 0x02, 0x75, 0x78, 0xb1, 0xd7, 0x3c,
+0xfc, 0xf9, 0x8c, 0xc5, 0x0b, 0x74, 0xee, 0xd2, 0xe0, 0x72, 0xff, 0xb3,
+0x75, 0xe6, 0x8b, 0x8d, 0x1e, 0x60, 0x78, 0xcf, 0x5f, 0x30, 0x89, 0xc2,
+0xfd, 0x3f, 0x90, 0xaf, 0x2b, 0xdd, 0x19, 0x7c, 0x7b, 0x66, 0x82, 0x38,
+0x3f, 0x1d, 0x06, 0x5a, 0x2c, 0x10, 0x30, 0x36, 0x4c, 0x4f, 0x7d, 0x68,
+0xcb, 0x87, 0x31, 0x4d, 0xbd, 0x9b, 0x04, 0x82, 0x46, 0x0d, 0xd8, 0x4d,
+0x59, 0xe6, 0x3d, 0x03, 0xce, 0xea, 0x2f, 0xc2, 0x5e, 0x7b, 0xd1, 0xe0,
+0x2b, 0x8d, 0x9e, 0x0e, 0xdb, 0xcd, 0xd2, 0xa8, 0x98, 0xa6, 0x00, 0xd8,
+0xa6, 0x35, 0x81, 0xec, 0xdc, 0xee, 0xcb, 0x65, 0x1e, 0x41, 0xb4, 0xab,
+0xe0, 0x77, 0x63, 0xc1, 0x95, 0x82, 0x29, 0x54, 0xe3, 0xb7, 0x74, 0xee,
+0x6c, 0xe5, 0x86, 0x90, 0x4b, 0xfa, 0xf0, 0x18, 0x1a, 0xd7, 0x38, 0x73,
+0xc1, 0x5f, 0x32, 0x94, 0xd6, 0xd7, 0xaa, 0xf4, 0xb6, 0xd7, 0x65, 0xbc,
+0xa3, 0x0b, 0x6d, 0xe3, 0xd2, 0xd1, 0xa3, 0x11, 0x24, 0x6b, 0x12, 0x01,
+0xcc, 0xee, 0x66, 0xd3, 0x9c, 0x3b, 0xb7, 0xe6, 0x42, 0x54, 0x96, 0xec,
+0x86, 0x55, 0x3a, 0x81, 0x00, 0x51, 0x93, 0x7a, 0x8f, 0xe8, 0xe4, 0x5f,
+0x4b, 0x90, 0x1c, 0xa9, 0x75, 0x2d, 0x8a, 0x68, 0xec, 0x32, 0x26, 0xe6,
+0xdb, 0x65, 0xbf, 0x3f, 0x04, 0x60, 0xc1, 0xa5, 0xa6, 0xbd, 0x3d, 0xfe,
+0x1a, 0x55, 0x8f, 0x76, 0x31, 0x6d, 0xfb, 0x6f, 0xbf, 0x4d, 0xbc, 0xe6,
0x30, 0x82, 0x04, 0x20, 0x30, 0x82, 0x03, 0x08, 0xa0, 0x03, 0x02, 0x01,
-0x02, 0x02, 0x14, 0x15, 0x6c, 0x2a, 0xad, 0x3a, 0x2d, 0xb5, 0xb4, 0x2e,
-0x81, 0x9d, 0x0c, 0xd9, 0x2f, 0x26, 0x2c, 0x1e, 0xac, 0x21, 0x14, 0x30,
+0x02, 0x02, 0x14, 0x74, 0x98, 0x82, 0x8b, 0x39, 0xcf, 0x41, 0xe8, 0xac,
+0xff, 0x24, 0x6e, 0xb2, 0x8a, 0xc6, 0x6c, 0x72, 0x25, 0x90, 0x09, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x30, 0x81, 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
@@ -476,9 +476,9 @@ const unsigned char RAW_CERT_CHAIN_A[] = {
0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x43, 0x68,
0x61, 0x69, 0x6e, 0x41, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65,
0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d,
-0x32, 0x35, 0x30, 0x35, 0x30, 0x38, 0x32, 0x32, 0x30, 0x37, 0x31, 0x30,
-0x5a, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x35, 0x30, 0x38, 0x32, 0x32, 0x30,
-0x37, 0x31, 0x30, 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06,
+0x32, 0x36, 0x30, 0x35, 0x30, 0x39, 0x32, 0x31, 0x33, 0x35, 0x35, 0x31,
+0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x35, 0x30, 0x39, 0x32, 0x31, 0x33,
+0x35, 0x35, 0x31, 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06,
0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11,
0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66,
0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55,
@@ -492,62 +492,62 @@ const unsigned char RAW_CERT_CHAIN_A[] = {
0x2d, 0x61, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63,
0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
-0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x95,
-0xc0, 0xd1, 0xf3, 0x6a, 0xbd, 0xc9, 0xe0, 0xee, 0x14, 0x0a, 0x09, 0xca,
-0x18, 0xe7, 0x0a, 0x9f, 0x9e, 0x34, 0x22, 0xa2, 0x06, 0x9c, 0xb4, 0xc8,
-0xdd, 0x0c, 0xa9, 0x20, 0x48, 0x9d, 0xd6, 0xa9, 0xf9, 0x61, 0xe1, 0xce,
-0x39, 0x42, 0x41, 0x5c, 0xb4, 0xb1, 0xba, 0xe9, 0xf0, 0x5f, 0xb6, 0xab,
-0x53, 0x2b, 0x4c, 0x74, 0x9c, 0x26, 0xaa, 0x33, 0x5d, 0xd6, 0x50, 0x67,
-0xbd, 0x9f, 0x52, 0x21, 0xe0, 0xf6, 0x2d, 0x92, 0x1f, 0x42, 0x90, 0x13,
-0x1d, 0xed, 0x62, 0x83, 0x51, 0xfa, 0xa0, 0x3b, 0xac, 0x32, 0x71, 0x3d,
-0x4f, 0x21, 0x11, 0x33, 0xf9, 0x00, 0xf7, 0xd4, 0x9b, 0xdc, 0x65, 0xff,
-0x71, 0x3c, 0x0f, 0x7f, 0x94, 0x7b, 0xbc, 0xe5, 0x08, 0xec, 0xda, 0xc8,
-0x4f, 0x45, 0xb5, 0xd1, 0x34, 0xde, 0x24, 0x4b, 0xf9, 0xfe, 0x75, 0x3d,
-0x99, 0x97, 0x63, 0xf6, 0x0f, 0x2f, 0xb1, 0x77, 0xfd, 0xf8, 0xc2, 0xb3,
-0xed, 0xd5, 0xbb, 0x68, 0xf5, 0x6e, 0x57, 0x7e, 0x5b, 0xd0, 0xe4, 0x41,
-0x67, 0x21, 0x55, 0x62, 0x92, 0x0c, 0x12, 0x3c, 0xf0, 0xf4, 0x3a, 0xe4,
-0xc2, 0x66, 0x04, 0x44, 0xf4, 0xaf, 0xc5, 0x86, 0xa1, 0xff, 0xb9, 0x03,
-0x9d, 0x4c, 0xe4, 0xc5, 0xe3, 0xf8, 0xb9, 0x35, 0xf6, 0x1a, 0x65, 0x20,
-0x93, 0xf6, 0x0e, 0xfc, 0xac, 0xdc, 0x5b, 0x97, 0x87, 0xe4, 0xad, 0x1c,
-0x4a, 0xfc, 0x5f, 0xb0, 0xbb, 0xd6, 0x94, 0x72, 0x3b, 0x4f, 0xbe, 0x3f,
-0xfe, 0x76, 0xea, 0xa1, 0xdf, 0x12, 0xc0, 0xd8, 0x88, 0x8b, 0xbd, 0x30,
-0xa9, 0x87, 0x6c, 0xaf, 0x72, 0xab, 0x20, 0xa8, 0x2e, 0x4d, 0x01, 0x80,
-0xb5, 0xcd, 0x32, 0x90, 0x6c, 0x35, 0x6f, 0xbd, 0x1f, 0xf7, 0x6a, 0xb1,
-0xb1, 0xdc, 0x18, 0x24, 0x15, 0xff, 0xd1, 0xef, 0xb5, 0xe8, 0xef, 0x94,
-0x45, 0xf3, 0xa1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x72, 0x30, 0x70,
+0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf,
+0xfb, 0xa0, 0xf1, 0x89, 0x70, 0x45, 0xf8, 0xe9, 0xc5, 0xc0, 0xde, 0x49,
+0xb9, 0x22, 0x8a, 0x0a, 0x16, 0xbc, 0xf0, 0x4d, 0xf9, 0x70, 0xa2, 0x4c,
+0xab, 0x3d, 0x4e, 0x22, 0x04, 0xf8, 0xa6, 0xb9, 0xb8, 0x78, 0x33, 0x63,
+0x7f, 0x4b, 0xb9, 0x9f, 0xef, 0xc3, 0xda, 0xce, 0xea, 0x6b, 0x8f, 0x5e,
+0x7b, 0x96, 0x94, 0x97, 0x34, 0xde, 0xb9, 0x15, 0x86, 0x79, 0xcf, 0x61,
+0x9e, 0x21, 0x6d, 0x84, 0x88, 0xc4, 0x01, 0x5d, 0xc9, 0x2a, 0xc8, 0x7c,
+0x0b, 0xed, 0x5c, 0x76, 0x95, 0x57, 0xb5, 0x0d, 0x80, 0x25, 0x67, 0x5a,
+0xd2, 0x9f, 0x25, 0x64, 0x48, 0xa8, 0xbd, 0x89, 0x4d, 0x93, 0x06, 0x2e,
+0xc5, 0x27, 0xe7, 0xfa, 0x49, 0x59, 0x22, 0x4e, 0xe4, 0x82, 0xa0, 0xdc,
+0x10, 0x7e, 0xf7, 0x2f, 0xb4, 0xc5, 0x01, 0x4f, 0xf2, 0x8b, 0x62, 0xc2,
+0xcd, 0x70, 0x06, 0x70, 0xa4, 0x8c, 0x05, 0x7a, 0x8a, 0x82, 0x82, 0x57,
+0x02, 0x37, 0x04, 0x24, 0xa6, 0x3d, 0x56, 0xcf, 0x2f, 0x6e, 0x95, 0x52,
+0xc1, 0x08, 0xd6, 0x8e, 0x07, 0x47, 0x23, 0xfd, 0xc5, 0xf3, 0x86, 0x29,
+0x7a, 0xaa, 0x46, 0x1d, 0xba, 0x9f, 0xd5, 0x8d, 0xc3, 0x4d, 0x20, 0xd9,
+0x31, 0xf0, 0x53, 0x4b, 0x92, 0xb4, 0x82, 0x85, 0x06, 0x3b, 0xd9, 0xde,
+0x43, 0x86, 0x66, 0xfc, 0x29, 0x15, 0xc4, 0xa9, 0x6c, 0xb1, 0x70, 0xb4,
+0x0d, 0xe1, 0x37, 0x1e, 0x92, 0x4a, 0xc3, 0x51, 0x4b, 0xbd, 0x59, 0xd4,
+0xa7, 0x3e, 0x64, 0x55, 0x50, 0xb0, 0x7a, 0x28, 0xf9, 0xea, 0x77, 0x66,
+0xd3, 0x2f, 0x97, 0xc6, 0xf8, 0xe9, 0x80, 0x1a, 0x22, 0xc8, 0x29, 0x47,
+0xfa, 0x24, 0xf7, 0x9a, 0x71, 0xd7, 0xed, 0x16, 0x2c, 0x32, 0x7e, 0x6d,
+0xc6, 0x47, 0x06, 0x9e, 0xdd, 0xf2, 0xee, 0xbc, 0xfe, 0x01, 0xc9, 0x3c,
+0xaf, 0xf3, 0xcd, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x72, 0x30, 0x70,
0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30,
0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
0x02, 0x05, 0xa0, 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c,
0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
-0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x33,
-0x09, 0x98, 0xae, 0xd4, 0xa7, 0x25, 0x93, 0x32, 0xe3, 0xcd, 0x77, 0xf9,
-0xfb, 0x9a, 0x04, 0x3c, 0x53, 0x13, 0x39, 0x30, 0x1f, 0x06, 0x03, 0x55,
-0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x6d, 0x76, 0xf6, 0xca,
-0xd3, 0xa1, 0x4e, 0xff, 0xa2, 0x4d, 0x59, 0x8a, 0x53, 0x28, 0x15, 0x5c,
-0x5a, 0xfa, 0x69, 0x4c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf9,
+0x20, 0x9b, 0xe2, 0x69, 0x11, 0xcb, 0xf7, 0x01, 0x4e, 0xd4, 0x93, 0xa5,
+0xbf, 0xe3, 0x99, 0x99, 0x0e, 0xb1, 0x92, 0x30, 0x1f, 0x06, 0x03, 0x55,
+0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x3e, 0x55, 0xb6, 0xa0,
+0x53, 0x80, 0xf0, 0x03, 0xc8, 0x9d, 0xcd, 0x87, 0x80, 0x7f, 0x62, 0x6d,
+0xae, 0x36, 0x93, 0xf2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
-0x38, 0xb4, 0xc7, 0xe8, 0x42, 0x3a, 0x9c, 0xc7, 0x7c, 0xb5, 0x1c, 0xe1,
-0x1b, 0x99, 0x06, 0x00, 0x9e, 0x0f, 0x60, 0xb2, 0x99, 0x6b, 0xc1, 0xc2,
-0x0e, 0x9a, 0x7b, 0x89, 0x5f, 0xd5, 0xa0, 0x16, 0x49, 0x38, 0x8c, 0xa1,
-0x51, 0x8b, 0xfd, 0xaf, 0xd4, 0x2a, 0x0e, 0xa0, 0x10, 0x36, 0x4a, 0x20,
-0xab, 0x1c, 0xa6, 0x0e, 0xe0, 0xda, 0x48, 0xc3, 0x29, 0xbb, 0x79, 0x0a,
-0x05, 0xf0, 0x5a, 0x7d, 0xc8, 0x59, 0x85, 0x2b, 0xe2, 0xcc, 0xba, 0xac,
-0x84, 0x45, 0x68, 0xc7, 0xf1, 0xe9, 0xfb, 0xa6, 0xbf, 0x40, 0xa8, 0x67,
-0xf6, 0xc4, 0xf6, 0xb8, 0x06, 0x3f, 0xcd, 0x16, 0x13, 0x52, 0x68, 0x78,
-0x06, 0xd2, 0xd3, 0x33, 0xd5, 0x03, 0x6b, 0x4f, 0xa7, 0x72, 0xd1, 0xf8,
-0x4e, 0xed, 0x78, 0x65, 0x3d, 0x60, 0x64, 0xcb, 0x5f, 0x1d, 0x6e, 0x31,
-0x92, 0x74, 0x50, 0x40, 0x7c, 0x78, 0x3e, 0xf4, 0x23, 0xf7, 0x37, 0x24,
-0x73, 0x60, 0x0f, 0x9a, 0x16, 0xe5, 0xf1, 0xc7, 0x6b, 0xec, 0x8f, 0xee,
-0x38, 0xba, 0x65, 0xe4, 0xcf, 0x5f, 0x4c, 0x0c, 0x2b, 0xdc, 0x9a, 0x17,
-0x3e, 0xa9, 0xcc, 0xd1, 0xc1, 0x2e, 0x92, 0x7e, 0xb3, 0x1d, 0x5f, 0xde,
-0xed, 0x63, 0xbb, 0xb3, 0xff, 0x71, 0xb8, 0x8b, 0x6e, 0x27, 0x86, 0x1e,
-0xb1, 0xf2, 0x8b, 0xdd, 0xf0, 0xdb, 0xaa, 0x66, 0xc7, 0x31, 0x23, 0x69,
-0xa9, 0xa8, 0x0c, 0x73, 0x5d, 0x96, 0x57, 0x39, 0xaa, 0x5c, 0xf3, 0x88,
-0x46, 0x71, 0x46, 0x13, 0xd5, 0x88, 0x3e, 0x37, 0xf4, 0xd5, 0xf8, 0xf8,
-0x11, 0xe5, 0x50, 0x4a, 0x66, 0x5a, 0x08, 0xfc, 0xcc, 0x37, 0xd3, 0x78,
-0x5b, 0xd1, 0x4b, 0xc2, 0x3c, 0xaa, 0xe0, 0x82, 0x3b, 0x08, 0xec, 0x1f,
-0x34, 0xd2, 0xec, 0xa2, 0x12, 0x8d, 0x71, 0x85, 0x1d, 0xb9, 0x24, 0x8a,
-0xc9, 0xfa, 0xde, 0xe3
+0x3c, 0x77, 0x6d, 0xae, 0xa6, 0x5f, 0x50, 0x5b, 0xf0, 0x19, 0xd4, 0x47,
+0xef, 0xdb, 0xb5, 0xd9, 0x62, 0x8e, 0xc1, 0x6e, 0xae, 0x55, 0x6d, 0x48,
+0xab, 0x16, 0xe7, 0xc9, 0xad, 0x26, 0x89, 0x0f, 0x44, 0x9e, 0xfa, 0x9a,
+0x5b, 0x87, 0x55, 0x17, 0x5b, 0xac, 0x00, 0x35, 0x77, 0x88, 0x82, 0x41,
+0xe2, 0x71, 0x0c, 0x43, 0x5f, 0x2f, 0x71, 0xf0, 0xfa, 0xdd, 0x67, 0xa8,
+0x52, 0x95, 0xe7, 0xab, 0x86, 0x37, 0x6c, 0x6e, 0xcc, 0x26, 0x18, 0xf0,
+0xa5, 0x5d, 0x59, 0xf0, 0xe2, 0x7e, 0xeb, 0x1e, 0x6f, 0x16, 0x35, 0xa4,
+0x89, 0xda, 0xce, 0x48, 0xab, 0xe4, 0x06, 0x67, 0x87, 0x38, 0x71, 0x69,
+0xf0, 0xb3, 0x11, 0xd9, 0x31, 0xac, 0xda, 0x75, 0x92, 0x5f, 0x35, 0xe1,
+0xf9, 0x7f, 0x25, 0x3a, 0x08, 0x5e, 0x67, 0x2f, 0xdf, 0x0b, 0x2e, 0x32,
+0xda, 0x26, 0xe1, 0x25, 0x01, 0xae, 0x33, 0x65, 0x7f, 0xd4, 0x5b, 0xaf,
+0x08, 0xe6, 0xb3, 0x7f, 0xe5, 0x67, 0xd7, 0x88, 0x00, 0xeb, 0x0d, 0x18,
+0x59, 0x99, 0xa1, 0xec, 0xaa, 0x3f, 0xd6, 0x82, 0x28, 0xa0, 0x3a, 0x52,
+0x71, 0x9e, 0x76, 0x64, 0xe5, 0xa8, 0x53, 0x40, 0x2e, 0xc8, 0xbb, 0x4a,
+0x4a, 0x09, 0xf4, 0x33, 0x89, 0x0a, 0x5b, 0xf3, 0x08, 0xc0, 0xc0, 0xf7,
+0x1b, 0xbe, 0x6d, 0x76, 0x30, 0x33, 0x8a, 0x35, 0x77, 0x8a, 0xb5, 0x1a,
+0xa9, 0xc0, 0xc3, 0x18, 0xdb, 0x90, 0x6d, 0x2e, 0xd0, 0x99, 0xbb, 0xfd,
+0x9d, 0x06, 0xbc, 0x24, 0x68, 0x84, 0xd2, 0x58, 0xb0, 0xf6, 0xbd, 0x06,
+0x51, 0x8e, 0x02, 0x66, 0xec, 0xcd, 0xad, 0xd2, 0xde, 0xbd, 0x9d, 0xc5,
+0xe1, 0x35, 0x4a, 0x58, 0x87, 0xed, 0x5c, 0x8e, 0x58, 0x5a, 0x2b, 0x39,
+0x9d, 0xd5, 0xfd, 0xc4, 0xa0, 0xf2, 0xbe, 0xa1, 0x5f, 0xb6, 0x20, 0xf4,
+0xf3, 0xd9, 0xc7, 0xa8
};
const size_t RAW_CERT_CHAIN_A_len = sizeof(RAW_CERT_CHAIN_A);
@@ -558,8 +558,8 @@ const unsigned char CERT_CHAIN_A_P7B[] = {
0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x09, 0x34, 0x30, 0x82, 0x04,
0x20, 0x30, 0x82, 0x03, 0x08, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
-0x15, 0x6c, 0x2a, 0xad, 0x3a, 0x2d, 0xb5, 0xb4, 0x2e, 0x81, 0x9d, 0x0c,
-0xd9, 0x2f, 0x26, 0x2c, 0x1e, 0xac, 0x21, 0x14, 0x30, 0x0d, 0x06, 0x09,
+0x74, 0x98, 0x82, 0x8b, 0x39, 0xcf, 0x41, 0xe8, 0xac, 0xff, 0x24, 0x6e,
+0xb2, 0x8a, 0xc6, 0x6c, 0x72, 0x25, 0x90, 0x09, 0x30, 0x0d, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
0x81, 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
@@ -573,9 +573,9 @@ const unsigned char CERT_CHAIN_A_P7B[] = {
0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x31, 0x1f, 0x30, 0x1d,
0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x43, 0x68, 0x61, 0x69, 0x6e,
0x41, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61,
-0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x35, 0x30,
-0x35, 0x30, 0x38, 0x32, 0x32, 0x30, 0x37, 0x31, 0x30, 0x5a, 0x17, 0x0d,
-0x32, 0x36, 0x30, 0x35, 0x30, 0x38, 0x32, 0x32, 0x30, 0x37, 0x31, 0x30,
+0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x36, 0x30,
+0x35, 0x30, 0x39, 0x32, 0x31, 0x33, 0x35, 0x35, 0x31, 0x5a, 0x17, 0x0d,
+0x32, 0x37, 0x30, 0x35, 0x30, 0x39, 0x32, 0x31, 0x33, 0x35, 0x35, 0x31,
0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e,
@@ -590,64 +590,64 @@ const unsigned char CERT_CHAIN_A_P7B[] = {
0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
-0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x95, 0xc0, 0xd1, 0xf3,
-0x6a, 0xbd, 0xc9, 0xe0, 0xee, 0x14, 0x0a, 0x09, 0xca, 0x18, 0xe7, 0x0a,
-0x9f, 0x9e, 0x34, 0x22, 0xa2, 0x06, 0x9c, 0xb4, 0xc8, 0xdd, 0x0c, 0xa9,
-0x20, 0x48, 0x9d, 0xd6, 0xa9, 0xf9, 0x61, 0xe1, 0xce, 0x39, 0x42, 0x41,
-0x5c, 0xb4, 0xb1, 0xba, 0xe9, 0xf0, 0x5f, 0xb6, 0xab, 0x53, 0x2b, 0x4c,
-0x74, 0x9c, 0x26, 0xaa, 0x33, 0x5d, 0xd6, 0x50, 0x67, 0xbd, 0x9f, 0x52,
-0x21, 0xe0, 0xf6, 0x2d, 0x92, 0x1f, 0x42, 0x90, 0x13, 0x1d, 0xed, 0x62,
-0x83, 0x51, 0xfa, 0xa0, 0x3b, 0xac, 0x32, 0x71, 0x3d, 0x4f, 0x21, 0x11,
-0x33, 0xf9, 0x00, 0xf7, 0xd4, 0x9b, 0xdc, 0x65, 0xff, 0x71, 0x3c, 0x0f,
-0x7f, 0x94, 0x7b, 0xbc, 0xe5, 0x08, 0xec, 0xda, 0xc8, 0x4f, 0x45, 0xb5,
-0xd1, 0x34, 0xde, 0x24, 0x4b, 0xf9, 0xfe, 0x75, 0x3d, 0x99, 0x97, 0x63,
-0xf6, 0x0f, 0x2f, 0xb1, 0x77, 0xfd, 0xf8, 0xc2, 0xb3, 0xed, 0xd5, 0xbb,
-0x68, 0xf5, 0x6e, 0x57, 0x7e, 0x5b, 0xd0, 0xe4, 0x41, 0x67, 0x21, 0x55,
-0x62, 0x92, 0x0c, 0x12, 0x3c, 0xf0, 0xf4, 0x3a, 0xe4, 0xc2, 0x66, 0x04,
-0x44, 0xf4, 0xaf, 0xc5, 0x86, 0xa1, 0xff, 0xb9, 0x03, 0x9d, 0x4c, 0xe4,
-0xc5, 0xe3, 0xf8, 0xb9, 0x35, 0xf6, 0x1a, 0x65, 0x20, 0x93, 0xf6, 0x0e,
-0xfc, 0xac, 0xdc, 0x5b, 0x97, 0x87, 0xe4, 0xad, 0x1c, 0x4a, 0xfc, 0x5f,
-0xb0, 0xbb, 0xd6, 0x94, 0x72, 0x3b, 0x4f, 0xbe, 0x3f, 0xfe, 0x76, 0xea,
-0xa1, 0xdf, 0x12, 0xc0, 0xd8, 0x88, 0x8b, 0xbd, 0x30, 0xa9, 0x87, 0x6c,
-0xaf, 0x72, 0xab, 0x20, 0xa8, 0x2e, 0x4d, 0x01, 0x80, 0xb5, 0xcd, 0x32,
-0x90, 0x6c, 0x35, 0x6f, 0xbd, 0x1f, 0xf7, 0x6a, 0xb1, 0xb1, 0xdc, 0x18,
-0x24, 0x15, 0xff, 0xd1, 0xef, 0xb5, 0xe8, 0xef, 0x94, 0x45, 0xf3, 0xa1,
+0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf, 0xfb, 0xa0, 0xf1,
+0x89, 0x70, 0x45, 0xf8, 0xe9, 0xc5, 0xc0, 0xde, 0x49, 0xb9, 0x22, 0x8a,
+0x0a, 0x16, 0xbc, 0xf0, 0x4d, 0xf9, 0x70, 0xa2, 0x4c, 0xab, 0x3d, 0x4e,
+0x22, 0x04, 0xf8, 0xa6, 0xb9, 0xb8, 0x78, 0x33, 0x63, 0x7f, 0x4b, 0xb9,
+0x9f, 0xef, 0xc3, 0xda, 0xce, 0xea, 0x6b, 0x8f, 0x5e, 0x7b, 0x96, 0x94,
+0x97, 0x34, 0xde, 0xb9, 0x15, 0x86, 0x79, 0xcf, 0x61, 0x9e, 0x21, 0x6d,
+0x84, 0x88, 0xc4, 0x01, 0x5d, 0xc9, 0x2a, 0xc8, 0x7c, 0x0b, 0xed, 0x5c,
+0x76, 0x95, 0x57, 0xb5, 0x0d, 0x80, 0x25, 0x67, 0x5a, 0xd2, 0x9f, 0x25,
+0x64, 0x48, 0xa8, 0xbd, 0x89, 0x4d, 0x93, 0x06, 0x2e, 0xc5, 0x27, 0xe7,
+0xfa, 0x49, 0x59, 0x22, 0x4e, 0xe4, 0x82, 0xa0, 0xdc, 0x10, 0x7e, 0xf7,
+0x2f, 0xb4, 0xc5, 0x01, 0x4f, 0xf2, 0x8b, 0x62, 0xc2, 0xcd, 0x70, 0x06,
+0x70, 0xa4, 0x8c, 0x05, 0x7a, 0x8a, 0x82, 0x82, 0x57, 0x02, 0x37, 0x04,
+0x24, 0xa6, 0x3d, 0x56, 0xcf, 0x2f, 0x6e, 0x95, 0x52, 0xc1, 0x08, 0xd6,
+0x8e, 0x07, 0x47, 0x23, 0xfd, 0xc5, 0xf3, 0x86, 0x29, 0x7a, 0xaa, 0x46,
+0x1d, 0xba, 0x9f, 0xd5, 0x8d, 0xc3, 0x4d, 0x20, 0xd9, 0x31, 0xf0, 0x53,
+0x4b, 0x92, 0xb4, 0x82, 0x85, 0x06, 0x3b, 0xd9, 0xde, 0x43, 0x86, 0x66,
+0xfc, 0x29, 0x15, 0xc4, 0xa9, 0x6c, 0xb1, 0x70, 0xb4, 0x0d, 0xe1, 0x37,
+0x1e, 0x92, 0x4a, 0xc3, 0x51, 0x4b, 0xbd, 0x59, 0xd4, 0xa7, 0x3e, 0x64,
+0x55, 0x50, 0xb0, 0x7a, 0x28, 0xf9, 0xea, 0x77, 0x66, 0xd3, 0x2f, 0x97,
+0xc6, 0xf8, 0xe9, 0x80, 0x1a, 0x22, 0xc8, 0x29, 0x47, 0xfa, 0x24, 0xf7,
+0x9a, 0x71, 0xd7, 0xed, 0x16, 0x2c, 0x32, 0x7e, 0x6d, 0xc6, 0x47, 0x06,
+0x9e, 0xdd, 0xf2, 0xee, 0xbc, 0xfe, 0x01, 0xc9, 0x3c, 0xaf, 0xf3, 0xcd,
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x72, 0x30, 0x70, 0x30, 0x09, 0x06,
0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03,
0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0,
0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06,
0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1d, 0x06,
-0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x33, 0x09, 0x98, 0xae,
-0xd4, 0xa7, 0x25, 0x93, 0x32, 0xe3, 0xcd, 0x77, 0xf9, 0xfb, 0x9a, 0x04,
-0x3c, 0x53, 0x13, 0x39, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
-0x18, 0x30, 0x16, 0x80, 0x14, 0x6d, 0x76, 0xf6, 0xca, 0xd3, 0xa1, 0x4e,
-0xff, 0xa2, 0x4d, 0x59, 0x8a, 0x53, 0x28, 0x15, 0x5c, 0x5a, 0xfa, 0x69,
-0x4c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
-0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x38, 0xb4, 0xc7,
-0xe8, 0x42, 0x3a, 0x9c, 0xc7, 0x7c, 0xb5, 0x1c, 0xe1, 0x1b, 0x99, 0x06,
-0x00, 0x9e, 0x0f, 0x60, 0xb2, 0x99, 0x6b, 0xc1, 0xc2, 0x0e, 0x9a, 0x7b,
-0x89, 0x5f, 0xd5, 0xa0, 0x16, 0x49, 0x38, 0x8c, 0xa1, 0x51, 0x8b, 0xfd,
-0xaf, 0xd4, 0x2a, 0x0e, 0xa0, 0x10, 0x36, 0x4a, 0x20, 0xab, 0x1c, 0xa6,
-0x0e, 0xe0, 0xda, 0x48, 0xc3, 0x29, 0xbb, 0x79, 0x0a, 0x05, 0xf0, 0x5a,
-0x7d, 0xc8, 0x59, 0x85, 0x2b, 0xe2, 0xcc, 0xba, 0xac, 0x84, 0x45, 0x68,
-0xc7, 0xf1, 0xe9, 0xfb, 0xa6, 0xbf, 0x40, 0xa8, 0x67, 0xf6, 0xc4, 0xf6,
-0xb8, 0x06, 0x3f, 0xcd, 0x16, 0x13, 0x52, 0x68, 0x78, 0x06, 0xd2, 0xd3,
-0x33, 0xd5, 0x03, 0x6b, 0x4f, 0xa7, 0x72, 0xd1, 0xf8, 0x4e, 0xed, 0x78,
-0x65, 0x3d, 0x60, 0x64, 0xcb, 0x5f, 0x1d, 0x6e, 0x31, 0x92, 0x74, 0x50,
-0x40, 0x7c, 0x78, 0x3e, 0xf4, 0x23, 0xf7, 0x37, 0x24, 0x73, 0x60, 0x0f,
-0x9a, 0x16, 0xe5, 0xf1, 0xc7, 0x6b, 0xec, 0x8f, 0xee, 0x38, 0xba, 0x65,
-0xe4, 0xcf, 0x5f, 0x4c, 0x0c, 0x2b, 0xdc, 0x9a, 0x17, 0x3e, 0xa9, 0xcc,
-0xd1, 0xc1, 0x2e, 0x92, 0x7e, 0xb3, 0x1d, 0x5f, 0xde, 0xed, 0x63, 0xbb,
-0xb3, 0xff, 0x71, 0xb8, 0x8b, 0x6e, 0x27, 0x86, 0x1e, 0xb1, 0xf2, 0x8b,
-0xdd, 0xf0, 0xdb, 0xaa, 0x66, 0xc7, 0x31, 0x23, 0x69, 0xa9, 0xa8, 0x0c,
-0x73, 0x5d, 0x96, 0x57, 0x39, 0xaa, 0x5c, 0xf3, 0x88, 0x46, 0x71, 0x46,
-0x13, 0xd5, 0x88, 0x3e, 0x37, 0xf4, 0xd5, 0xf8, 0xf8, 0x11, 0xe5, 0x50,
-0x4a, 0x66, 0x5a, 0x08, 0xfc, 0xcc, 0x37, 0xd3, 0x78, 0x5b, 0xd1, 0x4b,
-0xc2, 0x3c, 0xaa, 0xe0, 0x82, 0x3b, 0x08, 0xec, 0x1f, 0x34, 0xd2, 0xec,
-0xa2, 0x12, 0x8d, 0x71, 0x85, 0x1d, 0xb9, 0x24, 0x8a, 0xc9, 0xfa, 0xde,
-0xe3, 0x30, 0x82, 0x05, 0x0c, 0x30, 0x82, 0x02, 0xf4, 0xa0, 0x03, 0x02,
-0x01, 0x02, 0x02, 0x14, 0x36, 0x1c, 0xce, 0x27, 0xef, 0xbb, 0xb2, 0x64,
-0xa5, 0xcf, 0x7a, 0xfd, 0x78, 0x3c, 0xf1, 0xbc, 0xe7, 0x95, 0x58, 0xf4,
+0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf9, 0x20, 0x9b, 0xe2,
+0x69, 0x11, 0xcb, 0xf7, 0x01, 0x4e, 0xd4, 0x93, 0xa5, 0xbf, 0xe3, 0x99,
+0x99, 0x0e, 0xb1, 0x92, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+0x18, 0x30, 0x16, 0x80, 0x14, 0x3e, 0x55, 0xb6, 0xa0, 0x53, 0x80, 0xf0,
+0x03, 0xc8, 0x9d, 0xcd, 0x87, 0x80, 0x7f, 0x62, 0x6d, 0xae, 0x36, 0x93,
+0xf2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3c, 0x77, 0x6d,
+0xae, 0xa6, 0x5f, 0x50, 0x5b, 0xf0, 0x19, 0xd4, 0x47, 0xef, 0xdb, 0xb5,
+0xd9, 0x62, 0x8e, 0xc1, 0x6e, 0xae, 0x55, 0x6d, 0x48, 0xab, 0x16, 0xe7,
+0xc9, 0xad, 0x26, 0x89, 0x0f, 0x44, 0x9e, 0xfa, 0x9a, 0x5b, 0x87, 0x55,
+0x17, 0x5b, 0xac, 0x00, 0x35, 0x77, 0x88, 0x82, 0x41, 0xe2, 0x71, 0x0c,
+0x43, 0x5f, 0x2f, 0x71, 0xf0, 0xfa, 0xdd, 0x67, 0xa8, 0x52, 0x95, 0xe7,
+0xab, 0x86, 0x37, 0x6c, 0x6e, 0xcc, 0x26, 0x18, 0xf0, 0xa5, 0x5d, 0x59,
+0xf0, 0xe2, 0x7e, 0xeb, 0x1e, 0x6f, 0x16, 0x35, 0xa4, 0x89, 0xda, 0xce,
+0x48, 0xab, 0xe4, 0x06, 0x67, 0x87, 0x38, 0x71, 0x69, 0xf0, 0xb3, 0x11,
+0xd9, 0x31, 0xac, 0xda, 0x75, 0x92, 0x5f, 0x35, 0xe1, 0xf9, 0x7f, 0x25,
+0x3a, 0x08, 0x5e, 0x67, 0x2f, 0xdf, 0x0b, 0x2e, 0x32, 0xda, 0x26, 0xe1,
+0x25, 0x01, 0xae, 0x33, 0x65, 0x7f, 0xd4, 0x5b, 0xaf, 0x08, 0xe6, 0xb3,
+0x7f, 0xe5, 0x67, 0xd7, 0x88, 0x00, 0xeb, 0x0d, 0x18, 0x59, 0x99, 0xa1,
+0xec, 0xaa, 0x3f, 0xd6, 0x82, 0x28, 0xa0, 0x3a, 0x52, 0x71, 0x9e, 0x76,
+0x64, 0xe5, 0xa8, 0x53, 0x40, 0x2e, 0xc8, 0xbb, 0x4a, 0x4a, 0x09, 0xf4,
+0x33, 0x89, 0x0a, 0x5b, 0xf3, 0x08, 0xc0, 0xc0, 0xf7, 0x1b, 0xbe, 0x6d,
+0x76, 0x30, 0x33, 0x8a, 0x35, 0x77, 0x8a, 0xb5, 0x1a, 0xa9, 0xc0, 0xc3,
+0x18, 0xdb, 0x90, 0x6d, 0x2e, 0xd0, 0x99, 0xbb, 0xfd, 0x9d, 0x06, 0xbc,
+0x24, 0x68, 0x84, 0xd2, 0x58, 0xb0, 0xf6, 0xbd, 0x06, 0x51, 0x8e, 0x02,
+0x66, 0xec, 0xcd, 0xad, 0xd2, 0xde, 0xbd, 0x9d, 0xc5, 0xe1, 0x35, 0x4a,
+0x58, 0x87, 0xed, 0x5c, 0x8e, 0x58, 0x5a, 0x2b, 0x39, 0x9d, 0xd5, 0xfd,
+0xc4, 0xa0, 0xf2, 0xbe, 0xa1, 0x5f, 0xb6, 0x20, 0xf4, 0xf3, 0xd9, 0xc7,
+0xa8, 0x30, 0x82, 0x05, 0x0c, 0x30, 0x82, 0x02, 0xf4, 0xa0, 0x03, 0x02,
+0x01, 0x02, 0x02, 0x14, 0x55, 0x35, 0x79, 0x1c, 0xb8, 0x76, 0xdf, 0x38,
+0x63, 0x54, 0xc5, 0x6f, 0xe6, 0xd8, 0xc2, 0xaf, 0x32, 0xac, 0xaa, 0xe1,
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
0x0b, 0x05, 0x00, 0x30, 0x81, 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06,
@@ -660,9 +660,9 @@ const unsigned char CERT_CHAIN_A_P7B[] = {
0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x52, 0x6f, 0x6f,
0x74, 0x20, 0x43, 0x41, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
0x03, 0x0c, 0x0e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x20, 0x52, 0x6f,
-0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x35, 0x30,
-0x35, 0x30, 0x38, 0x32, 0x32, 0x30, 0x37, 0x31, 0x30, 0x5a, 0x17, 0x0d,
-0x33, 0x30, 0x30, 0x35, 0x30, 0x37, 0x32, 0x32, 0x30, 0x37, 0x31, 0x30,
+0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x36, 0x30,
+0x35, 0x30, 0x39, 0x32, 0x31, 0x33, 0x35, 0x35, 0x31, 0x5a, 0x17, 0x0d,
+0x33, 0x31, 0x30, 0x35, 0x30, 0x38, 0x32, 0x31, 0x33, 0x35, 0x35, 0x31,
0x5a, 0x30, 0x81, 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e,
@@ -678,82 +678,82 @@ const unsigned char CERT_CHAIN_A_P7B[] = {
0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
-0x82, 0x01, 0x01, 0x00, 0xb7, 0x48, 0xf5, 0x71, 0x92, 0x7b, 0xd3, 0x68,
-0xe0, 0x31, 0xd2, 0x43, 0x03, 0xe2, 0x41, 0x7b, 0x48, 0xc7, 0x32, 0xef,
-0x35, 0x4c, 0xa0, 0x8e, 0x92, 0xf2, 0x40, 0x6e, 0x90, 0x7a, 0xbf, 0x57,
-0x2c, 0x1e, 0x66, 0x8c, 0x2b, 0x19, 0xca, 0xde, 0x78, 0x40, 0x23, 0x90,
-0xbd, 0xf4, 0xcf, 0x4e, 0x84, 0xf1, 0xf2, 0x3d, 0xd6, 0xd0, 0xbf, 0xfa,
-0x94, 0x37, 0xda, 0x93, 0x2f, 0x29, 0xea, 0x62, 0xb7, 0x04, 0xb8, 0x45,
-0x6a, 0x2f, 0xbe, 0x76, 0x13, 0x48, 0x02, 0x12, 0x84, 0x6e, 0x5b, 0x1e,
-0x2f, 0x44, 0x80, 0x19, 0x75, 0x44, 0x81, 0x02, 0xc0, 0x55, 0x79, 0x9c,
-0x20, 0x59, 0x35, 0xcc, 0x1e, 0x27, 0x9b, 0xcb, 0x3e, 0xfb, 0x71, 0x65,
-0x27, 0xbd, 0xb9, 0x32, 0x04, 0xd0, 0xa0, 0x5c, 0x60, 0xfc, 0xf0, 0xc3,
-0xf2, 0xf8, 0x9f, 0xad, 0x7a, 0x15, 0xcc, 0x41, 0xdd, 0x16, 0x39, 0x1e,
-0xff, 0x7d, 0xe1, 0xc8, 0xc5, 0x91, 0xde, 0x95, 0x2b, 0xc8, 0x29, 0xb2,
-0x74, 0xf3, 0xea, 0x7b, 0x3d, 0xaf, 0x70, 0x97, 0xd1, 0x48, 0x4d, 0x6d,
-0x09, 0xd2, 0xb9, 0xe0, 0xb4, 0x52, 0xa1, 0xe2, 0xf5, 0x7c, 0x07, 0xe2,
-0xc1, 0x51, 0x90, 0xb2, 0xe2, 0x6e, 0xf4, 0xaa, 0x2f, 0xda, 0x59, 0x0a,
-0xd0, 0x17, 0xb9, 0xc4, 0xf7, 0xed, 0x6f, 0xf1, 0x75, 0x5f, 0x37, 0xa6,
-0x08, 0x86, 0xa0, 0x36, 0x30, 0xa3, 0xad, 0x06, 0xcc, 0xa3, 0xe7, 0x2e,
-0x5f, 0xc0, 0x74, 0xb5, 0x59, 0xc8, 0x03, 0x31, 0xd6, 0x71, 0x8c, 0xa0,
-0x19, 0xcc, 0x34, 0x40, 0x88, 0x86, 0xb9, 0x57, 0xa5, 0x6c, 0xf4, 0x21,
-0x3d, 0x6d, 0x55, 0x53, 0x5f, 0x25, 0x4b, 0x8b, 0xad, 0xd4, 0x65, 0xd8,
-0xca, 0xc1, 0xc9, 0xe7, 0x44, 0x52, 0x6f, 0x4b, 0x2f, 0x81, 0xc3, 0x8c,
-0xf5, 0xf4, 0x09, 0x64, 0x0b, 0xe6, 0xad, 0x2d, 0x02, 0x03, 0x01, 0x00,
+0x82, 0x01, 0x01, 0x00, 0xb4, 0x63, 0xe7, 0xd5, 0xd8, 0x91, 0xa3, 0x70,
+0xb0, 0xfb, 0xbf, 0x95, 0xed, 0xbb, 0x50, 0xa3, 0xff, 0x74, 0x34, 0x45,
+0x20, 0xfc, 0xe8, 0xf3, 0x11, 0xa9, 0x01, 0x4b, 0x14, 0x61, 0x0b, 0xf8,
+0x73, 0x71, 0xc0, 0x5c, 0x58, 0x8c, 0x89, 0xf0, 0x2c, 0x87, 0xbb, 0x16,
+0x69, 0xc4, 0xd7, 0xa6, 0x67, 0x78, 0x5f, 0xac, 0xce, 0xbd, 0x74, 0xe3,
+0x87, 0x41, 0x71, 0x8e, 0xb6, 0x8e, 0x19, 0xe7, 0x72, 0xa4, 0xf0, 0x44,
+0xfd, 0x4d, 0x24, 0xf4, 0x3d, 0x31, 0xae, 0x1c, 0x86, 0x4e, 0xeb, 0xcc,
+0x24, 0xa9, 0xe9, 0x9e, 0x42, 0x7c, 0x08, 0x4f, 0xd6, 0x02, 0x7e, 0x4a,
+0xb0, 0x61, 0xef, 0x93, 0xd1, 0x89, 0x4c, 0x19, 0x67, 0xe2, 0x1d, 0x48,
+0xc6, 0x19, 0xad, 0x0e, 0xe6, 0x00, 0x27, 0x6a, 0x4c, 0xcf, 0x0d, 0x29,
+0x3e, 0xba, 0x4c, 0x4d, 0x34, 0xa9, 0x34, 0x52, 0xf5, 0x8a, 0x72, 0xd9,
+0xcd, 0x9d, 0x5a, 0x0b, 0xff, 0xce, 0x7e, 0x0a, 0x1b, 0x64, 0x7f, 0x60,
+0x2d, 0x08, 0x56, 0xcf, 0x25, 0xda, 0xbe, 0x02, 0x89, 0xce, 0x54, 0x20,
+0x4f, 0xf8, 0x45, 0x72, 0x5c, 0x98, 0xad, 0xb4, 0x19, 0x9d, 0xe2, 0xa1,
+0x04, 0xe4, 0xe3, 0x2a, 0xc9, 0x92, 0x34, 0x61, 0xfc, 0x08, 0x77, 0x7b,
+0x3d, 0x41, 0x06, 0x74, 0xd9, 0x08, 0x0d, 0xbd, 0x5a, 0x2c, 0xa3, 0x5e,
+0x57, 0xb9, 0xc0, 0xa3, 0xcf, 0x1f, 0xa6, 0xe5, 0x62, 0xe8, 0x75, 0x17,
+0x98, 0x0a, 0xda, 0xd7, 0x2b, 0x5a, 0x57, 0x8d, 0xfc, 0xd7, 0x5f, 0x61,
+0xa6, 0xb3, 0x10, 0x46, 0x8a, 0xa6, 0x36, 0xe1, 0xaa, 0xf9, 0x8b, 0xc0,
+0xc2, 0x77, 0x89, 0x2b, 0x59, 0x9c, 0xa5, 0xd7, 0xea, 0x17, 0x37, 0x47,
+0x55, 0xb9, 0x23, 0x89, 0x46, 0xee, 0x97, 0x13, 0x44, 0xd3, 0x92, 0x75,
+0xdb, 0x28, 0xf6, 0xc5, 0xfc, 0x08, 0x6f, 0xbf, 0x02, 0x03, 0x01, 0x00,
0x01, 0xa3, 0x66, 0x30, 0x64, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
-0x04, 0x16, 0x04, 0x14, 0x6d, 0x76, 0xf6, 0xca, 0xd3, 0xa1, 0x4e, 0xff,
-0xa2, 0x4d, 0x59, 0x8a, 0x53, 0x28, 0x15, 0x5c, 0x5a, 0xfa, 0x69, 0x4c,
+0x04, 0x16, 0x04, 0x14, 0x3e, 0x55, 0xb6, 0xa0, 0x53, 0x80, 0xf0, 0x03,
+0xc8, 0x9d, 0xcd, 0x87, 0x80, 0x7f, 0x62, 0x6d, 0xae, 0x36, 0x93, 0xf2,
0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
-0x14, 0xb6, 0x3c, 0x52, 0x3c, 0x43, 0x68, 0x11, 0x95, 0x13, 0x8c, 0x57,
-0x2e, 0x17, 0x0f, 0xc3, 0x96, 0x13, 0x86, 0x01, 0x59, 0x30, 0x0d, 0x06,
+0x14, 0xeb, 0x5c, 0xc9, 0x3a, 0x7e, 0x10, 0x39, 0xd4, 0xf9, 0xd1, 0xac,
+0x31, 0xac, 0xf5, 0xb1, 0xd8, 0xd1, 0xdc, 0x65, 0xb6, 0x30, 0x0d, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
-0x03, 0x82, 0x02, 0x01, 0x00, 0x93, 0x46, 0xb9, 0xdc, 0x7e, 0x64, 0x3d,
-0x69, 0x03, 0x33, 0xba, 0x2a, 0xd2, 0xae, 0x9f, 0xdb, 0x90, 0x97, 0x69,
-0xfc, 0x28, 0xff, 0x66, 0x9a, 0xe1, 0x30, 0xb2, 0x3a, 0xce, 0x6d, 0x5f,
-0x8a, 0x06, 0x97, 0x01, 0x61, 0x07, 0x1c, 0x4b, 0x91, 0x62, 0xd6, 0x8f,
-0x97, 0x67, 0xcf, 0x0a, 0x7b, 0x5c, 0x50, 0x80, 0x5c, 0x26, 0x74, 0xdd,
-0x53, 0x70, 0xa6, 0xfe, 0x41, 0xe3, 0x8a, 0xd2, 0x6a, 0x66, 0xd7, 0x8f,
-0x33, 0xec, 0x84, 0xc2, 0xeb, 0xc4, 0x60, 0xdf, 0x38, 0xb6, 0xbf, 0x52,
-0x39, 0x82, 0x37, 0x3e, 0xda, 0xb5, 0xa9, 0x61, 0x08, 0x52, 0xf1, 0xbf,
-0x9b, 0x2a, 0x72, 0x3e, 0xf5, 0xba, 0xc1, 0x69, 0x97, 0xd7, 0xa4, 0x33,
-0xa9, 0xb7, 0x26, 0xb6, 0x53, 0x17, 0xdf, 0x7e, 0x80, 0xc2, 0xcd, 0xc3,
-0xda, 0x91, 0x54, 0x84, 0x1b, 0xce, 0xa3, 0xf9, 0x3e, 0xf6, 0x38, 0x16,
-0x34, 0xd9, 0x82, 0x06, 0x85, 0x8e, 0xda, 0x4d, 0x30, 0x84, 0x50, 0x59,
-0x94, 0xc1, 0xf7, 0xa2, 0xc7, 0xf7, 0xdd, 0x09, 0xe4, 0x03, 0x8b, 0xc9,
-0x6f, 0x6d, 0x3e, 0x1a, 0x6a, 0x78, 0x62, 0xe4, 0x3a, 0xa8, 0xac, 0x67,
-0x7a, 0x9c, 0x42, 0x96, 0x79, 0x5c, 0x25, 0xb0, 0x71, 0x3b, 0xd7, 0xdf,
-0x67, 0x46, 0x08, 0x70, 0x5f, 0xec, 0xd8, 0x29, 0x38, 0xf7, 0xac, 0xe3,
-0x74, 0x17, 0xc2, 0x1f, 0x1f, 0xe6, 0x6e, 0x89, 0x0a, 0x48, 0xf9, 0x19,
-0x6c, 0x65, 0xf0, 0x90, 0x85, 0x0d, 0xa4, 0xa0, 0x44, 0xc5, 0xf7, 0x3e,
-0x59, 0xd1, 0x2d, 0xf0, 0x1f, 0x53, 0x6f, 0xbb, 0x3a, 0xf9, 0x3e, 0x77,
-0xb2, 0x23, 0x5b, 0x13, 0x09, 0x07, 0xbe, 0xcc, 0xba, 0xf9, 0xdd, 0x0f,
-0x1d, 0x1b, 0x8e, 0x03, 0xfc, 0xc2, 0x28, 0xe2, 0xbe, 0xb7, 0x08, 0x42,
-0x64, 0x32, 0xee, 0x74, 0x52, 0x28, 0x8b, 0xcb, 0x8f, 0x6b, 0x86, 0xbc,
-0x4d, 0xbd, 0x9c, 0x83, 0x49, 0xc8, 0xdc, 0xa1, 0x97, 0x12, 0xe6, 0xe7,
-0x06, 0x6e, 0xc7, 0x60, 0xe9, 0x59, 0xbb, 0xfe, 0xac, 0x15, 0x11, 0x11,
-0x58, 0x2b, 0x7e, 0xf5, 0x5a, 0x4d, 0xac, 0xc3, 0x11, 0x94, 0x0e, 0xf9,
-0x40, 0x82, 0x3f, 0x73, 0x87, 0x40, 0x98, 0x51, 0xcf, 0x68, 0xfa, 0x9f,
-0x89, 0xe5, 0xbe, 0xfc, 0x8c, 0xd5, 0x41, 0x8f, 0x50, 0x45, 0xb0, 0x97,
-0x7a, 0x1a, 0x72, 0xfb, 0x67, 0xe9, 0x5b, 0x5b, 0xba, 0x38, 0x51, 0xb1,
-0xa4, 0x70, 0x4d, 0xaf, 0xfb, 0xe2, 0x91, 0xfd, 0xcc, 0xf5, 0x5a, 0x90,
-0x09, 0xea, 0x92, 0x72, 0x7f, 0x03, 0x3a, 0x4c, 0xa5, 0x36, 0x89, 0xd5,
-0x15, 0x20, 0xa8, 0xbb, 0x10, 0xf9, 0xad, 0xdf, 0x03, 0xfe, 0x8a, 0xbd,
-0x8c, 0xe1, 0x68, 0x91, 0x5d, 0x5f, 0xc9, 0xb0, 0x6f, 0x24, 0xe6, 0x2e,
-0x28, 0x7e, 0xf0, 0x05, 0xf9, 0xe3, 0xbb, 0xa1, 0xdb, 0x87, 0xa0, 0x51,
-0xe9, 0x04, 0x8e, 0x5b, 0x4f, 0xf1, 0x06, 0x62, 0xf3, 0x1c, 0x2e, 0x6a,
-0x5f, 0x4c, 0xce, 0x41, 0x6b, 0x3a, 0x46, 0x70, 0xff, 0x0d, 0x49, 0x65,
-0x46, 0xa2, 0x74, 0xac, 0x27, 0x12, 0x8f, 0xc3, 0x16, 0x9d, 0x5f, 0x0a,
-0x74, 0x8e, 0x7b, 0x3e, 0x2c, 0xa3, 0x68, 0x92, 0xca, 0x11, 0xe1, 0xad,
-0x9f, 0x1f, 0x36, 0x8f, 0x6e, 0xb5, 0x88, 0x3e, 0x76, 0x36, 0x0b, 0x0a,
-0xf1, 0x35, 0xa1, 0xad, 0x94, 0x27, 0xbd, 0xd5, 0xba, 0x77, 0x34, 0xcd,
-0xb8, 0x9e, 0xf5, 0x45, 0xe6, 0x19, 0x6b, 0xb3, 0x29, 0x9a, 0x9f, 0xf4,
-0x7a, 0x50, 0x75, 0x6e, 0x5a, 0x80, 0x36, 0x74, 0xed, 0x9a, 0x12, 0xbe,
-0xed, 0x9b, 0xbc, 0xb1, 0xed, 0x9a, 0x24, 0xb7, 0x76, 0x1b, 0x39, 0x36,
-0x1a, 0x59, 0xa9, 0xd1, 0xdc, 0xc8, 0xd7, 0xc7, 0x33, 0xd5, 0xf2, 0x61,
-0x31, 0x31, 0x00
+0x03, 0x82, 0x02, 0x01, 0x00, 0x78, 0x8f, 0x3e, 0xba, 0x86, 0x02, 0x71,
+0xd8, 0x16, 0x0d, 0x16, 0x80, 0x4a, 0x0c, 0xa0, 0x82, 0xb9, 0xbf, 0x63,
+0xcc, 0x65, 0x85, 0xdd, 0xef, 0x47, 0x9e, 0xb6, 0xf8, 0x3a, 0x52, 0xa7,
+0x85, 0x22, 0x1c, 0xc4, 0xd6, 0x12, 0x0c, 0xa4, 0x79, 0xd4, 0x00, 0xb7,
+0xac, 0xba, 0x60, 0xba, 0xd3, 0xf6, 0x86, 0x30, 0xa0, 0xf5, 0x16, 0xe3,
+0x36, 0x53, 0x88, 0x39, 0xab, 0xcb, 0xde, 0x8f, 0xc0, 0xbc, 0x68, 0xec,
+0x05, 0x8a, 0xca, 0x40, 0x65, 0x26, 0xbf, 0x9a, 0x29, 0x8a, 0x50, 0x04,
+0xf9, 0x89, 0x19, 0x0d, 0x38, 0xf8, 0x36, 0x41, 0x97, 0x34, 0xf3, 0xcb,
+0x34, 0x0d, 0x97, 0xa0, 0xb7, 0x9b, 0xaa, 0x6e, 0x37, 0x66, 0xc6, 0x17,
+0x9c, 0x58, 0xf1, 0x7c, 0x2c, 0x7b, 0x03, 0x7b, 0xd0, 0x58, 0x15, 0x11,
+0xe9, 0xc7, 0x95, 0x09, 0x0e, 0x2b, 0xeb, 0x2a, 0x68, 0x5b, 0x78, 0xe7,
+0x25, 0x73, 0xfb, 0x6e, 0x28, 0x63, 0x66, 0x3d, 0xe2, 0x84, 0x99, 0xa9,
+0x11, 0x0b, 0xea, 0x41, 0x27, 0x16, 0x24, 0x31, 0xed, 0x2e, 0xba, 0x3a,
+0xfc, 0xb6, 0x61, 0x6c, 0xc8, 0xf2, 0xff, 0x96, 0x3f, 0x27, 0x57, 0x44,
+0x70, 0x36, 0x87, 0x87, 0x97, 0xc1, 0x9e, 0x38, 0x00, 0x40, 0xe9, 0x0f,
+0x76, 0x94, 0x37, 0x9d, 0x9b, 0x7b, 0xe8, 0x11, 0x0d, 0x07, 0x2b, 0x3c,
+0xee, 0x21, 0x76, 0x7f, 0x76, 0xf5, 0x9e, 0x49, 0x34, 0x84, 0xcc, 0x8b,
+0x8e, 0x00, 0xa4, 0x72, 0x3d, 0x80, 0x9e, 0x7f, 0x21, 0x0d, 0x72, 0x07,
+0x0d, 0xd4, 0xbc, 0x0d, 0xb2, 0x1c, 0xb2, 0x5a, 0xf4, 0x62, 0xc9, 0xf7,
+0x1d, 0x65, 0xb8, 0x74, 0xc2, 0xea, 0x12, 0xa9, 0x18, 0x7b, 0xb1, 0xea,
+0x3f, 0x4a, 0x16, 0x91, 0xe1, 0x2d, 0xe3, 0x15, 0x3f, 0x3e, 0x16, 0x4a,
+0x7b, 0x41, 0x2c, 0xf5, 0xb9, 0xad, 0xcc, 0x94, 0xd3, 0x39, 0xaa, 0x6d,
+0x43, 0x79, 0x78, 0x76, 0x5b, 0x1d, 0x0c, 0x17, 0xc3, 0x15, 0x0f, 0x09,
+0xc5, 0xcd, 0xed, 0x51, 0xba, 0xd3, 0x73, 0x64, 0x8c, 0x95, 0xd0, 0x6e,
+0xdf, 0x85, 0x57, 0x82, 0x46, 0x00, 0xf6, 0x65, 0x48, 0x11, 0x89, 0xa2,
+0x58, 0xcc, 0xd3, 0xa4, 0x6f, 0x9c, 0x2e, 0x02, 0x75, 0x78, 0xb1, 0xd7,
+0x3c, 0xfc, 0xf9, 0x8c, 0xc5, 0x0b, 0x74, 0xee, 0xd2, 0xe0, 0x72, 0xff,
+0xb3, 0x75, 0xe6, 0x8b, 0x8d, 0x1e, 0x60, 0x78, 0xcf, 0x5f, 0x30, 0x89,
+0xc2, 0xfd, 0x3f, 0x90, 0xaf, 0x2b, 0xdd, 0x19, 0x7c, 0x7b, 0x66, 0x82,
+0x38, 0x3f, 0x1d, 0x06, 0x5a, 0x2c, 0x10, 0x30, 0x36, 0x4c, 0x4f, 0x7d,
+0x68, 0xcb, 0x87, 0x31, 0x4d, 0xbd, 0x9b, 0x04, 0x82, 0x46, 0x0d, 0xd8,
+0x4d, 0x59, 0xe6, 0x3d, 0x03, 0xce, 0xea, 0x2f, 0xc2, 0x5e, 0x7b, 0xd1,
+0xe0, 0x2b, 0x8d, 0x9e, 0x0e, 0xdb, 0xcd, 0xd2, 0xa8, 0x98, 0xa6, 0x00,
+0xd8, 0xa6, 0x35, 0x81, 0xec, 0xdc, 0xee, 0xcb, 0x65, 0x1e, 0x41, 0xb4,
+0xab, 0xe0, 0x77, 0x63, 0xc1, 0x95, 0x82, 0x29, 0x54, 0xe3, 0xb7, 0x74,
+0xee, 0x6c, 0xe5, 0x86, 0x90, 0x4b, 0xfa, 0xf0, 0x18, 0x1a, 0xd7, 0x38,
+0x73, 0xc1, 0x5f, 0x32, 0x94, 0xd6, 0xd7, 0xaa, 0xf4, 0xb6, 0xd7, 0x65,
+0xbc, 0xa3, 0x0b, 0x6d, 0xe3, 0xd2, 0xd1, 0xa3, 0x11, 0x24, 0x6b, 0x12,
+0x01, 0xcc, 0xee, 0x66, 0xd3, 0x9c, 0x3b, 0xb7, 0xe6, 0x42, 0x54, 0x96,
+0xec, 0x86, 0x55, 0x3a, 0x81, 0x00, 0x51, 0x93, 0x7a, 0x8f, 0xe8, 0xe4,
+0x5f, 0x4b, 0x90, 0x1c, 0xa9, 0x75, 0x2d, 0x8a, 0x68, 0xec, 0x32, 0x26,
+0xe6, 0xdb, 0x65, 0xbf, 0x3f, 0x04, 0x60, 0xc1, 0xa5, 0xa6, 0xbd, 0x3d,
+0xfe, 0x1a, 0x55, 0x8f, 0x76, 0x31, 0x6d, 0xfb, 0x6f, 0xbf, 0x4d, 0xbc,
+0xe6, 0x31, 0x00
};
const size_t CERT_CHAIN_A_P7B_len = sizeof(CERT_CHAIN_A_P7B);
@@ -761,29 +761,29 @@ const size_t CERT_CHAIN_A_P7B_len = sizeof(CERT_CHAIN_A_P7B);
const unsigned char LEAF_A_PUBKEY[] = {
0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
-0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x95, 0xc0, 0xd1,
-0xf3, 0x6a, 0xbd, 0xc9, 0xe0, 0xee, 0x14, 0x0a, 0x09, 0xca, 0x18, 0xe7,
-0x0a, 0x9f, 0x9e, 0x34, 0x22, 0xa2, 0x06, 0x9c, 0xb4, 0xc8, 0xdd, 0x0c,
-0xa9, 0x20, 0x48, 0x9d, 0xd6, 0xa9, 0xf9, 0x61, 0xe1, 0xce, 0x39, 0x42,
-0x41, 0x5c, 0xb4, 0xb1, 0xba, 0xe9, 0xf0, 0x5f, 0xb6, 0xab, 0x53, 0x2b,
-0x4c, 0x74, 0x9c, 0x26, 0xaa, 0x33, 0x5d, 0xd6, 0x50, 0x67, 0xbd, 0x9f,
-0x52, 0x21, 0xe0, 0xf6, 0x2d, 0x92, 0x1f, 0x42, 0x90, 0x13, 0x1d, 0xed,
-0x62, 0x83, 0x51, 0xfa, 0xa0, 0x3b, 0xac, 0x32, 0x71, 0x3d, 0x4f, 0x21,
-0x11, 0x33, 0xf9, 0x00, 0xf7, 0xd4, 0x9b, 0xdc, 0x65, 0xff, 0x71, 0x3c,
-0x0f, 0x7f, 0x94, 0x7b, 0xbc, 0xe5, 0x08, 0xec, 0xda, 0xc8, 0x4f, 0x45,
-0xb5, 0xd1, 0x34, 0xde, 0x24, 0x4b, 0xf9, 0xfe, 0x75, 0x3d, 0x99, 0x97,
-0x63, 0xf6, 0x0f, 0x2f, 0xb1, 0x77, 0xfd, 0xf8, 0xc2, 0xb3, 0xed, 0xd5,
-0xbb, 0x68, 0xf5, 0x6e, 0x57, 0x7e, 0x5b, 0xd0, 0xe4, 0x41, 0x67, 0x21,
-0x55, 0x62, 0x92, 0x0c, 0x12, 0x3c, 0xf0, 0xf4, 0x3a, 0xe4, 0xc2, 0x66,
-0x04, 0x44, 0xf4, 0xaf, 0xc5, 0x86, 0xa1, 0xff, 0xb9, 0x03, 0x9d, 0x4c,
-0xe4, 0xc5, 0xe3, 0xf8, 0xb9, 0x35, 0xf6, 0x1a, 0x65, 0x20, 0x93, 0xf6,
-0x0e, 0xfc, 0xac, 0xdc, 0x5b, 0x97, 0x87, 0xe4, 0xad, 0x1c, 0x4a, 0xfc,
-0x5f, 0xb0, 0xbb, 0xd6, 0x94, 0x72, 0x3b, 0x4f, 0xbe, 0x3f, 0xfe, 0x76,
-0xea, 0xa1, 0xdf, 0x12, 0xc0, 0xd8, 0x88, 0x8b, 0xbd, 0x30, 0xa9, 0x87,
-0x6c, 0xaf, 0x72, 0xab, 0x20, 0xa8, 0x2e, 0x4d, 0x01, 0x80, 0xb5, 0xcd,
-0x32, 0x90, 0x6c, 0x35, 0x6f, 0xbd, 0x1f, 0xf7, 0x6a, 0xb1, 0xb1, 0xdc,
-0x18, 0x24, 0x15, 0xff, 0xd1, 0xef, 0xb5, 0xe8, 0xef, 0x94, 0x45, 0xf3,
-0xa1, 0x02, 0x03, 0x01, 0x00, 0x01
+0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf, 0xfb, 0xa0,
+0xf1, 0x89, 0x70, 0x45, 0xf8, 0xe9, 0xc5, 0xc0, 0xde, 0x49, 0xb9, 0x22,
+0x8a, 0x0a, 0x16, 0xbc, 0xf0, 0x4d, 0xf9, 0x70, 0xa2, 0x4c, 0xab, 0x3d,
+0x4e, 0x22, 0x04, 0xf8, 0xa6, 0xb9, 0xb8, 0x78, 0x33, 0x63, 0x7f, 0x4b,
+0xb9, 0x9f, 0xef, 0xc3, 0xda, 0xce, 0xea, 0x6b, 0x8f, 0x5e, 0x7b, 0x96,
+0x94, 0x97, 0x34, 0xde, 0xb9, 0x15, 0x86, 0x79, 0xcf, 0x61, 0x9e, 0x21,
+0x6d, 0x84, 0x88, 0xc4, 0x01, 0x5d, 0xc9, 0x2a, 0xc8, 0x7c, 0x0b, 0xed,
+0x5c, 0x76, 0x95, 0x57, 0xb5, 0x0d, 0x80, 0x25, 0x67, 0x5a, 0xd2, 0x9f,
+0x25, 0x64, 0x48, 0xa8, 0xbd, 0x89, 0x4d, 0x93, 0x06, 0x2e, 0xc5, 0x27,
+0xe7, 0xfa, 0x49, 0x59, 0x22, 0x4e, 0xe4, 0x82, 0xa0, 0xdc, 0x10, 0x7e,
+0xf7, 0x2f, 0xb4, 0xc5, 0x01, 0x4f, 0xf2, 0x8b, 0x62, 0xc2, 0xcd, 0x70,
+0x06, 0x70, 0xa4, 0x8c, 0x05, 0x7a, 0x8a, 0x82, 0x82, 0x57, 0x02, 0x37,
+0x04, 0x24, 0xa6, 0x3d, 0x56, 0xcf, 0x2f, 0x6e, 0x95, 0x52, 0xc1, 0x08,
+0xd6, 0x8e, 0x07, 0x47, 0x23, 0xfd, 0xc5, 0xf3, 0x86, 0x29, 0x7a, 0xaa,
+0x46, 0x1d, 0xba, 0x9f, 0xd5, 0x8d, 0xc3, 0x4d, 0x20, 0xd9, 0x31, 0xf0,
+0x53, 0x4b, 0x92, 0xb4, 0x82, 0x85, 0x06, 0x3b, 0xd9, 0xde, 0x43, 0x86,
+0x66, 0xfc, 0x29, 0x15, 0xc4, 0xa9, 0x6c, 0xb1, 0x70, 0xb4, 0x0d, 0xe1,
+0x37, 0x1e, 0x92, 0x4a, 0xc3, 0x51, 0x4b, 0xbd, 0x59, 0xd4, 0xa7, 0x3e,
+0x64, 0x55, 0x50, 0xb0, 0x7a, 0x28, 0xf9, 0xea, 0x77, 0x66, 0xd3, 0x2f,
+0x97, 0xc6, 0xf8, 0xe9, 0x80, 0x1a, 0x22, 0xc8, 0x29, 0x47, 0xfa, 0x24,
+0xf7, 0x9a, 0x71, 0xd7, 0xed, 0x16, 0x2c, 0x32, 0x7e, 0x6d, 0xc6, 0x47,
+0x06, 0x9e, 0xdd, 0xf2, 0xee, 0xbc, 0xfe, 0x01, 0xc9, 0x3c, 0xaf, 0xf3,
+0xcd, 0x02, 0x03, 0x01, 0x00, 0x01
};
const size_t LEAF_A_PUBKEY_len = sizeof(LEAF_A_PUBKEY);
@@ -791,8 +791,8 @@ const size_t LEAF_A_PUBKEY_len = sizeof(LEAF_A_PUBKEY);
/* Chain B - Root CA Certificate (DER format) */
const unsigned char ROOT_B_CERT[] = {
0x30, 0x82, 0x05, 0xed, 0x30, 0x82, 0x03, 0xd5, 0xa0, 0x03, 0x02, 0x01,
-0x02, 0x02, 0x14, 0x06, 0x8a, 0xfc, 0xd2, 0x43, 0x7a, 0x71, 0x1d, 0xfe,
-0x6e, 0xa1, 0x3f, 0x19, 0x3f, 0x4b, 0x2f, 0x3f, 0xd4, 0x22, 0x4f, 0x30,
+0x02, 0x02, 0x14, 0x48, 0xbd, 0xd8, 0x60, 0x05, 0x7f, 0x38, 0x97, 0x56,
+0xb4, 0xc6, 0xcd, 0x61, 0x51, 0xdc, 0x40, 0x1e, 0x80, 0xf7, 0x1d, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x30, 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
@@ -805,9 +805,9 @@ const unsigned char ROOT_B_CERT[] = {
0x0c, 0x07, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x17, 0x30,
0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x43, 0x68, 0x61, 0x69,
0x6e, 0x42, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
-0x17, 0x0d, 0x32, 0x35, 0x30, 0x35, 0x30, 0x38, 0x32, 0x32, 0x30, 0x37,
-0x31, 0x31, 0x5a, 0x17, 0x0d, 0x33, 0x35, 0x30, 0x35, 0x30, 0x36, 0x32,
-0x32, 0x30, 0x37, 0x31, 0x31, 0x5a, 0x30, 0x7e, 0x31, 0x0b, 0x30, 0x09,
+0x17, 0x0d, 0x32, 0x36, 0x30, 0x35, 0x30, 0x39, 0x32, 0x31, 0x33, 0x35,
+0x35, 0x32, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x30, 0x35, 0x30, 0x36, 0x32,
+0x31, 0x33, 0x35, 0x35, 0x32, 0x5a, 0x30, 0x7e, 0x31, 0x0b, 0x30, 0x09,
0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30,
0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69,
0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
@@ -820,111 +820,111 @@ const unsigned char ROOT_B_CERT[] = {
0x43, 0x68, 0x61, 0x69, 0x6e, 0x42, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
0x43, 0x41, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02,
-0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0x8f,
-0x7c, 0x9b, 0x6b, 0x98, 0xad, 0xc5, 0x19, 0x31, 0x35, 0xb4, 0x98, 0xcd,
-0xf1, 0x30, 0xf0, 0xd9, 0xa0, 0x49, 0xeb, 0xef, 0x9d, 0xe0, 0xbe, 0x98,
-0xa3, 0x01, 0x55, 0xad, 0xc3, 0xb0, 0xd9, 0x61, 0xcc, 0xd0, 0x7c, 0xe0,
-0x3b, 0x96, 0xf0, 0x96, 0xf3, 0x65, 0x11, 0x4e, 0xb8, 0xa8, 0xeb, 0x8c,
-0x0d, 0x52, 0x24, 0x46, 0x81, 0x0a, 0x2f, 0xc3, 0x69, 0x6c, 0xd1, 0x5a,
-0x22, 0x49, 0x26, 0xca, 0xdb, 0x41, 0xe7, 0x92, 0xe2, 0x33, 0xe6, 0x8d,
-0x52, 0x2c, 0xa5, 0xe3, 0x4a, 0x0e, 0xfa, 0xaa, 0x4f, 0x91, 0xf7, 0x0e,
-0x2a, 0x34, 0xcf, 0xf0, 0xdf, 0x7a, 0xcf, 0x5a, 0x23, 0x52, 0xe7, 0x5d,
-0x24, 0x26, 0xa5, 0xd8, 0xde, 0xcb, 0xf6, 0xaa, 0xd8, 0x22, 0xaa, 0xd2,
-0xa5, 0x73, 0x7f, 0x3a, 0x45, 0xc1, 0xa5, 0xd8, 0xb0, 0x45, 0xcb, 0xb3,
-0x28, 0xf7, 0x42, 0x0e, 0x36, 0xc0, 0xea, 0x61, 0x63, 0x34, 0x09, 0xb6,
-0x23, 0x2b, 0x8c, 0xf5, 0x3e, 0xd9, 0xc5, 0xe2, 0x6b, 0x46, 0x18, 0x65,
-0xd5, 0x78, 0xbe, 0xf7, 0xf3, 0x59, 0x2c, 0xd1, 0xb9, 0x1e, 0xd8, 0xb4,
-0x97, 0xa5, 0xcd, 0x60, 0x19, 0xf7, 0xde, 0x64, 0x59, 0x64, 0x0e, 0xb5,
-0xc0, 0x15, 0x99, 0x61, 0x51, 0xfa, 0x52, 0xb8, 0x4c, 0xf9, 0x51, 0xf4,
-0x99, 0xe2, 0x93, 0x43, 0x5a, 0xca, 0x00, 0xbb, 0xb9, 0x54, 0x7b, 0xfe,
-0x30, 0xba, 0x6f, 0x4a, 0xab, 0x94, 0xb8, 0xfa, 0xb8, 0x6c, 0x57, 0xa3,
-0x29, 0xaf, 0x15, 0xfa, 0xe9, 0xc3, 0xa5, 0x6d, 0xa9, 0x5a, 0xec, 0xca,
-0x09, 0x67, 0xb7, 0x37, 0x5c, 0xb0, 0x79, 0xe8, 0x8e, 0x82, 0x54, 0x4a,
-0x2c, 0x5b, 0x06, 0xcf, 0x6d, 0x58, 0xe7, 0x88, 0xa5, 0xd8, 0xff, 0x00,
-0x9a, 0x78, 0x2e, 0x1b, 0xdb, 0xc6, 0xe1, 0x4d, 0xeb, 0x2c, 0xd2, 0xd9,
-0xbb, 0x64, 0x0b, 0x2c, 0xc3, 0x98, 0x40, 0xc7, 0xf8, 0xf9, 0x2e, 0x31,
-0xdb, 0x40, 0x1a, 0xfa, 0x12, 0xcb, 0x07, 0x71, 0xe0, 0x57, 0x90, 0x1a,
-0x05, 0xc5, 0x5e, 0x01, 0xb9, 0xcb, 0x3f, 0x44, 0x08, 0x52, 0xaf, 0x36,
-0x87, 0x59, 0xe8, 0x72, 0x9a, 0x23, 0x65, 0x23, 0x4e, 0x3e, 0x0f, 0x96,
-0x3a, 0xa3, 0x88, 0x0f, 0xd8, 0x1a, 0xd5, 0x35, 0xb7, 0xe0, 0x7d, 0x2a,
-0xba, 0x3d, 0x8a, 0xce, 0xab, 0x81, 0xfb, 0x5d, 0xb1, 0x3e, 0xa5, 0x5d,
-0xf8, 0xa7, 0x86, 0xef, 0x49, 0x49, 0xee, 0x2c, 0x4e, 0x1c, 0x16, 0xe4,
-0xe4, 0x53, 0xc8, 0x8a, 0x71, 0x45, 0xc7, 0x98, 0xd9, 0x19, 0x0c, 0x3e,
-0xe8, 0x0b, 0x5e, 0x3b, 0xc8, 0x15, 0x68, 0x3b, 0xc8, 0x57, 0xee, 0xa3,
-0xac, 0xf4, 0xaf, 0x8c, 0xec, 0x33, 0x8a, 0x28, 0x61, 0x4a, 0xfb, 0x24,
-0xfc, 0xae, 0xf6, 0xc6, 0xfa, 0x58, 0xe7, 0xa2, 0x52, 0x7c, 0x64, 0x50,
-0x01, 0xa6, 0xa0, 0xb8, 0xb1, 0xde, 0xd0, 0xf0, 0xa8, 0xe3, 0x2b, 0x6a,
-0x6d, 0x7d, 0x7b, 0xfe, 0xca, 0xb4, 0x27, 0xf9, 0x76, 0x61, 0x25, 0x97,
-0x5b, 0xb0, 0xde, 0x2f, 0x00, 0x8e, 0x16, 0x0d, 0x6e, 0x72, 0x47, 0x18,
-0x42, 0xbf, 0xd8, 0x7d, 0x4a, 0x7e, 0xfd, 0x0b, 0x41, 0xe3, 0x16, 0xab,
-0xba, 0xa3, 0xad, 0xc5, 0x3f, 0x3e, 0xf7, 0xd6, 0xd6, 0x68, 0xc0, 0x42,
-0x47, 0x95, 0xc8, 0x99, 0x8e, 0x40, 0x3d, 0x6f, 0xa1, 0x95, 0x7e, 0x0a,
-0x0c, 0x3d, 0xac, 0xf6, 0x89, 0x2e, 0xb2, 0xf2, 0x76, 0xe8, 0x1c, 0xf0,
-0xc5, 0xe8, 0x52, 0x37, 0x85, 0x82, 0x72, 0x12, 0x7a, 0x62, 0x94, 0xbf,
-0x63, 0xe8, 0xcd, 0xec, 0x5e, 0x29, 0x3b, 0x31, 0xf1, 0x97, 0x54, 0x78,
-0x79, 0x2f, 0x7b, 0x55, 0x49, 0x86, 0x4c, 0x7b, 0x2f, 0xeb, 0xd7, 0xd7,
-0x95, 0x9b, 0x36, 0x3d, 0x92, 0x44, 0xd9, 0x02, 0x03, 0x01, 0x00, 0x01,
+0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xcf,
+0x0f, 0xcf, 0x90, 0x53, 0x93, 0xcf, 0xac, 0xc5, 0xee, 0x7a, 0x4f, 0x38,
+0xad, 0x0b, 0xf6, 0x79, 0xdc, 0xe8, 0xdc, 0x6c, 0x65, 0x19, 0x21, 0x23,
+0xf0, 0xdc, 0x3c, 0x1c, 0xb3, 0x6d, 0xf2, 0x48, 0x88, 0x2a, 0xe3, 0xa5,
+0x43, 0xb4, 0xa4, 0xbf, 0xab, 0xc3, 0x3e, 0xe6, 0x4d, 0x64, 0x62, 0xdb,
+0xcd, 0xb0, 0x6f, 0x20, 0x5d, 0xf9, 0xd0, 0x0c, 0x41, 0xdd, 0x27, 0x8f,
+0xff, 0x75, 0xe2, 0x14, 0xa9, 0xe9, 0x7d, 0x15, 0x94, 0x25, 0xff, 0xa9,
+0x97, 0x06, 0x11, 0x03, 0xc9, 0x64, 0x8a, 0x79, 0x7d, 0xd6, 0x12, 0x86,
+0x2d, 0xe2, 0xa1, 0xaf, 0xca, 0x2c, 0xfa, 0x13, 0x67, 0x93, 0xfe, 0x63,
+0xbb, 0x26, 0x45, 0xc3, 0xbd, 0x0e, 0x98, 0x1f, 0xb0, 0x38, 0xfd, 0x06,
+0x99, 0x38, 0x9a, 0x3b, 0x26, 0xd3, 0xab, 0xc5, 0xec, 0xc7, 0x73, 0xad,
+0x2a, 0xce, 0x2f, 0xfe, 0x29, 0x8b, 0x16, 0xeb, 0xed, 0x1f, 0xc7, 0x7d,
+0x0c, 0xfb, 0x91, 0x69, 0x25, 0x57, 0x8f, 0x31, 0x18, 0x66, 0x70, 0x3e,
+0x4d, 0x63, 0x5b, 0x47, 0xd9, 0xc3, 0x26, 0xc2, 0x41, 0x63, 0x98, 0x07,
+0xb7, 0x55, 0xd6, 0x6b, 0xe2, 0x0d, 0x6a, 0x98, 0x1b, 0x7d, 0x51, 0xd2,
+0x3d, 0xd4, 0x03, 0x21, 0xda, 0x99, 0xaf, 0x55, 0x34, 0x65, 0x66, 0xfa,
+0xb1, 0x25, 0xc3, 0xf4, 0xf7, 0xcc, 0x37, 0xeb, 0xba, 0x1c, 0x27, 0x24,
+0x86, 0x2f, 0x72, 0x2e, 0x14, 0x88, 0x63, 0x4d, 0xa7, 0xa4, 0xb7, 0xdc,
+0x9c, 0x86, 0x79, 0xa4, 0xf1, 0x53, 0xca, 0x46, 0x73, 0xd4, 0x28, 0x45,
+0x1f, 0xd7, 0x36, 0x58, 0x0a, 0x90, 0xcd, 0xaf, 0xfb, 0x56, 0x4a, 0x6c,
+0x9b, 0x22, 0xbc, 0xe2, 0x19, 0xce, 0x56, 0x69, 0x1b, 0xff, 0x48, 0xd8,
+0x5a, 0x0e, 0x6b, 0xdd, 0x7c, 0x18, 0x46, 0x0c, 0xb0, 0xe2, 0x92, 0x26,
+0x0e, 0x65, 0x0e, 0x42, 0x23, 0x0f, 0x9b, 0x79, 0xa7, 0x96, 0x9b, 0xd2,
+0xe6, 0xb7, 0xa2, 0x3c, 0x1f, 0x42, 0x55, 0x93, 0x37, 0x82, 0xce, 0xe8,
+0xd1, 0xac, 0xf0, 0xd1, 0x1c, 0x85, 0x42, 0xa1, 0x4a, 0xfe, 0xe7, 0xfb,
+0xf0, 0x65, 0x4e, 0xde, 0x54, 0xf1, 0x88, 0xb0, 0x3b, 0xcc, 0xd0, 0x3c,
+0x7f, 0xe8, 0x05, 0xf7, 0x09, 0x94, 0x2c, 0xb8, 0x92, 0x9f, 0x48, 0x13,
+0xb4, 0xc3, 0xa8, 0x7c, 0x1a, 0xc0, 0xcf, 0xa0, 0xb2, 0xfb, 0x10, 0x31,
+0x28, 0xdd, 0x75, 0xb1, 0x8b, 0x35, 0x4c, 0x6b, 0xab, 0x6a, 0x3d, 0x37,
+0xa3, 0x8e, 0xa4, 0xa3, 0xd7, 0xb5, 0x5a, 0xb8, 0x42, 0x0b, 0xdf, 0xe4,
+0x68, 0x86, 0x73, 0x4f, 0x74, 0x8e, 0xb1, 0xab, 0x03, 0x3b, 0x1c, 0x48,
+0x45, 0xed, 0x5a, 0x8c, 0x26, 0xc0, 0x5c, 0x89, 0x84, 0x84, 0xab, 0x36,
+0xe5, 0xbc, 0x7b, 0x83, 0xe3, 0x5c, 0xba, 0x0c, 0x5c, 0x39, 0x4e, 0x4b,
+0xf9, 0x77, 0xb6, 0x6a, 0xb0, 0x6f, 0x2f, 0x93, 0xb0, 0xa5, 0x7f, 0xc2,
+0x9b, 0xda, 0x16, 0x1a, 0xbf, 0x79, 0x0b, 0x1e, 0x5a, 0x38, 0x2d, 0x70,
+0x38, 0x7f, 0x84, 0x8a, 0x84, 0xfe, 0x63, 0xed, 0x79, 0x69, 0x67, 0x97,
+0xc9, 0x23, 0x4e, 0xa2, 0xf5, 0xed, 0xe0, 0xfa, 0x59, 0x24, 0x84, 0x91,
+0x88, 0xc2, 0x1c, 0x03, 0xf9, 0xbc, 0x3a, 0xab, 0x97, 0x83, 0x1e, 0x19,
+0x52, 0x79, 0x3f, 0xfb, 0xdd, 0x22, 0x67, 0xb5, 0x51, 0x4a, 0xdb, 0xd7,
+0xfd, 0x82, 0x25, 0xcd, 0x1f, 0x68, 0x82, 0x91, 0x1c, 0x53, 0xcd, 0x48,
+0x93, 0xbd, 0x1d, 0xd6, 0x17, 0x1e, 0xac, 0x80, 0x5a, 0x45, 0x8f, 0xe5,
+0xa4, 0x5d, 0x43, 0xc1, 0xd5, 0x36, 0xc9, 0x09, 0x45, 0xe1, 0x71, 0x62,
+0xa4, 0x62, 0x0f, 0xcc, 0x85, 0x1a, 0x89, 0x7d, 0x0e, 0x03, 0x33, 0x4f,
+0x33, 0x37, 0xc8, 0x5d, 0x3c, 0xbf, 0xa1, 0x02, 0x03, 0x01, 0x00, 0x01,
0xa3, 0x63, 0x30, 0x61, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
-0x16, 0x04, 0x14, 0x0d, 0x1a, 0x6c, 0x57, 0x86, 0x74, 0x9c, 0xb6, 0x5c,
-0xd1, 0x3e, 0x2e, 0x5d, 0xe8, 0x94, 0x30, 0xba, 0x38, 0x08, 0x80, 0x30,
+0x16, 0x04, 0x14, 0xde, 0xea, 0xb2, 0x07, 0x9c, 0x6b, 0x08, 0xe2, 0xd9,
+0x37, 0xf7, 0x9e, 0x25, 0x1f, 0xde, 0xaa, 0x6d, 0x5b, 0x81, 0xd3, 0x30,
0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
-0x0d, 0x1a, 0x6c, 0x57, 0x86, 0x74, 0x9c, 0xb6, 0x5c, 0xd1, 0x3e, 0x2e,
-0x5d, 0xe8, 0x94, 0x30, 0xba, 0x38, 0x08, 0x80, 0x30, 0x0f, 0x06, 0x03,
+0xde, 0xea, 0xb2, 0x07, 0x9c, 0x6b, 0x08, 0xe2, 0xd9, 0x37, 0xf7, 0x9e,
+0x25, 0x1f, 0xde, 0xaa, 0x6d, 0x5b, 0x81, 0xd3, 0x30, 0x0f, 0x06, 0x03,
0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01,
-0x00, 0x18, 0x6e, 0xfc, 0x15, 0x41, 0xda, 0xda, 0x6a, 0x55, 0xce, 0xdc,
-0x1e, 0xc2, 0x74, 0x98, 0x7b, 0x62, 0xe1, 0xe0, 0xee, 0xf7, 0xd0, 0x67,
-0x46, 0x23, 0xce, 0x5f, 0xcc, 0xcc, 0x46, 0x0b, 0xb1, 0x40, 0x29, 0x89,
-0x22, 0xf1, 0x70, 0x05, 0x97, 0x6d, 0xc6, 0x52, 0x27, 0xac, 0x87, 0x61,
-0x01, 0xd0, 0xf5, 0x1c, 0xf4, 0x5c, 0x84, 0xe9, 0x46, 0xb2, 0xac, 0xea,
-0x8b, 0x02, 0xed, 0x30, 0x2f, 0x6e, 0xc1, 0x09, 0x50, 0x78, 0xea, 0x64,
-0xf7, 0xb5, 0xd4, 0x2c, 0xc5, 0x65, 0x56, 0xad, 0x10, 0x0f, 0x4a, 0x2b,
-0x2d, 0xb8, 0x93, 0x32, 0x84, 0xab, 0x08, 0x53, 0xcb, 0xd7, 0xab, 0x9b,
-0xf2, 0xe1, 0x08, 0xf4, 0x18, 0x32, 0x92, 0xc3, 0x42, 0x86, 0x29, 0xd4,
-0x89, 0xe2, 0x58, 0x7e, 0xa6, 0x75, 0x17, 0xea, 0x0a, 0xa2, 0x2f, 0xa4,
-0xe8, 0x20, 0x27, 0xf0, 0xd7, 0xe3, 0x0b, 0x77, 0x5b, 0xea, 0x7a, 0x5b,
-0x10, 0x1b, 0x82, 0x22, 0x06, 0xdc, 0xa0, 0xb9, 0xbf, 0x21, 0xfb, 0x06,
-0x2d, 0xc6, 0x57, 0x06, 0x38, 0xce, 0x25, 0xab, 0x31, 0x68, 0x10, 0xb8,
-0x54, 0xc6, 0xe4, 0x74, 0x14, 0x20, 0x27, 0x6c, 0x0d, 0xa3, 0xb3, 0x3b,
-0x21, 0x9f, 0x99, 0x2d, 0xe2, 0x17, 0xf0, 0x9a, 0xa2, 0xf2, 0x2d, 0x8d,
-0xcf, 0x4e, 0xc4, 0x00, 0xbb, 0x0c, 0x54, 0x56, 0x32, 0xbc, 0xf8, 0xeb,
-0x70, 0x9f, 0xf2, 0x10, 0x08, 0x2d, 0x76, 0xe0, 0x67, 0x56, 0x5a, 0x2f,
-0x6a, 0xf1, 0x0d, 0xed, 0xf5, 0x06, 0x3a, 0x74, 0xa2, 0xf2, 0xf1, 0xc2,
-0x1d, 0x87, 0x19, 0x73, 0xdb, 0xd1, 0x04, 0xfa, 0x8d, 0xe8, 0x2c, 0x7d,
-0xdf, 0xa2, 0xd2, 0x09, 0xb1, 0xed, 0xe2, 0x89, 0x23, 0xb0, 0xdc, 0x4b,
-0x7d, 0x78, 0x5b, 0x50, 0x8d, 0x48, 0x23, 0xd1, 0x5e, 0xa2, 0x20, 0x86,
-0x15, 0xfc, 0x5b, 0x47, 0x28, 0xfb, 0x1d, 0x30, 0xb9, 0x8a, 0x28, 0x56,
-0xed, 0x1f, 0x1a, 0x61, 0xf9, 0xfe, 0x39, 0x2c, 0x4c, 0x64, 0x98, 0x67,
-0xf4, 0xbe, 0xc3, 0xb9, 0xfb, 0x08, 0x13, 0x16, 0xbc, 0x13, 0xb6, 0x53,
-0x27, 0x5d, 0xc7, 0x6e, 0x50, 0xf9, 0xf5, 0x21, 0x59, 0xaa, 0x43, 0x4c,
-0x59, 0x7e, 0x4b, 0x87, 0xb3, 0xbe, 0xca, 0x61, 0xd0, 0x42, 0x84, 0x83,
-0x40, 0xc1, 0xb3, 0xad, 0xfa, 0x84, 0x6b, 0x4e, 0xea, 0x6f, 0xbc, 0xcd,
-0x68, 0x2d, 0x7d, 0xcf, 0x27, 0x55, 0xd2, 0x10, 0xf6, 0xc4, 0xaf, 0x75,
-0xfb, 0xf2, 0xfb, 0x87, 0x47, 0x17, 0x7c, 0x59, 0x77, 0x35, 0xac, 0x0a,
-0xc5, 0x86, 0xc6, 0xe5, 0x1d, 0x33, 0xb0, 0xed, 0x28, 0x5d, 0x6f, 0x93,
-0x69, 0x26, 0x0c, 0x9c, 0x00, 0x5b, 0x2e, 0xb0, 0x0b, 0x49, 0xb3, 0xf7,
-0xf4, 0x57, 0xea, 0xc8, 0x7c, 0x80, 0x24, 0x9b, 0x2f, 0x02, 0xad, 0xc3,
-0xa6, 0x12, 0x77, 0x3d, 0x08, 0x18, 0x17, 0x38, 0xd2, 0x3f, 0xa7, 0xbd,
-0x82, 0x80, 0x06, 0x4a, 0xf3, 0x3a, 0xb8, 0xa1, 0x23, 0xad, 0xd8, 0x51,
-0xb9, 0xf8, 0x33, 0xd5, 0x4b, 0x2d, 0xdc, 0x7f, 0x22, 0x8b, 0xb6, 0x38,
-0x19, 0x56, 0x71, 0xc5, 0xf6, 0xdd, 0x88, 0xfd, 0x81, 0xbe, 0xef, 0x2f,
-0x3b, 0xf9, 0x5a, 0x55, 0x34, 0xb2, 0xbe, 0x28, 0xfc, 0x19, 0x45, 0x93,
-0x55, 0xec, 0x4f, 0x4c, 0x97, 0x14, 0xbe, 0x83, 0x81, 0xb4, 0xd0, 0x0d,
-0x01, 0x0b, 0x9a, 0x5d, 0x70, 0x1d, 0xb0, 0x90, 0x41, 0x41, 0x99, 0x39,
-0x99, 0xd0, 0xca, 0x41, 0xed, 0x3a, 0xc3, 0xda, 0x3f, 0x6e, 0x98, 0xa2,
-0xa0, 0x4a, 0xb6, 0x0e, 0x69, 0xc8, 0x26, 0xa1, 0x55, 0x81, 0xff, 0xcf,
-0xb2, 0x58, 0xb2, 0x01, 0x4e, 0x89, 0xa3, 0x13, 0xcf, 0x5b, 0x42, 0x6d,
-0x05, 0x38, 0x0e, 0x45, 0x36, 0xae, 0x8b, 0x40, 0x89
+0x00, 0x64, 0xd7, 0x7d, 0x53, 0x0b, 0xa5, 0x57, 0x59, 0x51, 0xec, 0x76,
+0xf1, 0x86, 0x09, 0xc2, 0x63, 0xe4, 0x1e, 0x25, 0x99, 0x36, 0x78, 0x1f,
+0x95, 0xe0, 0x67, 0x2b, 0x1e, 0xb9, 0x63, 0x4e, 0x09, 0x6d, 0x06, 0xc3,
+0x06, 0x85, 0x9d, 0xb2, 0x49, 0x14, 0x93, 0xf8, 0x93, 0xce, 0x55, 0x57,
+0xca, 0x63, 0x15, 0xed, 0x03, 0x40, 0x04, 0x8f, 0x2e, 0xf9, 0xd2, 0x28,
+0xa4, 0xaa, 0x91, 0x59, 0x2c, 0x68, 0x0c, 0xc7, 0x71, 0x52, 0xa2, 0x10,
+0x6a, 0xd8, 0x72, 0xd2, 0x05, 0xab, 0x5c, 0x2d, 0xda, 0x97, 0xdc, 0xbb,
+0x2f, 0x3b, 0xc2, 0xa2, 0x3c, 0x8a, 0x5b, 0x9f, 0xc6, 0x6d, 0x41, 0x1b,
+0xd5, 0x9e, 0x98, 0x8e, 0x67, 0x67, 0x9a, 0xf6, 0xb7, 0xf2, 0xf9, 0xbd,
+0x12, 0xb0, 0xdb, 0x34, 0x86, 0x37, 0xcd, 0xef, 0x7d, 0xdc, 0x0d, 0xbd,
+0x9b, 0x54, 0xf4, 0xf3, 0x52, 0xf6, 0x6a, 0xea, 0x2c, 0x24, 0x83, 0xa2,
+0x93, 0x2d, 0xd6, 0x66, 0x64, 0x8d, 0x27, 0x73, 0x38, 0x07, 0x0b, 0xc8,
+0xb7, 0x60, 0x0a, 0x3c, 0x3d, 0x69, 0xfe, 0x06, 0x2f, 0xbf, 0x8c, 0xb0,
+0xea, 0xf8, 0x23, 0x14, 0x0a, 0x5e, 0xcf, 0x00, 0x80, 0x0b, 0xfa, 0x36,
+0x03, 0x4c, 0x4b, 0x95, 0xc1, 0x39, 0xc8, 0x96, 0x17, 0xb9, 0x70, 0xdd,
+0xf6, 0xe4, 0x06, 0x13, 0x18, 0x8e, 0x4f, 0xb4, 0xd3, 0xd9, 0x15, 0x3c,
+0xa8, 0x9d, 0x40, 0xdc, 0x71, 0xcc, 0xca, 0x4d, 0x56, 0x8b, 0x73, 0x24,
+0xa7, 0x0d, 0xbf, 0xff, 0x65, 0xe4, 0x49, 0xbe, 0xd5, 0x06, 0x32, 0xf0,
+0x92, 0x7b, 0xd1, 0x15, 0x7a, 0x3e, 0xbd, 0x10, 0xc3, 0xe7, 0x2c, 0x99,
+0x1a, 0x6d, 0x95, 0x53, 0xe7, 0xed, 0xc0, 0x70, 0x01, 0xaa, 0x4e, 0xa1,
+0x27, 0x44, 0xdf, 0x21, 0x3c, 0x28, 0xc4, 0x00, 0x82, 0x23, 0x58, 0x9a,
+0x82, 0x0c, 0xd5, 0x4a, 0x6f, 0x75, 0xb5, 0x75, 0x08, 0xc8, 0x9d, 0x62,
+0x56, 0xcf, 0xab, 0xf3, 0xea, 0x5a, 0x2d, 0x15, 0x86, 0x0c, 0xee, 0x7b,
+0x45, 0x73, 0x64, 0x9f, 0x2b, 0x35, 0x09, 0xe8, 0xf9, 0x8f, 0x51, 0x5f,
+0xb4, 0x28, 0x54, 0x06, 0x02, 0x21, 0x4f, 0xb1, 0xf4, 0x26, 0x31, 0x73,
+0xa6, 0x1e, 0x5c, 0x20, 0x21, 0xbd, 0x0c, 0xdd, 0xf9, 0xca, 0x95, 0x16,
+0xf6, 0xd5, 0x74, 0xeb, 0x68, 0x7a, 0x98, 0x89, 0x6e, 0xa6, 0xfe, 0x41,
+0x9d, 0x74, 0xb1, 0xa2, 0x16, 0x28, 0x5d, 0x37, 0x2a, 0xa3, 0x5f, 0x95,
+0x46, 0xf8, 0x3b, 0xfc, 0x73, 0xe5, 0x29, 0xd4, 0x01, 0xd1, 0x3a, 0x35,
+0xbd, 0xad, 0x78, 0x16, 0xdf, 0x3a, 0xdc, 0x3d, 0x68, 0x41, 0x23, 0xe6,
+0xf5, 0xa4, 0xf8, 0x26, 0xdb, 0xd2, 0x81, 0x90, 0x95, 0x4a, 0x63, 0xa9,
+0xa2, 0xc1, 0x50, 0xb5, 0x2a, 0xf5, 0xfb, 0x1a, 0x96, 0x00, 0x5e, 0x0b,
+0x7a, 0xf3, 0x69, 0x15, 0x0b, 0x9b, 0x2a, 0xbd, 0x33, 0x5e, 0x90, 0xd9,
+0x78, 0x1f, 0xc2, 0x38, 0x6c, 0xce, 0x16, 0x22, 0x5a, 0x7f, 0xf7, 0xcd,
+0xe8, 0x98, 0xa6, 0x59, 0xd4, 0xb5, 0x8b, 0xdd, 0x25, 0xbe, 0x1c, 0x72,
+0x08, 0x14, 0xd9, 0x1e, 0x03, 0xcc, 0x0c, 0x4e, 0xd0, 0x74, 0xfe, 0xdb,
+0x0a, 0xee, 0x4a, 0xcf, 0xb7, 0xf6, 0x09, 0x74, 0x4c, 0xb3, 0xe8, 0x74,
+0xc7, 0x6d, 0x48, 0x46, 0x77, 0xe2, 0xb9, 0x78, 0x9b, 0xdc, 0xcb, 0xde,
+0xad, 0x12, 0xd5, 0x59, 0x97, 0x66, 0x08, 0x56, 0xa4, 0x52, 0xd5, 0x59,
+0xc9, 0x09, 0x6d, 0x73, 0x0b, 0x31, 0x17, 0xb5, 0x9e, 0x24, 0x73, 0xb6,
+0x15, 0x0a, 0x36, 0xc5, 0xd8, 0x69, 0x58, 0xbf, 0xf2, 0xff, 0x58, 0x85,
+0xfb, 0x28, 0xd7, 0x3f, 0x60, 0x60, 0x83, 0x61, 0x4b, 0x5b, 0x52, 0x3d,
+0x89, 0x05, 0xf9, 0x6a, 0x90, 0xd5, 0x3f, 0x5e, 0x51
};
const size_t ROOT_B_CERT_len = sizeof(ROOT_B_CERT);
/* Chain B - Intermediate CA Certificate (DER format) */
const unsigned char INTERMEDIATE_B_CERT[] = {
0x30, 0x82, 0x05, 0x01, 0x30, 0x82, 0x02, 0xe9, 0xa0, 0x03, 0x02, 0x01,
-0x02, 0x02, 0x14, 0x05, 0x04, 0xe4, 0x03, 0x5b, 0xaa, 0x51, 0x2f, 0xbc,
-0x1c, 0x07, 0xe3, 0x2c, 0x93, 0x4d, 0x60, 0xe0, 0x08, 0x42, 0x99, 0x30,
+0x02, 0x02, 0x14, 0x45, 0x5a, 0xfe, 0x48, 0x80, 0xa8, 0x0e, 0x2d, 0xbb,
+0x84, 0x1d, 0x3b, 0x12, 0xac, 0x5f, 0xee, 0xdc, 0xf7, 0x64, 0xca, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x30, 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
@@ -937,9 +937,9 @@ const unsigned char INTERMEDIATE_B_CERT[] = {
0x0c, 0x07, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x17, 0x30,
0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x43, 0x68, 0x61, 0x69,
0x6e, 0x42, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
-0x17, 0x0d, 0x32, 0x35, 0x30, 0x35, 0x30, 0x38, 0x32, 0x32, 0x30, 0x37,
-0x31, 0x32, 0x5a, 0x17, 0x0d, 0x33, 0x30, 0x30, 0x35, 0x30, 0x37, 0x32,
-0x32, 0x30, 0x37, 0x31, 0x32, 0x5a, 0x30, 0x81, 0x8e, 0x31, 0x0b, 0x30,
+0x17, 0x0d, 0x32, 0x36, 0x30, 0x35, 0x30, 0x39, 0x32, 0x31, 0x33, 0x35,
+0x35, 0x32, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x30, 0x38, 0x32,
+0x31, 0x33, 0x35, 0x35, 0x32, 0x5a, 0x30, 0x81, 0x8e, 0x31, 0x0b, 0x30,
0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c,
0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
@@ -954,90 +954,90 @@ const unsigned char INTERMEDIATE_B_CERT[] = {
0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
-0x82, 0x01, 0x01, 0x00, 0x93, 0xde, 0x1b, 0x4b, 0x12, 0xd0, 0xc5, 0xa0,
-0x1a, 0xea, 0xf3, 0xaa, 0x71, 0x34, 0x09, 0xc6, 0x57, 0x9f, 0x7a, 0x77,
-0x93, 0xa0, 0x4b, 0x35, 0xd0, 0x58, 0x92, 0x27, 0x57, 0xe6, 0x1c, 0x5b,
-0x02, 0xbf, 0x18, 0xa6, 0x68, 0x25, 0x67, 0x5f, 0x85, 0x44, 0x89, 0xc4,
-0xec, 0x44, 0x61, 0x00, 0xf3, 0xbd, 0xd5, 0x53, 0x33, 0x5a, 0x05, 0x44,
-0x1c, 0x44, 0x52, 0x25, 0x10, 0xed, 0x30, 0xa6, 0x6c, 0xae, 0x98, 0xeb,
-0x39, 0x91, 0x75, 0x0f, 0xb2, 0xe2, 0x7d, 0x74, 0x5b, 0x8c, 0xc6, 0xa0,
-0xbe, 0x04, 0x28, 0x5f, 0x35, 0xff, 0xd5, 0xfb, 0xe8, 0x8e, 0x02, 0x42,
-0xb5, 0x9c, 0x7a, 0xd5, 0xbf, 0xf2, 0x72, 0xa4, 0x01, 0x20, 0x3a, 0xbe,
-0x79, 0xfb, 0xe6, 0x40, 0x7a, 0xb8, 0xab, 0x8e, 0x61, 0x50, 0x90, 0xb9,
-0x3d, 0xd8, 0xbe, 0xe9, 0x98, 0xa4, 0x73, 0xb3, 0x7d, 0xe7, 0x81, 0xd5,
-0x1e, 0xb0, 0x2c, 0x05, 0x3a, 0x31, 0xff, 0x81, 0xaa, 0xb8, 0x5b, 0xfa,
-0x6a, 0xfe, 0x64, 0x02, 0x57, 0xef, 0xc3, 0x71, 0x0a, 0x6e, 0xb0, 0xf7,
-0x0a, 0x47, 0x99, 0xea, 0x30, 0xbe, 0x8a, 0x63, 0x61, 0x69, 0x43, 0x1c,
-0x52, 0x7c, 0x62, 0x71, 0xe0, 0xee, 0xa7, 0xb3, 0x29, 0x51, 0x25, 0x10,
-0x42, 0x41, 0x9e, 0xb4, 0x99, 0x1e, 0x75, 0x7e, 0x69, 0x60, 0xac, 0xad,
-0x6f, 0x5d, 0xf9, 0xea, 0x62, 0x81, 0x86, 0x40, 0xdd, 0x77, 0x61, 0xbf,
-0xc7, 0x11, 0xad, 0x95, 0x56, 0x03, 0x41, 0xb8, 0xb8, 0x98, 0xc0, 0x00,
-0x72, 0x9f, 0x43, 0x9c, 0xdf, 0xfc, 0xaf, 0x2a, 0x0a, 0xd1, 0x35, 0x7d,
-0xc3, 0x9b, 0x56, 0x9d, 0x11, 0x02, 0x51, 0x00, 0x73, 0x51, 0xc7, 0xdb,
-0x38, 0x8d, 0x85, 0xb7, 0x3a, 0x5e, 0xe3, 0x72, 0x13, 0x63, 0xad, 0xe7,
-0x26, 0xd9, 0x7c, 0xc4, 0x9d, 0x66, 0x8b, 0x01, 0x02, 0x03, 0x01, 0x00,
+0x82, 0x01, 0x01, 0x00, 0x8e, 0x70, 0xdc, 0x22, 0x84, 0x63, 0x1f, 0x43,
+0x7b, 0xa0, 0x85, 0x56, 0x5e, 0xfc, 0x14, 0xb5, 0x6a, 0x23, 0x0a, 0x9a,
+0xc6, 0x42, 0x6f, 0xe0, 0xc8, 0x40, 0xae, 0xa2, 0x8d, 0xa8, 0x0f, 0xfb,
+0xac, 0x48, 0x05, 0x3e, 0xa5, 0x29, 0xe4, 0x15, 0xd2, 0x7b, 0x70, 0x1e,
+0x2b, 0x48, 0xcd, 0xc2, 0x10, 0x85, 0x52, 0xda, 0x04, 0x69, 0x54, 0xa9,
+0x56, 0x8c, 0x78, 0xc3, 0x4c, 0x61, 0x89, 0xf8, 0x20, 0x83, 0x0f, 0x30,
+0x59, 0x74, 0x0d, 0xad, 0x31, 0x2f, 0xe9, 0xe9, 0x67, 0x73, 0x80, 0x07,
+0x10, 0x02, 0x21, 0x08, 0x8a, 0xec, 0x98, 0x08, 0x2d, 0xb7, 0x7d, 0x22,
+0xda, 0x36, 0x89, 0xb4, 0x05, 0x3b, 0x88, 0x05, 0xba, 0x77, 0x5b, 0xca,
+0xa0, 0x31, 0x65, 0xe7, 0xbb, 0x80, 0xd8, 0xec, 0x55, 0x43, 0x0a, 0xe1,
+0x8c, 0x9f, 0x2b, 0x11, 0x4d, 0xea, 0xd1, 0xf2, 0xfa, 0xf0, 0x93, 0x8b,
+0x95, 0xe1, 0xfd, 0x97, 0xc4, 0x2e, 0xc5, 0x53, 0x9e, 0x9a, 0x0d, 0xa2,
+0x0e, 0xb4, 0xe0, 0x62, 0x27, 0x99, 0x68, 0x67, 0xb2, 0xb3, 0xf0, 0x2b,
+0xa3, 0x11, 0xee, 0xd3, 0xee, 0x23, 0x8c, 0x40, 0x09, 0x5e, 0xd3, 0x0d,
+0xb7, 0x08, 0x4b, 0x29, 0x94, 0x2a, 0x8f, 0x67, 0xbf, 0x1c, 0xc1, 0x5f,
+0x9e, 0x41, 0x6c, 0x90, 0xaa, 0x33, 0x38, 0xc5, 0x48, 0xce, 0xc3, 0x84,
+0x7b, 0x61, 0x8b, 0x67, 0xe4, 0x58, 0x2d, 0xd9, 0x58, 0x09, 0x35, 0x4f,
+0x28, 0x69, 0x8c, 0xaf, 0x93, 0x7a, 0x68, 0x9b, 0x2c, 0x59, 0xa4, 0x44,
+0x3b, 0x21, 0x23, 0xd2, 0x01, 0xe1, 0xd9, 0xfd, 0xeb, 0xb2, 0x02, 0x9d,
+0x9b, 0x3f, 0xbf, 0x14, 0x93, 0x28, 0x04, 0x11, 0xa9, 0x96, 0xae, 0xe8,
+0xfc, 0x55, 0x64, 0x83, 0x8e, 0x15, 0xe4, 0xce, 0x09, 0x11, 0xfe, 0x99,
+0xe8, 0xce, 0xac, 0x88, 0xf9, 0x01, 0x07, 0xe7, 0x02, 0x03, 0x01, 0x00,
0x01, 0xa3, 0x66, 0x30, 0x64, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
-0x04, 0x16, 0x04, 0x14, 0x50, 0xa1, 0xf6, 0x3a, 0x70, 0x94, 0x00, 0xb6,
-0x1c, 0xfe, 0x3a, 0xab, 0x20, 0x4d, 0x23, 0x3f, 0xc6, 0x60, 0x28, 0xc0,
+0x04, 0x16, 0x04, 0x14, 0xe0, 0xcc, 0x27, 0xd7, 0x07, 0x2b, 0xd4, 0xb5,
+0x6f, 0xd9, 0xf6, 0xc9, 0x34, 0x3e, 0x84, 0xbc, 0x61, 0xfa, 0xf5, 0xbc,
0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
-0x14, 0x0d, 0x1a, 0x6c, 0x57, 0x86, 0x74, 0x9c, 0xb6, 0x5c, 0xd1, 0x3e,
-0x2e, 0x5d, 0xe8, 0x94, 0x30, 0xba, 0x38, 0x08, 0x80, 0x30, 0x0d, 0x06,
+0x14, 0xde, 0xea, 0xb2, 0x07, 0x9c, 0x6b, 0x08, 0xe2, 0xd9, 0x37, 0xf7,
+0x9e, 0x25, 0x1f, 0xde, 0xaa, 0x6d, 0x5b, 0x81, 0xd3, 0x30, 0x0d, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
-0x03, 0x82, 0x02, 0x01, 0x00, 0x78, 0x10, 0x7a, 0x32, 0xe4, 0xbc, 0xd3,
-0x2a, 0x67, 0xed, 0x20, 0xd1, 0xba, 0x6b, 0xd5, 0xa8, 0x03, 0x98, 0x38,
-0x9d, 0x62, 0x63, 0x39, 0x31, 0xd9, 0x99, 0x6c, 0x98, 0x51, 0xd7, 0xe7,
-0x68, 0x89, 0x60, 0x19, 0xfd, 0xcf, 0xcb, 0x69, 0x04, 0x69, 0x64, 0x9f,
-0xbd, 0x4c, 0x28, 0x91, 0x81, 0x82, 0x88, 0xa2, 0x56, 0xac, 0xa6, 0xad,
-0x9f, 0xde, 0xdb, 0xd6, 0xd3, 0x1a, 0xe2, 0xcf, 0x53, 0xfe, 0x42, 0x3e,
-0xf3, 0x4c, 0x3f, 0x27, 0x39, 0xff, 0x00, 0xf6, 0xc9, 0x79, 0xc3, 0x34,
-0x13, 0x78, 0x82, 0xe5, 0x1d, 0x4a, 0x31, 0xfd, 0x38, 0xce, 0x2f, 0xf6,
-0xd5, 0xb7, 0x2a, 0x43, 0xdc, 0x95, 0x53, 0x91, 0x97, 0x41, 0x31, 0x37,
-0x59, 0xf0, 0xf2, 0xbc, 0xa1, 0x1d, 0x29, 0x7b, 0x3a, 0x74, 0x21, 0x83,
-0xbc, 0x9b, 0x2d, 0x8d, 0x69, 0x28, 0xf8, 0xd2, 0x0b, 0x5f, 0x68, 0xf0,
-0x6c, 0x22, 0x82, 0x74, 0x25, 0x85, 0x5a, 0x32, 0x7d, 0x2a, 0xf3, 0x5e,
-0xb4, 0xe6, 0x5e, 0xa3, 0xe2, 0x12, 0xac, 0x4c, 0x1c, 0x1f, 0xb0, 0x53,
-0xd7, 0xe6, 0x04, 0x26, 0x28, 0xf9, 0x52, 0x4e, 0x8b, 0xb3, 0x7a, 0xb4,
-0x96, 0xb5, 0xf0, 0x82, 0x0f, 0xa3, 0x42, 0x6c, 0xe2, 0xa5, 0x30, 0x44,
-0x81, 0x8f, 0xf8, 0xa1, 0x20, 0x5b, 0xc3, 0xf9, 0xe2, 0x4d, 0x96, 0x1c,
-0xd3, 0x1e, 0x5b, 0xe7, 0xaf, 0x14, 0x23, 0x0b, 0x5c, 0x90, 0x6d, 0xa3,
-0xa8, 0x4c, 0x0b, 0x63, 0x77, 0x52, 0x5a, 0xd4, 0x73, 0x60, 0x4f, 0x08,
-0x77, 0xf9, 0x7f, 0xe8, 0xc2, 0x20, 0xe3, 0xa8, 0x52, 0x12, 0x69, 0x53,
-0x65, 0x01, 0x72, 0x8f, 0x66, 0x05, 0xc3, 0xea, 0x4c, 0x77, 0x26, 0x40,
-0xa9, 0x19, 0xeb, 0x3b, 0x67, 0xad, 0x07, 0xcb, 0x6f, 0xde, 0xa3, 0x73,
-0xc1, 0xcf, 0x66, 0xe7, 0xb2, 0x46, 0x82, 0xe6, 0xd6, 0x97, 0x02, 0xd2,
-0x71, 0xc3, 0x4f, 0xe0, 0x25, 0xcd, 0xe4, 0x30, 0x3a, 0x21, 0xfb, 0xfd,
-0xdd, 0xb7, 0x4f, 0xdf, 0x7e, 0x0f, 0xa0, 0x4f, 0xf5, 0x6a, 0x2d, 0x26,
-0x02, 0xaa, 0x62, 0x6f, 0x86, 0x50, 0xa3, 0xf2, 0x9f, 0xe3, 0xf6, 0xb3,
-0x74, 0x39, 0xb8, 0x12, 0xee, 0xfa, 0x92, 0x90, 0x7d, 0x4f, 0xa5, 0xa5,
-0xb3, 0xd2, 0x5f, 0x6b, 0x47, 0x05, 0x66, 0x85, 0xd8, 0xf0, 0xcf, 0xf0,
-0x1d, 0x9e, 0xb2, 0x96, 0x19, 0x9b, 0xef, 0x95, 0xbe, 0x69, 0x8d, 0xbd,
-0xc9, 0xfc, 0x33, 0x7f, 0x95, 0x80, 0x35, 0x87, 0xea, 0xea, 0xd9, 0x64,
-0xcc, 0xef, 0x27, 0x20, 0x90, 0xb1, 0xf9, 0x4d, 0xca, 0xca, 0x8b, 0xcb,
-0x47, 0x40, 0x25, 0x88, 0x85, 0x0e, 0xf4, 0x2c, 0x81, 0xb7, 0xd1, 0xa9,
-0x0d, 0x3f, 0x7d, 0x37, 0xb6, 0x7b, 0xf2, 0x4d, 0x5c, 0x4e, 0x9f, 0x77,
-0xc2, 0xd2, 0x6b, 0xe1, 0x5d, 0x55, 0x45, 0xfc, 0x22, 0xc9, 0x16, 0xdd,
-0x75, 0xe8, 0x9b, 0xd9, 0x81, 0x57, 0xd5, 0x81, 0x4f, 0x1f, 0x10, 0xf0,
-0xf5, 0xad, 0x31, 0x01, 0x17, 0xdf, 0x6c, 0xc0, 0xbb, 0x57, 0xe7, 0x05,
-0x05, 0x6b, 0x85, 0xd2, 0xf3, 0xef, 0x13, 0x8a, 0xdc, 0xa5, 0x53, 0x9b,
-0x27, 0x5e, 0x9b, 0x73, 0x0f, 0x55, 0xa8, 0x5f, 0xba, 0x6c, 0x99, 0xce,
-0xfb, 0x42, 0x37, 0x6c, 0xaa, 0x84, 0x18, 0x7c, 0x97, 0xec, 0x4b, 0xe5,
-0x69, 0xfe, 0xfd, 0xfb, 0xf7, 0x49, 0xa5, 0xcb, 0x9c, 0x44, 0x4c, 0x44,
-0x5b, 0x32, 0xad, 0xc8, 0x3c, 0x1c, 0xc6, 0x70, 0x2d, 0x42, 0x6a, 0xce,
-0x56, 0x4b, 0x4f, 0x28, 0x15, 0xca, 0x6c, 0x25, 0x55, 0xd2, 0xe0, 0x7e,
-0xd2, 0x9a, 0xd0, 0xe5, 0x05, 0x95, 0xdc, 0xa9, 0xad, 0xf9, 0x0e, 0x6e,
-0x99, 0x84, 0xed, 0xc4, 0x5d, 0x2b, 0xed, 0x81, 0x26, 0x51, 0xfa, 0xd4,
-0x36
+0x03, 0x82, 0x02, 0x01, 0x00, 0x12, 0xec, 0x8b, 0x75, 0xce, 0x0f, 0xc6,
+0x60, 0x9f, 0x8a, 0xf7, 0x8b, 0x79, 0xe8, 0x1a, 0x3c, 0xde, 0x87, 0x8e,
+0xb5, 0x3e, 0x7c, 0x95, 0x70, 0x1a, 0x33, 0xfd, 0x21, 0xbc, 0x87, 0xc6,
+0x50, 0xa0, 0x9e, 0x90, 0x66, 0xfe, 0x51, 0xa6, 0x6d, 0xc0, 0xd3, 0x0a,
+0x1e, 0x82, 0x53, 0x9c, 0x34, 0xea, 0x08, 0xdd, 0xbe, 0x47, 0x5f, 0xd5,
+0x4b, 0xa9, 0xbb, 0xe4, 0x48, 0xed, 0x3a, 0xfa, 0x4f, 0x7a, 0x9f, 0x3d,
+0x3c, 0x9d, 0x63, 0xa7, 0x77, 0xf0, 0x09, 0xcd, 0x63, 0xdc, 0x65, 0xa9,
+0xc2, 0xd1, 0x41, 0xd7, 0xcd, 0x3f, 0x68, 0xde, 0x16, 0x30, 0xec, 0xfa,
+0x9c, 0x94, 0x5d, 0x3a, 0xae, 0x11, 0xf3, 0x96, 0xff, 0xf4, 0x3a, 0x67,
+0x4b, 0x7f, 0xab, 0xce, 0x80, 0x33, 0xe3, 0x6e, 0x05, 0x23, 0xa0, 0x81,
+0x01, 0x2a, 0xbe, 0x19, 0xc7, 0xe2, 0xdb, 0x90, 0x6c, 0xd0, 0x8b, 0xf1,
+0x76, 0x41, 0xc2, 0xa6, 0x57, 0x73, 0x14, 0x27, 0x76, 0xdc, 0xae, 0x75,
+0xba, 0xf8, 0x47, 0x67, 0xec, 0xe4, 0x69, 0x0f, 0x12, 0xe3, 0x89, 0x33,
+0xb2, 0xa4, 0xee, 0x34, 0x10, 0x03, 0xce, 0xd6, 0xf6, 0xb2, 0xbb, 0xe3,
+0xcb, 0x51, 0x16, 0x8c, 0xdb, 0xf7, 0x0c, 0x38, 0x4f, 0x68, 0xeb, 0xd0,
+0x19, 0xe2, 0x7f, 0x1c, 0x36, 0x27, 0x63, 0xf1, 0xc3, 0x7b, 0x52, 0x96,
+0x63, 0xcd, 0xda, 0x70, 0x01, 0x01, 0xa9, 0x6f, 0x63, 0x14, 0x8a, 0x42,
+0xd6, 0x8e, 0xcf, 0x4b, 0x59, 0xd7, 0xfb, 0x11, 0x9d, 0x44, 0xd8, 0x1c,
+0xb4, 0xb8, 0xf6, 0x96, 0xa7, 0xa1, 0x7a, 0x48, 0xfc, 0x32, 0x41, 0xda,
+0xff, 0x21, 0xa8, 0xd4, 0xb0, 0x35, 0xe7, 0x75, 0x89, 0x7b, 0xb6, 0xac,
+0xbf, 0x2c, 0x3d, 0x0a, 0x67, 0x43, 0x07, 0x5a, 0x2c, 0xf6, 0x56, 0x0d,
+0x61, 0x00, 0x77, 0x31, 0x29, 0xad, 0x3f, 0x57, 0xf4, 0x85, 0x37, 0x1e,
+0x7c, 0x69, 0xf4, 0x04, 0xfe, 0xfd, 0x1c, 0x5c, 0xab, 0x37, 0x11, 0x14,
+0xe4, 0xd5, 0x7e, 0x5e, 0x99, 0xae, 0xc4, 0x75, 0xda, 0xae, 0x2b, 0x96,
+0x56, 0xaf, 0x79, 0x41, 0xec, 0x77, 0x2e, 0xec, 0x81, 0x9e, 0xbe, 0x0c,
+0xa8, 0xb3, 0xd2, 0x59, 0x23, 0x53, 0x3c, 0xe3, 0x33, 0x9a, 0x96, 0xee,
+0x75, 0x02, 0x43, 0x61, 0x49, 0x4c, 0x8c, 0x3e, 0x0d, 0x1b, 0x09, 0xec,
+0xf7, 0x5a, 0x48, 0xaa, 0x47, 0x08, 0xfd, 0xa0, 0x8b, 0x59, 0x48, 0x23,
+0xe1, 0x6f, 0x1e, 0x10, 0x37, 0x31, 0xbe, 0xd7, 0x15, 0x6e, 0x71, 0x24,
+0x9c, 0x05, 0x2e, 0xf8, 0x2f, 0xfe, 0xca, 0x23, 0xe5, 0xa6, 0x20, 0xdd,
+0xe5, 0x2d, 0x28, 0xca, 0xec, 0x33, 0x3c, 0x96, 0xb0, 0x67, 0x8f, 0xa7,
+0x4b, 0x18, 0x68, 0xce, 0x5f, 0xdf, 0xb4, 0x59, 0x5a, 0x49, 0x9e, 0x04,
+0x51, 0x63, 0xec, 0xd0, 0x53, 0x38, 0xd8, 0x66, 0xf5, 0xf2, 0xce, 0xcf,
+0xee, 0x59, 0xfc, 0xe4, 0x2d, 0x72, 0xe8, 0x6c, 0xc7, 0xc5, 0x82, 0xb0,
+0xb4, 0x81, 0x57, 0x99, 0x2f, 0x94, 0xaa, 0xf4, 0xd6, 0xb2, 0x1b, 0x0f,
+0x7a, 0xae, 0x61, 0x0d, 0x17, 0x8d, 0x1c, 0x69, 0x0d, 0x7f, 0xc4, 0x7a,
+0x48, 0x7c, 0xa2, 0x78, 0x22, 0xbe, 0x16, 0x2c, 0x4c, 0xdf, 0x87, 0x51,
+0xfb, 0x53, 0x21, 0x9e, 0xd2, 0x8c, 0xb9, 0x79, 0x6d, 0x20, 0x32, 0x80,
+0x3f, 0x18, 0x45, 0xfe, 0x4f, 0xcd, 0x68, 0xff, 0x14, 0xcb, 0x88, 0x26,
+0x9f, 0x02, 0x4c, 0x55, 0xb8, 0x85, 0x68, 0x42, 0x34, 0x18, 0x91, 0xea,
+0x07, 0xbe, 0xff, 0x54, 0x8e, 0xf1, 0x4e, 0xa0, 0xc8, 0x6a, 0x39, 0x17,
+0xbc, 0xff, 0xb7, 0x80, 0x5e, 0xaf, 0xd2, 0x0f, 0x63, 0xd0, 0x66, 0xad,
+0xfa, 0xe5, 0xc0, 0x37, 0xc5, 0x9b, 0xaf, 0xa2, 0xd6, 0x11, 0x63, 0x21,
+0x76
};
const size_t INTERMEDIATE_B_CERT_len = sizeof(INTERMEDIATE_B_CERT);
/* Chain B - Leaf/Server Certificate (DER format) */
const unsigned char LEAF_B_CERT[] = {
0x30, 0x82, 0x04, 0x16, 0x30, 0x82, 0x02, 0xfe, 0xa0, 0x03, 0x02, 0x01,
-0x02, 0x02, 0x14, 0x71, 0xba, 0x4b, 0xc0, 0x11, 0x9e, 0x97, 0xb8, 0xf6,
-0x34, 0x19, 0xbd, 0x5c, 0x77, 0x32, 0xe5, 0xfa, 0x58, 0x7b, 0x9e, 0x30,
+0x02, 0x02, 0x14, 0x27, 0xa7, 0x62, 0xec, 0x07, 0xb9, 0x03, 0x42, 0xeb,
+0x4f, 0xd5, 0xba, 0xd2, 0xb9, 0xbf, 0x53, 0xa5, 0x7b, 0x49, 0x81, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x30, 0x81, 0x8e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
@@ -1051,9 +1051,9 @@ const unsigned char LEAF_B_CERT[] = {
0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03,
0x55, 0x04, 0x03, 0x0c, 0x16, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x42, 0x20,
0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65,
-0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x35, 0x30,
-0x38, 0x32, 0x32, 0x30, 0x37, 0x31, 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x36,
-0x30, 0x35, 0x30, 0x38, 0x32, 0x32, 0x30, 0x37, 0x31, 0x32, 0x5a, 0x30,
+0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x35, 0x30,
+0x39, 0x32, 0x31, 0x33, 0x35, 0x35, 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x37,
+0x30, 0x35, 0x30, 0x39, 0x32, 0x31, 0x33, 0x35, 0x35, 0x32, 0x5a, 0x30,
0x81, 0x86, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61,
@@ -1068,69 +1068,69 @@ const unsigned char LEAF_B_CERT[] = {
0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
-0x00, 0xaa, 0x19, 0xbe, 0xe0, 0xf0, 0x0e, 0x06, 0x83, 0x54, 0xde, 0x6f,
-0xfd, 0x12, 0x4a, 0x50, 0x21, 0xc8, 0x41, 0x10, 0xdb, 0x8d, 0x06, 0xc8,
-0x59, 0x06, 0x52, 0xdb, 0xb2, 0xa3, 0x75, 0x68, 0x5b, 0x78, 0x0f, 0x5f,
-0x7e, 0xb9, 0xed, 0xa6, 0xed, 0x1f, 0xc0, 0x46, 0xab, 0x5a, 0xcf, 0xf6,
-0xbb, 0x8b, 0xe3, 0x6d, 0xe8, 0x32, 0xa4, 0xa7, 0x36, 0xdc, 0xf2, 0x4c,
-0x37, 0xba, 0xd8, 0x65, 0x72, 0x7e, 0xc6, 0x1e, 0xd6, 0x9c, 0x3c, 0xf9,
-0xf1, 0xb9, 0x68, 0x4a, 0x94, 0xb2, 0x98, 0xdd, 0x94, 0x67, 0x78, 0xa8,
-0x03, 0x8b, 0x18, 0xc1, 0x35, 0x78, 0xca, 0x00, 0xb9, 0xd4, 0xd5, 0x0a,
-0x63, 0x35, 0x51, 0x4f, 0x13, 0x9e, 0x97, 0x02, 0x70, 0x58, 0xf5, 0x4f,
-0xcd, 0xb9, 0x38, 0x54, 0xc6, 0x31, 0x85, 0x4c, 0x02, 0x46, 0xf5, 0xd3,
-0x91, 0xdb, 0x52, 0x67, 0x6c, 0x09, 0xae, 0xcb, 0x13, 0x89, 0x98, 0xd8,
-0x70, 0x8b, 0x1b, 0xf5, 0xb2, 0x0e, 0x3e, 0x74, 0xd9, 0x4d, 0x94, 0x84,
-0x2f, 0xc9, 0xbe, 0xbe, 0xcf, 0xa5, 0xf1, 0x51, 0xe7, 0xa5, 0x3d, 0xe8,
-0x37, 0xa3, 0xc7, 0x1e, 0x85, 0x6f, 0xc6, 0xdb, 0xe1, 0x1a, 0xa5, 0x05,
-0xb1, 0xd9, 0x89, 0x72, 0x1f, 0x28, 0x78, 0x59, 0xae, 0x1d, 0xde, 0xc0,
-0x36, 0x03, 0x0a, 0x27, 0xed, 0x81, 0x16, 0xc0, 0xa6, 0x60, 0x60, 0x6c,
-0x42, 0x5a, 0xb3, 0x65, 0xd4, 0xa2, 0xd0, 0xcd, 0x5c, 0x31, 0xbb, 0x87,
-0x8a, 0xe6, 0xf4, 0x32, 0xe8, 0x9c, 0x0d, 0x14, 0x40, 0x34, 0xf1, 0x83,
-0x63, 0x9a, 0xc6, 0x93, 0x40, 0x25, 0x77, 0x20, 0xfe, 0xe8, 0x07, 0x27,
-0x08, 0x2d, 0x50, 0x39, 0x13, 0x16, 0x52, 0xab, 0xba, 0x67, 0x1c, 0xce,
-0xd9, 0x9e, 0x3f, 0x6b, 0xae, 0x59, 0xc6, 0xdb, 0x75, 0xc9, 0xfb, 0xe9,
-0xae, 0x8b, 0xab, 0x49, 0x5b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x72,
+0x00, 0xb9, 0xd2, 0xee, 0x46, 0x8a, 0xcc, 0x21, 0x76, 0x0e, 0xe6, 0xaf,
+0xad, 0x65, 0x0b, 0xc4, 0xfc, 0x76, 0x83, 0xe6, 0x52, 0x40, 0xaa, 0x5c,
+0x81, 0x8c, 0x33, 0xfd, 0x04, 0x91, 0x8d, 0x91, 0xef, 0x07, 0x43, 0xbc,
+0x11, 0x94, 0x16, 0xe2, 0xb3, 0x00, 0x75, 0x2f, 0x4a, 0x00, 0x0c, 0x45,
+0xff, 0x2d, 0xeb, 0x99, 0x7b, 0xbf, 0xeb, 0xe8, 0x60, 0xb1, 0xd8, 0x44,
+0xc3, 0x38, 0xc1, 0x69, 0x9c, 0xaf, 0xfd, 0xd7, 0x0a, 0x1e, 0xda, 0x47,
+0x02, 0x31, 0xec, 0x0a, 0xcf, 0x43, 0xbd, 0x28, 0xaf, 0x8b, 0x64, 0xf2,
+0xd8, 0x13, 0xe7, 0xcb, 0x3e, 0x36, 0xb9, 0x50, 0x0a, 0x18, 0x87, 0x8f,
+0xb5, 0x30, 0xe5, 0xa6, 0x3c, 0x03, 0x79, 0x89, 0x48, 0x79, 0x5c, 0x09,
+0x32, 0x4b, 0xa3, 0xc1, 0xcd, 0x5c, 0x9a, 0x2f, 0x50, 0x61, 0xca, 0xe5,
+0xbe, 0x08, 0x6e, 0x62, 0xee, 0x7c, 0x06, 0xb8, 0x68, 0x50, 0x47, 0x29,
+0x94, 0x93, 0xb6, 0xc9, 0x6b, 0x30, 0xaa, 0x3c, 0xc6, 0xb5, 0x90, 0x4e,
+0x71, 0x0c, 0x48, 0x39, 0xc9, 0x0b, 0x5b, 0x6f, 0xce, 0xaf, 0x74, 0xda,
+0xc1, 0x91, 0x3b, 0xd1, 0x44, 0x99, 0xd6, 0x69, 0x3e, 0xfe, 0x20, 0x71,
+0x4e, 0x30, 0x2a, 0x48, 0x54, 0xc2, 0xe6, 0x57, 0x6a, 0xd1, 0x9d, 0xb7,
+0x11, 0x5c, 0x7a, 0xc8, 0x07, 0xce, 0xc2, 0xd0, 0xd9, 0xdc, 0xb1, 0xb1,
+0xe4, 0x21, 0x95, 0x8d, 0x0a, 0x6c, 0x98, 0x8c, 0xf9, 0x1d, 0xd4, 0x3f,
+0x33, 0x8c, 0x0d, 0xa9, 0x92, 0x6c, 0x0c, 0xcb, 0x5b, 0x8b, 0x4a, 0x26,
+0x00, 0x3f, 0x55, 0x2f, 0x98, 0x8f, 0x73, 0x54, 0x9c, 0xd4, 0xc5, 0x0b,
+0x5a, 0xf9, 0x3a, 0x67, 0x54, 0xd1, 0xba, 0x4a, 0x31, 0xcb, 0xf6, 0x75,
+0xb0, 0xbf, 0x02, 0x29, 0x6e, 0x30, 0x1a, 0x01, 0xee, 0x1a, 0xfc, 0xf0,
+0xc8, 0x2e, 0x23, 0x64, 0xc9, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x72,
0x30, 0x70, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30,
0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25,
0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
-0x14, 0x92, 0xe8, 0x63, 0xd3, 0xbc, 0x30, 0x1e, 0x29, 0x98, 0xa2, 0x10,
-0x19, 0x50, 0x28, 0xf0, 0x80, 0xe9, 0x25, 0x9b, 0xd0, 0x30, 0x1f, 0x06,
-0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x50, 0xa1,
-0xf6, 0x3a, 0x70, 0x94, 0x00, 0xb6, 0x1c, 0xfe, 0x3a, 0xab, 0x20, 0x4d,
-0x23, 0x3f, 0xc6, 0x60, 0x28, 0xc0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+0x14, 0xdd, 0x01, 0x70, 0xe4, 0x6b, 0x18, 0x94, 0x52, 0xa6, 0x9a, 0xef,
+0x1a, 0x74, 0x1f, 0x85, 0x7a, 0x44, 0x82, 0xb1, 0x49, 0x30, 0x1f, 0x06,
+0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe0, 0xcc,
+0x27, 0xd7, 0x07, 0x2b, 0xd4, 0xb5, 0x6f, 0xd9, 0xf6, 0xc9, 0x34, 0x3e,
+0x84, 0xbc, 0x61, 0xfa, 0xf5, 0xbc, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01,
-0x01, 0x00, 0x56, 0xe1, 0x1c, 0x0d, 0x70, 0xe9, 0x60, 0x98, 0xb8, 0x91,
-0xf8, 0x80, 0x11, 0xa9, 0xf6, 0x92, 0xc2, 0x70, 0xdb, 0xe5, 0x90, 0x5c,
-0x99, 0xaa, 0x96, 0xfd, 0x1b, 0x2e, 0x39, 0xd2, 0xcc, 0x0f, 0xc6, 0x56,
-0xe5, 0xbd, 0x6f, 0x42, 0x5b, 0xa1, 0x83, 0x63, 0xfb, 0xd2, 0x9b, 0x9d,
-0x3c, 0xd3, 0xe9, 0x7c, 0x2c, 0x6a, 0x75, 0x93, 0xea, 0x9f, 0xbf, 0x5e,
-0xb7, 0xa0, 0x1c, 0x83, 0x8c, 0xa0, 0xca, 0x41, 0x2d, 0x4e, 0xb6, 0x3f,
-0xa3, 0xe5, 0x68, 0x8c, 0xa9, 0xe8, 0x0b, 0x81, 0x34, 0x11, 0x3e, 0x25,
-0x68, 0x14, 0xd2, 0xcd, 0xb1, 0xaf, 0x21, 0xf4, 0xc1, 0xdf, 0xb6, 0x28,
-0x4c, 0x5f, 0x3f, 0x35, 0xfb, 0xb7, 0xfd, 0x12, 0xe3, 0xdd, 0x72, 0xef,
-0x04, 0x79, 0x24, 0x81, 0xcf, 0xb2, 0x71, 0xf7, 0x1e, 0x76, 0xb5, 0x8e,
-0x5c, 0x3e, 0xb6, 0x1c, 0x8e, 0x20, 0xb7, 0x6b, 0x56, 0x65, 0xf8, 0xb5,
-0x12, 0x53, 0x66, 0xf5, 0x16, 0x3a, 0x21, 0x28, 0x29, 0x86, 0x55, 0x50,
-0x6c, 0x36, 0x07, 0x00, 0x6d, 0x90, 0xe5, 0x9f, 0x22, 0x41, 0x90, 0x8a,
-0x8e, 0x36, 0x74, 0x66, 0x76, 0x03, 0xbd, 0x35, 0xc2, 0x33, 0x81, 0xf8,
-0x03, 0xae, 0xf6, 0x25, 0xb1, 0x3f, 0x36, 0xee, 0xd0, 0x97, 0x06, 0xa9,
-0x0b, 0xe5, 0x79, 0xa4, 0xf3, 0x87, 0xad, 0x17, 0x8e, 0xf5, 0x36, 0x61,
-0x8e, 0xc2, 0xad, 0xde, 0xe0, 0x9a, 0x7e, 0xd6, 0x62, 0x8f, 0x5f, 0x46,
-0x16, 0x9c, 0x26, 0x3c, 0x79, 0x2f, 0xc1, 0x8f, 0x47, 0xfb, 0x24, 0xb7,
-0x0b, 0x30, 0x1a, 0x65, 0xea, 0x73, 0xdc, 0xbe, 0x33, 0xdf, 0x97, 0x64,
-0x72, 0x83, 0x96, 0x1a, 0x73, 0x59, 0x1c, 0xf1, 0x4b, 0xa1, 0xd0, 0x7c,
-0x3c, 0xfc, 0xe6, 0xff, 0xe5, 0xbc, 0x0c, 0x88, 0x7f, 0xaf, 0x65, 0xda,
-0x43, 0x24, 0xe8, 0xeb, 0x65, 0x9e
+0x01, 0x00, 0x44, 0x6b, 0xe1, 0x5b, 0xbb, 0x84, 0x2f, 0x29, 0xbe, 0x30,
+0xec, 0x1a, 0xc1, 0xa0, 0x8b, 0x55, 0xee, 0x00, 0xa1, 0xbd, 0x0e, 0x67,
+0xf6, 0x30, 0x9a, 0xbf, 0x1f, 0x8e, 0x9e, 0x14, 0xa5, 0x54, 0x84, 0xe9,
+0xef, 0x9d, 0xb4, 0x6a, 0x89, 0x8e, 0x6f, 0xb9, 0xb1, 0xac, 0xd3, 0x62,
+0xf9, 0x8b, 0x00, 0xd9, 0xcf, 0x47, 0xe7, 0x0f, 0xe8, 0x52, 0xef, 0x2d,
+0x5e, 0xa7, 0x07, 0x5f, 0xa9, 0x7f, 0xdd, 0x74, 0xbd, 0x15, 0xe3, 0x42,
+0xb3, 0xe5, 0x07, 0xb9, 0x47, 0xf1, 0x15, 0x08, 0x96, 0xe2, 0x9d, 0xe1,
+0xe8, 0xb0, 0xeb, 0x9e, 0x30, 0x44, 0xbb, 0x1d, 0x16, 0xac, 0x6d, 0x53,
+0x1b, 0x01, 0xb9, 0x97, 0xd8, 0x37, 0xf3, 0x46, 0x28, 0xdd, 0x60, 0x80,
+0x29, 0x4b, 0xb8, 0x02, 0x17, 0x73, 0xeb, 0x5e, 0x5d, 0x57, 0xdf, 0xee,
+0x7f, 0x1e, 0x33, 0x12, 0x68, 0x1c, 0x22, 0x19, 0x4b, 0xbb, 0x2b, 0x2e,
+0xa7, 0x66, 0x42, 0xe8, 0xc1, 0x35, 0x1e, 0x0c, 0x61, 0xbc, 0x54, 0xb8,
+0x15, 0x45, 0x3f, 0x63, 0xfa, 0x75, 0x8c, 0xeb, 0xce, 0x81, 0x83, 0x5e,
+0x99, 0xe3, 0x75, 0x44, 0xb6, 0x05, 0x4b, 0x10, 0xad, 0x11, 0xc1, 0x29,
+0x59, 0x13, 0xca, 0x94, 0x69, 0x7a, 0xd1, 0x98, 0x06, 0x91, 0x86, 0xdc,
+0x27, 0xdf, 0xf3, 0x85, 0xd0, 0x2f, 0xd3, 0x72, 0x12, 0x49, 0x5e, 0xdf,
+0xa3, 0x0c, 0x17, 0x1b, 0x71, 0x83, 0xc8, 0xb0, 0x32, 0xb8, 0x15, 0x73,
+0xbc, 0x66, 0xe5, 0x71, 0x60, 0x5c, 0x12, 0xed, 0xa5, 0x46, 0x48, 0x5d,
+0xa4, 0x2d, 0xd3, 0x85, 0xca, 0x0e, 0x20, 0x56, 0x82, 0x84, 0x49, 0x44,
+0x0a, 0x73, 0x45, 0xff, 0x4d, 0x13, 0x53, 0x1e, 0x5e, 0xee, 0xbe, 0x03,
+0xc2, 0xe7, 0x78, 0xa9, 0xc5, 0x49, 0x8f, 0xf9, 0xec, 0x67, 0xa1, 0xaa,
+0x9c, 0x4c, 0x1b, 0xfe, 0x7d, 0x96
};
const size_t LEAF_B_CERT_len = sizeof(LEAF_B_CERT);
/* Chain B - Raw Certificate Chain (Intermediate+Leaf) (DER format) */
const unsigned char RAW_CERT_CHAIN_B[] = {
0x30, 0x82, 0x05, 0x01, 0x30, 0x82, 0x02, 0xe9, 0xa0, 0x03, 0x02, 0x01,
-0x02, 0x02, 0x14, 0x05, 0x04, 0xe4, 0x03, 0x5b, 0xaa, 0x51, 0x2f, 0xbc,
-0x1c, 0x07, 0xe3, 0x2c, 0x93, 0x4d, 0x60, 0xe0, 0x08, 0x42, 0x99, 0x30,
+0x02, 0x02, 0x14, 0x45, 0x5a, 0xfe, 0x48, 0x80, 0xa8, 0x0e, 0x2d, 0xbb,
+0x84, 0x1d, 0x3b, 0x12, 0xac, 0x5f, 0xee, 0xdc, 0xf7, 0x64, 0xca, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x30, 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
@@ -1143,9 +1143,9 @@ const unsigned char RAW_CERT_CHAIN_B[] = {
0x0c, 0x07, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x17, 0x30,
0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x43, 0x68, 0x61, 0x69,
0x6e, 0x42, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
-0x17, 0x0d, 0x32, 0x35, 0x30, 0x35, 0x30, 0x38, 0x32, 0x32, 0x30, 0x37,
-0x31, 0x32, 0x5a, 0x17, 0x0d, 0x33, 0x30, 0x30, 0x35, 0x30, 0x37, 0x32,
-0x32, 0x30, 0x37, 0x31, 0x32, 0x5a, 0x30, 0x81, 0x8e, 0x31, 0x0b, 0x30,
+0x17, 0x0d, 0x32, 0x36, 0x30, 0x35, 0x30, 0x39, 0x32, 0x31, 0x33, 0x35,
+0x35, 0x32, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x30, 0x38, 0x32,
+0x31, 0x33, 0x35, 0x35, 0x32, 0x5a, 0x30, 0x81, 0x8e, 0x31, 0x0b, 0x30,
0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c,
0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
@@ -1160,84 +1160,84 @@ const unsigned char RAW_CERT_CHAIN_B[] = {
0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
-0x82, 0x01, 0x01, 0x00, 0x93, 0xde, 0x1b, 0x4b, 0x12, 0xd0, 0xc5, 0xa0,
-0x1a, 0xea, 0xf3, 0xaa, 0x71, 0x34, 0x09, 0xc6, 0x57, 0x9f, 0x7a, 0x77,
-0x93, 0xa0, 0x4b, 0x35, 0xd0, 0x58, 0x92, 0x27, 0x57, 0xe6, 0x1c, 0x5b,
-0x02, 0xbf, 0x18, 0xa6, 0x68, 0x25, 0x67, 0x5f, 0x85, 0x44, 0x89, 0xc4,
-0xec, 0x44, 0x61, 0x00, 0xf3, 0xbd, 0xd5, 0x53, 0x33, 0x5a, 0x05, 0x44,
-0x1c, 0x44, 0x52, 0x25, 0x10, 0xed, 0x30, 0xa6, 0x6c, 0xae, 0x98, 0xeb,
-0x39, 0x91, 0x75, 0x0f, 0xb2, 0xe2, 0x7d, 0x74, 0x5b, 0x8c, 0xc6, 0xa0,
-0xbe, 0x04, 0x28, 0x5f, 0x35, 0xff, 0xd5, 0xfb, 0xe8, 0x8e, 0x02, 0x42,
-0xb5, 0x9c, 0x7a, 0xd5, 0xbf, 0xf2, 0x72, 0xa4, 0x01, 0x20, 0x3a, 0xbe,
-0x79, 0xfb, 0xe6, 0x40, 0x7a, 0xb8, 0xab, 0x8e, 0x61, 0x50, 0x90, 0xb9,
-0x3d, 0xd8, 0xbe, 0xe9, 0x98, 0xa4, 0x73, 0xb3, 0x7d, 0xe7, 0x81, 0xd5,
-0x1e, 0xb0, 0x2c, 0x05, 0x3a, 0x31, 0xff, 0x81, 0xaa, 0xb8, 0x5b, 0xfa,
-0x6a, 0xfe, 0x64, 0x02, 0x57, 0xef, 0xc3, 0x71, 0x0a, 0x6e, 0xb0, 0xf7,
-0x0a, 0x47, 0x99, 0xea, 0x30, 0xbe, 0x8a, 0x63, 0x61, 0x69, 0x43, 0x1c,
-0x52, 0x7c, 0x62, 0x71, 0xe0, 0xee, 0xa7, 0xb3, 0x29, 0x51, 0x25, 0x10,
-0x42, 0x41, 0x9e, 0xb4, 0x99, 0x1e, 0x75, 0x7e, 0x69, 0x60, 0xac, 0xad,
-0x6f, 0x5d, 0xf9, 0xea, 0x62, 0x81, 0x86, 0x40, 0xdd, 0x77, 0x61, 0xbf,
-0xc7, 0x11, 0xad, 0x95, 0x56, 0x03, 0x41, 0xb8, 0xb8, 0x98, 0xc0, 0x00,
-0x72, 0x9f, 0x43, 0x9c, 0xdf, 0xfc, 0xaf, 0x2a, 0x0a, 0xd1, 0x35, 0x7d,
-0xc3, 0x9b, 0x56, 0x9d, 0x11, 0x02, 0x51, 0x00, 0x73, 0x51, 0xc7, 0xdb,
-0x38, 0x8d, 0x85, 0xb7, 0x3a, 0x5e, 0xe3, 0x72, 0x13, 0x63, 0xad, 0xe7,
-0x26, 0xd9, 0x7c, 0xc4, 0x9d, 0x66, 0x8b, 0x01, 0x02, 0x03, 0x01, 0x00,
+0x82, 0x01, 0x01, 0x00, 0x8e, 0x70, 0xdc, 0x22, 0x84, 0x63, 0x1f, 0x43,
+0x7b, 0xa0, 0x85, 0x56, 0x5e, 0xfc, 0x14, 0xb5, 0x6a, 0x23, 0x0a, 0x9a,
+0xc6, 0x42, 0x6f, 0xe0, 0xc8, 0x40, 0xae, 0xa2, 0x8d, 0xa8, 0x0f, 0xfb,
+0xac, 0x48, 0x05, 0x3e, 0xa5, 0x29, 0xe4, 0x15, 0xd2, 0x7b, 0x70, 0x1e,
+0x2b, 0x48, 0xcd, 0xc2, 0x10, 0x85, 0x52, 0xda, 0x04, 0x69, 0x54, 0xa9,
+0x56, 0x8c, 0x78, 0xc3, 0x4c, 0x61, 0x89, 0xf8, 0x20, 0x83, 0x0f, 0x30,
+0x59, 0x74, 0x0d, 0xad, 0x31, 0x2f, 0xe9, 0xe9, 0x67, 0x73, 0x80, 0x07,
+0x10, 0x02, 0x21, 0x08, 0x8a, 0xec, 0x98, 0x08, 0x2d, 0xb7, 0x7d, 0x22,
+0xda, 0x36, 0x89, 0xb4, 0x05, 0x3b, 0x88, 0x05, 0xba, 0x77, 0x5b, 0xca,
+0xa0, 0x31, 0x65, 0xe7, 0xbb, 0x80, 0xd8, 0xec, 0x55, 0x43, 0x0a, 0xe1,
+0x8c, 0x9f, 0x2b, 0x11, 0x4d, 0xea, 0xd1, 0xf2, 0xfa, 0xf0, 0x93, 0x8b,
+0x95, 0xe1, 0xfd, 0x97, 0xc4, 0x2e, 0xc5, 0x53, 0x9e, 0x9a, 0x0d, 0xa2,
+0x0e, 0xb4, 0xe0, 0x62, 0x27, 0x99, 0x68, 0x67, 0xb2, 0xb3, 0xf0, 0x2b,
+0xa3, 0x11, 0xee, 0xd3, 0xee, 0x23, 0x8c, 0x40, 0x09, 0x5e, 0xd3, 0x0d,
+0xb7, 0x08, 0x4b, 0x29, 0x94, 0x2a, 0x8f, 0x67, 0xbf, 0x1c, 0xc1, 0x5f,
+0x9e, 0x41, 0x6c, 0x90, 0xaa, 0x33, 0x38, 0xc5, 0x48, 0xce, 0xc3, 0x84,
+0x7b, 0x61, 0x8b, 0x67, 0xe4, 0x58, 0x2d, 0xd9, 0x58, 0x09, 0x35, 0x4f,
+0x28, 0x69, 0x8c, 0xaf, 0x93, 0x7a, 0x68, 0x9b, 0x2c, 0x59, 0xa4, 0x44,
+0x3b, 0x21, 0x23, 0xd2, 0x01, 0xe1, 0xd9, 0xfd, 0xeb, 0xb2, 0x02, 0x9d,
+0x9b, 0x3f, 0xbf, 0x14, 0x93, 0x28, 0x04, 0x11, 0xa9, 0x96, 0xae, 0xe8,
+0xfc, 0x55, 0x64, 0x83, 0x8e, 0x15, 0xe4, 0xce, 0x09, 0x11, 0xfe, 0x99,
+0xe8, 0xce, 0xac, 0x88, 0xf9, 0x01, 0x07, 0xe7, 0x02, 0x03, 0x01, 0x00,
0x01, 0xa3, 0x66, 0x30, 0x64, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
-0x04, 0x16, 0x04, 0x14, 0x50, 0xa1, 0xf6, 0x3a, 0x70, 0x94, 0x00, 0xb6,
-0x1c, 0xfe, 0x3a, 0xab, 0x20, 0x4d, 0x23, 0x3f, 0xc6, 0x60, 0x28, 0xc0,
+0x04, 0x16, 0x04, 0x14, 0xe0, 0xcc, 0x27, 0xd7, 0x07, 0x2b, 0xd4, 0xb5,
+0x6f, 0xd9, 0xf6, 0xc9, 0x34, 0x3e, 0x84, 0xbc, 0x61, 0xfa, 0xf5, 0xbc,
0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
-0x14, 0x0d, 0x1a, 0x6c, 0x57, 0x86, 0x74, 0x9c, 0xb6, 0x5c, 0xd1, 0x3e,
-0x2e, 0x5d, 0xe8, 0x94, 0x30, 0xba, 0x38, 0x08, 0x80, 0x30, 0x0d, 0x06,
+0x14, 0xde, 0xea, 0xb2, 0x07, 0x9c, 0x6b, 0x08, 0xe2, 0xd9, 0x37, 0xf7,
+0x9e, 0x25, 0x1f, 0xde, 0xaa, 0x6d, 0x5b, 0x81, 0xd3, 0x30, 0x0d, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
-0x03, 0x82, 0x02, 0x01, 0x00, 0x78, 0x10, 0x7a, 0x32, 0xe4, 0xbc, 0xd3,
-0x2a, 0x67, 0xed, 0x20, 0xd1, 0xba, 0x6b, 0xd5, 0xa8, 0x03, 0x98, 0x38,
-0x9d, 0x62, 0x63, 0x39, 0x31, 0xd9, 0x99, 0x6c, 0x98, 0x51, 0xd7, 0xe7,
-0x68, 0x89, 0x60, 0x19, 0xfd, 0xcf, 0xcb, 0x69, 0x04, 0x69, 0x64, 0x9f,
-0xbd, 0x4c, 0x28, 0x91, 0x81, 0x82, 0x88, 0xa2, 0x56, 0xac, 0xa6, 0xad,
-0x9f, 0xde, 0xdb, 0xd6, 0xd3, 0x1a, 0xe2, 0xcf, 0x53, 0xfe, 0x42, 0x3e,
-0xf3, 0x4c, 0x3f, 0x27, 0x39, 0xff, 0x00, 0xf6, 0xc9, 0x79, 0xc3, 0x34,
-0x13, 0x78, 0x82, 0xe5, 0x1d, 0x4a, 0x31, 0xfd, 0x38, 0xce, 0x2f, 0xf6,
-0xd5, 0xb7, 0x2a, 0x43, 0xdc, 0x95, 0x53, 0x91, 0x97, 0x41, 0x31, 0x37,
-0x59, 0xf0, 0xf2, 0xbc, 0xa1, 0x1d, 0x29, 0x7b, 0x3a, 0x74, 0x21, 0x83,
-0xbc, 0x9b, 0x2d, 0x8d, 0x69, 0x28, 0xf8, 0xd2, 0x0b, 0x5f, 0x68, 0xf0,
-0x6c, 0x22, 0x82, 0x74, 0x25, 0x85, 0x5a, 0x32, 0x7d, 0x2a, 0xf3, 0x5e,
-0xb4, 0xe6, 0x5e, 0xa3, 0xe2, 0x12, 0xac, 0x4c, 0x1c, 0x1f, 0xb0, 0x53,
-0xd7, 0xe6, 0x04, 0x26, 0x28, 0xf9, 0x52, 0x4e, 0x8b, 0xb3, 0x7a, 0xb4,
-0x96, 0xb5, 0xf0, 0x82, 0x0f, 0xa3, 0x42, 0x6c, 0xe2, 0xa5, 0x30, 0x44,
-0x81, 0x8f, 0xf8, 0xa1, 0x20, 0x5b, 0xc3, 0xf9, 0xe2, 0x4d, 0x96, 0x1c,
-0xd3, 0x1e, 0x5b, 0xe7, 0xaf, 0x14, 0x23, 0x0b, 0x5c, 0x90, 0x6d, 0xa3,
-0xa8, 0x4c, 0x0b, 0x63, 0x77, 0x52, 0x5a, 0xd4, 0x73, 0x60, 0x4f, 0x08,
-0x77, 0xf9, 0x7f, 0xe8, 0xc2, 0x20, 0xe3, 0xa8, 0x52, 0x12, 0x69, 0x53,
-0x65, 0x01, 0x72, 0x8f, 0x66, 0x05, 0xc3, 0xea, 0x4c, 0x77, 0x26, 0x40,
-0xa9, 0x19, 0xeb, 0x3b, 0x67, 0xad, 0x07, 0xcb, 0x6f, 0xde, 0xa3, 0x73,
-0xc1, 0xcf, 0x66, 0xe7, 0xb2, 0x46, 0x82, 0xe6, 0xd6, 0x97, 0x02, 0xd2,
-0x71, 0xc3, 0x4f, 0xe0, 0x25, 0xcd, 0xe4, 0x30, 0x3a, 0x21, 0xfb, 0xfd,
-0xdd, 0xb7, 0x4f, 0xdf, 0x7e, 0x0f, 0xa0, 0x4f, 0xf5, 0x6a, 0x2d, 0x26,
-0x02, 0xaa, 0x62, 0x6f, 0x86, 0x50, 0xa3, 0xf2, 0x9f, 0xe3, 0xf6, 0xb3,
-0x74, 0x39, 0xb8, 0x12, 0xee, 0xfa, 0x92, 0x90, 0x7d, 0x4f, 0xa5, 0xa5,
-0xb3, 0xd2, 0x5f, 0x6b, 0x47, 0x05, 0x66, 0x85, 0xd8, 0xf0, 0xcf, 0xf0,
-0x1d, 0x9e, 0xb2, 0x96, 0x19, 0x9b, 0xef, 0x95, 0xbe, 0x69, 0x8d, 0xbd,
-0xc9, 0xfc, 0x33, 0x7f, 0x95, 0x80, 0x35, 0x87, 0xea, 0xea, 0xd9, 0x64,
-0xcc, 0xef, 0x27, 0x20, 0x90, 0xb1, 0xf9, 0x4d, 0xca, 0xca, 0x8b, 0xcb,
-0x47, 0x40, 0x25, 0x88, 0x85, 0x0e, 0xf4, 0x2c, 0x81, 0xb7, 0xd1, 0xa9,
-0x0d, 0x3f, 0x7d, 0x37, 0xb6, 0x7b, 0xf2, 0x4d, 0x5c, 0x4e, 0x9f, 0x77,
-0xc2, 0xd2, 0x6b, 0xe1, 0x5d, 0x55, 0x45, 0xfc, 0x22, 0xc9, 0x16, 0xdd,
-0x75, 0xe8, 0x9b, 0xd9, 0x81, 0x57, 0xd5, 0x81, 0x4f, 0x1f, 0x10, 0xf0,
-0xf5, 0xad, 0x31, 0x01, 0x17, 0xdf, 0x6c, 0xc0, 0xbb, 0x57, 0xe7, 0x05,
-0x05, 0x6b, 0x85, 0xd2, 0xf3, 0xef, 0x13, 0x8a, 0xdc, 0xa5, 0x53, 0x9b,
-0x27, 0x5e, 0x9b, 0x73, 0x0f, 0x55, 0xa8, 0x5f, 0xba, 0x6c, 0x99, 0xce,
-0xfb, 0x42, 0x37, 0x6c, 0xaa, 0x84, 0x18, 0x7c, 0x97, 0xec, 0x4b, 0xe5,
-0x69, 0xfe, 0xfd, 0xfb, 0xf7, 0x49, 0xa5, 0xcb, 0x9c, 0x44, 0x4c, 0x44,
-0x5b, 0x32, 0xad, 0xc8, 0x3c, 0x1c, 0xc6, 0x70, 0x2d, 0x42, 0x6a, 0xce,
-0x56, 0x4b, 0x4f, 0x28, 0x15, 0xca, 0x6c, 0x25, 0x55, 0xd2, 0xe0, 0x7e,
-0xd2, 0x9a, 0xd0, 0xe5, 0x05, 0x95, 0xdc, 0xa9, 0xad, 0xf9, 0x0e, 0x6e,
-0x99, 0x84, 0xed, 0xc4, 0x5d, 0x2b, 0xed, 0x81, 0x26, 0x51, 0xfa, 0xd4,
-0x36, 0x30, 0x82, 0x04, 0x16, 0x30, 0x82, 0x02, 0xfe, 0xa0, 0x03, 0x02,
-0x01, 0x02, 0x02, 0x14, 0x71, 0xba, 0x4b, 0xc0, 0x11, 0x9e, 0x97, 0xb8,
-0xf6, 0x34, 0x19, 0xbd, 0x5c, 0x77, 0x32, 0xe5, 0xfa, 0x58, 0x7b, 0x9e,
+0x03, 0x82, 0x02, 0x01, 0x00, 0x12, 0xec, 0x8b, 0x75, 0xce, 0x0f, 0xc6,
+0x60, 0x9f, 0x8a, 0xf7, 0x8b, 0x79, 0xe8, 0x1a, 0x3c, 0xde, 0x87, 0x8e,
+0xb5, 0x3e, 0x7c, 0x95, 0x70, 0x1a, 0x33, 0xfd, 0x21, 0xbc, 0x87, 0xc6,
+0x50, 0xa0, 0x9e, 0x90, 0x66, 0xfe, 0x51, 0xa6, 0x6d, 0xc0, 0xd3, 0x0a,
+0x1e, 0x82, 0x53, 0x9c, 0x34, 0xea, 0x08, 0xdd, 0xbe, 0x47, 0x5f, 0xd5,
+0x4b, 0xa9, 0xbb, 0xe4, 0x48, 0xed, 0x3a, 0xfa, 0x4f, 0x7a, 0x9f, 0x3d,
+0x3c, 0x9d, 0x63, 0xa7, 0x77, 0xf0, 0x09, 0xcd, 0x63, 0xdc, 0x65, 0xa9,
+0xc2, 0xd1, 0x41, 0xd7, 0xcd, 0x3f, 0x68, 0xde, 0x16, 0x30, 0xec, 0xfa,
+0x9c, 0x94, 0x5d, 0x3a, 0xae, 0x11, 0xf3, 0x96, 0xff, 0xf4, 0x3a, 0x67,
+0x4b, 0x7f, 0xab, 0xce, 0x80, 0x33, 0xe3, 0x6e, 0x05, 0x23, 0xa0, 0x81,
+0x01, 0x2a, 0xbe, 0x19, 0xc7, 0xe2, 0xdb, 0x90, 0x6c, 0xd0, 0x8b, 0xf1,
+0x76, 0x41, 0xc2, 0xa6, 0x57, 0x73, 0x14, 0x27, 0x76, 0xdc, 0xae, 0x75,
+0xba, 0xf8, 0x47, 0x67, 0xec, 0xe4, 0x69, 0x0f, 0x12, 0xe3, 0x89, 0x33,
+0xb2, 0xa4, 0xee, 0x34, 0x10, 0x03, 0xce, 0xd6, 0xf6, 0xb2, 0xbb, 0xe3,
+0xcb, 0x51, 0x16, 0x8c, 0xdb, 0xf7, 0x0c, 0x38, 0x4f, 0x68, 0xeb, 0xd0,
+0x19, 0xe2, 0x7f, 0x1c, 0x36, 0x27, 0x63, 0xf1, 0xc3, 0x7b, 0x52, 0x96,
+0x63, 0xcd, 0xda, 0x70, 0x01, 0x01, 0xa9, 0x6f, 0x63, 0x14, 0x8a, 0x42,
+0xd6, 0x8e, 0xcf, 0x4b, 0x59, 0xd7, 0xfb, 0x11, 0x9d, 0x44, 0xd8, 0x1c,
+0xb4, 0xb8, 0xf6, 0x96, 0xa7, 0xa1, 0x7a, 0x48, 0xfc, 0x32, 0x41, 0xda,
+0xff, 0x21, 0xa8, 0xd4, 0xb0, 0x35, 0xe7, 0x75, 0x89, 0x7b, 0xb6, 0xac,
+0xbf, 0x2c, 0x3d, 0x0a, 0x67, 0x43, 0x07, 0x5a, 0x2c, 0xf6, 0x56, 0x0d,
+0x61, 0x00, 0x77, 0x31, 0x29, 0xad, 0x3f, 0x57, 0xf4, 0x85, 0x37, 0x1e,
+0x7c, 0x69, 0xf4, 0x04, 0xfe, 0xfd, 0x1c, 0x5c, 0xab, 0x37, 0x11, 0x14,
+0xe4, 0xd5, 0x7e, 0x5e, 0x99, 0xae, 0xc4, 0x75, 0xda, 0xae, 0x2b, 0x96,
+0x56, 0xaf, 0x79, 0x41, 0xec, 0x77, 0x2e, 0xec, 0x81, 0x9e, 0xbe, 0x0c,
+0xa8, 0xb3, 0xd2, 0x59, 0x23, 0x53, 0x3c, 0xe3, 0x33, 0x9a, 0x96, 0xee,
+0x75, 0x02, 0x43, 0x61, 0x49, 0x4c, 0x8c, 0x3e, 0x0d, 0x1b, 0x09, 0xec,
+0xf7, 0x5a, 0x48, 0xaa, 0x47, 0x08, 0xfd, 0xa0, 0x8b, 0x59, 0x48, 0x23,
+0xe1, 0x6f, 0x1e, 0x10, 0x37, 0x31, 0xbe, 0xd7, 0x15, 0x6e, 0x71, 0x24,
+0x9c, 0x05, 0x2e, 0xf8, 0x2f, 0xfe, 0xca, 0x23, 0xe5, 0xa6, 0x20, 0xdd,
+0xe5, 0x2d, 0x28, 0xca, 0xec, 0x33, 0x3c, 0x96, 0xb0, 0x67, 0x8f, 0xa7,
+0x4b, 0x18, 0x68, 0xce, 0x5f, 0xdf, 0xb4, 0x59, 0x5a, 0x49, 0x9e, 0x04,
+0x51, 0x63, 0xec, 0xd0, 0x53, 0x38, 0xd8, 0x66, 0xf5, 0xf2, 0xce, 0xcf,
+0xee, 0x59, 0xfc, 0xe4, 0x2d, 0x72, 0xe8, 0x6c, 0xc7, 0xc5, 0x82, 0xb0,
+0xb4, 0x81, 0x57, 0x99, 0x2f, 0x94, 0xaa, 0xf4, 0xd6, 0xb2, 0x1b, 0x0f,
+0x7a, 0xae, 0x61, 0x0d, 0x17, 0x8d, 0x1c, 0x69, 0x0d, 0x7f, 0xc4, 0x7a,
+0x48, 0x7c, 0xa2, 0x78, 0x22, 0xbe, 0x16, 0x2c, 0x4c, 0xdf, 0x87, 0x51,
+0xfb, 0x53, 0x21, 0x9e, 0xd2, 0x8c, 0xb9, 0x79, 0x6d, 0x20, 0x32, 0x80,
+0x3f, 0x18, 0x45, 0xfe, 0x4f, 0xcd, 0x68, 0xff, 0x14, 0xcb, 0x88, 0x26,
+0x9f, 0x02, 0x4c, 0x55, 0xb8, 0x85, 0x68, 0x42, 0x34, 0x18, 0x91, 0xea,
+0x07, 0xbe, 0xff, 0x54, 0x8e, 0xf1, 0x4e, 0xa0, 0xc8, 0x6a, 0x39, 0x17,
+0xbc, 0xff, 0xb7, 0x80, 0x5e, 0xaf, 0xd2, 0x0f, 0x63, 0xd0, 0x66, 0xad,
+0xfa, 0xe5, 0xc0, 0x37, 0xc5, 0x9b, 0xaf, 0xa2, 0xd6, 0x11, 0x63, 0x21,
+0x76, 0x30, 0x82, 0x04, 0x16, 0x30, 0x82, 0x02, 0xfe, 0xa0, 0x03, 0x02,
+0x01, 0x02, 0x02, 0x14, 0x27, 0xa7, 0x62, 0xec, 0x07, 0xb9, 0x03, 0x42,
+0xeb, 0x4f, 0xd5, 0xba, 0xd2, 0xb9, 0xbf, 0x53, 0xa5, 0x7b, 0x49, 0x81,
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
0x0b, 0x05, 0x00, 0x30, 0x81, 0x8e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06,
@@ -1251,9 +1251,9 @@ const unsigned char RAW_CERT_CHAIN_B[] = {
0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x31, 0x1f, 0x30, 0x1d, 0x06,
0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x42,
0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74,
-0x65, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x35,
-0x30, 0x38, 0x32, 0x32, 0x30, 0x37, 0x31, 0x32, 0x5a, 0x17, 0x0d, 0x32,
-0x36, 0x30, 0x35, 0x30, 0x38, 0x32, 0x32, 0x30, 0x37, 0x31, 0x32, 0x5a,
+0x65, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x35,
+0x30, 0x39, 0x32, 0x31, 0x33, 0x35, 0x35, 0x32, 0x5a, 0x17, 0x0d, 0x32,
+0x37, 0x30, 0x35, 0x30, 0x39, 0x32, 0x31, 0x33, 0x35, 0x35, 0x32, 0x5a,
0x30, 0x81, 0x86, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69,
@@ -1268,61 +1268,61 @@ const unsigned char RAW_CERT_CHAIN_B[] = {
0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
-0x01, 0x00, 0xaa, 0x19, 0xbe, 0xe0, 0xf0, 0x0e, 0x06, 0x83, 0x54, 0xde,
-0x6f, 0xfd, 0x12, 0x4a, 0x50, 0x21, 0xc8, 0x41, 0x10, 0xdb, 0x8d, 0x06,
-0xc8, 0x59, 0x06, 0x52, 0xdb, 0xb2, 0xa3, 0x75, 0x68, 0x5b, 0x78, 0x0f,
-0x5f, 0x7e, 0xb9, 0xed, 0xa6, 0xed, 0x1f, 0xc0, 0x46, 0xab, 0x5a, 0xcf,
-0xf6, 0xbb, 0x8b, 0xe3, 0x6d, 0xe8, 0x32, 0xa4, 0xa7, 0x36, 0xdc, 0xf2,
-0x4c, 0x37, 0xba, 0xd8, 0x65, 0x72, 0x7e, 0xc6, 0x1e, 0xd6, 0x9c, 0x3c,
-0xf9, 0xf1, 0xb9, 0x68, 0x4a, 0x94, 0xb2, 0x98, 0xdd, 0x94, 0x67, 0x78,
-0xa8, 0x03, 0x8b, 0x18, 0xc1, 0x35, 0x78, 0xca, 0x00, 0xb9, 0xd4, 0xd5,
-0x0a, 0x63, 0x35, 0x51, 0x4f, 0x13, 0x9e, 0x97, 0x02, 0x70, 0x58, 0xf5,
-0x4f, 0xcd, 0xb9, 0x38, 0x54, 0xc6, 0x31, 0x85, 0x4c, 0x02, 0x46, 0xf5,
-0xd3, 0x91, 0xdb, 0x52, 0x67, 0x6c, 0x09, 0xae, 0xcb, 0x13, 0x89, 0x98,
-0xd8, 0x70, 0x8b, 0x1b, 0xf5, 0xb2, 0x0e, 0x3e, 0x74, 0xd9, 0x4d, 0x94,
-0x84, 0x2f, 0xc9, 0xbe, 0xbe, 0xcf, 0xa5, 0xf1, 0x51, 0xe7, 0xa5, 0x3d,
-0xe8, 0x37, 0xa3, 0xc7, 0x1e, 0x85, 0x6f, 0xc6, 0xdb, 0xe1, 0x1a, 0xa5,
-0x05, 0xb1, 0xd9, 0x89, 0x72, 0x1f, 0x28, 0x78, 0x59, 0xae, 0x1d, 0xde,
-0xc0, 0x36, 0x03, 0x0a, 0x27, 0xed, 0x81, 0x16, 0xc0, 0xa6, 0x60, 0x60,
-0x6c, 0x42, 0x5a, 0xb3, 0x65, 0xd4, 0xa2, 0xd0, 0xcd, 0x5c, 0x31, 0xbb,
-0x87, 0x8a, 0xe6, 0xf4, 0x32, 0xe8, 0x9c, 0x0d, 0x14, 0x40, 0x34, 0xf1,
-0x83, 0x63, 0x9a, 0xc6, 0x93, 0x40, 0x25, 0x77, 0x20, 0xfe, 0xe8, 0x07,
-0x27, 0x08, 0x2d, 0x50, 0x39, 0x13, 0x16, 0x52, 0xab, 0xba, 0x67, 0x1c,
-0xce, 0xd9, 0x9e, 0x3f, 0x6b, 0xae, 0x59, 0xc6, 0xdb, 0x75, 0xc9, 0xfb,
-0xe9, 0xae, 0x8b, 0xab, 0x49, 0x5b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+0x01, 0x00, 0xb9, 0xd2, 0xee, 0x46, 0x8a, 0xcc, 0x21, 0x76, 0x0e, 0xe6,
+0xaf, 0xad, 0x65, 0x0b, 0xc4, 0xfc, 0x76, 0x83, 0xe6, 0x52, 0x40, 0xaa,
+0x5c, 0x81, 0x8c, 0x33, 0xfd, 0x04, 0x91, 0x8d, 0x91, 0xef, 0x07, 0x43,
+0xbc, 0x11, 0x94, 0x16, 0xe2, 0xb3, 0x00, 0x75, 0x2f, 0x4a, 0x00, 0x0c,
+0x45, 0xff, 0x2d, 0xeb, 0x99, 0x7b, 0xbf, 0xeb, 0xe8, 0x60, 0xb1, 0xd8,
+0x44, 0xc3, 0x38, 0xc1, 0x69, 0x9c, 0xaf, 0xfd, 0xd7, 0x0a, 0x1e, 0xda,
+0x47, 0x02, 0x31, 0xec, 0x0a, 0xcf, 0x43, 0xbd, 0x28, 0xaf, 0x8b, 0x64,
+0xf2, 0xd8, 0x13, 0xe7, 0xcb, 0x3e, 0x36, 0xb9, 0x50, 0x0a, 0x18, 0x87,
+0x8f, 0xb5, 0x30, 0xe5, 0xa6, 0x3c, 0x03, 0x79, 0x89, 0x48, 0x79, 0x5c,
+0x09, 0x32, 0x4b, 0xa3, 0xc1, 0xcd, 0x5c, 0x9a, 0x2f, 0x50, 0x61, 0xca,
+0xe5, 0xbe, 0x08, 0x6e, 0x62, 0xee, 0x7c, 0x06, 0xb8, 0x68, 0x50, 0x47,
+0x29, 0x94, 0x93, 0xb6, 0xc9, 0x6b, 0x30, 0xaa, 0x3c, 0xc6, 0xb5, 0x90,
+0x4e, 0x71, 0x0c, 0x48, 0x39, 0xc9, 0x0b, 0x5b, 0x6f, 0xce, 0xaf, 0x74,
+0xda, 0xc1, 0x91, 0x3b, 0xd1, 0x44, 0x99, 0xd6, 0x69, 0x3e, 0xfe, 0x20,
+0x71, 0x4e, 0x30, 0x2a, 0x48, 0x54, 0xc2, 0xe6, 0x57, 0x6a, 0xd1, 0x9d,
+0xb7, 0x11, 0x5c, 0x7a, 0xc8, 0x07, 0xce, 0xc2, 0xd0, 0xd9, 0xdc, 0xb1,
+0xb1, 0xe4, 0x21, 0x95, 0x8d, 0x0a, 0x6c, 0x98, 0x8c, 0xf9, 0x1d, 0xd4,
+0x3f, 0x33, 0x8c, 0x0d, 0xa9, 0x92, 0x6c, 0x0c, 0xcb, 0x5b, 0x8b, 0x4a,
+0x26, 0x00, 0x3f, 0x55, 0x2f, 0x98, 0x8f, 0x73, 0x54, 0x9c, 0xd4, 0xc5,
+0x0b, 0x5a, 0xf9, 0x3a, 0x67, 0x54, 0xd1, 0xba, 0x4a, 0x31, 0xcb, 0xf6,
+0x75, 0xb0, 0xbf, 0x02, 0x29, 0x6e, 0x30, 0x1a, 0x01, 0xee, 0x1a, 0xfc,
+0xf0, 0xc8, 0x2e, 0x23, 0x64, 0xc9, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
0x72, 0x30, 0x70, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02,
0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d,
0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
0x07, 0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
-0x04, 0x14, 0x92, 0xe8, 0x63, 0xd3, 0xbc, 0x30, 0x1e, 0x29, 0x98, 0xa2,
-0x10, 0x19, 0x50, 0x28, 0xf0, 0x80, 0xe9, 0x25, 0x9b, 0xd0, 0x30, 0x1f,
-0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x50,
-0xa1, 0xf6, 0x3a, 0x70, 0x94, 0x00, 0xb6, 0x1c, 0xfe, 0x3a, 0xab, 0x20,
-0x4d, 0x23, 0x3f, 0xc6, 0x60, 0x28, 0xc0, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+0x04, 0x14, 0xdd, 0x01, 0x70, 0xe4, 0x6b, 0x18, 0x94, 0x52, 0xa6, 0x9a,
+0xef, 0x1a, 0x74, 0x1f, 0x85, 0x7a, 0x44, 0x82, 0xb1, 0x49, 0x30, 0x1f,
+0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe0,
+0xcc, 0x27, 0xd7, 0x07, 0x2b, 0xd4, 0xb5, 0x6f, 0xd9, 0xf6, 0xc9, 0x34,
+0x3e, 0x84, 0xbc, 0x61, 0xfa, 0xf5, 0xbc, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
-0x01, 0x01, 0x00, 0x56, 0xe1, 0x1c, 0x0d, 0x70, 0xe9, 0x60, 0x98, 0xb8,
-0x91, 0xf8, 0x80, 0x11, 0xa9, 0xf6, 0x92, 0xc2, 0x70, 0xdb, 0xe5, 0x90,
-0x5c, 0x99, 0xaa, 0x96, 0xfd, 0x1b, 0x2e, 0x39, 0xd2, 0xcc, 0x0f, 0xc6,
-0x56, 0xe5, 0xbd, 0x6f, 0x42, 0x5b, 0xa1, 0x83, 0x63, 0xfb, 0xd2, 0x9b,
-0x9d, 0x3c, 0xd3, 0xe9, 0x7c, 0x2c, 0x6a, 0x75, 0x93, 0xea, 0x9f, 0xbf,
-0x5e, 0xb7, 0xa0, 0x1c, 0x83, 0x8c, 0xa0, 0xca, 0x41, 0x2d, 0x4e, 0xb6,
-0x3f, 0xa3, 0xe5, 0x68, 0x8c, 0xa9, 0xe8, 0x0b, 0x81, 0x34, 0x11, 0x3e,
-0x25, 0x68, 0x14, 0xd2, 0xcd, 0xb1, 0xaf, 0x21, 0xf4, 0xc1, 0xdf, 0xb6,
-0x28, 0x4c, 0x5f, 0x3f, 0x35, 0xfb, 0xb7, 0xfd, 0x12, 0xe3, 0xdd, 0x72,
-0xef, 0x04, 0x79, 0x24, 0x81, 0xcf, 0xb2, 0x71, 0xf7, 0x1e, 0x76, 0xb5,
-0x8e, 0x5c, 0x3e, 0xb6, 0x1c, 0x8e, 0x20, 0xb7, 0x6b, 0x56, 0x65, 0xf8,
-0xb5, 0x12, 0x53, 0x66, 0xf5, 0x16, 0x3a, 0x21, 0x28, 0x29, 0x86, 0x55,
-0x50, 0x6c, 0x36, 0x07, 0x00, 0x6d, 0x90, 0xe5, 0x9f, 0x22, 0x41, 0x90,
-0x8a, 0x8e, 0x36, 0x74, 0x66, 0x76, 0x03, 0xbd, 0x35, 0xc2, 0x33, 0x81,
-0xf8, 0x03, 0xae, 0xf6, 0x25, 0xb1, 0x3f, 0x36, 0xee, 0xd0, 0x97, 0x06,
-0xa9, 0x0b, 0xe5, 0x79, 0xa4, 0xf3, 0x87, 0xad, 0x17, 0x8e, 0xf5, 0x36,
-0x61, 0x8e, 0xc2, 0xad, 0xde, 0xe0, 0x9a, 0x7e, 0xd6, 0x62, 0x8f, 0x5f,
-0x46, 0x16, 0x9c, 0x26, 0x3c, 0x79, 0x2f, 0xc1, 0x8f, 0x47, 0xfb, 0x24,
-0xb7, 0x0b, 0x30, 0x1a, 0x65, 0xea, 0x73, 0xdc, 0xbe, 0x33, 0xdf, 0x97,
-0x64, 0x72, 0x83, 0x96, 0x1a, 0x73, 0x59, 0x1c, 0xf1, 0x4b, 0xa1, 0xd0,
-0x7c, 0x3c, 0xfc, 0xe6, 0xff, 0xe5, 0xbc, 0x0c, 0x88, 0x7f, 0xaf, 0x65,
-0xda, 0x43, 0x24, 0xe8, 0xeb, 0x65, 0x9e
+0x01, 0x01, 0x00, 0x44, 0x6b, 0xe1, 0x5b, 0xbb, 0x84, 0x2f, 0x29, 0xbe,
+0x30, 0xec, 0x1a, 0xc1, 0xa0, 0x8b, 0x55, 0xee, 0x00, 0xa1, 0xbd, 0x0e,
+0x67, 0xf6, 0x30, 0x9a, 0xbf, 0x1f, 0x8e, 0x9e, 0x14, 0xa5, 0x54, 0x84,
+0xe9, 0xef, 0x9d, 0xb4, 0x6a, 0x89, 0x8e, 0x6f, 0xb9, 0xb1, 0xac, 0xd3,
+0x62, 0xf9, 0x8b, 0x00, 0xd9, 0xcf, 0x47, 0xe7, 0x0f, 0xe8, 0x52, 0xef,
+0x2d, 0x5e, 0xa7, 0x07, 0x5f, 0xa9, 0x7f, 0xdd, 0x74, 0xbd, 0x15, 0xe3,
+0x42, 0xb3, 0xe5, 0x07, 0xb9, 0x47, 0xf1, 0x15, 0x08, 0x96, 0xe2, 0x9d,
+0xe1, 0xe8, 0xb0, 0xeb, 0x9e, 0x30, 0x44, 0xbb, 0x1d, 0x16, 0xac, 0x6d,
+0x53, 0x1b, 0x01, 0xb9, 0x97, 0xd8, 0x37, 0xf3, 0x46, 0x28, 0xdd, 0x60,
+0x80, 0x29, 0x4b, 0xb8, 0x02, 0x17, 0x73, 0xeb, 0x5e, 0x5d, 0x57, 0xdf,
+0xee, 0x7f, 0x1e, 0x33, 0x12, 0x68, 0x1c, 0x22, 0x19, 0x4b, 0xbb, 0x2b,
+0x2e, 0xa7, 0x66, 0x42, 0xe8, 0xc1, 0x35, 0x1e, 0x0c, 0x61, 0xbc, 0x54,
+0xb8, 0x15, 0x45, 0x3f, 0x63, 0xfa, 0x75, 0x8c, 0xeb, 0xce, 0x81, 0x83,
+0x5e, 0x99, 0xe3, 0x75, 0x44, 0xb6, 0x05, 0x4b, 0x10, 0xad, 0x11, 0xc1,
+0x29, 0x59, 0x13, 0xca, 0x94, 0x69, 0x7a, 0xd1, 0x98, 0x06, 0x91, 0x86,
+0xdc, 0x27, 0xdf, 0xf3, 0x85, 0xd0, 0x2f, 0xd3, 0x72, 0x12, 0x49, 0x5e,
+0xdf, 0xa3, 0x0c, 0x17, 0x1b, 0x71, 0x83, 0xc8, 0xb0, 0x32, 0xb8, 0x15,
+0x73, 0xbc, 0x66, 0xe5, 0x71, 0x60, 0x5c, 0x12, 0xed, 0xa5, 0x46, 0x48,
+0x5d, 0xa4, 0x2d, 0xd3, 0x85, 0xca, 0x0e, 0x20, 0x56, 0x82, 0x84, 0x49,
+0x44, 0x0a, 0x73, 0x45, 0xff, 0x4d, 0x13, 0x53, 0x1e, 0x5e, 0xee, 0xbe,
+0x03, 0xc2, 0xe7, 0x78, 0xa9, 0xc5, 0x49, 0x8f, 0xf9, 0xec, 0x67, 0xa1,
+0xaa, 0x9c, 0x4c, 0x1b, 0xfe, 0x7d, 0x96
};
const size_t RAW_CERT_CHAIN_B_len = sizeof(RAW_CERT_CHAIN_B);
@@ -1333,8 +1333,8 @@ const unsigned char CERT_CHAIN_B_P7B[] = {
0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x09, 0x1f, 0x30, 0x82, 0x04,
0x16, 0x30, 0x82, 0x02, 0xfe, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
-0x71, 0xba, 0x4b, 0xc0, 0x11, 0x9e, 0x97, 0xb8, 0xf6, 0x34, 0x19, 0xbd,
-0x5c, 0x77, 0x32, 0xe5, 0xfa, 0x58, 0x7b, 0x9e, 0x30, 0x0d, 0x06, 0x09,
+0x27, 0xa7, 0x62, 0xec, 0x07, 0xb9, 0x03, 0x42, 0xeb, 0x4f, 0xd5, 0xba,
+0xd2, 0xb9, 0xbf, 0x53, 0xa5, 0x7b, 0x49, 0x81, 0x30, 0x0d, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
0x81, 0x8e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
@@ -1348,9 +1348,9 @@ const unsigned char CERT_CHAIN_B_P7B[] = {
0x20, 0x43, 0x41, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03,
0x0c, 0x16, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x42, 0x20, 0x49, 0x6e, 0x74,
0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41,
-0x30, 0x1e, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x35, 0x30, 0x38, 0x32, 0x32,
-0x30, 0x37, 0x31, 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x35, 0x30,
-0x38, 0x32, 0x32, 0x30, 0x37, 0x31, 0x32, 0x5a, 0x30, 0x81, 0x86, 0x31,
+0x30, 0x1e, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x35, 0x30, 0x39, 0x32, 0x31,
+0x33, 0x35, 0x35, 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x35, 0x30,
+0x39, 0x32, 0x31, 0x33, 0x35, 0x35, 0x32, 0x5a, 0x30, 0x81, 0x86, 0x31,
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43,
0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x11, 0x30,
@@ -1364,65 +1364,65 @@ const unsigned char CERT_CHAIN_B_P7B[] = {
0x62, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
-0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xaa, 0x19,
-0xbe, 0xe0, 0xf0, 0x0e, 0x06, 0x83, 0x54, 0xde, 0x6f, 0xfd, 0x12, 0x4a,
-0x50, 0x21, 0xc8, 0x41, 0x10, 0xdb, 0x8d, 0x06, 0xc8, 0x59, 0x06, 0x52,
-0xdb, 0xb2, 0xa3, 0x75, 0x68, 0x5b, 0x78, 0x0f, 0x5f, 0x7e, 0xb9, 0xed,
-0xa6, 0xed, 0x1f, 0xc0, 0x46, 0xab, 0x5a, 0xcf, 0xf6, 0xbb, 0x8b, 0xe3,
-0x6d, 0xe8, 0x32, 0xa4, 0xa7, 0x36, 0xdc, 0xf2, 0x4c, 0x37, 0xba, 0xd8,
-0x65, 0x72, 0x7e, 0xc6, 0x1e, 0xd6, 0x9c, 0x3c, 0xf9, 0xf1, 0xb9, 0x68,
-0x4a, 0x94, 0xb2, 0x98, 0xdd, 0x94, 0x67, 0x78, 0xa8, 0x03, 0x8b, 0x18,
-0xc1, 0x35, 0x78, 0xca, 0x00, 0xb9, 0xd4, 0xd5, 0x0a, 0x63, 0x35, 0x51,
-0x4f, 0x13, 0x9e, 0x97, 0x02, 0x70, 0x58, 0xf5, 0x4f, 0xcd, 0xb9, 0x38,
-0x54, 0xc6, 0x31, 0x85, 0x4c, 0x02, 0x46, 0xf5, 0xd3, 0x91, 0xdb, 0x52,
-0x67, 0x6c, 0x09, 0xae, 0xcb, 0x13, 0x89, 0x98, 0xd8, 0x70, 0x8b, 0x1b,
-0xf5, 0xb2, 0x0e, 0x3e, 0x74, 0xd9, 0x4d, 0x94, 0x84, 0x2f, 0xc9, 0xbe,
-0xbe, 0xcf, 0xa5, 0xf1, 0x51, 0xe7, 0xa5, 0x3d, 0xe8, 0x37, 0xa3, 0xc7,
-0x1e, 0x85, 0x6f, 0xc6, 0xdb, 0xe1, 0x1a, 0xa5, 0x05, 0xb1, 0xd9, 0x89,
-0x72, 0x1f, 0x28, 0x78, 0x59, 0xae, 0x1d, 0xde, 0xc0, 0x36, 0x03, 0x0a,
-0x27, 0xed, 0x81, 0x16, 0xc0, 0xa6, 0x60, 0x60, 0x6c, 0x42, 0x5a, 0xb3,
-0x65, 0xd4, 0xa2, 0xd0, 0xcd, 0x5c, 0x31, 0xbb, 0x87, 0x8a, 0xe6, 0xf4,
-0x32, 0xe8, 0x9c, 0x0d, 0x14, 0x40, 0x34, 0xf1, 0x83, 0x63, 0x9a, 0xc6,
-0x93, 0x40, 0x25, 0x77, 0x20, 0xfe, 0xe8, 0x07, 0x27, 0x08, 0x2d, 0x50,
-0x39, 0x13, 0x16, 0x52, 0xab, 0xba, 0x67, 0x1c, 0xce, 0xd9, 0x9e, 0x3f,
-0x6b, 0xae, 0x59, 0xc6, 0xdb, 0x75, 0xc9, 0xfb, 0xe9, 0xae, 0x8b, 0xab,
-0x49, 0x5b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x72, 0x30, 0x70, 0x30,
+0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb9, 0xd2,
+0xee, 0x46, 0x8a, 0xcc, 0x21, 0x76, 0x0e, 0xe6, 0xaf, 0xad, 0x65, 0x0b,
+0xc4, 0xfc, 0x76, 0x83, 0xe6, 0x52, 0x40, 0xaa, 0x5c, 0x81, 0x8c, 0x33,
+0xfd, 0x04, 0x91, 0x8d, 0x91, 0xef, 0x07, 0x43, 0xbc, 0x11, 0x94, 0x16,
+0xe2, 0xb3, 0x00, 0x75, 0x2f, 0x4a, 0x00, 0x0c, 0x45, 0xff, 0x2d, 0xeb,
+0x99, 0x7b, 0xbf, 0xeb, 0xe8, 0x60, 0xb1, 0xd8, 0x44, 0xc3, 0x38, 0xc1,
+0x69, 0x9c, 0xaf, 0xfd, 0xd7, 0x0a, 0x1e, 0xda, 0x47, 0x02, 0x31, 0xec,
+0x0a, 0xcf, 0x43, 0xbd, 0x28, 0xaf, 0x8b, 0x64, 0xf2, 0xd8, 0x13, 0xe7,
+0xcb, 0x3e, 0x36, 0xb9, 0x50, 0x0a, 0x18, 0x87, 0x8f, 0xb5, 0x30, 0xe5,
+0xa6, 0x3c, 0x03, 0x79, 0x89, 0x48, 0x79, 0x5c, 0x09, 0x32, 0x4b, 0xa3,
+0xc1, 0xcd, 0x5c, 0x9a, 0x2f, 0x50, 0x61, 0xca, 0xe5, 0xbe, 0x08, 0x6e,
+0x62, 0xee, 0x7c, 0x06, 0xb8, 0x68, 0x50, 0x47, 0x29, 0x94, 0x93, 0xb6,
+0xc9, 0x6b, 0x30, 0xaa, 0x3c, 0xc6, 0xb5, 0x90, 0x4e, 0x71, 0x0c, 0x48,
+0x39, 0xc9, 0x0b, 0x5b, 0x6f, 0xce, 0xaf, 0x74, 0xda, 0xc1, 0x91, 0x3b,
+0xd1, 0x44, 0x99, 0xd6, 0x69, 0x3e, 0xfe, 0x20, 0x71, 0x4e, 0x30, 0x2a,
+0x48, 0x54, 0xc2, 0xe6, 0x57, 0x6a, 0xd1, 0x9d, 0xb7, 0x11, 0x5c, 0x7a,
+0xc8, 0x07, 0xce, 0xc2, 0xd0, 0xd9, 0xdc, 0xb1, 0xb1, 0xe4, 0x21, 0x95,
+0x8d, 0x0a, 0x6c, 0x98, 0x8c, 0xf9, 0x1d, 0xd4, 0x3f, 0x33, 0x8c, 0x0d,
+0xa9, 0x92, 0x6c, 0x0c, 0xcb, 0x5b, 0x8b, 0x4a, 0x26, 0x00, 0x3f, 0x55,
+0x2f, 0x98, 0x8f, 0x73, 0x54, 0x9c, 0xd4, 0xc5, 0x0b, 0x5a, 0xf9, 0x3a,
+0x67, 0x54, 0xd1, 0xba, 0x4a, 0x31, 0xcb, 0xf6, 0x75, 0xb0, 0xbf, 0x02,
+0x29, 0x6e, 0x30, 0x1a, 0x01, 0xee, 0x1a, 0xfc, 0xf0, 0xc8, 0x2e, 0x23,
+0x64, 0xc9, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x72, 0x30, 0x70, 0x30,
0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e,
0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
0x05, 0xa0, 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30,
0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30,
-0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x92, 0xe8,
-0x63, 0xd3, 0xbc, 0x30, 0x1e, 0x29, 0x98, 0xa2, 0x10, 0x19, 0x50, 0x28,
-0xf0, 0x80, 0xe9, 0x25, 0x9b, 0xd0, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
-0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x50, 0xa1, 0xf6, 0x3a, 0x70,
-0x94, 0x00, 0xb6, 0x1c, 0xfe, 0x3a, 0xab, 0x20, 0x4d, 0x23, 0x3f, 0xc6,
-0x60, 0x28, 0xc0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x56,
-0xe1, 0x1c, 0x0d, 0x70, 0xe9, 0x60, 0x98, 0xb8, 0x91, 0xf8, 0x80, 0x11,
-0xa9, 0xf6, 0x92, 0xc2, 0x70, 0xdb, 0xe5, 0x90, 0x5c, 0x99, 0xaa, 0x96,
-0xfd, 0x1b, 0x2e, 0x39, 0xd2, 0xcc, 0x0f, 0xc6, 0x56, 0xe5, 0xbd, 0x6f,
-0x42, 0x5b, 0xa1, 0x83, 0x63, 0xfb, 0xd2, 0x9b, 0x9d, 0x3c, 0xd3, 0xe9,
-0x7c, 0x2c, 0x6a, 0x75, 0x93, 0xea, 0x9f, 0xbf, 0x5e, 0xb7, 0xa0, 0x1c,
-0x83, 0x8c, 0xa0, 0xca, 0x41, 0x2d, 0x4e, 0xb6, 0x3f, 0xa3, 0xe5, 0x68,
-0x8c, 0xa9, 0xe8, 0x0b, 0x81, 0x34, 0x11, 0x3e, 0x25, 0x68, 0x14, 0xd2,
-0xcd, 0xb1, 0xaf, 0x21, 0xf4, 0xc1, 0xdf, 0xb6, 0x28, 0x4c, 0x5f, 0x3f,
-0x35, 0xfb, 0xb7, 0xfd, 0x12, 0xe3, 0xdd, 0x72, 0xef, 0x04, 0x79, 0x24,
-0x81, 0xcf, 0xb2, 0x71, 0xf7, 0x1e, 0x76, 0xb5, 0x8e, 0x5c, 0x3e, 0xb6,
-0x1c, 0x8e, 0x20, 0xb7, 0x6b, 0x56, 0x65, 0xf8, 0xb5, 0x12, 0x53, 0x66,
-0xf5, 0x16, 0x3a, 0x21, 0x28, 0x29, 0x86, 0x55, 0x50, 0x6c, 0x36, 0x07,
-0x00, 0x6d, 0x90, 0xe5, 0x9f, 0x22, 0x41, 0x90, 0x8a, 0x8e, 0x36, 0x74,
-0x66, 0x76, 0x03, 0xbd, 0x35, 0xc2, 0x33, 0x81, 0xf8, 0x03, 0xae, 0xf6,
-0x25, 0xb1, 0x3f, 0x36, 0xee, 0xd0, 0x97, 0x06, 0xa9, 0x0b, 0xe5, 0x79,
-0xa4, 0xf3, 0x87, 0xad, 0x17, 0x8e, 0xf5, 0x36, 0x61, 0x8e, 0xc2, 0xad,
-0xde, 0xe0, 0x9a, 0x7e, 0xd6, 0x62, 0x8f, 0x5f, 0x46, 0x16, 0x9c, 0x26,
-0x3c, 0x79, 0x2f, 0xc1, 0x8f, 0x47, 0xfb, 0x24, 0xb7, 0x0b, 0x30, 0x1a,
-0x65, 0xea, 0x73, 0xdc, 0xbe, 0x33, 0xdf, 0x97, 0x64, 0x72, 0x83, 0x96,
-0x1a, 0x73, 0x59, 0x1c, 0xf1, 0x4b, 0xa1, 0xd0, 0x7c, 0x3c, 0xfc, 0xe6,
-0xff, 0xe5, 0xbc, 0x0c, 0x88, 0x7f, 0xaf, 0x65, 0xda, 0x43, 0x24, 0xe8,
-0xeb, 0x65, 0x9e, 0x30, 0x82, 0x05, 0x01, 0x30, 0x82, 0x02, 0xe9, 0xa0,
-0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x05, 0x04, 0xe4, 0x03, 0x5b, 0xaa,
-0x51, 0x2f, 0xbc, 0x1c, 0x07, 0xe3, 0x2c, 0x93, 0x4d, 0x60, 0xe0, 0x08,
-0x42, 0x99, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xdd, 0x01,
+0x70, 0xe4, 0x6b, 0x18, 0x94, 0x52, 0xa6, 0x9a, 0xef, 0x1a, 0x74, 0x1f,
+0x85, 0x7a, 0x44, 0x82, 0xb1, 0x49, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe0, 0xcc, 0x27, 0xd7, 0x07,
+0x2b, 0xd4, 0xb5, 0x6f, 0xd9, 0xf6, 0xc9, 0x34, 0x3e, 0x84, 0xbc, 0x61,
+0xfa, 0xf5, 0xbc, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x44,
+0x6b, 0xe1, 0x5b, 0xbb, 0x84, 0x2f, 0x29, 0xbe, 0x30, 0xec, 0x1a, 0xc1,
+0xa0, 0x8b, 0x55, 0xee, 0x00, 0xa1, 0xbd, 0x0e, 0x67, 0xf6, 0x30, 0x9a,
+0xbf, 0x1f, 0x8e, 0x9e, 0x14, 0xa5, 0x54, 0x84, 0xe9, 0xef, 0x9d, 0xb4,
+0x6a, 0x89, 0x8e, 0x6f, 0xb9, 0xb1, 0xac, 0xd3, 0x62, 0xf9, 0x8b, 0x00,
+0xd9, 0xcf, 0x47, 0xe7, 0x0f, 0xe8, 0x52, 0xef, 0x2d, 0x5e, 0xa7, 0x07,
+0x5f, 0xa9, 0x7f, 0xdd, 0x74, 0xbd, 0x15, 0xe3, 0x42, 0xb3, 0xe5, 0x07,
+0xb9, 0x47, 0xf1, 0x15, 0x08, 0x96, 0xe2, 0x9d, 0xe1, 0xe8, 0xb0, 0xeb,
+0x9e, 0x30, 0x44, 0xbb, 0x1d, 0x16, 0xac, 0x6d, 0x53, 0x1b, 0x01, 0xb9,
+0x97, 0xd8, 0x37, 0xf3, 0x46, 0x28, 0xdd, 0x60, 0x80, 0x29, 0x4b, 0xb8,
+0x02, 0x17, 0x73, 0xeb, 0x5e, 0x5d, 0x57, 0xdf, 0xee, 0x7f, 0x1e, 0x33,
+0x12, 0x68, 0x1c, 0x22, 0x19, 0x4b, 0xbb, 0x2b, 0x2e, 0xa7, 0x66, 0x42,
+0xe8, 0xc1, 0x35, 0x1e, 0x0c, 0x61, 0xbc, 0x54, 0xb8, 0x15, 0x45, 0x3f,
+0x63, 0xfa, 0x75, 0x8c, 0xeb, 0xce, 0x81, 0x83, 0x5e, 0x99, 0xe3, 0x75,
+0x44, 0xb6, 0x05, 0x4b, 0x10, 0xad, 0x11, 0xc1, 0x29, 0x59, 0x13, 0xca,
+0x94, 0x69, 0x7a, 0xd1, 0x98, 0x06, 0x91, 0x86, 0xdc, 0x27, 0xdf, 0xf3,
+0x85, 0xd0, 0x2f, 0xd3, 0x72, 0x12, 0x49, 0x5e, 0xdf, 0xa3, 0x0c, 0x17,
+0x1b, 0x71, 0x83, 0xc8, 0xb0, 0x32, 0xb8, 0x15, 0x73, 0xbc, 0x66, 0xe5,
+0x71, 0x60, 0x5c, 0x12, 0xed, 0xa5, 0x46, 0x48, 0x5d, 0xa4, 0x2d, 0xd3,
+0x85, 0xca, 0x0e, 0x20, 0x56, 0x82, 0x84, 0x49, 0x44, 0x0a, 0x73, 0x45,
+0xff, 0x4d, 0x13, 0x53, 0x1e, 0x5e, 0xee, 0xbe, 0x03, 0xc2, 0xe7, 0x78,
+0xa9, 0xc5, 0x49, 0x8f, 0xf9, 0xec, 0x67, 0xa1, 0xaa, 0x9c, 0x4c, 0x1b,
+0xfe, 0x7d, 0x96, 0x30, 0x82, 0x05, 0x01, 0x30, 0x82, 0x02, 0xe9, 0xa0,
+0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x45, 0x5a, 0xfe, 0x48, 0x80, 0xa8,
+0x0e, 0x2d, 0xbb, 0x84, 0x1d, 0x3b, 0x12, 0xac, 0x5f, 0xee, 0xdc, 0xf7,
+0x64, 0xca, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06,
0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11,
0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66,
@@ -1434,9 +1434,9 @@ const unsigned char CERT_CHAIN_B_P7B[] = {
0x55, 0x04, 0x0b, 0x0c, 0x07, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x43,
0x68, 0x61, 0x69, 0x6e, 0x42, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43,
-0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x35, 0x30, 0x38, 0x32,
-0x32, 0x30, 0x37, 0x31, 0x32, 0x5a, 0x17, 0x0d, 0x33, 0x30, 0x30, 0x35,
-0x30, 0x37, 0x32, 0x32, 0x30, 0x37, 0x31, 0x32, 0x5a, 0x30, 0x81, 0x8e,
+0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x35, 0x30, 0x39, 0x32,
+0x31, 0x33, 0x35, 0x35, 0x32, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35,
+0x30, 0x38, 0x32, 0x31, 0x33, 0x35, 0x35, 0x32, 0x5a, 0x30, 0x81, 0x8e,
0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a,
0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x11,
@@ -1451,82 +1451,82 @@ const unsigned char CERT_CHAIN_B_P7B[] = {
0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x82,
0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
-0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x93, 0xde, 0x1b, 0x4b, 0x12,
-0xd0, 0xc5, 0xa0, 0x1a, 0xea, 0xf3, 0xaa, 0x71, 0x34, 0x09, 0xc6, 0x57,
-0x9f, 0x7a, 0x77, 0x93, 0xa0, 0x4b, 0x35, 0xd0, 0x58, 0x92, 0x27, 0x57,
-0xe6, 0x1c, 0x5b, 0x02, 0xbf, 0x18, 0xa6, 0x68, 0x25, 0x67, 0x5f, 0x85,
-0x44, 0x89, 0xc4, 0xec, 0x44, 0x61, 0x00, 0xf3, 0xbd, 0xd5, 0x53, 0x33,
-0x5a, 0x05, 0x44, 0x1c, 0x44, 0x52, 0x25, 0x10, 0xed, 0x30, 0xa6, 0x6c,
-0xae, 0x98, 0xeb, 0x39, 0x91, 0x75, 0x0f, 0xb2, 0xe2, 0x7d, 0x74, 0x5b,
-0x8c, 0xc6, 0xa0, 0xbe, 0x04, 0x28, 0x5f, 0x35, 0xff, 0xd5, 0xfb, 0xe8,
-0x8e, 0x02, 0x42, 0xb5, 0x9c, 0x7a, 0xd5, 0xbf, 0xf2, 0x72, 0xa4, 0x01,
-0x20, 0x3a, 0xbe, 0x79, 0xfb, 0xe6, 0x40, 0x7a, 0xb8, 0xab, 0x8e, 0x61,
-0x50, 0x90, 0xb9, 0x3d, 0xd8, 0xbe, 0xe9, 0x98, 0xa4, 0x73, 0xb3, 0x7d,
-0xe7, 0x81, 0xd5, 0x1e, 0xb0, 0x2c, 0x05, 0x3a, 0x31, 0xff, 0x81, 0xaa,
-0xb8, 0x5b, 0xfa, 0x6a, 0xfe, 0x64, 0x02, 0x57, 0xef, 0xc3, 0x71, 0x0a,
-0x6e, 0xb0, 0xf7, 0x0a, 0x47, 0x99, 0xea, 0x30, 0xbe, 0x8a, 0x63, 0x61,
-0x69, 0x43, 0x1c, 0x52, 0x7c, 0x62, 0x71, 0xe0, 0xee, 0xa7, 0xb3, 0x29,
-0x51, 0x25, 0x10, 0x42, 0x41, 0x9e, 0xb4, 0x99, 0x1e, 0x75, 0x7e, 0x69,
-0x60, 0xac, 0xad, 0x6f, 0x5d, 0xf9, 0xea, 0x62, 0x81, 0x86, 0x40, 0xdd,
-0x77, 0x61, 0xbf, 0xc7, 0x11, 0xad, 0x95, 0x56, 0x03, 0x41, 0xb8, 0xb8,
-0x98, 0xc0, 0x00, 0x72, 0x9f, 0x43, 0x9c, 0xdf, 0xfc, 0xaf, 0x2a, 0x0a,
-0xd1, 0x35, 0x7d, 0xc3, 0x9b, 0x56, 0x9d, 0x11, 0x02, 0x51, 0x00, 0x73,
-0x51, 0xc7, 0xdb, 0x38, 0x8d, 0x85, 0xb7, 0x3a, 0x5e, 0xe3, 0x72, 0x13,
-0x63, 0xad, 0xe7, 0x26, 0xd9, 0x7c, 0xc4, 0x9d, 0x66, 0x8b, 0x01, 0x02,
+0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x8e, 0x70, 0xdc, 0x22, 0x84,
+0x63, 0x1f, 0x43, 0x7b, 0xa0, 0x85, 0x56, 0x5e, 0xfc, 0x14, 0xb5, 0x6a,
+0x23, 0x0a, 0x9a, 0xc6, 0x42, 0x6f, 0xe0, 0xc8, 0x40, 0xae, 0xa2, 0x8d,
+0xa8, 0x0f, 0xfb, 0xac, 0x48, 0x05, 0x3e, 0xa5, 0x29, 0xe4, 0x15, 0xd2,
+0x7b, 0x70, 0x1e, 0x2b, 0x48, 0xcd, 0xc2, 0x10, 0x85, 0x52, 0xda, 0x04,
+0x69, 0x54, 0xa9, 0x56, 0x8c, 0x78, 0xc3, 0x4c, 0x61, 0x89, 0xf8, 0x20,
+0x83, 0x0f, 0x30, 0x59, 0x74, 0x0d, 0xad, 0x31, 0x2f, 0xe9, 0xe9, 0x67,
+0x73, 0x80, 0x07, 0x10, 0x02, 0x21, 0x08, 0x8a, 0xec, 0x98, 0x08, 0x2d,
+0xb7, 0x7d, 0x22, 0xda, 0x36, 0x89, 0xb4, 0x05, 0x3b, 0x88, 0x05, 0xba,
+0x77, 0x5b, 0xca, 0xa0, 0x31, 0x65, 0xe7, 0xbb, 0x80, 0xd8, 0xec, 0x55,
+0x43, 0x0a, 0xe1, 0x8c, 0x9f, 0x2b, 0x11, 0x4d, 0xea, 0xd1, 0xf2, 0xfa,
+0xf0, 0x93, 0x8b, 0x95, 0xe1, 0xfd, 0x97, 0xc4, 0x2e, 0xc5, 0x53, 0x9e,
+0x9a, 0x0d, 0xa2, 0x0e, 0xb4, 0xe0, 0x62, 0x27, 0x99, 0x68, 0x67, 0xb2,
+0xb3, 0xf0, 0x2b, 0xa3, 0x11, 0xee, 0xd3, 0xee, 0x23, 0x8c, 0x40, 0x09,
+0x5e, 0xd3, 0x0d, 0xb7, 0x08, 0x4b, 0x29, 0x94, 0x2a, 0x8f, 0x67, 0xbf,
+0x1c, 0xc1, 0x5f, 0x9e, 0x41, 0x6c, 0x90, 0xaa, 0x33, 0x38, 0xc5, 0x48,
+0xce, 0xc3, 0x84, 0x7b, 0x61, 0x8b, 0x67, 0xe4, 0x58, 0x2d, 0xd9, 0x58,
+0x09, 0x35, 0x4f, 0x28, 0x69, 0x8c, 0xaf, 0x93, 0x7a, 0x68, 0x9b, 0x2c,
+0x59, 0xa4, 0x44, 0x3b, 0x21, 0x23, 0xd2, 0x01, 0xe1, 0xd9, 0xfd, 0xeb,
+0xb2, 0x02, 0x9d, 0x9b, 0x3f, 0xbf, 0x14, 0x93, 0x28, 0x04, 0x11, 0xa9,
+0x96, 0xae, 0xe8, 0xfc, 0x55, 0x64, 0x83, 0x8e, 0x15, 0xe4, 0xce, 0x09,
+0x11, 0xfe, 0x99, 0xe8, 0xce, 0xac, 0x88, 0xf9, 0x01, 0x07, 0xe7, 0x02,
0x03, 0x01, 0x00, 0x01, 0xa3, 0x66, 0x30, 0x64, 0x30, 0x12, 0x06, 0x03,
0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03,
-0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x50, 0xa1, 0xf6, 0x3a, 0x70,
-0x94, 0x00, 0xb6, 0x1c, 0xfe, 0x3a, 0xab, 0x20, 0x4d, 0x23, 0x3f, 0xc6,
-0x60, 0x28, 0xc0, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
-0x30, 0x16, 0x80, 0x14, 0x0d, 0x1a, 0x6c, 0x57, 0x86, 0x74, 0x9c, 0xb6,
-0x5c, 0xd1, 0x3e, 0x2e, 0x5d, 0xe8, 0x94, 0x30, 0xba, 0x38, 0x08, 0x80,
+0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xe0, 0xcc, 0x27, 0xd7, 0x07,
+0x2b, 0xd4, 0xb5, 0x6f, 0xd9, 0xf6, 0xc9, 0x34, 0x3e, 0x84, 0xbc, 0x61,
+0xfa, 0xf5, 0xbc, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+0x30, 0x16, 0x80, 0x14, 0xde, 0xea, 0xb2, 0x07, 0x9c, 0x6b, 0x08, 0xe2,
+0xd9, 0x37, 0xf7, 0x9e, 0x25, 0x1f, 0xde, 0xaa, 0x6d, 0x5b, 0x81, 0xd3,
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x78, 0x10, 0x7a, 0x32,
-0xe4, 0xbc, 0xd3, 0x2a, 0x67, 0xed, 0x20, 0xd1, 0xba, 0x6b, 0xd5, 0xa8,
-0x03, 0x98, 0x38, 0x9d, 0x62, 0x63, 0x39, 0x31, 0xd9, 0x99, 0x6c, 0x98,
-0x51, 0xd7, 0xe7, 0x68, 0x89, 0x60, 0x19, 0xfd, 0xcf, 0xcb, 0x69, 0x04,
-0x69, 0x64, 0x9f, 0xbd, 0x4c, 0x28, 0x91, 0x81, 0x82, 0x88, 0xa2, 0x56,
-0xac, 0xa6, 0xad, 0x9f, 0xde, 0xdb, 0xd6, 0xd3, 0x1a, 0xe2, 0xcf, 0x53,
-0xfe, 0x42, 0x3e, 0xf3, 0x4c, 0x3f, 0x27, 0x39, 0xff, 0x00, 0xf6, 0xc9,
-0x79, 0xc3, 0x34, 0x13, 0x78, 0x82, 0xe5, 0x1d, 0x4a, 0x31, 0xfd, 0x38,
-0xce, 0x2f, 0xf6, 0xd5, 0xb7, 0x2a, 0x43, 0xdc, 0x95, 0x53, 0x91, 0x97,
-0x41, 0x31, 0x37, 0x59, 0xf0, 0xf2, 0xbc, 0xa1, 0x1d, 0x29, 0x7b, 0x3a,
-0x74, 0x21, 0x83, 0xbc, 0x9b, 0x2d, 0x8d, 0x69, 0x28, 0xf8, 0xd2, 0x0b,
-0x5f, 0x68, 0xf0, 0x6c, 0x22, 0x82, 0x74, 0x25, 0x85, 0x5a, 0x32, 0x7d,
-0x2a, 0xf3, 0x5e, 0xb4, 0xe6, 0x5e, 0xa3, 0xe2, 0x12, 0xac, 0x4c, 0x1c,
-0x1f, 0xb0, 0x53, 0xd7, 0xe6, 0x04, 0x26, 0x28, 0xf9, 0x52, 0x4e, 0x8b,
-0xb3, 0x7a, 0xb4, 0x96, 0xb5, 0xf0, 0x82, 0x0f, 0xa3, 0x42, 0x6c, 0xe2,
-0xa5, 0x30, 0x44, 0x81, 0x8f, 0xf8, 0xa1, 0x20, 0x5b, 0xc3, 0xf9, 0xe2,
-0x4d, 0x96, 0x1c, 0xd3, 0x1e, 0x5b, 0xe7, 0xaf, 0x14, 0x23, 0x0b, 0x5c,
-0x90, 0x6d, 0xa3, 0xa8, 0x4c, 0x0b, 0x63, 0x77, 0x52, 0x5a, 0xd4, 0x73,
-0x60, 0x4f, 0x08, 0x77, 0xf9, 0x7f, 0xe8, 0xc2, 0x20, 0xe3, 0xa8, 0x52,
-0x12, 0x69, 0x53, 0x65, 0x01, 0x72, 0x8f, 0x66, 0x05, 0xc3, 0xea, 0x4c,
-0x77, 0x26, 0x40, 0xa9, 0x19, 0xeb, 0x3b, 0x67, 0xad, 0x07, 0xcb, 0x6f,
-0xde, 0xa3, 0x73, 0xc1, 0xcf, 0x66, 0xe7, 0xb2, 0x46, 0x82, 0xe6, 0xd6,
-0x97, 0x02, 0xd2, 0x71, 0xc3, 0x4f, 0xe0, 0x25, 0xcd, 0xe4, 0x30, 0x3a,
-0x21, 0xfb, 0xfd, 0xdd, 0xb7, 0x4f, 0xdf, 0x7e, 0x0f, 0xa0, 0x4f, 0xf5,
-0x6a, 0x2d, 0x26, 0x02, 0xaa, 0x62, 0x6f, 0x86, 0x50, 0xa3, 0xf2, 0x9f,
-0xe3, 0xf6, 0xb3, 0x74, 0x39, 0xb8, 0x12, 0xee, 0xfa, 0x92, 0x90, 0x7d,
-0x4f, 0xa5, 0xa5, 0xb3, 0xd2, 0x5f, 0x6b, 0x47, 0x05, 0x66, 0x85, 0xd8,
-0xf0, 0xcf, 0xf0, 0x1d, 0x9e, 0xb2, 0x96, 0x19, 0x9b, 0xef, 0x95, 0xbe,
-0x69, 0x8d, 0xbd, 0xc9, 0xfc, 0x33, 0x7f, 0x95, 0x80, 0x35, 0x87, 0xea,
-0xea, 0xd9, 0x64, 0xcc, 0xef, 0x27, 0x20, 0x90, 0xb1, 0xf9, 0x4d, 0xca,
-0xca, 0x8b, 0xcb, 0x47, 0x40, 0x25, 0x88, 0x85, 0x0e, 0xf4, 0x2c, 0x81,
-0xb7, 0xd1, 0xa9, 0x0d, 0x3f, 0x7d, 0x37, 0xb6, 0x7b, 0xf2, 0x4d, 0x5c,
-0x4e, 0x9f, 0x77, 0xc2, 0xd2, 0x6b, 0xe1, 0x5d, 0x55, 0x45, 0xfc, 0x22,
-0xc9, 0x16, 0xdd, 0x75, 0xe8, 0x9b, 0xd9, 0x81, 0x57, 0xd5, 0x81, 0x4f,
-0x1f, 0x10, 0xf0, 0xf5, 0xad, 0x31, 0x01, 0x17, 0xdf, 0x6c, 0xc0, 0xbb,
-0x57, 0xe7, 0x05, 0x05, 0x6b, 0x85, 0xd2, 0xf3, 0xef, 0x13, 0x8a, 0xdc,
-0xa5, 0x53, 0x9b, 0x27, 0x5e, 0x9b, 0x73, 0x0f, 0x55, 0xa8, 0x5f, 0xba,
-0x6c, 0x99, 0xce, 0xfb, 0x42, 0x37, 0x6c, 0xaa, 0x84, 0x18, 0x7c, 0x97,
-0xec, 0x4b, 0xe5, 0x69, 0xfe, 0xfd, 0xfb, 0xf7, 0x49, 0xa5, 0xcb, 0x9c,
-0x44, 0x4c, 0x44, 0x5b, 0x32, 0xad, 0xc8, 0x3c, 0x1c, 0xc6, 0x70, 0x2d,
-0x42, 0x6a, 0xce, 0x56, 0x4b, 0x4f, 0x28, 0x15, 0xca, 0x6c, 0x25, 0x55,
-0xd2, 0xe0, 0x7e, 0xd2, 0x9a, 0xd0, 0xe5, 0x05, 0x95, 0xdc, 0xa9, 0xad,
-0xf9, 0x0e, 0x6e, 0x99, 0x84, 0xed, 0xc4, 0x5d, 0x2b, 0xed, 0x81, 0x26,
-0x51, 0xfa, 0xd4, 0x36, 0x31, 0x00
+0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x12, 0xec, 0x8b, 0x75,
+0xce, 0x0f, 0xc6, 0x60, 0x9f, 0x8a, 0xf7, 0x8b, 0x79, 0xe8, 0x1a, 0x3c,
+0xde, 0x87, 0x8e, 0xb5, 0x3e, 0x7c, 0x95, 0x70, 0x1a, 0x33, 0xfd, 0x21,
+0xbc, 0x87, 0xc6, 0x50, 0xa0, 0x9e, 0x90, 0x66, 0xfe, 0x51, 0xa6, 0x6d,
+0xc0, 0xd3, 0x0a, 0x1e, 0x82, 0x53, 0x9c, 0x34, 0xea, 0x08, 0xdd, 0xbe,
+0x47, 0x5f, 0xd5, 0x4b, 0xa9, 0xbb, 0xe4, 0x48, 0xed, 0x3a, 0xfa, 0x4f,
+0x7a, 0x9f, 0x3d, 0x3c, 0x9d, 0x63, 0xa7, 0x77, 0xf0, 0x09, 0xcd, 0x63,
+0xdc, 0x65, 0xa9, 0xc2, 0xd1, 0x41, 0xd7, 0xcd, 0x3f, 0x68, 0xde, 0x16,
+0x30, 0xec, 0xfa, 0x9c, 0x94, 0x5d, 0x3a, 0xae, 0x11, 0xf3, 0x96, 0xff,
+0xf4, 0x3a, 0x67, 0x4b, 0x7f, 0xab, 0xce, 0x80, 0x33, 0xe3, 0x6e, 0x05,
+0x23, 0xa0, 0x81, 0x01, 0x2a, 0xbe, 0x19, 0xc7, 0xe2, 0xdb, 0x90, 0x6c,
+0xd0, 0x8b, 0xf1, 0x76, 0x41, 0xc2, 0xa6, 0x57, 0x73, 0x14, 0x27, 0x76,
+0xdc, 0xae, 0x75, 0xba, 0xf8, 0x47, 0x67, 0xec, 0xe4, 0x69, 0x0f, 0x12,
+0xe3, 0x89, 0x33, 0xb2, 0xa4, 0xee, 0x34, 0x10, 0x03, 0xce, 0xd6, 0xf6,
+0xb2, 0xbb, 0xe3, 0xcb, 0x51, 0x16, 0x8c, 0xdb, 0xf7, 0x0c, 0x38, 0x4f,
+0x68, 0xeb, 0xd0, 0x19, 0xe2, 0x7f, 0x1c, 0x36, 0x27, 0x63, 0xf1, 0xc3,
+0x7b, 0x52, 0x96, 0x63, 0xcd, 0xda, 0x70, 0x01, 0x01, 0xa9, 0x6f, 0x63,
+0x14, 0x8a, 0x42, 0xd6, 0x8e, 0xcf, 0x4b, 0x59, 0xd7, 0xfb, 0x11, 0x9d,
+0x44, 0xd8, 0x1c, 0xb4, 0xb8, 0xf6, 0x96, 0xa7, 0xa1, 0x7a, 0x48, 0xfc,
+0x32, 0x41, 0xda, 0xff, 0x21, 0xa8, 0xd4, 0xb0, 0x35, 0xe7, 0x75, 0x89,
+0x7b, 0xb6, 0xac, 0xbf, 0x2c, 0x3d, 0x0a, 0x67, 0x43, 0x07, 0x5a, 0x2c,
+0xf6, 0x56, 0x0d, 0x61, 0x00, 0x77, 0x31, 0x29, 0xad, 0x3f, 0x57, 0xf4,
+0x85, 0x37, 0x1e, 0x7c, 0x69, 0xf4, 0x04, 0xfe, 0xfd, 0x1c, 0x5c, 0xab,
+0x37, 0x11, 0x14, 0xe4, 0xd5, 0x7e, 0x5e, 0x99, 0xae, 0xc4, 0x75, 0xda,
+0xae, 0x2b, 0x96, 0x56, 0xaf, 0x79, 0x41, 0xec, 0x77, 0x2e, 0xec, 0x81,
+0x9e, 0xbe, 0x0c, 0xa8, 0xb3, 0xd2, 0x59, 0x23, 0x53, 0x3c, 0xe3, 0x33,
+0x9a, 0x96, 0xee, 0x75, 0x02, 0x43, 0x61, 0x49, 0x4c, 0x8c, 0x3e, 0x0d,
+0x1b, 0x09, 0xec, 0xf7, 0x5a, 0x48, 0xaa, 0x47, 0x08, 0xfd, 0xa0, 0x8b,
+0x59, 0x48, 0x23, 0xe1, 0x6f, 0x1e, 0x10, 0x37, 0x31, 0xbe, 0xd7, 0x15,
+0x6e, 0x71, 0x24, 0x9c, 0x05, 0x2e, 0xf8, 0x2f, 0xfe, 0xca, 0x23, 0xe5,
+0xa6, 0x20, 0xdd, 0xe5, 0x2d, 0x28, 0xca, 0xec, 0x33, 0x3c, 0x96, 0xb0,
+0x67, 0x8f, 0xa7, 0x4b, 0x18, 0x68, 0xce, 0x5f, 0xdf, 0xb4, 0x59, 0x5a,
+0x49, 0x9e, 0x04, 0x51, 0x63, 0xec, 0xd0, 0x53, 0x38, 0xd8, 0x66, 0xf5,
+0xf2, 0xce, 0xcf, 0xee, 0x59, 0xfc, 0xe4, 0x2d, 0x72, 0xe8, 0x6c, 0xc7,
+0xc5, 0x82, 0xb0, 0xb4, 0x81, 0x57, 0x99, 0x2f, 0x94, 0xaa, 0xf4, 0xd6,
+0xb2, 0x1b, 0x0f, 0x7a, 0xae, 0x61, 0x0d, 0x17, 0x8d, 0x1c, 0x69, 0x0d,
+0x7f, 0xc4, 0x7a, 0x48, 0x7c, 0xa2, 0x78, 0x22, 0xbe, 0x16, 0x2c, 0x4c,
+0xdf, 0x87, 0x51, 0xfb, 0x53, 0x21, 0x9e, 0xd2, 0x8c, 0xb9, 0x79, 0x6d,
+0x20, 0x32, 0x80, 0x3f, 0x18, 0x45, 0xfe, 0x4f, 0xcd, 0x68, 0xff, 0x14,
+0xcb, 0x88, 0x26, 0x9f, 0x02, 0x4c, 0x55, 0xb8, 0x85, 0x68, 0x42, 0x34,
+0x18, 0x91, 0xea, 0x07, 0xbe, 0xff, 0x54, 0x8e, 0xf1, 0x4e, 0xa0, 0xc8,
+0x6a, 0x39, 0x17, 0xbc, 0xff, 0xb7, 0x80, 0x5e, 0xaf, 0xd2, 0x0f, 0x63,
+0xd0, 0x66, 0xad, 0xfa, 0xe5, 0xc0, 0x37, 0xc5, 0x9b, 0xaf, 0xa2, 0xd6,
+0x11, 0x63, 0x21, 0x76, 0x31, 0x00
};
const size_t CERT_CHAIN_B_P7B_len = sizeof(CERT_CHAIN_B_P7B);
diff --git a/test/wh_test_crypto.c b/test/wh_test_crypto.c
index 11d11198..af563805 100644
--- a/test/wh_test_crypto.c
+++ b/test/wh_test_crypto.c
@@ -1159,7 +1159,13 @@ static int whTest_CryptoEccExportPublicDma(whClientContext* ctx, int devId,
int ret = 0;
whKeyId keyId = WH_KEYID_ERASED;
ecc_key pubKey[1] = {0};
- uint8_t hash[TEST_ECC_KEYSIZE] = {0};
+ /* Non-zero hash: wolfCrypt rejects all-zero hashes for ECDSA sign/verify
+ * unless WC_ALLOW_ECC_ZERO_HASH is defined. */
+ uint8_t hash[TEST_ECC_KEYSIZE] = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20};
uint8_t sig[ECC_MAX_SIG_SIZE] = {0};
word32 sigLen = sizeof(sig);
int verified = 0;