|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
|
|
|
+ * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
|
|
|
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
|
|
*
|
|
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
|
@@ -511,6 +511,14 @@ static double sigs_results[MAX_SIG_NUM][3]; /* keygen, sign, verify */
|
|
|
#define COND(unused_cond) (run && count < INT_MAX)
|
|
|
#define COUNT(d) (count)
|
|
|
|
|
|
+#define TAG_LEN 16
|
|
|
+
|
|
|
+static unsigned int mode_op; /* AE Mode of operation */
|
|
|
+static unsigned int aead = 0; /* AEAD flag */
|
|
|
+static unsigned char aead_iv[12]; /* For AEAD modes */
|
|
|
+static unsigned char aad[EVP_AEAD_TLS1_AAD_LEN] = { 0xcc };
|
|
|
+static int aead_ivlen = sizeof(aead_iv);
|
|
|
+
|
|
|
typedef struct loopargs_st {
|
|
|
ASYNC_JOB *inprogress_job;
|
|
|
ASYNC_WAIT_CTX *wait_ctx;
|
|
@@ -519,6 +527,7 @@ typedef struct loopargs_st {
|
|
|
unsigned char *buf_malloc;
|
|
|
unsigned char *buf2_malloc;
|
|
|
unsigned char *key;
|
|
|
+ unsigned char tag[TAG_LEN];
|
|
|
size_t buflen;
|
|
|
size_t sigsize;
|
|
|
size_t encsize;
|
|
@@ -798,12 +807,8 @@ static int EVP_Update_loop(void *args)
|
|
|
unsigned char *buf = tempargs->buf;
|
|
|
EVP_CIPHER_CTX *ctx = tempargs->ctx;
|
|
|
int outl, count, rc;
|
|
|
- unsigned char faketag[16] = { 0xcc };
|
|
|
|
|
|
if (decrypt) {
|
|
|
- if (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) {
|
|
|
- (void)EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(faketag), faketag);
|
|
|
- }
|
|
|
for (count = 0; COND(c[D_EVP][testnum]); count++) {
|
|
|
rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
|
|
|
if (rc != 1) {
|
|
@@ -831,44 +836,71 @@ static int EVP_Update_loop(void *args)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
+ * To make AEAD benchmarking more relevant perform TLS-like operations,
|
|
|
+ * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
|
|
|
+ * payload length is not actually limited by 16KB...
|
|
|
* CCM does not support streaming. For the purpose of performance measurement,
|
|
|
* each message is encrypted using the same (key,iv)-pair. Do not use this
|
|
|
* code in your application.
|
|
|
*/
|
|
|
-static int EVP_Update_loop_ccm(void *args)
|
|
|
+static int EVP_Update_loop_aead_enc(void *args)
|
|
|
{
|
|
|
loopargs_t *tempargs = *(loopargs_t **) args;
|
|
|
unsigned char *buf = tempargs->buf;
|
|
|
+ unsigned char *key = tempargs->key;
|
|
|
EVP_CIPHER_CTX *ctx = tempargs->ctx;
|
|
|
- int outl, count, realcount = 0, final;
|
|
|
- unsigned char tag[12];
|
|
|
+ int outl, count, realcount = 0;
|
|
|
|
|
|
- if (decrypt) {
|
|
|
- for (count = 0; COND(c[D_EVP][testnum]); count++) {
|
|
|
- if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag),
|
|
|
- tag) > 0
|
|
|
- /* reset iv */
|
|
|
- && EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0
|
|
|
- /* counter is reset on every update */
|
|
|
- && EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0)
|
|
|
- realcount++;
|
|
|
+ for (count = 0; COND(c[D_EVP][testnum]); count++) {
|
|
|
+ /* Set length of iv (Doesn't apply to SIV mode) */
|
|
|
+ if (mode_op != EVP_CIPH_SIV_MODE) {
|
|
|
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
|
|
|
+ aead_ivlen, NULL)) {
|
|
|
+ BIO_printf(bio_err, "\nFailed to set iv length\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
}
|
|
|
- } else {
|
|
|
- for (count = 0; COND(c[D_EVP][testnum]); count++) {
|
|
|
- /* restore iv length field */
|
|
|
- if (EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]) > 0
|
|
|
- /* counter is reset on every update */
|
|
|
- && EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0)
|
|
|
- realcount++;
|
|
|
+ /* Set tag_len (Not for GCM/SIV at encryption stage) */
|
|
|
+ if (mode_op != EVP_CIPH_GCM_MODE
|
|
|
+ && mode_op != EVP_CIPH_SIV_MODE
|
|
|
+ && mode_op != EVP_CIPH_GCM_SIV_MODE) {
|
|
|
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
|
|
|
+ TAG_LEN, NULL)) {
|
|
|
+ BIO_printf(bio_err, "\nFailed to set tag length\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, aead_iv, -1)) {
|
|
|
+ BIO_printf(bio_err, "\nFailed to set key and iv\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ /* Set total length of input. Only required for CCM */
|
|
|
+ if (mode_op == EVP_CIPH_CCM_MODE) {
|
|
|
+ if (!EVP_EncryptUpdate(ctx, NULL, &outl,
|
|
|
+ NULL, lengths[testnum])) {
|
|
|
+ BIO_printf(bio_err, "\nCouldn't set input text length\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (aead) {
|
|
|
+ if (!EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad))) {
|
|
|
+ BIO_printf(bio_err, "\nCouldn't insert AAD when encrypting\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
}
|
|
|
+ if (!EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum])) {
|
|
|
+ BIO_printf(bio_err, "\nFailed to encrypt the data\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ if (EVP_EncryptFinal_ex(ctx, buf, &outl))
|
|
|
+ realcount++;
|
|
|
}
|
|
|
- if (decrypt)
|
|
|
- final = EVP_DecryptFinal_ex(ctx, buf, &outl);
|
|
|
- else
|
|
|
- final = EVP_EncryptFinal_ex(ctx, buf, &outl);
|
|
|
-
|
|
|
- if (final == 0)
|
|
|
- BIO_printf(bio_err, "Error finalizing ccm loop\n");
|
|
|
return realcount;
|
|
|
}
|
|
|
|
|
@@ -876,34 +908,87 @@ static int EVP_Update_loop_ccm(void *args)
|
|
|
* To make AEAD benchmarking more relevant perform TLS-like operations,
|
|
|
* 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
|
|
|
* payload length is not actually limited by 16KB...
|
|
|
+ * CCM does not support streaming. For the purpose of performance measurement,
|
|
|
+ * each message is decrypted using the same (key,iv)-pair. Do not use this
|
|
|
+ * code in your application.
|
|
|
+ * For decryption, we will use buf2 to preserve the input text in buf.
|
|
|
*/
|
|
|
-static int EVP_Update_loop_aead(void *args)
|
|
|
+static int EVP_Update_loop_aead_dec(void *args)
|
|
|
{
|
|
|
loopargs_t *tempargs = *(loopargs_t **) args;
|
|
|
unsigned char *buf = tempargs->buf;
|
|
|
+ unsigned char *outbuf = tempargs->buf2;
|
|
|
+ unsigned char *key = tempargs->key;
|
|
|
+ unsigned char tag[TAG_LEN];
|
|
|
EVP_CIPHER_CTX *ctx = tempargs->ctx;
|
|
|
int outl, count, realcount = 0;
|
|
|
- unsigned char aad[13] = { 0xcc };
|
|
|
- unsigned char faketag[16] = { 0xcc };
|
|
|
|
|
|
- if (decrypt) {
|
|
|
- for (count = 0; COND(c[D_EVP][testnum]); count++) {
|
|
|
- if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0
|
|
|
- && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
|
|
|
- sizeof(faketag), faketag) > 0
|
|
|
- && EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)) > 0
|
|
|
- && EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0
|
|
|
- && EVP_DecryptFinal_ex(ctx, buf + outl, &outl) > 0)
|
|
|
- realcount++;
|
|
|
+ for (count = 0; COND(c[D_EVP][testnum]); count++) {
|
|
|
+ /* Set the length of iv (Doesn't apply to SIV mode) */
|
|
|
+ if (mode_op != EVP_CIPH_SIV_MODE) {
|
|
|
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
|
|
|
+ aead_ivlen, NULL)) {
|
|
|
+ BIO_printf(bio_err, "\nFailed to set iv length\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
}
|
|
|
- } else {
|
|
|
- for (count = 0; COND(c[D_EVP][testnum]); count++) {
|
|
|
- if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0
|
|
|
- && EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)) > 0
|
|
|
- && EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0
|
|
|
- && EVP_EncryptFinal_ex(ctx, buf + outl, &outl) > 0)
|
|
|
- realcount++;
|
|
|
+
|
|
|
+ /* Set the tag length (Doesn't apply to SIV mode) */
|
|
|
+ if (mode_op != EVP_CIPH_SIV_MODE
|
|
|
+ && mode_op != EVP_CIPH_GCM_MODE
|
|
|
+ && mode_op != EVP_CIPH_GCM_SIV_MODE) {
|
|
|
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
|
|
|
+ TAG_LEN, NULL)) {
|
|
|
+ BIO_printf(bio_err, "\nFailed to set tag length\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, aead_iv, -1)) {
|
|
|
+ BIO_printf(bio_err, "\nFailed to set key and iv\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
}
|
|
|
+ /* Set iv before decryption (Doesn't apply to SIV mode) */
|
|
|
+ if (mode_op != EVP_CIPH_SIV_MODE) {
|
|
|
+ if (!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, aead_iv)) {
|
|
|
+ BIO_printf(bio_err, "\nFailed to set iv\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ memcpy(tag, tempargs->tag, TAG_LEN);
|
|
|
+
|
|
|
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
|
|
|
+ TAG_LEN, tag)) {
|
|
|
+ BIO_printf(bio_err, "\nFailed to set tag\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ /* Set the total length of cipher text. Only required for CCM */
|
|
|
+ if (mode_op == EVP_CIPH_CCM_MODE) {
|
|
|
+ if (!EVP_DecryptUpdate(ctx, NULL, &outl,
|
|
|
+ NULL, lengths[testnum])) {
|
|
|
+ BIO_printf(bio_err, "\nCouldn't set cipher text length\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (aead) {
|
|
|
+ if (!EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad))) {
|
|
|
+ BIO_printf(bio_err, "\nCouldn't insert AAD when decrypting\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!EVP_DecryptUpdate(ctx, outbuf, &outl, buf, lengths[testnum])) {
|
|
|
+ BIO_printf(bio_err, "\nFailed to decrypt the data\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ if (EVP_DecryptFinal_ex(ctx, outbuf, &outl))
|
|
|
+ realcount++;
|
|
|
}
|
|
|
return realcount;
|
|
|
}
|
|
@@ -1366,6 +1451,24 @@ static int SIG_verify_loop(void *args)
|
|
|
return count;
|
|
|
}
|
|
|
|
|
|
+static int check_block_size(EVP_CIPHER_CTX *ctx, int length)
|
|
|
+{
|
|
|
+ const EVP_CIPHER *ciph = EVP_CIPHER_CTX_get0_cipher(ctx);
|
|
|
+ int blocksize = EVP_CIPHER_CTX_get_block_size(ctx);
|
|
|
+
|
|
|
+ if (ciph == NULL || blocksize <= 0) {
|
|
|
+ BIO_printf(bio_err, "\nInvalid cipher!\n");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if (length % blocksize != 0) {
|
|
|
+ BIO_printf(bio_err,
|
|
|
+ "\nRequested encryption length not a multiple of block size for %s!\n",
|
|
|
+ EVP_CIPHER_get0_name(ciph));
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
static int run_benchmark(int async_jobs,
|
|
|
int (*loop_function) (void *), loopargs_t *loopargs)
|
|
|
{
|
|
@@ -1706,14 +1809,14 @@ int speed_main(int argc, char **argv)
|
|
|
OPTION_CHOICE o;
|
|
|
int async_init = 0, multiblock = 0, pr_header = 0;
|
|
|
uint8_t doit[ALGOR_NUM] = { 0 };
|
|
|
- int ret = 1, misalign = 0, lengths_single = 0, aead = 0;
|
|
|
+ int ret = 1, misalign = 0, lengths_single = 0;
|
|
|
STACK_OF(EVP_KEM) *kem_stack = NULL;
|
|
|
STACK_OF(EVP_SIGNATURE) *sig_stack = NULL;
|
|
|
long count = 0;
|
|
|
unsigned int size_num = SIZE_NUM;
|
|
|
unsigned int i, k, loopargs_len = 0, async_jobs = 0;
|
|
|
unsigned int idx;
|
|
|
- int keylen;
|
|
|
+ int keylen = 0;
|
|
|
int buflen;
|
|
|
size_t declen;
|
|
|
BIGNUM *bn = NULL;
|
|
@@ -2523,15 +2626,14 @@ int speed_main(int argc, char **argv)
|
|
|
if (doit[D_HMAC]) {
|
|
|
static const char hmac_key[] = "This is a key...";
|
|
|
int len = strlen(hmac_key);
|
|
|
+ size_t hmac_name_len = sizeof("hmac()") + strlen(evp_mac_mdname);
|
|
|
OSSL_PARAM params[3];
|
|
|
|
|
|
mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq());
|
|
|
if (mac == NULL || evp_mac_mdname == NULL)
|
|
|
goto end;
|
|
|
-
|
|
|
- evp_hmac_name = app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname),
|
|
|
- "HMAC name");
|
|
|
- sprintf(evp_hmac_name, "hmac(%s)", evp_mac_mdname);
|
|
|
+ evp_hmac_name = app_malloc(hmac_name_len, "HMAC name");
|
|
|
+ BIO_snprintf(evp_hmac_name, hmac_name_len, "hmac(%s)", evp_mac_mdname);
|
|
|
names[D_HMAC] = evp_hmac_name;
|
|
|
|
|
|
params[0] =
|
|
@@ -2575,6 +2677,8 @@ skip_hmac:
|
|
|
}
|
|
|
algindex = D_CBC_DES;
|
|
|
for (testnum = 0; st && testnum < size_num; testnum++) {
|
|
|
+ if (!check_block_size(loopargs[0].ctx, lengths[testnum]))
|
|
|
+ break;
|
|
|
print_message(names[D_CBC_DES], lengths[testnum], seconds.sym);
|
|
|
Time_F(START);
|
|
|
count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
|
|
@@ -2595,6 +2699,8 @@ skip_hmac:
|
|
|
}
|
|
|
algindex = D_EDE3_DES;
|
|
|
for (testnum = 0; st && testnum < size_num; testnum++) {
|
|
|
+ if (!check_block_size(loopargs[0].ctx, lengths[testnum]))
|
|
|
+ break;
|
|
|
print_message(names[D_EDE3_DES], lengths[testnum], seconds.sym);
|
|
|
Time_F(START);
|
|
|
count =
|
|
@@ -2619,6 +2725,8 @@ skip_hmac:
|
|
|
}
|
|
|
|
|
|
for (testnum = 0; st && testnum < size_num; testnum++) {
|
|
|
+ if (!check_block_size(loopargs[0].ctx, lengths[testnum]))
|
|
|
+ break;
|
|
|
print_message(names[algindex], lengths[testnum], seconds.sym);
|
|
|
Time_F(START);
|
|
|
count =
|
|
@@ -2644,6 +2752,8 @@ skip_hmac:
|
|
|
}
|
|
|
|
|
|
for (testnum = 0; st && testnum < size_num; testnum++) {
|
|
|
+ if (!check_block_size(loopargs[0].ctx, lengths[testnum]))
|
|
|
+ break;
|
|
|
print_message(names[algindex], lengths[testnum], seconds.sym);
|
|
|
Time_F(START);
|
|
|
count =
|
|
@@ -2668,6 +2778,8 @@ skip_hmac:
|
|
|
}
|
|
|
|
|
|
for (testnum = 0; st && testnum < size_num; testnum++) {
|
|
|
+ if (!check_block_size(loopargs[0].ctx, lengths[testnum]))
|
|
|
+ break;
|
|
|
print_message(names[algindex], lengths[testnum], seconds.sym);
|
|
|
Time_F(START);
|
|
|
count =
|
|
@@ -2727,12 +2839,20 @@ skip_hmac:
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /*-
|
|
|
+ * There are three scenarios for D_EVP:
|
|
|
+ * 1- Using authenticated encryption (AE) e.g. CCM, GCM, OCB etc.
|
|
|
+ * 2- Using AE + associated data (AD) i.e. AEAD using CCM, GCM, OCB etc.
|
|
|
+ * 3- Not using AE or AD e.g. ECB, CBC, CFB etc.
|
|
|
+ */
|
|
|
if (doit[D_EVP]) {
|
|
|
if (evp_cipher != NULL) {
|
|
|
- int (*loopfunc) (void *) = EVP_Update_loop;
|
|
|
+ int (*loopfunc) (void *);
|
|
|
+ int outlen = 0;
|
|
|
+ unsigned int ae_mode = 0;
|
|
|
|
|
|
- if (multiblock && (EVP_CIPHER_get_flags(evp_cipher) &
|
|
|
- EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
|
|
|
+ if (multiblock && (EVP_CIPHER_get_flags(evp_cipher)
|
|
|
+ & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
|
|
|
multiblock_speed(evp_cipher, lengths_single, &seconds);
|
|
|
ret = 0;
|
|
|
goto end;
|
|
@@ -2740,16 +2860,27 @@ skip_hmac:
|
|
|
|
|
|
names[D_EVP] = EVP_CIPHER_get0_name(evp_cipher);
|
|
|
|
|
|
- if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_CCM_MODE) {
|
|
|
- loopfunc = EVP_Update_loop_ccm;
|
|
|
- } else if (aead && (EVP_CIPHER_get_flags(evp_cipher) &
|
|
|
- EVP_CIPH_FLAG_AEAD_CIPHER)) {
|
|
|
- loopfunc = EVP_Update_loop_aead;
|
|
|
+ mode_op = EVP_CIPHER_get_mode(evp_cipher);
|
|
|
+
|
|
|
+ if (aead) {
|
|
|
if (lengths == lengths_list) {
|
|
|
lengths = aead_lengths_list;
|
|
|
size_num = OSSL_NELEM(aead_lengths_list);
|
|
|
}
|
|
|
}
|
|
|
+ if (mode_op == EVP_CIPH_GCM_MODE
|
|
|
+ || mode_op == EVP_CIPH_CCM_MODE
|
|
|
+ || mode_op == EVP_CIPH_OCB_MODE
|
|
|
+ || mode_op == EVP_CIPH_SIV_MODE
|
|
|
+ || mode_op == EVP_CIPH_GCM_SIV_MODE) {
|
|
|
+ ae_mode = 1;
|
|
|
+ if (decrypt)
|
|
|
+ loopfunc = EVP_Update_loop_aead_dec;
|
|
|
+ else
|
|
|
+ loopfunc = EVP_Update_loop_aead_enc;
|
|
|
+ } else {
|
|
|
+ loopfunc = EVP_Update_loop;
|
|
|
+ }
|
|
|
|
|
|
for (testnum = 0; testnum < size_num; testnum++) {
|
|
|
print_message(names[D_EVP], lengths[testnum], seconds.sym);
|
|
@@ -2760,38 +2891,147 @@ skip_hmac:
|
|
|
BIO_printf(bio_err, "\nEVP_CIPHER_CTX_new failure\n");
|
|
|
exit(1);
|
|
|
}
|
|
|
- if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher, NULL,
|
|
|
- NULL, iv, decrypt ? 0 : 1)) {
|
|
|
- BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
|
|
|
+
|
|
|
+ /*
|
|
|
+ * For AE modes, we must first encrypt the data to get
|
|
|
+ * a valid tag that enables us to decrypt. If we don't
|
|
|
+ * encrypt first, we won't have a valid tag that enables
|
|
|
+ * authenticity and hence decryption will fail.
|
|
|
+ */
|
|
|
+ if (!EVP_CipherInit_ex(loopargs[k].ctx,
|
|
|
+ evp_cipher, NULL, NULL, NULL,
|
|
|
+ ae_mode ? 1 : !decrypt)) {
|
|
|
+ BIO_printf(bio_err, "\nCouldn't init the context\n");
|
|
|
ERR_print_errors(bio_err);
|
|
|
exit(1);
|
|
|
}
|
|
|
|
|
|
+ /* Padding isn't needed */
|
|
|
EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
|
|
|
|
|
|
keylen = EVP_CIPHER_CTX_get_key_length(loopargs[k].ctx);
|
|
|
loopargs[k].key = app_malloc(keylen, "evp_cipher key");
|
|
|
EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key);
|
|
|
- if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
|
|
|
- loopargs[k].key, NULL, -1)) {
|
|
|
- BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
|
|
|
- ERR_print_errors(bio_err);
|
|
|
- exit(1);
|
|
|
- }
|
|
|
- OPENSSL_clear_free(loopargs[k].key, keylen);
|
|
|
|
|
|
- /* GCM-SIV/SIV mode only allows for a single Update operation */
|
|
|
- if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_SIV_MODE
|
|
|
- || EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_GCM_SIV_MODE)
|
|
|
- (void)EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
|
|
|
- EVP_CTRL_SET_SPEED, 1, NULL);
|
|
|
+ if (!ae_mode) {
|
|
|
+ if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
|
|
|
+ loopargs[k].key, iv, -1)) {
|
|
|
+ BIO_printf(bio_err, "\nFailed to set the key\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ } else if (mode_op == EVP_CIPH_SIV_MODE
|
|
|
+ || mode_op == EVP_CIPH_GCM_SIV_MODE) {
|
|
|
+ EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
|
|
|
+ EVP_CTRL_SET_SPEED, 1, NULL);
|
|
|
+ }
|
|
|
+ if (ae_mode && decrypt) {
|
|
|
+ /* Set length of iv (Doesn't apply to SIV mode) */
|
|
|
+ if (mode_op != EVP_CIPH_SIV_MODE) {
|
|
|
+ if (!EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
|
|
|
+ EVP_CTRL_AEAD_SET_IVLEN,
|
|
|
+ aead_ivlen, NULL)) {
|
|
|
+ BIO_printf(bio_err, "\nFailed to set iv length\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /* Set tag_len (Not for GCM/SIV at encryption stage) */
|
|
|
+ if (mode_op != EVP_CIPH_GCM_MODE
|
|
|
+ && mode_op != EVP_CIPH_SIV_MODE
|
|
|
+ && mode_op != EVP_CIPH_GCM_SIV_MODE) {
|
|
|
+ if (!EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
|
|
|
+ EVP_CTRL_AEAD_SET_TAG,
|
|
|
+ TAG_LEN, NULL)) {
|
|
|
+ BIO_printf(bio_err,
|
|
|
+ "\nFailed to set tag length\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
|
|
|
+ loopargs[k].key, aead_iv, -1)) {
|
|
|
+ BIO_printf(bio_err, "\nFailed to set the key\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ /* Set total length of input. Only required for CCM */
|
|
|
+ if (mode_op == EVP_CIPH_CCM_MODE) {
|
|
|
+ if (!EVP_EncryptUpdate(loopargs[k].ctx, NULL,
|
|
|
+ &outlen, NULL,
|
|
|
+ lengths[testnum])) {
|
|
|
+ BIO_printf(bio_err,
|
|
|
+ "\nCouldn't set input text length\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (aead) {
|
|
|
+ if (!EVP_EncryptUpdate(loopargs[k].ctx, NULL,
|
|
|
+ &outlen, aad, sizeof(aad))) {
|
|
|
+ BIO_printf(bio_err,
|
|
|
+ "\nCouldn't insert AAD when encrypting\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!EVP_EncryptUpdate(loopargs[k].ctx, loopargs[k].buf,
|
|
|
+ &outlen, loopargs[k].buf,
|
|
|
+ lengths[testnum])) {
|
|
|
+ BIO_printf(bio_err,
|
|
|
+ "\nFailed to to encrypt the data\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!EVP_EncryptFinal_ex(loopargs[k].ctx,
|
|
|
+ loopargs[k].buf, &outlen)) {
|
|
|
+ BIO_printf(bio_err,
|
|
|
+ "\nFailed finalize the encryption\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
|
|
|
+ EVP_CTRL_AEAD_GET_TAG,
|
|
|
+ TAG_LEN, &loopargs[k].tag)) {
|
|
|
+ BIO_printf(bio_err, "\nFailed to get the tag\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ EVP_CIPHER_CTX_free(loopargs[k].ctx);
|
|
|
+ loopargs[k].ctx = EVP_CIPHER_CTX_new();
|
|
|
+ if (loopargs[k].ctx == NULL) {
|
|
|
+ BIO_printf(bio_err,
|
|
|
+ "\nEVP_CIPHER_CTX_new failure\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher,
|
|
|
+ NULL, NULL, NULL, 0)) {
|
|
|
+ BIO_printf(bio_err,
|
|
|
+ "\nFailed initializing the context\n");
|
|
|
+ ERR_print_errors(bio_err);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
|
|
|
+
|
|
|
+ /* GCM-SIV/SIV only allows for one Update operation */
|
|
|
+ if (mode_op == EVP_CIPH_SIV_MODE
|
|
|
+ || mode_op == EVP_CIPH_GCM_SIV_MODE)
|
|
|
+ EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
|
|
|
+ EVP_CTRL_SET_SPEED, 1, NULL);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
Time_F(START);
|
|
|
count = run_benchmark(async_jobs, loopfunc, loopargs);
|
|
|
d = Time_F(STOP);
|
|
|
- for (k = 0; k < loopargs_len; k++)
|
|
|
+ for (k = 0; k < loopargs_len; k++) {
|
|
|
+ OPENSSL_clear_free(loopargs[k].key, keylen);
|
|
|
EVP_CIPHER_CTX_free(loopargs[k].ctx);
|
|
|
+ }
|
|
|
print_result(D_EVP, testnum, count, d);
|
|
|
}
|
|
|
} else if (evp_md_name != NULL) {
|
|
@@ -2810,6 +3050,7 @@ skip_hmac:
|
|
|
}
|
|
|
|
|
|
if (doit[D_EVP_CMAC]) {
|
|
|
+ size_t len = sizeof("cmac()") + strlen(evp_mac_ciphername);
|
|
|
OSSL_PARAM params[3];
|
|
|
EVP_CIPHER *cipher = NULL;
|
|
|
|
|
@@ -2825,9 +3066,8 @@ skip_hmac:
|
|
|
BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n");
|
|
|
goto end;
|
|
|
}
|
|
|
- evp_cmac_name = app_malloc(sizeof("cmac()")
|
|
|
- + strlen(evp_mac_ciphername), "CMAC name");
|
|
|
- sprintf(evp_cmac_name, "cmac(%s)", evp_mac_ciphername);
|
|
|
+ evp_cmac_name = app_malloc(len, "CMAC name");
|
|
|
+ BIO_snprintf(evp_cmac_name, len, "cmac(%s)", evp_mac_ciphername);
|
|
|
names[D_EVP_CMAC] = evp_cmac_name;
|
|
|
|
|
|
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
|
|
@@ -4728,7 +4968,6 @@ static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
|
|
|
print_message(alg_name, mblengths[j], seconds->sym);
|
|
|
Time_F(START);
|
|
|
for (count = 0; run && count < INT_MAX; count++) {
|
|
|
- unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
|
|
|
EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
|
|
|
size_t len = mblengths[j];
|
|
|
int packlen;
|