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;