1/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * test_dec.c -- Benchmark decryption using aligned and non-aligned buffers.
4 */
5
6#include <assert.h>
7#include <stdint.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#ifndef WIN32
12#include <unistd.h>
13#else
14#include <getopt.h>
15#endif
16
17#include <openssl/aead.h>
18#include <openssl/rand.h>
19
20#define MAX_SIZE 1400
21
22int
23main (int argc, char **argv)
24{
25    EVP_AEAD_CTX aead_ctx;
26    int opt, n = 1, r;
27    size_t sealed_len, opened_len;
28    unsigned char key[16];
29    unsigned char data[1328];
30    unsigned char sealed_buf[63 + MAX_SIZE], *sealed = sealed_buf;
31    unsigned char opened_buf[63 + MAX_SIZE], *opened = opened_buf;
32
33    while (-1 != (opt = getopt(argc, argv, "an:")))
34    {
35        switch (opt)
36        {
37        case 'a':
38            if ((uintptr_t) sealed & (64 - 1))
39                sealed += 64 - ((uintptr_t) sealed & (64 - 1));
40            if ((uintptr_t) opened & (64 - 1))
41                opened += 64 - ((uintptr_t) opened & (64 - 1));
42            break;
43        case 'n':                   /* Number of decrypt iterations */
44            n = atoi(optarg);
45            break;
46        default:
47            exit(EXIT_FAILURE);
48        }
49    }
50
51    RAND_bytes(key, sizeof(key));
52    RAND_bytes(data, sizeof(data));
53
54    EVP_AEAD_CTX_init(&aead_ctx, EVP_aead_aes_128_gcm(), key, sizeof(key),
55                                                                    12, NULL);
56    r = EVP_AEAD_CTX_seal(&aead_ctx, sealed, &sealed_len, MAX_SIZE,
57                              key, sizeof(key), data, sizeof(data), NULL, 0);
58    if (!r)
59    {
60        fprintf(stderr, "cannot seal\n");
61        exit(EXIT_FAILURE);
62    }
63
64    printf("buffers are %saligned\n", ((uintptr_t) opened & (64 - 1)) ||
65                            ((uintptr_t) sealed & (64 - 1)) ?  "not " : "");
66
67    /* Check that decryption works first time around */
68    r = EVP_AEAD_CTX_open(&aead_ctx, opened, &opened_len, MAX_SIZE,
69                          key, sizeof(key), sealed, sealed_len, NULL, 0);
70    assert(r && opened_len == sizeof(data) &&
71                                0 == memcmp(data, opened, sizeof(data)));
72    --n;
73
74    /* Do no bother checking return value in the loop */
75    while (n-- > 0)
76    {
77        EVP_AEAD_CTX_open(&aead_ctx, opened, &opened_len, MAX_SIZE,
78                          key, sizeof(key), sealed, sealed_len, NULL, 0);
79    }
80
81    exit(EXIT_SUCCESS);
82}
83