/*
- * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
-#include "internal/e_os.h" /* strcasecmp and strncasecmp */
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/err.h>
}
if (expected->iv) {
if (expected->aead) {
- if (!EVP_CIPHER_CTX_ctrl(ctx_base, EVP_CTRL_AEAD_SET_IVLEN,
- expected->iv_len, 0)) {
+ if (EVP_CIPHER_CTX_ctrl(ctx_base, EVP_CTRL_AEAD_SET_IVLEN,
+ expected->iv_len, 0) <= 0) {
t->err = "INVALID_IV_LENGTH";
goto err;
}
tag = expected->tag;
}
if (tag || expected->aead != EVP_CIPH_GCM_MODE) {
- if (!EVP_CIPHER_CTX_ctrl(ctx_base, EVP_CTRL_AEAD_SET_TAG,
- expected->tag_len, tag))
+ if (EVP_CIPHER_CTX_ctrl(ctx_base, EVP_CTRL_AEAD_SET_TAG,
+ expected->tag_len, tag) <= 0)
goto err;
}
}
if (expected->rounds > 0) {
int rounds = (int)expected->rounds;
- if (!EVP_CIPHER_CTX_ctrl(ctx_base, EVP_CTRL_SET_RC5_ROUNDS, rounds, NULL)) {
+ if (EVP_CIPHER_CTX_ctrl(ctx_base, EVP_CTRL_SET_RC5_ROUNDS, rounds, NULL) <= 0) {
t->err = "INVALID_ROUNDS";
goto err;
}
if (expected->key_bits > 0) {
int bits = (int)expected->key_bits;
- if (!EVP_CIPHER_CTX_ctrl(ctx_base, EVP_CTRL_SET_RC2_KEY_BITS, bits, NULL)) {
+ if (EVP_CIPHER_CTX_ctrl(ctx_base, EVP_CTRL_SET_RC2_KEY_BITS, bits, NULL) <= 0) {
t->err = "INVALID KEY BITS";
goto err;
}
ERR_pop_to_mark();
if (expected->mac_key != NULL
- && !EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
+ && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
(int)expected->mac_key_len,
- (void *)expected->mac_key)) {
+ (void *)expected->mac_key) <= 0) {
t->err = "SET_MAC_KEY_ERROR";
goto err;
}
OPENSSL_free(tls_aad);
} else if (!enc && (expected->aead == EVP_CIPH_OCB_MODE
|| expected->tag_late)) {
- if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
- expected->tag_len, expected->tag)) {
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
+ expected->tag_len, expected->tag) <= 0) {
t->err = "TAG_SET_ERROR";
goto err;
}
t->err = "TAG_LENGTH_INTERNAL_ERROR";
goto err;
}
- if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG,
- expected->tag_len, rtag)) {
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG,
+ expected->tag_len, rtag) <= 0) {
t->err = "TAG_RETRIEVE_ERROR";
goto err;
}
&& 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;
size_t salt_len;
/* XOF mode? */
int xof;
+ /* Reinitialization fails */
+ int no_reinit;
/* Collection of controls */
STACK_OF(OPENSSL_STRING) *controls;
/* Output size */
return 0;
mdat->type = type;
- mdat->mac_name = OPENSSL_strdup(alg);
+ if (!TEST_ptr(mdat->mac_name = OPENSSL_strdup(alg))) {
+ OPENSSL_free(mdat);
+ return 0;
+ }
+
mdat->mac = mac;
- mdat->controls = sk_OPENSSL_STRING_new_null();
+ if (!TEST_ptr(mdat->controls = sk_OPENSSL_STRING_new_null())) {
+ OPENSSL_free(mdat->mac_name);
+ OPENSSL_free(mdat);
+ return 0;
+ }
+
mdat->output_size = mdat->block_size = -1;
t->data = mdat;
return 1;
return parse_bin(value, &mdata->salt, &mdata->salt_len);
if (strcmp(keyword, "Algorithm") == 0) {
mdata->alg = OPENSSL_strdup(value);
- if (!mdata->alg)
+ if (mdata->alg == NULL)
return -1;
return 1;
}
return parse_bin(value, &mdata->output, &mdata->output_len);
if (strcmp(keyword, "XOF") == 0)
return mdata->xof = 1;
- if (strcmp(keyword, "Ctrl") == 0)
- return sk_OPENSSL_STRING_push(mdata->controls,
- OPENSSL_strdup(value)) != 0;
+ if (strcmp(keyword, "NoReinit") == 0)
+ return mdata->no_reinit = 1;
+ if (strcmp(keyword, "Ctrl") == 0) {
+ char *data = OPENSSL_strdup(value);
+
+ if (data == NULL)
+ return -1;
+ return sk_OPENSSL_STRING_push(mdata->controls, data) != 0;
+ }
if (strcmp(keyword, "OutputSize") == 0) {
mdata->output_size = atoi(value);
if (mdata->output_size < 0)
const OSSL_PARAM *defined_params =
EVP_MAC_settable_ctx_params(expected->mac);
int xof;
+ int reinit = 1;
if (expected->alg == NULL)
TEST_info("Trying the EVP_MAC %s test", expected->mac_name);
expected->mac_name, expected->alg);
if (expected->alg != NULL) {
+ int skip = 0;
+
/*
* The underlying algorithm may be a cipher or a digest.
* We don't know which it is, but we can ask the MAC what it
*/
if (OSSL_PARAM_locate_const(defined_params,
OSSL_MAC_PARAM_CIPHER) != NULL) {
- params[params_n++] =
- OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
- expected->alg, 0);
+ if (is_cipher_disabled(expected->alg))
+ skip = 1;
+ else
+ params[params_n++] =
+ OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
+ expected->alg, 0);
} else if (OSSL_PARAM_locate_const(defined_params,
OSSL_MAC_PARAM_DIGEST) != NULL) {
- params[params_n++] =
- OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
- expected->alg, 0);
+ if (is_digest_disabled(expected->alg))
+ skip = 1;
+ else
+ params[params_n++] =
+ OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+ expected->alg, 0);
} else {
t->err = "MAC_BAD_PARAMS";
goto err;
}
+ if (skip) {
+ TEST_info("skipping, algorithm '%s' is disabled", expected->alg);
+ t->skip = 1;
+ t->err = NULL;
+ goto err;
+ }
}
if (expected->custom != NULL)
params[params_n++] =
goto err;
}
}
+ retry:
if (!EVP_MAC_update(ctx, expected->input, expected->input_len)) {
t->err = "MAC_UPDATE_ERROR";
goto err;
goto err;
}
}
+ /* FIPS(3.0.0): can't reinitialise MAC contexts #18100 */
+ if (reinit-- && fips_provider_version_gt(libctx, 3, 0, 0)) {
+ OSSL_PARAM ivparams[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
+ int ret;
+
+ /* If the MAC uses IV, we have to set it again */
+ if (expected->iv != NULL) {
+ ivparams[0] =
+ OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
+ expected->iv,
+ expected->iv_len);
+ ivparams[1] = OSSL_PARAM_construct_end();
+ }
+ ERR_set_mark();
+ ret = EVP_MAC_init(ctx, NULL, 0, ivparams);
+ if (expected->no_reinit) {
+ if (ret) {
+ ERR_clear_last_mark();
+ t->err = "MAC_REINIT_SHOULD_FAIL";
+ goto err;
+ }
+ } else if (ret) {
+ ERR_clear_last_mark();
+ OPENSSL_free(got);
+ got = NULL;
+ goto retry;
+ } else {
+ ERR_clear_last_mark();
+ t->err = "MAC_REINIT_ERROR";
+ goto err;
+ }
+ /* If reinitialization fails, it is unsupported by the algorithm */
+ ERR_pop_to_mark();
+ }
t->err = NULL;
/* Test the EVP_Q_mac interface as well */
return parse_bin(value, &kdata->output, &kdata->output_len);
if (strcmp(keyword, "Ctrl") == 0)
return pkey_test_ctrl(t, kdata->ctx, value);
+ if (strcmp(keyword, "KDFType") == 0) {
+ OSSL_PARAM params[2];
+
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE,
+ (char *)value, 0);
+ params[1] = OSSL_PARAM_construct_end();
+ if (EVP_PKEY_CTX_set_params(kdata->ctx, params) == 0)
+ return -1;
+ return 1;
+ }
+ if (strcmp(keyword, "KDFDigest") == 0) {
+ OSSL_PARAM params[2];
+
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,
+ (char *)value, 0);
+ params[1] = OSSL_PARAM_construct_end();
+ if (EVP_PKEY_CTX_set_params(kdata->ctx, params) == 0)
+ return -1;
+ return 1;
+ }
+ if (strcmp(keyword, "CEKAlg") == 0) {
+ OSSL_PARAM params[2];
+
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG,
+ (char *)value, 0);
+ params[1] = OSSL_PARAM_construct_end();
+ if (EVP_PKEY_CTX_set_params(kdata->ctx, params) == 0)
+ return -1;
+ return 1;
+ }
+ if (strcmp(keyword, "KDFOutlen") == 0) {
+ OSSL_PARAM params[2];
+ char *endptr;
+ size_t outlen = (size_t)strtoul(value, &endptr, 0);
+
+ if (endptr[0] != '\0')
+ return -1;
+
+ params[0] = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
+ &outlen);
+ params[1] = OSSL_PARAM_construct_end();
+ if (EVP_PKEY_CTX_set_params(kdata->ctx, params) == 0)
+ return -1;
+ return 1;
+ }
return 0;
}
goto err;
}
- if (EVP_PKEY_derive(dctx, NULL, &got_len) <= 0) {
+ if (EVP_PKEY_derive(dctx, NULL, &got_len) <= 0
+ || !TEST_size_t_ne(got_len, 0)) {
t->err = "DERIVE_ERROR";
goto err;
}
if (p != NULL)
*p++ = '\0';
+ if (strcmp(name, "r") == 0
+ && OSSL_PARAM_locate_const(defs, name) == NULL) {
+ TEST_info("skipping, setting 'r' is unsupported");
+ t->skip = 1;
+ goto end;
+ }
+
rv = OSSL_PARAM_allocate_from_text(kdata->p, defs, name, p,
p != NULL ? strlen(p) : 0, NULL);
*++kdata->p = OSSL_PARAM_construct_end();
TEST_info("skipping, '%s' is disabled", p);
t->skip = 1;
}
+ goto end;
}
if (p != NULL
&& (strcmp(name, "cipher") == 0
&& is_cipher_disabled(p)) {
TEST_info("skipping, '%s' is disabled", p);
t->skip = 1;
+ goto end;
}
if (p != NULL
&& (strcmp(name, "mac") == 0)
TEST_info("skipping, '%s' is disabled", p);
t->skip = 1;
}
+ end:
OPENSSL_free(name);
return 1;
}
t->err = "INTERNAL_ERROR";
goto err;
}
- if ((ctx = EVP_KDF_CTX_dup(expected->ctx)) != NULL) {
+ /* FIPS(3.0.0): can't dup KDF contexts #17572 */
+ if (fips_provider_version_gt(libctx, 3, 0, 0)
+ && (ctx = EVP_KDF_CTX_dup(expected->ctx)) != NULL) {
EVP_KDF_CTX_free(expected->ctx);
expected->ctx = ctx;
}
{
PKEY_KDF_DATA *expected = t->data;
unsigned char *got = NULL;
- size_t got_len = expected->output_len;
+ size_t got_len = 0;
+
+ if (fips_provider_version_eq(libctx, 3, 0, 0)) {
+ /* FIPS(3.0.0): can't deal with oversized output buffers #18533 */
+ got_len = expected->output_len;
+ } else {
+ /* Find out the KDF output size */
+ if (EVP_PKEY_derive(expected->ctx, NULL, &got_len) <= 0) {
+ t->err = "INTERNAL_ERROR";
+ goto err;
+ }
+
+ /*
+ * We may get an absurd output size, which signals that anything goes.
+ * If not, we specify a too big buffer for the output, to test that
+ * EVP_PKEY_derive() can cope with it.
+ */
+ if (got_len == SIZE_MAX || got_len == 0)
+ got_len = expected->output_len;
+ else
+ got_len = expected->output_len * 2;
+ }
if (!TEST_ptr(got = OPENSSL_malloc(got_len == 0 ? 1 : got_len))) {
t->err = "INTERNAL_ERROR";
t->err = "MALLOC_FAILURE";
goto err;
}
+ got_len *= 2;
if (!EVP_DigestSignFinal(expected->ctx, got, &got_len)) {
t->err = "DIGESTSIGNFINAL_ERROR";
goto err;
t->err = "MALLOC_FAILURE";
goto err;
}
+ got_len *= 2;
if (!EVP_DigestSign(expected->ctx, got, &got_len,
expected->osin, expected->osin_len)) {
t->err = "DIGESTSIGN_ERROR";
KEY_LIST *key, **klist;
EVP_PKEY *pkey;
PAIR *pp;
- int i, skip_availablein = 0;
+ int i, j, skipped = 0;
top:
do {
t->skip = 1;
return 0;
}
- skip_availablein++;
+ skipped++;
+ pp++;
+ goto start;
+ } else if (strcmp(pp->key, "FIPSversion") == 0) {
+ if (prov_available("fips")) {
+ j = fips_provider_version_match(libctx, pp->value);
+ if (j < 0) {
+ TEST_info("Line %d: error matching FIPS versions\n", t->s.curr);
+ return 0;
+ } else if (j == 0) {
+ TEST_info("skipping, FIPS provider incompatible version: %s:%d",
+ t->s.test_file, t->s.start);
+ t->skip = 1;
+ return 0;
+ }
+ }
+ skipped++;
pp++;
goto start;
}
*klist = key;
/* Go back and start a new stanza. */
- if ((t->s.numpairs - skip_availablein) != 1)
+ if ((t->s.numpairs - skipped) != 1)
TEST_info("Line %d: missing blank line\n", t->s.curr);
goto top;
}
return 0;
}
- for (pp++, i = 1; i < (t->s.numpairs - skip_availablein); pp++, i++) {
+ for (pp++, i = 1; i < (t->s.numpairs - skipped); pp++, i++) {
if (strcmp(pp->key, "Securitycheck") == 0) {
#if defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
#else
return 1;
#endif
#ifdef OPENSSL_NO_MD2
- if (strcasecmp(name, "MD2") == 0)
+ if (OPENSSL_strcasecmp(name, "MD2") == 0)
return 1;
#endif
#ifdef OPENSSL_NO_MDC2
- if (strcasecmp(name, "MDC2") == 0)
+ if (OPENSSL_strcasecmp(name, "MDC2") == 0)
return 1;
#endif
#ifdef OPENSSL_NO_MD4
- if (strcasecmp(name, "MD4") == 0)
+ if (OPENSSL_strcasecmp(name, "MD4") == 0)
return 1;
#endif
#ifdef OPENSSL_NO_MD5
- if (strcasecmp(name, "MD5") == 0)
+ if (OPENSSL_strcasecmp(name, "MD5") == 0)
return 1;
#endif
#ifdef OPENSSL_NO_RMD160
- if (strcasecmp(name, "RIPEMD160") == 0)
+ if (OPENSSL_strcasecmp(name, "RIPEMD160") == 0)
return 1;
#endif
#ifdef OPENSSL_NO_SM3
- if (strcasecmp(name, "SM3") == 0)
+ if (OPENSSL_strcasecmp(name, "SM3") == 0)
return 1;
#endif
#ifdef OPENSSL_NO_WHIRLPOOL
- if (strcasecmp(name, "WHIRLPOOL") == 0)
+ if (OPENSSL_strcasecmp(name, "WHIRLPOOL") == 0)
return 1;
#endif
return 0;