summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorVeronika Hanulíková <vhanulik@redhat.com>2023-07-13 17:07:00 +0200
committerDmitry Belyavskiy <beldmit@gmail.com>2023-08-30 21:53:08 +0200
commitd57d0b818935c20a7b468c0e717773ea8a3373e6 (patch)
treebd8c8d72310fffbdb2549523aa8f2e236d12bda9 /test
parent84364b9dc693a30fa55c22e684b45978a5bcc77b (diff)
Add option for in-place cipher testing in evp_test
The command line option enables setting in-place data processing for cipher testing in `evp_test`. The `both` option argument runs both - in-place and non-in-place testing. Reviewed-by: Tim Hudson <tjh@openssl.org> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> (Merged from https://github.com/openssl/openssl/pull/21546)
Diffstat (limited to 'test')
-rw-r--r--test/evp_test.c144
1 files changed, 87 insertions, 57 deletions
diff --git a/test/evp_test.c b/test/evp_test.c
index 19efa95901..0a33ed3ba8 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -72,6 +72,7 @@ typedef enum OPTION_choice {
OPT_ERR = -1,
OPT_EOF = 0,
OPT_CONFIG_FILE,
+ OPT_IN_PLACE,
OPT_TEST_ENUM
} OPTION_CHOICE;
@@ -111,6 +112,18 @@ static int memory_err_compare(EVP_TEST *t, const char *err,
return r;
}
+/* Option specific for evp test */
+static int process_mode_in_place;
+
+static int evp_test_process_mode(char *mode)
+{
+ if (strcmp(mode, "in_place") == 0)
+ return 1;
+ else if (strcmp(mode, "both") == 0)
+ return 0;
+ return -1;
+}
+
/*
* Structure used to hold a list of blocks of memory to test
* calls to "update" like functions.
@@ -713,8 +726,8 @@ static int cipher_test_parse(EVP_TEST *t, const char *keyword,
return 0;
}
-static int cipher_test_enc(EVP_TEST *t, int enc,
- size_t out_misalign, size_t inp_misalign, int frag)
+static int cipher_test_enc(EVP_TEST *t, int enc, size_t out_misalign,
+ size_t inp_misalign, int frag, int in_place)
{
CIPHER_DATA *expected = t->data;
unsigned char *in, *expected_out, *tmp = NULL;
@@ -740,7 +753,7 @@ static int cipher_test_enc(EVP_TEST *t, int enc,
expected_out = expected->plaintext;
out_len = expected->plaintext_len;
}
- if (inp_misalign == (size_t)-1) {
+ if (in_place == 1) {
/* Exercise in-place encryption */
tmp = OPENSSL_malloc(out_misalign + in_len + 2 * EVP_MAX_BLOCK_LENGTH);
if (!tmp)
@@ -1053,10 +1066,27 @@ static int cipher_test_enc(EVP_TEST *t, int enc,
return ok;
}
+/*
+ * XTS, SIV, CCM, stitched ciphers and Wrap modes have special
+ * requirements about input lengths so we don't fragment for those
+ */
+static int cipher_test_valid_fragmentation(CIPHER_DATA *cdat)
+{
+ return (cdat->aead == EVP_CIPH_CCM_MODE
+ || cdat->aead == EVP_CIPH_CBC_MODE
+ || (cdat->aead == -1
+ && EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_STREAM_CIPHER)
+ || ((EVP_CIPHER_get_flags(cdat->cipher) & EVP_CIPH_FLAG_CTS) != 0)
+ || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_SIV_MODE
+ || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_GCM_SIV_MODE
+ || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_XTS_MODE
+ || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_WRAP_MODE) ? 0 : 1;
+}
+
static int cipher_test_run(EVP_TEST *t)
{
CIPHER_DATA *cdat = t->data;
- int rv, frag = 0;
+ int rv, frag, fragmax, in_place;
size_t out_misalign, inp_misalign;
if (!cdat->key) {
@@ -1074,63 +1104,57 @@ static int cipher_test_run(EVP_TEST *t)
t->err = "NO_TAG";
return 0;
}
- for (out_misalign = 0; out_misalign <= 1;) {
+
+ fragmax = (cipher_test_valid_fragmentation(cdat) == 0) ? 0 : 1;
+ for (in_place = 1; in_place >= 0; in_place--) {
static char aux_err[64];
+
t->aux_err = aux_err;
- for (inp_misalign = (size_t)-1; inp_misalign != 2; inp_misalign++) {
- if (inp_misalign == (size_t)-1) {
- /* kludge: inp_misalign == -1 means "exercise in-place" */
- BIO_snprintf(aux_err, sizeof(aux_err),
- "%s in-place, %sfragmented",
- out_misalign ? "misaligned" : "aligned",
- frag ? "" : "not ");
- } else {
- BIO_snprintf(aux_err, sizeof(aux_err),
- "%s output and %s input, %sfragmented",
- out_misalign ? "misaligned" : "aligned",
- inp_misalign ? "misaligned" : "aligned",
- frag ? "" : "not ");
- }
- if (cdat->enc) {
- rv = cipher_test_enc(t, 1, out_misalign, inp_misalign, frag);
- /* Not fatal errors: return */
- if (rv != 1) {
- if (rv < 0)
- return 0;
- return 1;
- }
- }
- if (cdat->enc != 1) {
- rv = cipher_test_enc(t, 0, out_misalign, inp_misalign, frag);
- /* Not fatal errors: return */
- if (rv != 1) {
- if (rv < 0)
- return 0;
- return 1;
+ /* Test only in-place data processing */
+ if (process_mode_in_place == 1 && in_place == 0)
+ break;
+
+ for (frag = 0; frag <= fragmax; frag++) {
+ for (out_misalign = 0; out_misalign <= 1; out_misalign++) {
+ for (inp_misalign = 0; inp_misalign <= 1; inp_misalign++) {
+ /* Skip input misalign tests for in-place processing */
+ if (inp_misalign == 1 && in_place == 1)
+ break;
+ if (in_place == 1) {
+ BIO_snprintf(aux_err, sizeof(aux_err),
+ "%s in-place, %sfragmented",
+ out_misalign ? "misaligned" : "aligned",
+ frag ? "" : "not ");
+ } else {
+ BIO_snprintf(aux_err, sizeof(aux_err),
+ "%s output and %s input, %sfragmented",
+ out_misalign ? "misaligned" : "aligned",
+ inp_misalign ? "misaligned" : "aligned",
+ frag ? "" : "not ");
+ }
+ if (cdat->enc) {
+ rv = cipher_test_enc(t, 1, out_misalign, inp_misalign,
+ frag, in_place);
+ /* Not fatal errors: return */
+ if (rv != 1) {
+ if (rv < 0)
+ return 0;
+ return 1;
+ }
+ }
+ if (cdat->enc != 1) {
+ rv = cipher_test_enc(t, 0, out_misalign, inp_misalign,
+ frag, in_place);
+ /* Not fatal errors: return */
+ if (rv != 1) {
+ if (rv < 0)
+ return 0;
+ return 1;
+ }
+ }
}
}
}
-
- if (out_misalign == 1 && frag == 0) {
- /*
- * XTS, SIV, CCM, stitched ciphers and Wrap modes have special
- * requirements about input lengths so we don't fragment for those
- */
- if (cdat->aead == EVP_CIPH_CCM_MODE
- || cdat->aead == EVP_CIPH_CBC_MODE
- || (cdat->aead == -1
- && EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_STREAM_CIPHER)
- || ((EVP_CIPHER_get_flags(cdat->cipher) & EVP_CIPH_FLAG_CTS) != 0)
- || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_SIV_MODE
- || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_GCM_SIV_MODE
- || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_XTS_MODE
- || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_WRAP_MODE)
- break;
- out_misalign = 0;
- frag++;
- } else {
- out_misalign++;
- }
}
t->aux_err = NULL;
@@ -4070,6 +4094,8 @@ const OPTIONS *test_get_options(void)
OPT_TEST_OPTIONS_WITH_EXTRA_USAGE("[file...]\n"),
{ "config", OPT_CONFIG_FILE, '<',
"The configuration file to use for the libctx" },
+ { "process", OPT_IN_PLACE, 's',
+ "Mode for data processing by cipher tests [in_place/both], both by default"},
{ OPT_HELP_STR, 1, '-', "file\tFile to run tests on.\n" },
{ NULL }
};
@@ -4088,8 +4114,12 @@ int setup_tests(void)
case OPT_CONFIG_FILE:
config_file = opt_arg();
break;
+ case OPT_IN_PLACE:
+ if ((process_mode_in_place = evp_test_process_mode(opt_arg())) == -1)
+ return 0;
+ break;
case OPT_TEST_CASES:
- break;
+ break;
default:
case OPT_ERR:
return 0;