Commit d836d71b authored by Emilia Kasper's avatar Emilia Kasper
Browse files

Simplify tests part 2



1) Remove some unnecessary fixtures
2) Add EXECUTE_TEST_NO_TEARDOWN shorthand when a fixture exists but has
no teardown.
3) Fix return values in ct_test.c (introduced by an earlier refactoring,
oops)

Note that for parameterized tests, the index (test vector) usually holds all the
customization, and there should be no need for a separate test
fixture. The CTS test is an exception: it demonstrates how to combine
customization with parameterization.

Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
parent 8e47ee18
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -507,20 +507,20 @@ static int test_encode_tls_sct()
    SCT *sct = SCT_new();
    if (!SCT_set_version(sct, SCT_VERSION_V1)) {
        fprintf(stderr, "Failed to set SCT version\n");
        return 1;
        return 0;
    }
    if (!SCT_set1_log_id(sct, log_id, 32)) {
        fprintf(stderr, "Failed to set SCT log ID\n");
        return 1;
        return 0;
    }
    SCT_set_timestamp(sct, 1);
    if (!SCT_set_signature_nid(sct, NID_ecdsa_with_SHA256)) {
        fprintf(stderr, "Failed to set SCT signature NID\n");
        return 1;
        return 0;
    }
    if (!SCT_set1_signature(sct, signature, 71)) {
        fprintf(stderr, "Failed to set SCT signature\n");
        return 1;
        return 0;
    }
    sk_SCT_push(sct_list, sct);

+23 −46
Original line number Diff line number Diff line
@@ -21,74 +21,51 @@ typedef struct {
    const unsigned char expected[MDC2_DIGEST_LENGTH];
} TESTDATA;

typedef struct {
    const char *case_name;
    int num;
    const TESTDATA *data;
} SIMPLE_FIXTURE;

/**********************************************************************
 *
 * Test of mdc2 internal functions
 * Test driver
 *
 ***/

static SIMPLE_FIXTURE setup_mdc2(const char *const test_case_name)
static TESTDATA tests[] = {
    {
        "Now is the time for all ",
        {
    SIMPLE_FIXTURE fixture;
    fixture.case_name = test_case_name;
    return fixture;
            0x42, 0xE5, 0x0C, 0xD2, 0x24, 0xBA, 0xCE, 0xBA,
            0x76, 0x0B, 0xDD, 0x2B, 0xD4, 0x09, 0x28, 0x1A
        }
    }
};

static int execute_mdc2(SIMPLE_FIXTURE fixture)
/**********************************************************************
 *
 * Test of mdc2 internal functions
 *
 ***/

