Add RealTek AmebaPro2 (RTL8735B) HUK-in-TLS example

In-memory TLS 1.2 ECDHE-ECDSA handshake with the server certificate ECDSA P-256
signature produced on the HUK HW engine via a PK sign callback. The rest of TLS
(PRF/HMAC, record AES-GCM, ECDHE) stays in software: a whole-CTX WC_HUK_DEVID
would route TLS's own 32-byte HMAC keys (e.g. the P-256 ECDHE pre-master in the
PRF) to the HUK, whose key==seed semantics break key derivation. Validated on
RTL8735B silicon.
pull/575/head
David Garske 2026-07-02 16:18:01 -07:00
parent 9bdd578564
commit 36af63f1dd
4 changed files with 530 additions and 0 deletions

View File

@ -0,0 +1,57 @@
# RTL8735B (AmebaPro2) HUK-in-TLS example
In-memory TLS 1.2 ECDHE-ECDSA handshake (client + server in one firmware, no
networking) where the server's certificate ECDSA P-256 signature is produced on
the RTL8735B HW ECDSA engine via the wolfCrypt HUK crypto-callback port. The
ECDHE key agreement and record-layer AES-GCM run in software. Proves
HUK/HW-accelerated server authentication in a real TLS handshake.
Validated on RTL8735B silicon:
```
== TLS 1.2 ECDHE-ECDSA (server auth on HUK) ==
[PASS] TLS handshake completed
cipher: ECDHE-ECDSA-AES128-GCM-SHA256
[PASS] client write
[PASS] server read == client msg
```
## Key design point: use a PK sign callback, NOT a whole-CTX devId
Do NOT `wolfSSL_CTX_SetDevId(ctx, WC_HUK_DEVID)` for a TLS CTX. The HUK device
treats a 32-byte HMAC/AES key as a *HUK seed* (HKDF input), but TLS legitimately
uses 32-byte keys in its own crypto -- e.g. the P-256 ECDHE pre-master secret is
32 bytes and TLS 1.2's PRF computes `master_secret = HMAC-SHA256(pre_master,...)`
with it. Routing that PRF HMAC to the HUK derives the wrong master secret ->
wrong session keys -> the peer's Finished fails (`VERIFY_MAC_ERROR`, -305).
Instead, route ONLY the server's certificate signature to the HUK with a PK ECC
sign callback (`wolfSSL_CTX_SetEccSignCb`). Inside it, sign with a temporary
`ecc_key` whose `devId = WC_HUK_DEVID`, so only that ECDSA sign dispatches to the
HW engine while the PRF/HMAC, record AES, and ECDHE stay in software. See
`huk_ecc_sign_cb` in `main.c`. Requires `HAVE_PK_CALLBACKS`.
## Build
Install this directory at `<SDK>/component/example/wolfcrypt_huk_tls/` and select
it in the RealTek AmebaPro2 FreeRTOS SDK build:
```
cmake .. -DEXAMPLE=wolfcrypt_huk_tls -DWOLFSSL_ROOT=/path/to/wolfssl ...
```
(also copy `main.c` to `<SDK>/project/realtek_amebapro2_v0_example/src/main.c`).
See the `amebapro2-flash` build/flash flow used by the sibling `wolfcrypt_huk`
example.
## Notes
- P-256 test certificates come from wolfSSL's `certs_test.h` (`USE_CERT_BUFFERS_256`:
`serv_ecc_der_256`, `ecc_key_der_256`, `ca_ecc_cert_der_256`).
- `NO_ASN_TIME` is set (the board has no RTC, so certificate date checks are
skipped) -- do not use that in production without a real time source.
- `WOLFSSL_USER_IO` + `WOLFSSL_NO_SOCK`: the transport is two in-memory buffers
via custom `SetIORecv`/`SetIOSend` callbacks; no sockets are used.
- Model shown is the general HW-offload key (a plain P-256 server key signed on
the engine). A device-bound HUK-wrapped server key is a follow-on (the sign
callback would use a `wc_Rtl8735b_EccKey` via the key's `devCtx`).

301
rtl8735b/tls/main.c 100644
View File

@ -0,0 +1,301 @@
/* wolfCrypt AmebaPro2 (RTL8735B) HUK-in-TLS example -- built inside the RealTek
* FreeRTOS SDK. Runs an in-memory TLS 1.2 ECDHE-ECDSA handshake (client + server
* in one firmware, no networking) where the server's ECDSA P-256 authentication
* routes through the HUK crypto-callback device (wolfSSL_CTX_SetDevId), i.e. the
* server signature is produced on the RTL8735B HW ECDSA engine. The ECDHE key
* agreement and record-layer AES run in software (the engine has no arbitrary
* scalar-mult path; see the port README). Proves HUK-accelerated server auth in
* a real TLS handshake.
*
* Two server-key models (RTL_TLS_KEY_MODEL):
* 1 = general HW offload: a plain P-256 server key loaded from certs_test.h;
* with devId set, its handshake ECDSA sign dispatches to the HW engine.
* 2 = device-bound HUK-wrapped key (follow-on; see README).
*
* Build: configure with -DEXAMPLE=wolfcrypt_huk_tls (see wolfcrypt_huk_tls.cmake).
*/
#include <string.h>
#include "platform_stdlib.h"
#include "FreeRTOS.h"
#include "task.h"
#include "device_lock.h"
#include "hal_trng_sec.h"
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/ssl.h>
#include <wolfssl/certs_test.h>
#include <wolfssl/wolfcrypt/port/realtek/rtl8735b.h>
#ifndef RTL_TLS_KEY_MODEL
#define RTL_TLS_KEY_MODEL 1
#endif
#define STACKSIZE (16 * 1024)
#define BUFFER_SIZE 2048
#define CHECK(label, cond) \
dbg_printf("[%s] %s\r\n", (cond) ? "PASS" : "FAIL", (label))
/* wolfCrypt RNG seed hook (user_settings: CUSTOM_RAND_GENERATE_SEED), from the
* AmebaPro2 secure hardware TRNG. */
int rtl8735b_rand_seed(unsigned char* output, unsigned int sz)
{
static int inited = 0;
unsigned int i, n;
u32 r;
if (inited == 0) {
if (hal_trng_sec_init() != 0) {
return -1;
}
inited = 1;
}
for (i = 0; i < sz; ) {
r = hal_trng_sec_get_rand();
n = (sz - i) < 4u ? (sz - i) : 4u;
memcpy(output + i, &r, n);
i += n;
}
return 0;
}
/* In-memory transport: two shared buffers with WANT_READ/WANT_WRITE semantics.
* client -> server via server_buffer; server -> client via client_buffer. */
static unsigned char client_buffer[BUFFER_SIZE];
static int client_buffer_sz = 0;
static unsigned char server_buffer[BUFFER_SIZE];
static int server_buffer_sz = 0;
static int recv_client(WOLFSSL* ssl, char* buff, int sz, void* ctx)
{
(void)ssl; (void)ctx;
if (client_buffer_sz > 0) {
if (sz > client_buffer_sz) {
sz = client_buffer_sz;
}
memcpy(buff, client_buffer, sz);
if (sz < client_buffer_sz) {
memmove(client_buffer, client_buffer + sz, client_buffer_sz - sz);
}
client_buffer_sz -= sz;
return sz;
}
return WOLFSSL_CBIO_ERR_WANT_READ;
}
static int send_client(WOLFSSL* ssl, char* buff, int sz, void* ctx)
{
(void)ssl; (void)ctx;
if (server_buffer_sz < BUFFER_SIZE) {
if (sz > BUFFER_SIZE - server_buffer_sz) {
sz = BUFFER_SIZE - server_buffer_sz;
}
memcpy(server_buffer + server_buffer_sz, buff, sz);
server_buffer_sz += sz;
return sz;
}
return WOLFSSL_CBIO_ERR_WANT_WRITE;
}
static int recv_server(WOLFSSL* ssl, char* buff, int sz, void* ctx)
{
(void)ssl; (void)ctx;
if (server_buffer_sz > 0) {
if (sz > server_buffer_sz) {
sz = server_buffer_sz;
}
memcpy(buff, server_buffer, sz);
if (sz < server_buffer_sz) {
memmove(server_buffer, server_buffer + sz, server_buffer_sz - sz);
}
server_buffer_sz -= sz;
return sz;
}
return WOLFSSL_CBIO_ERR_WANT_READ;
}
static int send_server(WOLFSSL* ssl, char* buff, int sz, void* ctx)
{
(void)ssl; (void)ctx;
if (client_buffer_sz < BUFFER_SIZE) {
if (sz > BUFFER_SIZE - client_buffer_sz) {
sz = BUFFER_SIZE - client_buffer_sz;
}
memcpy(client_buffer + client_buffer_sz, buff, sz);
client_buffer_sz += sz;
return sz;
}
return WOLFSSL_CBIO_ERR_WANT_WRITE;
}
/* RNG for the ECDSA sign callback (the PK callback passes no rng). */
static WC_RNG g_signRng;
/* ECC sign PK callback: route ONLY the server's cert signature to the HUK HW
* ECDSA engine. A temp ecc_key with devId=WC_HUK_DEVID makes wc_ecc_sign_hash
* dispatch to the port's general HW offload (signs with the key's own scalar);
* the rest of TLS (PRF/HMAC, record AES, ECDHE) stays in software. */
static int huk_ecc_sign_cb(WOLFSSL* ssl, const byte* in, word32 inSz,
byte* out, word32* outSz, const byte* keyDer, word32 keySz, void* ctx)
{
ecc_key key;
word32 idx = 0;
int ret;
(void)ssl; (void)ctx;
ret = wc_ecc_init_ex(&key, NULL, WC_HUK_DEVID);
if (ret == 0) {
ret = wc_EccPrivateKeyDecode(keyDer, &idx, &key, keySz);
if (ret == 0) {
ret = wc_ecc_sign_hash(in, inSz, out, outSz, &g_signRng, &key);
}
wc_ecc_free(&key);
}
return ret;
}
static void huk_tls_test(void)
{
WOLFSSL_CTX* cctx = NULL;
WOLFSSL_CTX* sctx = NULL;
WOLFSSL* cssl = NULL;
WOLFSSL* sssl = NULL;
const char msg[] = "hello from HUK TLS client";
char rx[64];
int cdone = 0, sdone = 0;
int i, ret;
dbg_printf("\r\n== TLS 1.2 ECDHE-ECDSA (server auth on HUK) ==\r\n");
sctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method());
cctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
CHECK("CTX_new (client+server)", sctx != NULL && cctx != NULL);
if (sctx == NULL || cctx == NULL) {
goto cleanup;
}
/* RNG for the sign callback's nonce. */
ret = wc_InitRng(&g_signRng);
CHECK("sign-callback RNG init", ret == 0);
/* Route ONLY the server's cert ECDSA sign to the HUK HW engine (PK callback);
* TLS's own HMAC/PRF, record AES and ECDHE stay in software. */
wolfSSL_CTX_SetEccSignCb(sctx, huk_ecc_sign_cb);
/* Restrict to ECDHE-ECDSA + AES-GCM so server auth uses ECDSA (HUK). */
wolfSSL_CTX_set_cipher_list(sctx, "ECDHE-ECDSA-AES128-GCM-SHA256");
wolfSSL_CTX_set_cipher_list(cctx, "ECDHE-ECDSA-AES128-GCM-SHA256");
/* Server: P-256 cert + key (model 1: general HW offload). */
ret = wolfSSL_CTX_use_certificate_buffer(sctx, serv_ecc_der_256,
sizeof_serv_ecc_der_256, WOLFSSL_FILETYPE_ASN1);
CHECK("server use_certificate", ret == WOLFSSL_SUCCESS);
ret = wolfSSL_CTX_use_PrivateKey_buffer(sctx, ecc_key_der_256,
sizeof_ecc_key_der_256, WOLFSSL_FILETYPE_ASN1);
CHECK("server use_PrivateKey", ret == WOLFSSL_SUCCESS);
/* Client: trust the CA that signed the server cert. */
ret = wolfSSL_CTX_load_verify_buffer(cctx, ca_ecc_cert_der_256,
sizeof_ca_ecc_cert_der_256, WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
dbg_printf("load_verify ret=%d\r\n", ret);
}
CHECK("client load_verify (CA)", ret == WOLFSSL_SUCCESS);
wolfSSL_SetIORecv(sctx, recv_server);
wolfSSL_SetIOSend(sctx, send_server);
wolfSSL_SetIORecv(cctx, recv_client);
wolfSSL_SetIOSend(cctx, send_client);
sssl = wolfSSL_new(sctx);
cssl = wolfSSL_new(cctx);
CHECK("wolfSSL_new (client+server)", sssl != NULL && cssl != NULL);
if (sssl == NULL || cssl == NULL) {
goto cleanup;
}
/* Drive the handshake: interleave connect/accept until both complete. */
for (i = 0; i < 20 && (cdone == 0 || sdone == 0); i++) {
if (cdone == 0) {
ret = wolfSSL_connect(cssl);
if (ret == WOLFSSL_SUCCESS) {
cdone = 1;
}
else if (wolfSSL_get_error(cssl, ret) != WOLFSSL_ERROR_WANT_READ &&
wolfSSL_get_error(cssl, ret) != WOLFSSL_ERROR_WANT_WRITE) {
dbg_printf("client err %d\r\n", wolfSSL_get_error(cssl, ret));
break;
}
}
if (sdone == 0) {
ret = wolfSSL_accept(sssl);
if (ret == WOLFSSL_SUCCESS) {
sdone = 1;
}
else if (wolfSSL_get_error(sssl, ret) != WOLFSSL_ERROR_WANT_READ &&
wolfSSL_get_error(sssl, ret) != WOLFSSL_ERROR_WANT_WRITE) {
dbg_printf("server err %d\r\n", wolfSSL_get_error(sssl, ret));
break;
}
}
}
CHECK("TLS handshake completed", cdone == 1 && sdone == 1);
if (cdone == 1 && sdone == 1) {
dbg_printf("cipher: %s\r\n", wolfSSL_get_cipher(sssl));
/* Exchange one application record client -> server. */
ret = wolfSSL_write(cssl, msg, (int)sizeof(msg));
CHECK("client write", ret == (int)sizeof(msg));
memset(rx, 0, sizeof(rx));
ret = wolfSSL_read(sssl, rx, sizeof(rx) - 1);
CHECK("server read == client msg",
ret == (int)sizeof(msg) && memcmp(rx, msg, sizeof(msg)) == 0);
}
cleanup:
if (cssl != NULL) wolfSSL_free(cssl);
if (sssl != NULL) wolfSSL_free(sssl);
if (cctx != NULL) wolfSSL_CTX_free(cctx);
if (sctx != NULL) wolfSSL_CTX_free(sctx);
wc_FreeRng(&g_signRng);
}
static void wolf_tls_thread(void* param)
{
int ret;
(void)param;
dbg_printf("\r\n=== wolfCrypt AmebaPro2 (RTL8735B) HUK-in-TLS example ===\r\n");
device_mutex_lock(RT_DEV_LOCK_CRYPTO);
ret = wolfSSL_Init();
CHECK("wolfSSL_Init", ret == WOLFSSL_SUCCESS);
if (ret == WOLFSSL_SUCCESS) {
ret = wc_Rtl8735b_HukRegister(WC_HUK_DEVID);
CHECK("wc_Rtl8735b_HukRegister", ret == 0);
}
if (ret == 0) {
huk_tls_test();
wc_Rtl8735b_HukUnRegister(WC_HUK_DEVID);
}
wolfSSL_Cleanup();
device_mutex_unlock(RT_DEV_LOCK_CRYPTO);
dbg_printf("\r\n=== done ===\r\n");
vTaskDelete(NULL);
}
int main(void)
{
if (xTaskCreate(wolf_tls_thread, "wolf_tls", STACKSIZE, NULL,
tskIDLE_PRIORITY + 1, NULL) != pdPASS) {
dbg_printf("xTaskCreate failed\r\n");
}
else {
vTaskStartScheduler();
}
while (1) {
}
}

