/*
- * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2024 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 "testutil.h"
#include "internal/nelem.h"
#include "crypto/bn_dh.h" /* _bignum_ffdhe2048_p */
-#include "../e_os.h" /* strcasecmp */
static OSSL_LIB_CTX *libctx = NULL;
static OSSL_PROVIDER *nullprov = NULL;
}
#endif
+static int test_evp_cipher_api_safety(void)
+{
+ int ret = 0;
+ EVP_CIPHER_CTX *ctx = NULL;
+
+ ctx = EVP_CIPHER_CTX_new();
+
+ if (!TEST_ptr(ctx))
+ goto err;
+
+ /*
+ * Ensure that EVP_CIPHER_get_block_size returns 0
+ * if we haven't initialized the cipher in this context
+ */
+ if (!TEST_int_eq(EVP_CIPHER_CTX_get_block_size(ctx), 0))
+ goto err_free;
+
+ /*
+ * Ensure that EVP_CIPHER_get_iv_length returns 0
+ * if we haven't initialized the cipher in this context
+ */
+ if (!TEST_int_eq(EVP_CIPHER_CTX_get_iv_length(ctx), 0))
+ goto err_free;
+
+ ret = 1;
+err_free:
+ EVP_CIPHER_CTX_free(ctx);
+err:
+ return ret;
+}
+
/*
* We're using some DH specific values in this test, so we skip compilation if
* we're in a no-dh build.
0x03, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
- unsigned char iv[16] = {
+ unsigned char iv[48] = {
+ 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
+ 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
+ 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
+ 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
};
goto err;
/* ccm fails on the second update - this matches OpenSSL 1_1_1 behaviour */
- ccm = (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE);
+ ccm = (EVP_CIPHER_get_mode(cipher) == EVP_CIPH_CCM_MODE);
/* siv cannot be called with NULL key as the iv is irrelevant */
- siv = (EVP_CIPHER_mode(cipher) == EVP_CIPH_SIV_MODE);
+ siv = (EVP_CIPHER_get_mode(cipher) == EVP_CIPH_SIV_MODE);
/*
* Skip init call with a null key for RC4 as the stream cipher does not
0x03, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
- static const unsigned char iv[16] = {
+ static const unsigned char iv[48] = {
+ 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
+ 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
+ 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
+ 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
};
if (!TEST_ptr(cipher = EVP_CIPHER_fetch(libctx, name, NULL)))
goto err;
- in_len = EVP_CIPHER_block_size(cipher) / 2;
+ in_len = EVP_CIPHER_get_block_size(cipher);
+ if (!TEST_int_gt(in_len, 0))
+ goto err;
+ if (in_len > 1)
+ in_len /= 2;
/* skip any ciphers that don't allow partial updates */
- if (((EVP_CIPHER_flags(cipher)
+ if (((EVP_CIPHER_get_flags(cipher)
& (EVP_CIPH_FLAG_CTS | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) != 0)
- || EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE
- || EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE
- || EVP_CIPHER_mode(cipher) == EVP_CIPH_WRAP_MODE) {
+ || EVP_CIPHER_get_mode(cipher) == EVP_CIPH_CCM_MODE
+ || EVP_CIPHER_get_mode(cipher) == EVP_CIPH_XTS_MODE
+ || EVP_CIPHER_get_mode(cipher) == EVP_CIPH_WRAP_MODE) {
ret = 1;
goto err;
}
|| !TEST_true(EVP_EncryptUpdate(ctx, out2, &out2_len, in, in_len)))
goto err;
- if (!TEST_mem_eq(out1, out1_len, out2, out2_len))
- goto err;
+ if (EVP_CIPHER_get_iv_length(cipher) != 0)
+ if (!TEST_mem_eq(out1, out1_len, out2, out2_len))
+ goto err;
- if (EVP_CIPHER_mode(cipher) != EVP_CIPH_SIV_MODE) {
+ if (EVP_CIPHER_get_mode(cipher) != EVP_CIPH_SIV_MODE) {
if (!TEST_true(EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv))
|| !TEST_true(EVP_EncryptUpdate(ctx, out3, &out3_len, in, in_len)))
goto err;
- if (!TEST_mem_eq(out1, out1_len, out3, out3_len))
- goto err;
+ if (EVP_CIPHER_get_iv_length(cipher) != 0)
+ if (!TEST_mem_eq(out1, out1_len, out3, out3_len))
+ goto err;
}
ret = 1;
err:
static int name_cmp(const char * const *a, const char * const *b)
{
- return strcasecmp(*a, *b);
+ return OPENSSL_strcasecmp(*a, *b);
}
static void collect_cipher_names(EVP_CIPHER *cipher, void *cipher_names_list)
{
STACK_OF(OPENSSL_STRING) *names = cipher_names_list;
- const char *name = EVP_CIPHER_name(cipher);
+ const char *name = EVP_CIPHER_get0_name(cipher);
char *namedup = NULL;
assert(name != NULL);
int ret = 0;
EVP_PKEY *pub = NULL;
EVP_PKEY *priv = NULL;
- EVP_PKEY_CTX *sctx = NULL, *rctx = NULL;
+ EVP_PKEY_CTX *sctx = NULL, *rctx = NULL, *dctx = NULL;
unsigned char secret[256] = { 0, };
unsigned char ct[256] = { 0, };
unsigned char unwrap[256] = { 0, };
&& TEST_ptr(sctx = EVP_PKEY_CTX_new_from_pkey(libctx, pub, NULL))
&& TEST_int_eq(EVP_PKEY_encapsulate_init(sctx, NULL), 1)
&& TEST_int_eq(EVP_PKEY_CTX_set_kem_op(sctx, "RSASVE"), 1)
- && TEST_int_eq(EVP_PKEY_encapsulate(sctx, NULL, &ctlen, NULL,
+ && TEST_ptr(dctx = EVP_PKEY_CTX_dup(sctx))
+ && TEST_int_eq(EVP_PKEY_encapsulate(dctx, NULL, &ctlen, NULL,
&secretlen), 1)
&& TEST_int_eq(ctlen, secretlen)
&& TEST_int_eq(ctlen, bits / 8)
- && TEST_int_eq(EVP_PKEY_encapsulate(sctx, ct, &ctlen, secret,
+ && TEST_int_eq(EVP_PKEY_encapsulate(dctx, ct, &ctlen, secret,
&secretlen), 1)
&& TEST_ptr(rctx = EVP_PKEY_CTX_new_from_pkey(libctx, priv, NULL))
&& TEST_int_eq(EVP_PKEY_decapsulate_init(rctx, NULL), 1)
EVP_PKEY_free(pub);
EVP_PKEY_free(priv);
EVP_PKEY_CTX_free(rctx);
+ EVP_PKEY_CTX_free(dctx);
EVP_PKEY_CTX_free(sctx);
return ret;
}
+#ifndef OPENSSL_NO_DES
+/*
+ * This test makes sure that EVP_CIPHER_CTX_rand_key() works correctly
+ * For fips mode this code would produce an error if the flag is not set.
+ */
+static int test_cipher_tdes_randkey(void)
+{
+ int ret;
+ EVP_CIPHER_CTX *ctx = NULL;
+ EVP_CIPHER *tdes_cipher = NULL, *aes_cipher = NULL;
+ unsigned char key[24] = { 0 };
+
+ ret = TEST_ptr(aes_cipher = EVP_CIPHER_fetch(libctx, "AES-256-CBC", NULL))
+ && TEST_int_eq(EVP_CIPHER_get_flags(aes_cipher) & EVP_CIPH_RAND_KEY, 0)
+ && TEST_ptr(tdes_cipher = EVP_CIPHER_fetch(libctx, "DES-EDE3-CBC", NULL))
+ && TEST_int_ne(EVP_CIPHER_get_flags(tdes_cipher) & EVP_CIPH_RAND_KEY, 0)
+ && TEST_ptr(ctx = EVP_CIPHER_CTX_new())
+ && TEST_true(EVP_CipherInit_ex(ctx, tdes_cipher, NULL, NULL, NULL, 1))
+ && TEST_int_gt(EVP_CIPHER_CTX_rand_key(ctx, key), 0);
+
+ EVP_CIPHER_CTX_free(ctx);
+ EVP_CIPHER_free(tdes_cipher);
+ EVP_CIPHER_free(aes_cipher);
+ return ret;
+}
+#endif /* OPENSSL_NO_DES */
+
static int kem_rsa_params(void)
{
int ret = 0;
params[1] = OSSL_PARAM_construct_end();
if (!TEST_ptr(gctx = EVP_PKEY_CTX_new_from_name(libctx, "DH", NULL))
- || !TEST_true(EVP_PKEY_keygen_init(gctx))
+ || !TEST_int_gt(EVP_PKEY_keygen_init(gctx), 0)
|| !TEST_true(EVP_PKEY_CTX_set_params(gctx, params))
|| !TEST_true(EVP_PKEY_keygen(gctx, &pkey)))
goto err;
if (!test_get_libctx(&libctx, &nullprov, config_file, &libprov, prov_name))
return 0;
+ ADD_TEST(test_evp_cipher_api_safety);
+
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DH)
ADD_ALL_TESTS(test_dsa_param_keygen, 3 * 3 * 3);
#endif
ADD_TEST(kem_rsa_params);
#ifndef OPENSSL_NO_DH
ADD_TEST(kem_invalid_keytype);
+#endif
+#ifndef OPENSSL_NO_DES
+ ADD_TEST(test_cipher_tdes_randkey);
#endif
return 1;
}