mirror of https://github.com/wolfSSL/wolfssl.git
Add TLS 1.3 crypto callback pend tests and byte-stream test memio
parent
58445f6372
commit
517c45f2ed
|
|
@ -71,7 +71,7 @@ jobs:
|
|||
run: |
|
||||
cat > "$RUNNER_TEMP/async-configs.json" <<'EOF'
|
||||
[
|
||||
{"comment": "The only entry that pairs the software async simulator with --enable-all. --enable-all turns on cryptocb, which stops configure.ac from auto-enabling the simulator, so the asynccrypt-all entries below define WOLFSSL_ASYNC_CRYPT but never actually return WC_PENDING_E. Without this one nothing exercises TLS 1.3 post-handshake auth or DTLS writes against a pending crypto op. The minutes value is a projection, not a CI measurement: this config takes 1.6 min locally where the asynccrypt-all entries below take 1.4 against their declared 3. Refresh it from the first real run.",
|
||||
{"comment": "The only entry that pairs the software async simulator with --enable-all. --enable-all turns on cryptocb, which stops configure.ac from auto-enabling the simulator, so the asynccrypt-all entries below define WOLFSSL_ASYNC_CRYPT but their built-in devices never return WC_PENDING_E; pending is exercised there by the tests that register their own pending callback (hkdf_cryptocb_async_test() in wolfCrypt, test_tls13_cryptocb_async in the api suite). Without this one nothing exercises TLS 1.3 post-handshake auth or DTLS writes against a pending crypto op. The minutes value is a projection, not a CI measurement: this config takes 1.6 min locally where the asynccrypt-all entries below take 1.4 against their declared 3. Refresh it from the first real run.",
|
||||
"name": "asynccrypt-sw-all-dtls13", "minutes": 3,
|
||||
"configure": ["--enable-asynccrypt-sw", "--enable-all",
|
||||
"--enable-dtls13",
|
||||
|
|
|
|||
|
|
@ -11241,3 +11241,374 @@ int test_tls13_is_init_finished_want_write(void)
|
|||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLF_CRYPTO_CB) && \
|
||||
defined(WOLFSSL_ASYNC_CRYPT) && defined(WOLFSSL_ASYNC_REINVOKE) && \
|
||||
defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
|
||||
#define TEST_TLS13_CB_PEND_DEVID_C 1
|
||||
#define TEST_TLS13_CB_PEND_DEVID_S 2
|
||||
#define TEST_TLS13_CB_PEND_JOBS 64
|
||||
|
||||
/* Which class of operation the callback pends. */
|
||||
enum TestTls13PendTarget {
|
||||
TEST_TLS13_PEND_AESGCM,
|
||||
TEST_TLS13_PEND_ECC_KEYGEN,
|
||||
TEST_TLS13_PEND_ECDSA_SIGN,
|
||||
TEST_TLS13_PEND_ECDSA_VERIFY,
|
||||
TEST_TLS13_PEND_KDF,
|
||||
TEST_TLS13_PEND_HMAC
|
||||
};
|
||||
|
||||
typedef struct TestTls13PendCtx {
|
||||
/* Job table keyed by request: first sight queues and pends, the
|
||||
* identical re-invocation completes (falls through to software). */
|
||||
unsigned long jobs[TEST_TLS13_CB_PEND_JOBS];
|
||||
int jobCount;
|
||||
int target; /* enum TestTls13PendTarget */
|
||||
int pended; /* WC_PENDING_E results issued; asserted non-zero */
|
||||
int seen; /* matching requests observed; asserted non-zero */
|
||||
} TestTls13PendCtx;
|
||||
|
||||
static int TestTls13PendMatches(int target, wc_CryptoInfo* info)
|
||||
{
|
||||
int match = 0;
|
||||
|
||||
switch (target) {
|
||||
#ifndef WOLF_CRYPTO_CB_ASYNC_POLL
|
||||
/* With WOLF_CRYPTO_CB_ASYNC_POLL the record ciphers follow the
|
||||
* poll-completion contract instead of re-invocation; that model is
|
||||
* covered by tests/api/test_async.c. */
|
||||
case TEST_TLS13_PEND_AESGCM:
|
||||
match = (info->algo_type == WC_ALGO_TYPE_CIPHER) &&
|
||||
(info->cipher.type == WC_CIPHER_AES_GCM);
|
||||
break;
|
||||
#endif
|
||||
case TEST_TLS13_PEND_ECC_KEYGEN:
|
||||
match = (info->algo_type == WC_ALGO_TYPE_PK) &&
|
||||
(info->pk.type == WC_PK_TYPE_EC_KEYGEN);
|
||||
break;
|
||||
case TEST_TLS13_PEND_ECDSA_SIGN:
|
||||
match = (info->algo_type == WC_ALGO_TYPE_PK) &&
|
||||
(info->pk.type == WC_PK_TYPE_ECDSA_SIGN);
|
||||
break;
|
||||
case TEST_TLS13_PEND_ECDSA_VERIFY:
|
||||
match = (info->algo_type == WC_ALGO_TYPE_PK) &&
|
||||
(info->pk.type == WC_PK_TYPE_ECDSA_VERIFY);
|
||||
break;
|
||||
case TEST_TLS13_PEND_KDF:
|
||||
match = (info->algo_type == WC_ALGO_TYPE_KDF);
|
||||
break;
|
||||
case TEST_TLS13_PEND_HMAC:
|
||||
match = (info->algo_type == WC_ALGO_TYPE_HMAC);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
/* Request fingerprint over the whole info struct: op class, sizes, pointers
|
||||
* and inline content distinguish interleaved requests. */
|
||||
static unsigned long TestTls13PendHash(wc_CryptoInfo* info)
|
||||
{
|
||||
unsigned long h = 5381;
|
||||
const unsigned char* b = (const unsigned char*)info;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(*info); i++)
|
||||
h = h * 33 + b[i];
|
||||
return h;
|
||||
}
|
||||
|
||||
static int TestTls13PendCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
||||
{
|
||||
TestTls13PendCtx* c = (TestTls13PendCtx*)ctx;
|
||||
unsigned long h;
|
||||
int i;
|
||||
|
||||
(void)devIdArg;
|
||||
|
||||
if (info == NULL || c == NULL)
|
||||
return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
#if defined(HAVE_HKDF) && !defined(NO_HMAC) && !defined(HAVE_SELFTEST) && \
|
||||
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
|
||||
if (c->target == TEST_TLS13_PEND_HMAC &&
|
||||
info->algo_type == WC_ALGO_TYPE_KDF) {
|
||||
/* Serve the key schedule synchronously in software; falling back
|
||||
* with the devId set would route its internal HMACs back here and
|
||||
* those cannot resume (see wolfcrypt/src/hmac.c). Only the
|
||||
* TLS-layer transcript HMACs are left to pend. */
|
||||
if (info->kdf.type == WC_KDF_TYPE_HKDF_EXTRACT) {
|
||||
return wc_HKDF_Extract_ex(info->kdf.hkdf_extract.hashType,
|
||||
info->kdf.hkdf_extract.salt, info->kdf.hkdf_extract.saltSz,
|
||||
info->kdf.hkdf_extract.inKey, info->kdf.hkdf_extract.inKeySz,
|
||||
info->kdf.hkdf_extract.out, NULL, INVALID_DEVID);
|
||||
}
|
||||
if (info->kdf.type == WC_KDF_TYPE_HKDF_EXPAND) {
|
||||
return wc_HKDF_Expand_ex(info->kdf.hkdf_expand.hashType,
|
||||
info->kdf.hkdf_expand.inKey, info->kdf.hkdf_expand.inKeySz,
|
||||
info->kdf.hkdf_expand.info, info->kdf.hkdf_expand.infoSz,
|
||||
info->kdf.hkdf_expand.out, info->kdf.hkdf_expand.outSz,
|
||||
NULL, INVALID_DEVID);
|
||||
}
|
||||
if (info->kdf.type == WC_KDF_TYPE_HKDF) {
|
||||
return wc_HKDF_ex(info->kdf.hkdf.hashType,
|
||||
info->kdf.hkdf.inKey, info->kdf.hkdf.inKeySz,
|
||||
info->kdf.hkdf.salt, info->kdf.hkdf.saltSz,
|
||||
info->kdf.hkdf.info, info->kdf.hkdf.infoSz,
|
||||
info->kdf.hkdf.out, info->kdf.hkdf.outSz,
|
||||
NULL, INVALID_DEVID);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!TestTls13PendMatches(c->target, info))
|
||||
return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
|
||||
c->seen++;
|
||||
h = TestTls13PendHash(info);
|
||||
for (i = 0; i < c->jobCount; i++) {
|
||||
if (c->jobs[i] == h) {
|
||||
/* Re-invocation of a pended request: complete it. */
|
||||
c->jobs[i] = c->jobs[--c->jobCount];
|
||||
return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
if (c->jobCount < TEST_TLS13_CB_PEND_JOBS) {
|
||||
c->jobs[c->jobCount++] = h;
|
||||
c->pended++;
|
||||
return WC_PENDING_E;
|
||||
}
|
||||
|
||||
return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
}
|
||||
|
||||
/* wolfSSL_write()/wolfSSL_read() can return WC_PENDING_E just as the
|
||||
* handshake does; drive them with the poll-and-retry loop the application is
|
||||
* expected to use. Returns the byte count, or the error. */
|
||||
static int TestTls13PendWrite(WOLFSSL* ssl, const char* buf, int sz)
|
||||
{
|
||||
int ret;
|
||||
int err;
|
||||
int rounds = 0;
|
||||
|
||||
do {
|
||||
ret = wolfSSL_write(ssl, buf, sz);
|
||||
if (ret > 0)
|
||||
break;
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
|
||||
if (wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW) < 0)
|
||||
return -1;
|
||||
}
|
||||
else if (err != WOLFSSL_ERROR_WANT_READ &&
|
||||
err != WOLFSSL_ERROR_WANT_WRITE) {
|
||||
return ret;
|
||||
}
|
||||
} while (++rounds < 100);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int TestTls13PendRead(WOLFSSL* ssl, char* buf, int sz)
|
||||
{
|
||||
int ret;
|
||||
int err;
|
||||
int rounds = 0;
|
||||
|
||||
do {
|
||||
ret = wolfSSL_read(ssl, buf, sz);
|
||||
if (ret > 0)
|
||||
break;
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
|
||||
if (wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW) < 0)
|
||||
return -1;
|
||||
}
|
||||
else if (err != WOLFSSL_ERROR_WANT_READ &&
|
||||
err != WOLFSSL_ERROR_WANT_WRITE) {
|
||||
return ret;
|
||||
}
|
||||
} while (++rounds < 100);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* One TLS 1.3 handshake with the given operation class pending on both sides,
|
||||
* then application data both ways so records queued after the handshake are
|
||||
* parsed by the peer as well. */
|
||||
static int test_tls13_cryptocb_pend_one(int target, int mutual)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
WOLFSSL_CTX* ctx_c = NULL;
|
||||
WOLFSSL_CTX* ctx_s = NULL;
|
||||
WOLFSSL* ssl_c = NULL;
|
||||
WOLFSSL* ssl_s = NULL;
|
||||
TestTls13PendCtx cliCtx;
|
||||
TestTls13PendCtx srvCtx;
|
||||
struct test_memio_ctx memio;
|
||||
const char msg[] = "hello over TLS 1.3";
|
||||
char buf[64];
|
||||
|
||||
XMEMSET(&cliCtx, 0, sizeof(cliCtx));
|
||||
XMEMSET(&srvCtx, 0, sizeof(srvCtx));
|
||||
XMEMSET(&memio, 0, sizeof(memio));
|
||||
cliCtx.target = target;
|
||||
srvCtx.target = target;
|
||||
|
||||
ExpectIntEQ(wc_CryptoCb_RegisterDevice(TEST_TLS13_CB_PEND_DEVID_C,
|
||||
TestTls13PendCb, &cliCtx), 0);
|
||||
ExpectIntEQ(wc_CryptoCb_RegisterDevice(TEST_TLS13_CB_PEND_DEVID_S,
|
||||
TestTls13PendCb, &srvCtx), 0);
|
||||
|
||||
/* devId set on the CTX before credentials and SSL objects so all of
|
||||
* it inherits the devId. ECC credentials: an RSA key under a devId
|
||||
* would be treated as device-held. */
|
||||
ExpectNotNull(ctx_c = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
|
||||
ExpectNotNull(ctx_s = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
|
||||
ExpectIntEQ(wolfSSL_CTX_SetDevId(ctx_c, TEST_TLS13_CB_PEND_DEVID_C),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_CTX_SetDevId(ctx_s, TEST_TLS13_CB_PEND_DEVID_S),
|
||||
WOLFSSL_SUCCESS);
|
||||
#ifdef HAVE_AESGCM
|
||||
if (target == TEST_TLS13_PEND_AESGCM) {
|
||||
/* Pin the AEAD so the pend assertion cannot depend on suite
|
||||
* preference ordering. */
|
||||
ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx_c,
|
||||
"TLS13-AES128-GCM-SHA256"), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx_s,
|
||||
"TLS13-AES128-GCM-SHA256"), WOLFSSL_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx_c,
|
||||
"./certs/ca-ecc-cert.pem", 0), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx_s,
|
||||
"./certs/server-ecc.pem"), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx_s, "./certs/ecc-key.pem",
|
||||
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
|
||||
if (mutual) {
|
||||
/* Mutual auth: pending verifies of the client's chain and CV
|
||||
* cover the received-marker restores. */
|
||||
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx_c,
|
||||
"./certs/client-ecc-cert.pem"), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx_c,
|
||||
"./certs/ecc-client-key.pem", WOLFSSL_FILETYPE_PEM),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx_s,
|
||||
"./certs/client-ecc-cert.pem", 0), WOLFSSL_SUCCESS);
|
||||
wolfSSL_CTX_set_verify(ctx_s, WOLFSSL_VERIFY_PEER |
|
||||
WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
|
||||
}
|
||||
|
||||
ExpectNotNull(ssl_c = wolfSSL_new(ctx_c));
|
||||
ExpectNotNull(ssl_s = wolfSSL_new(ctx_s));
|
||||
|
||||
/* Pin the group so every run negotiates the same way; the default offer
|
||||
* can trigger HelloRetryRequest or a PQC key share, which are separate
|
||||
* scenarios from the pend-resume paths this test covers. */
|
||||
if (EXPECT_SUCCESS()) {
|
||||
int groups[1];
|
||||
groups[0] = WOLFSSL_ECC_SECP256R1;
|
||||
ExpectIntEQ(wolfSSL_set_groups(ssl_c, groups, 1), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_set_groups(ssl_s, groups, 1), WOLFSSL_SUCCESS);
|
||||
}
|
||||
|
||||
/* The shared memio transport; its TLS path serves a byte stream, so
|
||||
* the re-read patterns of pending crypto operations cannot desync it. */
|
||||
if (EXPECT_SUCCESS()) {
|
||||
wolfSSL_SSLSetIORecv(ssl_c, test_memio_read_cb);
|
||||
wolfSSL_SSLSetIOSend(ssl_c, test_memio_write_cb);
|
||||
wolfSSL_SSLSetIORecv(ssl_s, test_memio_read_cb);
|
||||
wolfSSL_SSLSetIOSend(ssl_s, test_memio_write_cb);
|
||||
wolfSSL_SetIOReadCtx(ssl_c, &memio);
|
||||
wolfSSL_SetIOWriteCtx(ssl_c, &memio);
|
||||
wolfSSL_SetIOReadCtx(ssl_s, &memio);
|
||||
wolfSSL_SetIOWriteCtx(ssl_s, &memio);
|
||||
}
|
||||
|
||||
/* Generous rounds: pending every KDF request costs one poll-and-retry
|
||||
* round trip per operation, and a TLS 1.3 handshake with session tickets
|
||||
* runs a couple of hundred of them. */
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 600, NULL), 0);
|
||||
|
||||
/* Assert per-side pends so the test cannot pass without exercising a
|
||||
* resume path; the client signs nothing unless mutual. */
|
||||
ExpectIntGT(srvCtx.seen, 0);
|
||||
ExpectIntGT(srvCtx.pended, 0);
|
||||
if (mutual || target != TEST_TLS13_PEND_ECDSA_SIGN) {
|
||||
ExpectIntGT(cliCtx.seen, 0);
|
||||
ExpectIntGT(cliCtx.pended, 0);
|
||||
}
|
||||
|
||||
ExpectIntEQ(TestTls13PendWrite(ssl_c, msg, (int)sizeof(msg)),
|
||||
(int)sizeof(msg));
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
ExpectIntEQ(TestTls13PendRead(ssl_s, buf, (int)sizeof(buf)),
|
||||
(int)sizeof(msg));
|
||||
ExpectIntEQ(XMEMCMP(buf, msg, sizeof(msg)), 0);
|
||||
|
||||
ExpectIntEQ(TestTls13PendWrite(ssl_s, msg, (int)sizeof(msg)),
|
||||
(int)sizeof(msg));
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
ExpectIntEQ(TestTls13PendRead(ssl_c, buf, (int)sizeof(buf)),
|
||||
(int)sizeof(msg));
|
||||
ExpectIntEQ(XMEMCMP(buf, msg, sizeof(msg)), 0);
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
wc_CryptoCb_UnRegisterDevice(TEST_TLS13_CB_PEND_DEVID_C);
|
||||
wc_CryptoCb_UnRegisterDevice(TEST_TLS13_CB_PEND_DEVID_S);
|
||||
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#endif /* guards */
|
||||
|
||||
/* Drive TLS 1.3 handshakes and application data with the poll-and-retry
|
||||
* loop while a crypto callback pends each matching request. */
|
||||
int test_tls13_cryptocb_async(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLF_CRYPTO_CB) && \
|
||||
defined(WOLFSSL_ASYNC_CRYPT) && defined(WOLFSSL_ASYNC_REINVOKE) && \
|
||||
defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
#if defined(HAVE_AESGCM) && !defined(WOLF_CRYPTO_CB_ASYNC_POLL)
|
||||
ExpectIntEQ(test_tls13_cryptocb_pend_one(TEST_TLS13_PEND_AESGCM, 0),
|
||||
TEST_SUCCESS);
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
ExpectIntEQ(test_tls13_cryptocb_pend_one(TEST_TLS13_PEND_ECC_KEYGEN, 0),
|
||||
TEST_SUCCESS);
|
||||
ExpectIntEQ(test_tls13_cryptocb_pend_one(TEST_TLS13_PEND_ECDSA_SIGN, 0),
|
||||
TEST_SUCCESS);
|
||||
/* Mutual auth with pending verifies: regression for the msgsReceived
|
||||
* marker restores (a pended Certificate/CertificateVerify replay used
|
||||
* to leave its marker clear and fail Finished with OUT_OF_ORDER_E). */
|
||||
ExpectIntEQ(test_tls13_cryptocb_pend_one(TEST_TLS13_PEND_ECDSA_VERIFY, 1),
|
||||
TEST_SUCCESS);
|
||||
#endif
|
||||
#if defined(HAVE_HKDF) && !defined(NO_HMAC)
|
||||
ExpectIntEQ(test_tls13_cryptocb_pend_one(TEST_TLS13_PEND_KDF, 0),
|
||||
TEST_SUCCESS);
|
||||
ExpectIntEQ(test_tls13_cryptocb_pend_one(TEST_TLS13_PEND_KDF, 1),
|
||||
TEST_SUCCESS);
|
||||
#if !defined(HAVE_SELFTEST) && \
|
||||
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
|
||||
/* Transcript HMACs (Finished verify_data) pending on both sides. */
|
||||
ExpectIntEQ(test_tls13_cryptocb_pend_one(TEST_TLS13_PEND_HMAC, 0),
|
||||
TEST_SUCCESS);
|
||||
ExpectIntEQ(test_tls13_cryptocb_pend_one(TEST_TLS13_PEND_HMAC, 1),
|
||||
TEST_SUCCESS);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ int test_tls13_pqc_hybrid_async_server(void);
|
|||
int test_tls13_pha_status_request(void);
|
||||
int test_tls13_x25519_keyshare_masks_reserved_bit(void);
|
||||
int test_tls13_is_init_finished_want_write(void);
|
||||
int test_tls13_cryptocb_async(void);
|
||||
|
||||
#define TEST_TLS13_DECLS \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_apis), \
|
||||
|
|
@ -241,6 +242,7 @@ int test_tls13_is_init_finished_want_write(void);
|
|||
TEST_DECL_GROUP("tls13", test_tls13_pqc_hybrid_async_server), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_pha_status_request), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_x25519_keyshare_masks_reserved_bit), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_is_init_finished_want_write)
|
||||
TEST_DECL_GROUP("tls13", test_tls13_is_init_finished_want_write), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_cryptocb_async)
|
||||
|
||||
#endif /* WOLFCRYPT_TEST_TLS13_H */
|
||||
|
|
|
|||
|
|
@ -129,7 +129,44 @@ int test_memio_read_cb(WOLFSSL *ssl, char *data, int sz, void *ctx)
|
|||
if (*len == 0 || *msg_pos >= *msg_count)
|
||||
return WOLFSSL_CBIO_ERR_WANT_READ;
|
||||
|
||||
/* Calculate how much we can read from current message */
|
||||
if (!is_dtls) {
|
||||
/* TLS is a byte stream: serve across message boundaries so
|
||||
* pending-crypto re-read patterns cannot desync the slots. */
|
||||
int rem;
|
||||
|
||||
read_sz = *len;
|
||||
if (read_sz > sz)
|
||||
read_sz = sz;
|
||||
|
||||
XMEMCPY(data, buf, (size_t)read_sz);
|
||||
XMEMMOVE(buf, buf + read_sz, (size_t)(*len - read_sz));
|
||||
*len -= read_sz;
|
||||
|
||||
rem = read_sz;
|
||||
while (rem > 0 && *msg_pos < *msg_count) {
|
||||
if (msg_sizes[*msg_pos] > rem) {
|
||||
msg_sizes[*msg_pos] -= rem;
|
||||
rem = 0;
|
||||
}
|
||||
else {
|
||||
rem -= msg_sizes[*msg_pos];
|
||||
msg_sizes[*msg_pos] = 0;
|
||||
(*msg_pos)++;
|
||||
}
|
||||
}
|
||||
if (rem != 0) {
|
||||
/* Slot accounting desynced from the byte count; fail loudly. */
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
}
|
||||
if (*msg_pos >= *msg_count && *len == 0) {
|
||||
*msg_pos = 0;
|
||||
*msg_count = 0;
|
||||
}
|
||||
|
||||
return read_sz;
|
||||
}
|
||||
|
||||
/* DTLS: datagram boundaries matter, serve one message at a time. */
|
||||
read_sz = msg_sizes[*msg_pos];
|
||||
if (read_sz > sz)
|
||||
read_sz = sz;
|
||||
|
|
|
|||
Loading…
Reference in New Issue