View File

@ -0,0 +1,99 @@
/* user_settings.h -- wolfSSL config for the AmebaPro2 (RTL8735B) HUK-in-TLS
* example (RealTek FreeRTOS SDK). In-memory TLS 1.2 ECDHE-ECDSA handshake with
* the server's ECDSA P-256 auth routed to the HUK crypto-callback device. */
#ifndef RTL8735B_HUK_TLS_USER_SETTINGS_H
#define RTL8735B_HUK_TLS_USER_SETTINGS_H
#ifdef __cplusplus
extern "C" {
#endif
/* ---- HUK crypto-callback device (our RealTek port) ---- */
#define WOLFSSL_RTL8735B_HUK
#define WOLF_CRYPTO_CB
/* ---- platform / RTOS ---- */
#define WOLFSSL_GENERAL_ALIGNMENT 4
#define SIZEOF_LONG_LONG 8
#define SINGLE_THREADED /* HW crypto serialized by the SDK device_lock */
#define NO_FILESYSTEM
#define NO_WRITEV
#define NO_MAIN_DRIVER
#define WOLFSSL_USER_IO /* custom SetIORecv/Send; no sockets/netinet */
#define WOLFSSL_NO_SOCK /* no built-in socket headers (bare metal) */
#define WOLFSSL_SMALL_STACK
#define WOLFSSL_IGNORE_FILE_WARN
#define NO_ERROR_STRINGS
/* ---- TLS layer: TLS 1.2 only, ECDHE-ECDSA-AES-GCM ---- */
#define NO_OLD_TLS /* TLS 1.2+ only (no SSLv3/TLS1.0/1.1) */
#define WOLFSSL_TLS13 /* harmless; harness uses TLSv1_2 methods */
#define HAVE_TLS_EXTENSIONS
#define HAVE_SUPPORTED_CURVES /* ECDHE curve negotiation */
#define HAVE_EXTENDED_MASTER
#define HAVE_ENCRYPT_THEN_MAC
#define HAVE_HKDF /* TLS 1.3 key schedule (kdf.c) */
#define WOLFSSL_NO_TLS12_RENEGOTIATION
#define NO_SESSION_CACHE /* save RAM (no resumption cache) */
#define WOLFSSL_AEAD_ONLY /* AES-GCM suites only (no CBC-HMAC) */
#define HAVE_PK_CALLBACKS /* route ONLY the server ECDSA sign to the HUK
* (whole-CTX devId would send TLS's own 32-byte
* HMAC/PRF + record AES to the HUK too, whose
* key==HUK-seed semantics break TLS) */
/* ---- test certificate buffers (serv_ecc/ecc_key/ca_ecc, P-256) ---- */
#define USE_CERT_BUFFERS_256
#define NO_ASN_TIME /* no RTC on the board -> skip cert date checks */
/* ---- AES modes: GCM for TLS records; ECB/CBC/CTR for the HUK device ---- */
#define HAVE_AESGCM
#define WOLFSSL_AES_DIRECT
#define HAVE_AES_ECB
#define HAVE_AES_CBC
#define WOLFSSL_AES_COUNTER
#define WOLFSSL_AES_256
#define WOLFSSL_AES_128
#define GCM_TABLE_4BIT
/* ---- hashing + DRBG ---- */
#undef NO_SHA256
#define WOLFSSL_SHA256
#define WOLFSSL_SHA384 /* some TLS sigalg/PRF paths */
#define HAVE_HASHDRBG
/* ---- ECC / ECDSA / ECDHE (P-256) ---- */
#define HAVE_ECC
#define HAVE_ECC_SIGN
#define HAVE_ECC_VERIFY
#define HAVE_ECC_DHE /* ECDHE key agreement (software) */
#define ECC_USER_CURVES
#define HAVE_ECC256 /* P-256 only */
#define ECC_TIMING_RESISTANT
#define WOLFSSL_SP_MATH_ALL
#define HAVE_SUPPORTED_CURVES
/* ---- trims ---- */
#define NO_RSA
#define NO_DSA
#define NO_DH
#define NO_DES3
#define NO_RC4
#define NO_MD4
#define NO_MD5
#define NO_PWDBASED
#define NO_PKCS12
#define NO_PKCS8
/* ---- custom RNG seed hook (provided in main.c via the SDK TRNG) ---- */
#define CUSTOM_RAND_GENERATE_SEED rtl8735b_rand_seed
#ifndef __ASSEMBLER__
#include <stddef.h>
int rtl8735b_rand_seed(unsigned char* output, unsigned int sz);
#endif
#ifdef __cplusplus
}
#endif
#endif /* RTL8735B_HUK_TLS_USER_SETTINGS_H */