static int test_mdc2(int idx)
{
    unsigned char md[MDC2_DIGEST_LENGTH];
    MDC2_CTX c;
    const TESTDATA testdata = tests[idx];

    MDC2_Init(&c);
    MDC2_Update(&c, (const unsigned char *)fixture.data->input,
                strlen(fixture.data->input));
    MDC2_Update(&c, (const unsigned char *)testdata.input,
                strlen(testdata.input));
    MDC2_Final(&(md[0]), &c);

    if (memcmp(fixture.data->expected, md, MDC2_DIGEST_LENGTH)) {
        fprintf(stderr, "mdc2 test %d: unexpected output\n", fixture.num);
    if (memcmp(testdata.expected, md, MDC2_DIGEST_LENGTH)) {
        fprintf(stderr, "mdc2 test %d: unexpected output\n", idx);
        return 0;
    }

    return 1;
}

static void teardown_mdc2(SIMPLE_FIXTURE fixture)
{
}

/**********************************************************************
 *
 * Test driver
 *
 ***/

static TESTDATA tests[] = {
    {
        "Now is the time for all ",
        {
            0x42, 0xE5, 0x0C, 0xD2, 0x24, 0xBA, 0xCE, 0xBA,
            0x76, 0x0B, 0xDD, 0x2B, 0xD4, 0x09, 0x28, 0x1A
        }
    }
};

static int drive_tests(int idx)
{
    SETUP_TEST_FIXTURE(SIMPLE_FIXTURE, setup_mdc2);
    fixture.num = idx;
    fixture.data = &tests[idx];
    EXECUTE_TEST(execute_mdc2, teardown_mdc2);
}

int main(int argc, char **argv)
{
    ADD_ALL_TESTS(drive_tests, OSSL_NELEM(tests));
    ADD_ALL_TESTS(test_mdc2, OSSL_NELEM(tests));

    return run_tests(argv[0]);
}
+258 −345
Original line number Diff line number Diff line
@@ -29,316 +29,6 @@ typedef struct {
 *
 ***/

typedef struct {
    const char *case_name;
    int num;
    const AES_KEY *encrypt_key_schedule;
    const AES_KEY *decrypt_key_schedule;
    const unsigned char *input;
    SIZED_DATA iv;
    const SIZED_DATA *vector;
} CTS128_FIXTURE;

static CTS128_FIXTURE setup_cts128(const char *const test_case_name)
{
    CTS128_FIXTURE fixture;
    fixture.case_name = test_case_name;
    return fixture;
}

static int execute_cts128(CTS128_FIXTURE fixture)
{
    const unsigned char *test_iv = fixture.iv.data;
    size_t test_iv_len = fixture.iv.size;
    const unsigned char *vector = fixture.vector->data;
    size_t len = fixture.vector->size;
    const unsigned char *test_input = fixture.input;
    const AES_KEY *encrypt_key_schedule = fixture.encrypt_key_schedule;
    const AES_KEY *decrypt_key_schedule = fixture.decrypt_key_schedule;
    unsigned char iv[16];
    unsigned char cleartext[64], ciphertext[64];
    size_t tail;

    fprintf(stderr, "vector_%" OSSLzu "\n", len);
    fflush(stdout);

    if ((tail = len % 16) == 0)
        tail = 16;
    tail += 16;

    /* test block-based encryption */
    memcpy(iv, test_iv, test_iv_len);
    CRYPTO_cts128_encrypt_block(test_input, ciphertext, len,
                                encrypt_key_schedule, iv,
                                (block128_f)AES_encrypt);
    if (memcmp(ciphertext, vector, len)) {
        fprintf(stderr, "block encrypt: output_%" OSSLzu " mismatch\n", len);
        return 0;
    }
    if (memcmp(iv, vector + len - tail, sizeof(iv))) {
        fprintf(stderr, "block encrypt: iv_%" OSSLzu " mismatch\n", len);
        return 0;
    }

    /* test block-based decryption */
    memcpy(iv, test_iv, test_iv_len);
    CRYPTO_cts128_decrypt_block(ciphertext, cleartext, len,
                                decrypt_key_schedule, iv,
                                (block128_f)AES_decrypt);
    if (memcmp(cleartext, test_input, len)) {
        fprintf(stderr, "block decrypt: input_%" OSSLzu " mismatch\n", len);
        return 0;
    }
    if (memcmp(iv, vector + len - tail, sizeof(iv))) {
        fprintf(stderr, "block decrypt: iv_%" OSSLzu " mismatch\n", len);
        return 0;
    }

    /* test streamed encryption */
    memcpy(iv, test_iv, test_iv_len);
    CRYPTO_cts128_encrypt(test_input, ciphertext, len, encrypt_key_schedule,
                          iv, (cbc128_f) AES_cbc_encrypt);
    if (memcmp(ciphertext, vector, len)) {
        fprintf(stderr, "stream encrypt: output_%" OSSLzu " mismatch\n", len);
        return 0;
    }
    if (memcmp(iv, vector + len - tail, sizeof(iv))) {
        fprintf(stderr, "stream encrypt: iv_%" OSSLzu " mismatch\n", len);
        return 0;
    }

    /* test streamed decryption */
    memcpy(iv, test_iv, test_iv_len);
    CRYPTO_cts128_decrypt(ciphertext, cleartext, len, decrypt_key_schedule, iv,
                          (cbc128_f)AES_cbc_encrypt);
    if (memcmp(cleartext, test_input, len)) {
        fprintf(stderr, "stream decrypt: input_%" OSSLzu " mismatch\n", len);
        return 0;
    }
    if (memcmp(iv, vector + len - tail, sizeof(iv))) {
        fprintf(stderr, "stream decrypt: iv_%" OSSLzu " mismatch\n", len);
        return 0;
    }

    return 1;
}

static int execute_cts128_nist(CTS128_FIXTURE fixture)
{
    const unsigned char *test_iv = fixture.iv.data;
    size_t test_iv_len = fixture.iv.size;
    const unsigned char *vector = fixture.vector->data;
    size_t len = fixture.vector->size;
    const unsigned char *test_input = fixture.input;
    const AES_KEY *encrypt_key_schedule = fixture.encrypt_key_schedule;
    const AES_KEY *decrypt_key_schedule = fixture.decrypt_key_schedule;
    unsigned char iv[16];
    unsigned char cleartext[64], ciphertext[64], nistvector[64];
    size_t tail;

    fprintf(stderr, "nistvector_%" OSSLzu "\n", len);
    fflush(stdout);

    if ((tail = len % 16) == 0)
        tail = 16;

    len -= 16 + tail;
    memcpy(nistvector, vector, len);
    /* flip two last blocks */
    memcpy(nistvector + len, vector + len + 16, tail);
    memcpy(nistvector + len + tail, vector + len, 16);
    len += 16 + tail;
    tail = 16;

    /* test block-based encryption */
    memcpy(iv, test_iv, test_iv_len);
    CRYPTO_nistcts128_encrypt_block(test_input, ciphertext, len,
                                    encrypt_key_schedule, iv,
                                    (block128_f)AES_encrypt);
    if (memcmp(ciphertext, nistvector, len)) {
        fprintf(stderr, "output_%" OSSLzu " mismatch\n", len);
        return 0;
    }
    if (memcmp(iv, nistvector + len - tail, sizeof(iv))) {
        fprintf(stderr, "iv_%" OSSLzu " mismatch\n", len);
        return 0;
    }

    /* test block-based decryption */
    memcpy(iv, test_iv, test_iv_len);
    CRYPTO_nistcts128_decrypt_block(ciphertext, cleartext, len,
                                    decrypt_key_schedule, iv,
                                    (block128_f)AES_decrypt);
    if (memcmp(cleartext, test_input, len)) {
        fprintf(stderr, "input_%" OSSLzu " mismatch\n", len);
        return 0;
    }
    if (memcmp(iv, nistvector + len - tail, sizeof(iv))) {
        fprintf(stderr, "iv_%" OSSLzu " mismatch\n", len);
        return 0;
    }

    /* test streamed encryption */
    memcpy(iv, test_iv, test_iv_len);
    CRYPTO_nistcts128_encrypt(test_input, ciphertext, len,
                              encrypt_key_schedule, iv,
                              (cbc128_f)AES_cbc_encrypt);
    if (memcmp(ciphertext, nistvector, len)) {
        fprintf(stderr, "output_%" OSSLzu " mismatch\n", len);
        return 0;
    }
    if (memcmp(iv, nistvector + len - tail, sizeof(iv))) {
        fprintf(stderr, "iv_%" OSSLzu " mismatch\n", len);
        return 0;
    }

    /* test streamed decryption */
    memcpy(iv, test_iv, test_iv_len);
    CRYPTO_nistcts128_decrypt(ciphertext, cleartext, len, decrypt_key_schedule,
                              iv, (cbc128_f)AES_cbc_encrypt);
    if (memcmp(cleartext, test_input, len)) {
        fprintf(stderr, "input_%" OSSLzu " mismatch\n", len);
        return 0;
    }
    if (memcmp(iv, nistvector + len - tail, sizeof(iv))) {
        fprintf(stderr, "iv_%" OSSLzu " mismatch\n", len);
        return 0;
    }

    return 1;
}

static void teardown_cts128(CTS128_FIXTURE fixture)
{
}

/**********************************************************************
 *
 * Test of gcm128
 *
 ***/

typedef struct {
    const char *case_name;
    int num;
    SIZED_DATA K;
    SIZED_DATA IV;
    SIZED_DATA A;
    SIZED_DATA P;
    SIZED_DATA C;
    SIZED_DATA T;
} GCM128_FIXTURE;

static GCM128_FIXTURE setup_gcm128(const char *const test_case_name)
{
    GCM128_FIXTURE fixture;
    fixture.case_name = test_case_name;
    return fixture;
}

static int execute_gcm128(GCM128_FIXTURE fixture)
{
    unsigned char out[512];
    SIZED_DATA *K = &fixture.K;
    SIZED_DATA *IV = &fixture.IV;
    SIZED_DATA *A = &fixture.A;
    SIZED_DATA *P = &fixture.P;
    SIZED_DATA *C = &fixture.C;
    SIZED_DATA *T = &fixture.T;
    int n = fixture.num;
    GCM128_CONTEXT ctx;
    AES_KEY key;
    int err = 0;

    AES_set_encrypt_key(K->data, K->size * 8, &key);

    CRYPTO_gcm128_init(&ctx, &key, (block128_f)AES_encrypt);
    CRYPTO_gcm128_setiv(&ctx, IV->data, IV->size);
    memset(out, 0, P->size);
    if (A->data)
        CRYPTO_gcm128_aad(&ctx, A->data, A->size);
    if (P->data)
        CRYPTO_gcm128_encrypt( &ctx, P->data, out, P->size);
    if (CRYPTO_gcm128_finish(&ctx, T->data, 16)
        || (C->data && memcmp(out, C->data, P->size)))
        err++, fprintf(stderr, "encrypt test#%d failed.\n", n);

    CRYPTO_gcm128_setiv(&ctx, IV->data, IV->size);
    memset(out, 0, P->size);
    if (A->data)
        CRYPTO_gcm128_aad(&ctx, A->data, A->size);
    if (C->data)
        CRYPTO_gcm128_decrypt(&ctx, C->data, out, P->size);
    if (CRYPTO_gcm128_finish(&ctx, T->data, 16)
        || (P->data && memcmp(out, P->data, P->size)))
        err++, fprintf(stderr, "decrypt test#%d failed.\n", n);

    return err == 0;
}

static void teardown_gcm128(GCM128_FIXTURE fixture)
{
}

static void benchmark_gcm128(const unsigned char *K, size_t Klen,
                             const unsigned char *IV, size_t IVlen)
{
#ifdef OPENSSL_CPUID_OBJ
    GCM128_CONTEXT ctx;
    AES_KEY key;
    size_t start, gcm_t, ctr_t, OPENSSL_rdtsc();
    union {
        u64 u;
        u8 c[1024];
    } buf;

    AES_set_encrypt_key(K, Klen * 8, &key);
    CRYPTO_gcm128_init(&ctx, &key, (block128_f) AES_encrypt);
    CRYPTO_gcm128_setiv(&ctx, IV, IVlen);

    CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf));
    start = OPENSSL_rdtsc();
    CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf));
    gcm_t = OPENSSL_rdtsc() - start;

    CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf),
                          &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres,
                          (block128_f) AES_encrypt);
    start = OPENSSL_rdtsc();
    CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf),
                          &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres,
                          (block128_f) AES_encrypt);
    ctr_t = OPENSSL_rdtsc() - start;

    printf("%.2f-%.2f=%.2f\n",
           gcm_t / (double)sizeof(buf),
           ctr_t / (double)sizeof(buf),
           (gcm_t - ctr_t) / (double)sizeof(buf));
