1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
25392f7a3SLiteSpeed Tech#include <assert.h>
35392f7a3SLiteSpeed Tech#include <stdio.h>
45392f7a3SLiteSpeed Tech#include <stdlib.h>
55392f7a3SLiteSpeed Tech#include <string.h>
65392f7a3SLiteSpeed Tech#include <sys/queue.h>
75392f7a3SLiteSpeed Tech
85392f7a3SLiteSpeed Tech#include "lsquic.h"
95392f7a3SLiteSpeed Tech#include "lsquic_types.h"
105392f7a3SLiteSpeed Tech#include "lsquic_parse.h"
115392f7a3SLiteSpeed Tech
125392f7a3SLiteSpeed Tech
135392f7a3SLiteSpeed Techstruct test {
145392f7a3SLiteSpeed Tech    int                 lineno;
155392f7a3SLiteSpeed Tech    const struct parse_funcs *
165392f7a3SLiteSpeed Tech                        pf;
175392f7a3SLiteSpeed Tech    uint64_t            offset;
185392f7a3SLiteSpeed Tech    size_t              avail;      /* Space to write stream frame to */
195392f7a3SLiteSpeed Tech    size_t              min_sz;     /* Minimum size needed to generate CRYPTO
205392f7a3SLiteSpeed Tech                                     * frame.  Any sizes smaller than this
215392f7a3SLiteSpeed Tech                                     * should fail.
225392f7a3SLiteSpeed Tech                                     */
235392f7a3SLiteSpeed Tech    size_t              data_sz;
245392f7a3SLiteSpeed Tech    char                data[0x100];
255392f7a3SLiteSpeed Tech
265392f7a3SLiteSpeed Tech    /* Output.  This is how we expect the resulting frame to look.
275392f7a3SLiteSpeed Tech     */
285392f7a3SLiteSpeed Tech    int                 len;        /* Return value of pf_gen_crypto_frame() */
295392f7a3SLiteSpeed Tech    char                out[0x100];
305392f7a3SLiteSpeed Tech};
315392f7a3SLiteSpeed Tech
325392f7a3SLiteSpeed Techstruct test_ctx {
335392f7a3SLiteSpeed Tech    const struct test   *test;
345392f7a3SLiteSpeed Tech    unsigned             off;
355392f7a3SLiteSpeed Tech};
365392f7a3SLiteSpeed Tech
375392f7a3SLiteSpeed Tech
385392f7a3SLiteSpeed Techstatic size_t
39b8fa6195SDmitri Tikhonovcrypto_read (void *ctx, void *buf, size_t len, int *fin)
405392f7a3SLiteSpeed Tech{
415392f7a3SLiteSpeed Tech    struct test_ctx *test_ctx = ctx;
425392f7a3SLiteSpeed Tech    if (test_ctx->test->data_sz - test_ctx->off < len)
435392f7a3SLiteSpeed Tech        len = test_ctx->test->data_sz - test_ctx->off;
445392f7a3SLiteSpeed Tech    memcpy(buf, test_ctx->test->data, len);
455392f7a3SLiteSpeed Tech    test_ctx->off += len;
465392f7a3SLiteSpeed Tech    return len;
475392f7a3SLiteSpeed Tech}
485392f7a3SLiteSpeed Tech
495392f7a3SLiteSpeed Tech
505392f7a3SLiteSpeed Techstatic void
515392f7a3SLiteSpeed Techinit_ctx (struct test_ctx *test_ctx, const struct test *test)
525392f7a3SLiteSpeed Tech{
535392f7a3SLiteSpeed Tech    test_ctx->test = test;
545392f7a3SLiteSpeed Tech    test_ctx->off  = 0;
555392f7a3SLiteSpeed Tech}
565392f7a3SLiteSpeed Tech
575392f7a3SLiteSpeed Tech
585392f7a3SLiteSpeed Techstatic void
59f07b3eaeSTyler Youngrun_test (const struct test *const test)
605392f7a3SLiteSpeed Tech{
615392f7a3SLiteSpeed Tech
625392f7a3SLiteSpeed Tech    int len;
635392f7a3SLiteSpeed Tech    size_t min;
645392f7a3SLiteSpeed Tech    struct test_ctx test_ctx;
655392f7a3SLiteSpeed Tech    unsigned char out[0x100];
665392f7a3SLiteSpeed Tech
675392f7a3SLiteSpeed Tech    if (test->len > 0)
685392f7a3SLiteSpeed Tech    {
695392f7a3SLiteSpeed Tech        /* Test that all sizes under specified min fail to produce a frame */
705392f7a3SLiteSpeed Tech        for (min = 0; min < test->min_sz; ++min)
715392f7a3SLiteSpeed Tech        {
725392f7a3SLiteSpeed Tech            init_ctx(&test_ctx, test);
73b8fa6195SDmitri Tikhonov            len = test->pf->pf_gen_crypto_frame(out, min, 0, test->offset, 0,
745392f7a3SLiteSpeed Tech                        test->data_sz, crypto_read, &test_ctx);
755392f7a3SLiteSpeed Tech            assert(-1 == len);
765392f7a3SLiteSpeed Tech        }
775392f7a3SLiteSpeed Tech
785392f7a3SLiteSpeed Tech        /* Test that it succeeds now: */
795392f7a3SLiteSpeed Tech        init_ctx(&test_ctx, test);
80b8fa6195SDmitri Tikhonov        len = test->pf->pf_gen_crypto_frame(out, min, 0, test->offset, 0,
815392f7a3SLiteSpeed Tech                    test->data_sz, crypto_read, &test_ctx);
825392f7a3SLiteSpeed Tech        assert(len == (int) min);
835392f7a3SLiteSpeed Tech    }
845392f7a3SLiteSpeed Tech
855392f7a3SLiteSpeed Tech    init_ctx(&test_ctx, test);
86b8fa6195SDmitri Tikhonov    len = test->pf->pf_gen_crypto_frame(out, test->avail, 0, test->offset, 0,
875392f7a3SLiteSpeed Tech                test->data_sz, crypto_read, &test_ctx);
885392f7a3SLiteSpeed Tech
895392f7a3SLiteSpeed Tech    if (test->len > 0) {
905392f7a3SLiteSpeed Tech        assert(test->len == len);
915392f7a3SLiteSpeed Tech        assert(0 == memcmp(test->out, out, test->len));
925392f7a3SLiteSpeed Tech    }
935392f7a3SLiteSpeed Tech    else
945392f7a3SLiteSpeed Tech    {
955392f7a3SLiteSpeed Tech        assert(len < 0);
965392f7a3SLiteSpeed Tech    }
975392f7a3SLiteSpeed Tech}
985392f7a3SLiteSpeed Tech
995392f7a3SLiteSpeed Tech
1005392f7a3SLiteSpeed Techint
1015392f7a3SLiteSpeed Techmain (void)
1025392f7a3SLiteSpeed Tech{
1036ff1e9b8SGeorge Wang    const struct test tests[] = {
1046ff1e9b8SGeorge Wang
1056ff1e9b8SGeorge Wang        {   .lineno     = __LINE__,
1066ff1e9b8SGeorge Wang            .pf         = select_pf_by_ver(LSQVER_ID27),
1076ff1e9b8SGeorge Wang            .offset     = 0,
1086ff1e9b8SGeorge Wang            .data_sz    = 10,
1096ff1e9b8SGeorge Wang            .data       = "0123456789",
1106ff1e9b8SGeorge Wang            .avail      = 0x100,
1116ff1e9b8SGeorge Wang            .out        =
1126ff1e9b8SGeorge Wang            { /* Type */    0x06,
1136ff1e9b8SGeorge Wang              /* Offset */  0x00,
1146ff1e9b8SGeorge Wang              /* Size */    0x0A,
1156ff1e9b8SGeorge Wang              /* Data */    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
1166ff1e9b8SGeorge Wang            },
1176ff1e9b8SGeorge Wang            .len        = 1 + 1 + 1 + 10,
1186ff1e9b8SGeorge Wang            .min_sz     = 1 + 1 + 1 + 1,
1196ff1e9b8SGeorge Wang        },
1206ff1e9b8SGeorge Wang
1216ff1e9b8SGeorge Wang        {   .lineno     = __LINE__,
1226ff1e9b8SGeorge Wang            .pf         = select_pf_by_ver(LSQVER_ID27),
1236ff1e9b8SGeorge Wang            .offset     = 500,
1246ff1e9b8SGeorge Wang            .data_sz    = 10,
1256ff1e9b8SGeorge Wang            .data       = "0123456789",
1266ff1e9b8SGeorge Wang            .avail      = 0x100,
1276ff1e9b8SGeorge Wang            .out        =
1286ff1e9b8SGeorge Wang            { /* Type */    0x06,
1296ff1e9b8SGeorge Wang              /* Offset */  0x41, 0xF4,
1306ff1e9b8SGeorge Wang              /* Size */    0x0A,
1316ff1e9b8SGeorge Wang              /* Data */    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
1326ff1e9b8SGeorge Wang            },
1336ff1e9b8SGeorge Wang            .len        = 1 + 2 + 1 + 10,
1346ff1e9b8SGeorge Wang            .min_sz     = 1 + 2 + 1 + 1,
1356ff1e9b8SGeorge Wang        },
1366ff1e9b8SGeorge Wang
1376ff1e9b8SGeorge Wang    };
138f07b3eaeSTyler Young
1395392f7a3SLiteSpeed Tech    unsigned i;
1405392f7a3SLiteSpeed Tech    for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
141f07b3eaeSTyler Young        run_test(&tests[i]);
1425392f7a3SLiteSpeed Tech    return 0;
1435392f7a3SLiteSpeed Tech}
144