View File

@ -0,0 +1,73 @@
# wolfCrypt AmebaPro2 (RTL8735B) HUK-in-TLS example -- RealTek FreeRTOS SDK wiring.
#
# Install at <SDK>/component/example/wolfcrypt_huk_tls/ and select with:
# cmake .. -DEXAMPLE=wolfcrypt_huk_tls -DWOLFSSL_ROOT=/path/to/wolfssl ...
# (also copy main.c to <SDK>/project/realtek_amebapro2_v0_example/src/main.c)
#
# Adds the wolfCrypt sources + the wolfSSL TLS layer + the RealTek HUK port,
# this example's include path, and -DWOLFSSL_USER_SETTINGS to the SDK app build.
if(NOT DEFINED WOLFSSL_ROOT OR WOLFSSL_ROOT STREQUAL "")
if(DEFINED ENV{WOLFSSL_ROOT})
set(WOLFSSL_ROOT $ENV{WOLFSSL_ROOT})
else()
set(WOLFSSL_ROOT ${CMAKE_CURRENT_LIST_DIR}/../../../../wolfssl)
endif()
endif()
if(NOT EXISTS "${WOLFSSL_ROOT}/wolfcrypt/src/aes.c")
message(FATAL_ERROR
"WOLFSSL_ROOT='${WOLFSSL_ROOT}' is not a wolfSSL tree. "
"Pass -DWOLFSSL_ROOT=/path/to/wolfssl.")
endif()
message(STATUS "wolfCrypt HUK-TLS example: WOLFSSL_ROOT=${WOLFSSL_ROOT}")
### header search paths ###
list(APPEND app_example_inc_path
${WOLFSSL_ROOT}
${CMAKE_CURRENT_LIST_DIR} # user_settings.h
)
### compile definitions (become -D...) ###
list(APPEND app_example_flags
WOLFSSL_USER_SETTINGS
)
### source files ###
list(APPEND app_example_sources
# --- wolfCrypt ---
${WOLFSSL_ROOT}/wolfcrypt/src/aes.c
${WOLFSSL_ROOT}/wolfcrypt/src/sha256.c
${WOLFSSL_ROOT}/wolfcrypt/src/sha512.c # SHA-384/512
${WOLFSSL_ROOT}/wolfcrypt/src/sha.c # SHA-1 (TLS sigalg paths)
${WOLFSSL_ROOT}/wolfcrypt/src/hash.c
${WOLFSSL_ROOT}/wolfcrypt/src/hmac.c
${WOLFSSL_ROOT}/wolfcrypt/src/kdf.c # TLS PRF / HKDF
${WOLFSSL_ROOT}/wolfcrypt/src/random.c
${WOLFSSL_ROOT}/wolfcrypt/src/memory.c
${WOLFSSL_ROOT}/wolfcrypt/src/wc_port.c
${WOLFSSL_ROOT}/wolfcrypt/src/cryptocb.c
${WOLFSSL_ROOT}/wolfcrypt/src/error.c
${WOLFSSL_ROOT}/wolfcrypt/src/logging.c
${WOLFSSL_ROOT}/wolfcrypt/src/wc_encrypt.c
${WOLFSSL_ROOT}/wolfcrypt/src/ecc.c
${WOLFSSL_ROOT}/wolfcrypt/src/asn.c
${WOLFSSL_ROOT}/wolfcrypt/src/coding.c
${WOLFSSL_ROOT}/wolfcrypt/src/sp_int.c
${WOLFSSL_ROOT}/wolfcrypt/src/wolfmath.c
${WOLFSSL_ROOT}/wolfcrypt/src/port/realtek/rtl8735b.c
# --- wolfSSL TLS layer ---
${WOLFSSL_ROOT}/src/internal.c
${WOLFSSL_ROOT}/src/keys.c
${WOLFSSL_ROOT}/src/tls.c
${WOLFSSL_ROOT}/src/tls13.c
${WOLFSSL_ROOT}/src/wolfio.c
${WOLFSSL_ROOT}/src/ssl.c
${WOLFSSL_ROOT}/src/ssl_load.c
${WOLFSSL_ROOT}/src/ssl_certman.c
${WOLFSSL_ROOT}/src/ssl_misc.c
${WOLFSSL_ROOT}/src/ssl_sess.c
${WOLFSSL_ROOT}/src/ssl_asn1.c
${WOLFSSL_ROOT}/src/ssl_crypto.c
${WOLFSSL_ROOT}/src/x509.c
${WOLFSSL_ROOT}/src/x509_str.c
)