# ifdef GHASH
    {
        void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
                             const u8 *inp, size_t len) = ctx.ghash;

        GHASH((&ctx), buf.c, sizeof(buf));
        start = OPENSSL_rdtsc();
        for (i = 0; i < 100; ++i)
            GHASH((&ctx), buf.c, sizeof(buf));
        gcm_t = OPENSSL_rdtsc() - start;
        printf("%.2f\n", gcm_t / (double)sizeof(buf) / (double)i);
    }
# endif
#else
    fprintf(stderr,
            "Benchmarking of modes isn't available on this platform\n");
#endif
}

/**********************************************************************
 *
 * Test driver
 *
 ***/

/* cts128 test vectors from RFC 3962 */
static const unsigned char cts128_test_key[16] = "chicken teriyaki";
static const unsigned char cts128_test_input[64] =
@@ -433,32 +123,174 @@ static AES_KEY *cts128_decrypt_key_schedule()
    return &ks;
}

static int drive_cts128_tests(int idx)
typedef struct {
    const char *case_name;
    int num;
    size_t (*transform_output)(const unsigned char *in, unsigned char *out,
                               size_t len);
    size_t (*encrypt_block)(const unsigned char *in,
                            unsigned char *out, size_t len,
                            const void *key, unsigned char ivec[16],
                            block128_f block);
    size_t (*encrypt)(const unsigned char *in, unsigned char *out,
                      size_t len, const void *key,
                      unsigned char ivec[16], cbc128_f cbc);
    size_t (*decrypt_block)(const unsigned char *in,
                            unsigned char *out, size_t len,
                            const void *key, unsigned char ivec[16],
                            block128_f block);
    size_t (*decrypt)(const unsigned char *in, unsigned char *out,
                      size_t len, const void *key,
                      unsigned char ivec[16], cbc128_f cbc);
} CTS128_FIXTURE;


static CTS128_FIXTURE setup_cts128(const char *const test_case_name)
{
    CTS128_FIXTURE fixture;
    fixture.case_name = test_case_name;
    return fixture;
}

static size_t transform_output(const unsigned char *in, unsigned char *out,
                               size_t len)
{
    size_t tail;

    memcpy(out, in, len);
    if ((tail = len % 16) == 0)
        tail = 16;
    tail += 16;

    return tail;
}

static size_t transform_output_nist(const unsigned char *in, unsigned char *out,
                                    size_t len)
{
    size_t tail;

    if ((tail = len % 16) == 0)
        tail = 16;
    len -= 16 + tail;
    memcpy(out, in, len);
    /* flip two last blocks */
    memcpy(out + len, in + len + 16, tail);
    memcpy(out + len + tail, in + len, 16);
    len += 16 + tail;
    tail = 16;

    return tail;
}

static int execute_cts128(CTS128_FIXTURE fixture)
{
    const unsigned char *test_iv = cts128_test_iv;
    size_t test_iv_len = sizeof(cts128_test_iv);
    const unsigned char *orig_vector = cts128_vectors[fixture.num].data;
    size_t len = cts128_vectors[fixture.num].size;
    const unsigned char *test_input = cts128_test_input;
    const AES_KEY *encrypt_key_schedule = cts128_encrypt_key_schedule();
    const AES_KEY *decrypt_key_schedule = cts128_decrypt_key_schedule();
    unsigned char iv[16];
    /* The largest test inputs are = 64 bytes. */
    unsigned char cleartext[64], ciphertext[64], vector[64];
    size_t tail;

    fprintf(stderr, "%s_vector_%" OSSLzu "\n", fixture.case_name, len);
    fflush(stdout);

    tail = fixture.transform_output(orig_vector, vector, len);

    /* test block-based encryption */
    memcpy(iv, test_iv, test_iv_len);
    fixture.encrypt_block(test_input, ciphertext, len,
                          encrypt_key_schedule, iv,
                          (block128_f)AES_encrypt);
    if (memcmp(ciphertext, vector, len)) {
        fprintf(stderr, "block encrypt: output_%" OSSLzu " mismatch\n", len);
        return 0;
    }
    if (memcmp(iv, vector + len - tail, sizeof(iv))) {
        fprintf(stderr, "block encrypt: iv_%" OSSLzu " mismatch\n", len);
        return 0;
    }

    /* test block-based decryption */
    memcpy(iv, test_iv, test_iv_len);
    fixture.decrypt_block(ciphertext, cleartext, len,
                          decrypt_key_schedule, iv,
                          (block128_f)AES_decrypt);
    if (memcmp(cleartext, test_input, len)) {
        fprintf(stderr, "block decrypt: input_%" OSSLzu " mismatch\n", len);
        return 0;
    }
    if (memcmp(iv, vector + len - tail, sizeof(iv))) {
        fprintf(stderr, "block decrypt: iv_%" OSSLzu " mismatch\n", len);
        return 0;
    }

    /* test streamed encryption */
    memcpy(iv, test_iv, test_iv_len);
    fixture.encrypt(test_input, ciphertext, len, encrypt_key_schedule,
                    iv, (cbc128_f) AES_cbc_encrypt);
    if (memcmp(ciphertext, vector, len)) {
        fprintf(stderr, "stream encrypt: output_%" OSSLzu " mismatch\n", len);
        return 0;
    }
    if (memcmp(iv, vector + len - tail, sizeof(iv))) {
        fprintf(stderr, "stream encrypt: iv_%" OSSLzu " mismatch\n", len);
        return 0;
    }

    /* test streamed decryption */
    memcpy(iv, test_iv, test_iv_len);
    fixture.decrypt(ciphertext, cleartext, len, decrypt_key_schedule, iv,
                    (cbc128_f)AES_cbc_encrypt);
    if (memcmp(cleartext, test_input, len)) {
        fprintf(stderr, "stream decrypt: input_%" OSSLzu " mismatch\n", len);
        return 0;
    }
    if (memcmp(iv, vector + len - tail, sizeof(iv))) {
        fprintf(stderr, "stream decrypt: iv_%" OSSLzu " mismatch\n", len);
        return 0;
    }

    return 1;
}

static int test_cts128(int idx)
{
    SETUP_TEST_FIXTURE(CTS128_FIXTURE, setup_cts128);
    fixture.transform_output = transform_output;
    fixture.encrypt_block = CRYPTO_cts128_encrypt_block;
    fixture.encrypt = CRYPTO_cts128_encrypt;
    fixture.decrypt_block = CRYPTO_cts128_decrypt_block;
    fixture.decrypt = CRYPTO_cts128_decrypt;
    fixture.case_name = "cts128";
    fixture.num = idx;
    fixture.encrypt_key_schedule = cts128_encrypt_key_schedule();
    fixture.decrypt_key_schedule = cts128_decrypt_key_schedule();
    fixture.input = cts128_test_input;
    fixture.iv.size = sizeof(cts128_test_iv);
    fixture.iv.data = cts128_test_iv;
    fixture.vector = &cts128_vectors[idx];
    EXECUTE_TEST(execute_cts128, teardown_cts128);
    EXECUTE_TEST_NO_TEARDOWN(execute_cts128);
}

static int drive_cts128_nist_tests(int idx)
static int test_cts128_nist(int idx)
{
    SETUP_TEST_FIXTURE(CTS128_FIXTURE, setup_cts128);
    fixture.transform_output = transform_output_nist;
    fixture.encrypt_block = CRYPTO_nistcts128_encrypt_block;
    fixture.encrypt = CRYPTO_nistcts128_encrypt;
    fixture.decrypt_block = CRYPTO_nistcts128_decrypt_block;
    fixture.decrypt = CRYPTO_nistcts128_decrypt;
    fixture.case_name = "cts128_nist";
    fixture.num = idx;
    fixture.encrypt_key_schedule = cts128_encrypt_key_schedule();
    fixture.decrypt_key_schedule = cts128_decrypt_key_schedule();
    fixture.input = cts128_test_input;
    fixture.iv.size = sizeof(cts128_test_iv);
    fixture.iv.data = cts128_test_iv;
    fixture.vector = &cts128_vectors[idx];
    EXECUTE_TEST(execute_cts128_nist, teardown_cts128);
    EXECUTE_TEST_NO_TEARDOWN(execute_cts128);
}

/**********************************************************************
 *
 * Test of gcm128
 *
 ***/

/* Test Case 1 */
static const u8 K1[16], P1[] = { 0 }, A1[] = { 0 }, IV1[12], C1[] = { 0 };
static const u8 T1[] = {
@@ -1032,23 +864,104 @@ static struct gcm128_data {
    GCM128_TEST_VECTOR(20)
};

static int drive_gcm128_tests(int idx)
static int test_gcm128(int idx)
{
    SETUP_TEST_FIXTURE(GCM128_FIXTURE, setup_gcm128);
    fixture.num = idx;
    fixture.K.size = gcm128_vectors[idx].K.size;
    fixture.K.data = fixture.K.size == 1 ? NULL : gcm128_vectors[idx].K.data;
    fixture.IV.size = gcm128_vectors[idx].IV.size;
    fixture.IV.data = fixture.IV.size == 1 ? NULL : gcm128_vectors[idx].IV.data;
    fixture.A.size = gcm128_vectors[idx].A.size;
    fixture.A.data = fixture.A.size == 1 ? NULL : gcm128_vectors[idx].A.data;
    fixture.P.size = gcm128_vectors[idx].P.size;
    fixture.P.data = fixture.P.size == 1 ? NULL : gcm128_vectors[idx].P.data;
    fixture.C.size = gcm128_vectors[idx].C.size;
    fixture.C.data = fixture.C.size == 1 ? NULL : gcm128_vectors[idx].C.data;
    fixture.T.size = gcm128_vectors[idx].T.size;
    fixture.T.data = fixture.T.size == 1 ? NULL : gcm128_vectors[idx].T.data;
    EXECUTE_TEST(execute_gcm128, teardown_gcm128);
    unsigned char out[512];
    SIZED_DATA K = gcm128_vectors[idx].K;
    SIZED_DATA IV = gcm128_vectors[idx].IV;
    SIZED_DATA A = gcm128_vectors[idx].A;
    SIZED_DATA P = gcm128_vectors[idx].P;
    SIZED_DATA C = gcm128_vectors[idx].C;
    SIZED_DATA T = gcm128_vectors[idx].T;
    GCM128_CONTEXT ctx;
    AES_KEY key;
    int err = 0;

    /* Size 1 inputs are special-cased to signal NULL. */
    if (A.size == 1)
        A.data = NULL;
    if (P.size == 1)
        P.data = NULL;
    if (C.size == 1)
        C.data = NULL;

    AES_set_encrypt_key(K.data, K.size * 8, &key);

    CRYPTO_gcm128_init(&ctx, &key, (block128_f)AES_encrypt);
    CRYPTO_gcm128_setiv(&ctx, IV.data, IV.size);
    memset(out, 0, P.size);
    if (A.data)
        CRYPTO_gcm128_aad(&ctx, A.data, A.size);
    if (P.data)
        CRYPTO_gcm128_encrypt( &ctx, P.data, out, P.size);
    if (CRYPTO_gcm128_finish(&ctx, T.data, 16)
        || (C.data && memcmp(out, C.data, P.size)))
        err++, fprintf(stderr, "encrypt test#%d failed.\n", idx);

    CRYPTO_gcm128_setiv(&ctx, IV.data, IV.size);
    memset(out, 0, P.size);
    if (A.data)
        CRYPTO_gcm128_aad(&ctx, A.data, A.size);
    if (C.data)
        CRYPTO_gcm128_decrypt(&ctx, C.data, out, P.size);
    if (CRYPTO_gcm128_finish(&ctx, T.data, 16)
        || (P.data && memcmp(out, P.data, P.size)))
        err++, fprintf(stderr, "decrypt test#%d failed.\n", idx);

    return err == 0;
}

static void benchmark_gcm128(const unsigned char *K, size_t Klen,
                             const unsigned char *IV, size_t IVlen)
{
#ifdef OPENSSL_CPUID_OBJ
    GCM128_CONTEXT ctx;
    AES_KEY key;
    size_t start, gcm_t, ctr_t, OPENSSL_rdtsc();
    union {
        u64 u;
        u8 c[1024];
    } buf;

    AES_set_encrypt_key(K, Klen * 8, &key);
    CRYPTO_gcm128_init(&ctx, &key, (block128_f) AES_encrypt);
    CRYPTO_gcm128_setiv(&ctx, IV, IVlen);

    CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf));
    start = OPENSSL_rdtsc();
    CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf));
    gcm_t = OPENSSL_rdtsc() - start;

    CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf),
                          &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres,
                          (block128_f) AES_encrypt);
    start = OPENSSL_rdtsc();
    CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf),
                          &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres,
                          (block128_f) AES_encrypt);
    ctr_t = OPENSSL_rdtsc() - start;

    printf("%.2f-%.2f=%.2f\n",
           gcm_t / (double)sizeof(buf),
           ctr_t / (double)sizeof(buf),
           (gcm_t - ctr_t) / (double)sizeof(buf));
# ifdef GHASH
    {
        void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
                             const u8 *inp, size_t len) = ctx.ghash;

        GHASH((&ctx), buf.c, sizeof(buf));
        start = OPENSSL_rdtsc();
        for (i = 0; i < 100; ++i)
            GHASH((&ctx), buf.c, sizeof(buf));
        gcm_t = OPENSSL_rdtsc() - start;
        printf("%.2f\n", gcm_t / (double)sizeof(buf) / (double)i);
    }
# endif
#else
    fprintf(stderr,
            "Benchmarking of modes isn't available on this platform\n");
#endif
}

int main(int argc, char **argv)
@@ -1064,9 +977,9 @@ int main(int argc, char **argv)
            goto help;
    }

    ADD_ALL_TESTS(drive_cts128_tests, OSSL_NELEM(cts128_vectors));
    ADD_ALL_TESTS(drive_cts128_nist_tests, OSSL_NELEM(cts128_vectors));
    ADD_ALL_TESTS(drive_gcm128_tests, OSSL_NELEM(gcm128_vectors));
    ADD_ALL_TESTS(test_cts128, OSSL_NELEM(cts128_vectors));
    ADD_ALL_TESTS(test_cts128_nist, OSSL_NELEM(cts128_vectors));
    ADD_ALL_TESTS(test_gcm128, OSSL_NELEM(gcm128_vectors));

    result = run_tests(argv[0]);

+83 −115

File changed.

Preview size limit exceeded, changes collapsed.

+6 −32

File changed.

Preview size limit exceeded, changes collapsed.

Loading