mirror of
https://github.com/openssl/openssl.git
synced 2024-11-24 18:43:34 +08:00
Add fips module integrity check
Add environment variable for setting CONF .include path Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/9769)
This commit is contained in:
parent
dd11c5f0fa
commit
7bb82f92d9
2
.gitignore
vendored
2
.gitignore
vendored
@ -61,6 +61,8 @@ Makefile
|
||||
/test/rsa_complex
|
||||
# Other generated files in test/
|
||||
/test/provider_internal_test.conf
|
||||
/test/fipsinstall.conf
|
||||
/providers/fipsinstall.conf
|
||||
|
||||
# Certain files that get created by tests on the fly
|
||||
/test/test-runs
|
||||
|
@ -128,6 +128,7 @@ static int write_config_fips_section(BIO *out, const char *section,
|
||||
int ret = 0;
|
||||
|
||||
if (!(BIO_printf(out, "[%s]\n", section) > 0
|
||||
&& BIO_printf(out, "activate = 1\n") > 0
|
||||
&& BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_VERSION,
|
||||
VERSION_VAL) > 0
|
||||
&& print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac,
|
||||
|
@ -352,6 +352,8 @@ static int def_load_bio(CONF *conf, BIO *in, long *line)
|
||||
&& (p != pname + 8 || *p == '=')) {
|
||||
char *include = NULL;
|
||||
BIO *next;
|
||||
const char *include_dir = ossl_safe_getenv("OPENSSL_CONF_INCLUDE");
|
||||
char *include_path = NULL;
|
||||
|
||||
if (*p == '=') {
|
||||
p++;
|
||||
@ -360,17 +362,34 @@ static int def_load_bio(CONF *conf, BIO *in, long *line)
|
||||
trim_ws(conf, p);
|
||||
if (!str_copy(conf, psection, &include, p))
|
||||
goto err;
|
||||
|
||||
if (include_dir != NULL) {
|
||||
size_t newlen = strlen(include_dir) + strlen(include) + 2;
|
||||
|
||||
include_path = OPENSSL_malloc(newlen);
|
||||
OPENSSL_strlcpy(include_path, include_dir, newlen);
|
||||
OPENSSL_strlcat(include_path, "/", newlen);
|
||||
OPENSSL_strlcat(include_path, include, newlen);
|
||||
} else {
|
||||
include_path = include;
|
||||
}
|
||||
|
||||
/* get the BIO of the included file */
|
||||
#ifndef OPENSSL_NO_POSIX_IO
|
||||
next = process_include(include, &dirctx, &dirpath);
|
||||
if (include != dirpath) {
|
||||
next = process_include(include_path, &dirctx, &dirpath);
|
||||
if (include_path != dirpath) {
|
||||
/* dirpath will contain include in case of a directory */
|
||||
OPENSSL_free(include);
|
||||
if (include_path != include)
|
||||
OPENSSL_free(include_path);
|
||||
}
|
||||
#else
|
||||
next = BIO_new_file(include, "r");
|
||||
next = BIO_new_file(include_path, "r");
|
||||
OPENSSL_free(include);
|
||||
if (include_path != include)
|
||||
OPENSSL_free(include_path);
|
||||
#endif
|
||||
|
||||
if (next != NULL) {
|
||||
/* push the currently processing BIO onto stack */
|
||||
if (biosk == NULL) {
|
||||
|
@ -871,7 +871,7 @@ static const OSSL_DISPATCH core_dispatch_[] = {
|
||||
{ OSSL_FUNC_CORE_VSET_ERROR, (void (*)(void))core_vset_error },
|
||||
{ OSSL_FUNC_BIO_NEW_FILE, (void (*)(void))BIO_new_file },
|
||||
{ OSSL_FUNC_BIO_NEW_MEMBUF, (void (*)(void))BIO_new_mem_buf },
|
||||
{ OSSL_FUNC_BIO_READ, (void (*)(void))BIO_read },
|
||||
{ OSSL_FUNC_BIO_READ_EX, (void (*)(void))BIO_read_ex },
|
||||
{ OSSL_FUNC_BIO_FREE, (void (*)(void))BIO_free },
|
||||
#endif
|
||||
|
||||
|
@ -40,7 +40,8 @@ It is strongly recommended to use absolute paths with the B<.include>
|
||||
directive. Relative paths are evaluated based on the application current
|
||||
working directory so unless the configuration file containing the
|
||||
B<.include> directive is application specific the inclusion will not
|
||||
work as expected.
|
||||
work as expected. The environment variable B<OPENSSL_CONF_INCLUDE> can also be
|
||||
used to specify the path to prepend to all .include paths.
|
||||
|
||||
There can be optional B<=> character and whitespace characters between
|
||||
B<.include> directive and the path which can be useful in cases the
|
||||
@ -487,6 +488,10 @@ Ignored in set-user-ID and set-group-ID programs.
|
||||
The path to the directory with OpenSSL modules, such as providers.
|
||||
Ignored in set-user-ID and set-group-ID programs.
|
||||
|
||||
=item B<OPENSSL_CONF_INCLUDE>
|
||||
|
||||
The optional path to prepend to all .include paths.
|
||||
|
||||
=back
|
||||
|
||||
=head1 BUGS
|
||||
|
@ -110,7 +110,7 @@ provider):
|
||||
CRYPTO_secure_allocated OSSL_FUNC_CRYPTO_SECURE_ALLOCATED
|
||||
BIO_new_file OSSL_FUNC_BIO_NEW_FILE
|
||||
BIO_new_mem_buf OSSL_FUNC_BIO_NEW_MEMBUF
|
||||
BIO_read OSSL_FUNC_BIO_READ
|
||||
BIO_read_ex OSSL_FUNC_BIO_READ_EX
|
||||
BIO_free OSSL_FUNC_BIO_FREE
|
||||
OPENSSL_cleanse OSSL_FUNC_OPENSSL_CLEANSE
|
||||
OPENSSL_hexstr2buf OSSL_FUNC_OPENSSL_HEXSTR2BUF
|
||||
@ -182,7 +182,7 @@ CRYPTO_strndup(), CRYPTO_free(), CRYPTO_clear_free(),
|
||||
CRYPTO_realloc(), CRYPTO_clear_realloc(), CRYPTO_secure_malloc(),
|
||||
CRYPTO_secure_zalloc(), CRYPTO_secure_free(),
|
||||
CRYPTO_secure_clear_free(), CRYPTO_secure_allocated(),
|
||||
BIO_new_file(), BIO_new_mem_buf(), BIO_read(), BIO_free(),
|
||||
BIO_new_file(), BIO_new_mem_buf(), BIO_read_ex(), BIO_free(),
|
||||
OPENSSL_cleanse(), and OPENSSL_hexstr2buf() correspond exactly to the
|
||||
public functions with the same name.
|
||||
As a matter of fact, the pointers in the B<OSSL_DISPATCH> array are
|
||||
|
@ -123,13 +123,13 @@ OSSL_CORE_MAKE_FUNC(void,
|
||||
/* Bio functions provided by the core */
|
||||
#define OSSL_FUNC_BIO_NEW_FILE 22
|
||||
#define OSSL_FUNC_BIO_NEW_MEMBUF 23
|
||||
#define OSSL_FUNC_BIO_READ 24
|
||||
#define OSSL_FUNC_BIO_READ_EX 24
|
||||
#define OSSL_FUNC_BIO_FREE 25
|
||||
|
||||
OSSL_CORE_MAKE_FUNC(BIO *, BIO_new_file, (const char *filename, const char *mode))
|
||||
OSSL_CORE_MAKE_FUNC(BIO *, BIO_new_membuf, (const void *buf, int len))
|
||||
OSSL_CORE_MAKE_FUNC(int, BIO_read, (BIO *bio, void *data, size_t data_len,
|
||||
size_t *bytes_read))
|
||||
OSSL_CORE_MAKE_FUNC(int, BIO_read_ex, (BIO *bio, void *data, size_t data_len,
|
||||
size_t *bytes_read))
|
||||
OSSL_CORE_MAKE_FUNC(int, BIO_free, (BIO *bio))
|
||||
|
||||
/* Functions provided by the provider to the Core, reserved numbers 1024-1535 */
|
||||
|
@ -1,2 +1,2 @@
|
||||
|
||||
SOURCE[../fips]=fipsprov.c
|
||||
SOURCE[../fips]=fipsprov.c selftest.c
|
||||
|
@ -464,8 +464,8 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
|
||||
case OSSL_FUNC_BIO_NEW_MEMBUF:
|
||||
selftest_params.bio_new_buffer_cb = OSSL_get_BIO_new_membuf(in);
|
||||
break;
|
||||
case OSSL_FUNC_BIO_READ:
|
||||
selftest_params.bio_read_cb = OSSL_get_BIO_read(in);
|
||||
case OSSL_FUNC_BIO_READ_EX:
|
||||
selftest_params.bio_read_ex_cb = OSSL_get_BIO_read_ex(in);
|
||||
break;
|
||||
case OSSL_FUNC_BIO_FREE:
|
||||
selftest_params.bio_free_cb = OSSL_get_BIO_free(in);
|
||||
@ -487,7 +487,15 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
|
||||
OPENSSL_CTX_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fgbl->prov = provider;
|
||||
|
||||
selftest_params.libctx = PROV_LIBRARY_CONTEXT_OF(ctx);
|
||||
if (!SELF_TEST_post(&selftest_params)) {
|
||||
OPENSSL_CTX_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out = fips_dispatch_table;
|
||||
*provctx = ctx;
|
||||
|
||||
|
150
providers/fips/selftest.c
Normal file
150
providers/fips/selftest.c
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/params.h>
|
||||
#include "selftest.h"
|
||||
|
||||
#define FIPS_STATE_INIT 0
|
||||
#define FIPS_STATE_RUNNING 1
|
||||
#define FIPS_STATE_SELFTEST 2
|
||||
#define FIPS_STATE_ERROR 3
|
||||
|
||||
/* The size of a temp buffer used to read in data */
|
||||
#define INTEGRITY_BUF_SIZE (4096)
|
||||
#define MAX_MD_SIZE 64
|
||||
#define MAC_NAME "HMAC"
|
||||
#define DIGEST_NAME "SHA256"
|
||||
|
||||
static int FIPS_state = FIPS_STATE_INIT;
|
||||
static unsigned char fixed_key[32] = { 0 };
|
||||
|
||||
/*
|
||||
* Calculate the HMAC SHA256 of data read using a BIO and read_cb, and verify
|
||||
* the result matches the expected value.
|
||||
* Return 1 if verified, or 0 if it fails.
|
||||
*/
|
||||
static int verify_integrity(BIO *bio, OSSL_BIO_read_ex_fn read_ex_cb,
|
||||
unsigned char *expected, size_t expected_len,
|
||||
OPENSSL_CTX *libctx)
|
||||
{
|
||||
int ret = 0, status;
|
||||
unsigned char out[MAX_MD_SIZE];
|
||||
unsigned char buf[INTEGRITY_BUF_SIZE];
|
||||
size_t bytes_read = 0, out_len = 0;
|
||||
EVP_MAC *mac = NULL;
|
||||
EVP_MAC_CTX *ctx = NULL;
|
||||
OSSL_PARAM params[3], *p = params;
|
||||
|
||||
mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
|
||||
ctx = EVP_MAC_CTX_new(mac);
|
||||
if (mac == NULL || ctx == NULL)
|
||||
goto err;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string("digest", DIGEST_NAME,
|
||||
strlen(DIGEST_NAME) + 1);
|
||||
*p++ = OSSL_PARAM_construct_octet_string("key", fixed_key,
|
||||
sizeof(fixed_key));
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
|
||||
if (EVP_MAC_CTX_set_params(ctx, params) <= 0
|
||||
|| !EVP_MAC_init(ctx))
|
||||
goto err;
|
||||
|
||||
while (1) {
|
||||
status = read_ex_cb(bio, buf, sizeof(buf), &bytes_read);
|
||||
if (status != 1)
|
||||
break;
|
||||
if (!EVP_MAC_update(ctx, buf, bytes_read))
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_MAC_final(ctx, out, &out_len, sizeof(out)))
|
||||
goto err;
|
||||
|
||||
if (expected_len != out_len
|
||||
|| memcmp(expected, out, out_len) != 0)
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_MAC_CTX_free(ctx);
|
||||
EVP_MAC_free(mac);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This API is triggered either on loading of the FIPS module or on demand */
|
||||
int SELF_TEST_post(SELF_TEST_POST_PARAMS *st)
|
||||
{
|
||||
int ok = 0;
|
||||
int kats_already_passed = 0;
|
||||
int on_demand_test = (FIPS_state != FIPS_STATE_INIT);
|
||||
long checksum_len;
|
||||
BIO *bio_module = NULL, *bio_indicator = NULL;
|
||||
unsigned char *module_checksum = NULL;
|
||||
unsigned char *indicator_checksum = NULL;
|
||||
|
||||
if (st == NULL
|
||||
|| FIPS_state == FIPS_STATE_ERROR
|
||||
|| FIPS_state == FIPS_STATE_SELFTEST
|
||||
|| st->module_checksum_data == NULL)
|
||||
goto end;
|
||||
|
||||
module_checksum = OPENSSL_hexstr2buf(st->module_checksum_data,
|
||||
&checksum_len);
|
||||
if (module_checksum == NULL)
|
||||
goto end;
|
||||
bio_module = (*st->bio_new_file_cb)(st->module_filename, "rb");
|
||||
|
||||
/* Always check the integrity of the fips module */
|
||||
if (bio_module == NULL
|
||||
|| !verify_integrity(bio_module, st->bio_read_ex_cb,
|
||||
module_checksum, checksum_len, st->libctx))
|
||||
goto end;
|
||||
|
||||
/* This will be NULL during installation - so the self test KATS will run */
|
||||
if (st->indicator_data != NULL) {
|
||||
/*
|
||||
* If the kats have already passed indicator is set - then check the
|
||||
* integrity of the indicator.
|
||||
*/
|
||||
if (st->indicator_checksum_data == NULL)
|
||||
goto end;
|
||||
indicator_checksum = OPENSSL_hexstr2buf(st->indicator_checksum_data,
|
||||
&checksum_len);
|
||||
if (indicator_checksum == NULL)
|
||||
goto end;
|
||||
|
||||
bio_indicator =
|
||||
(*st->bio_new_buffer_cb)(st->indicator_data,
|
||||
strlen(st->indicator_data));
|
||||
if (bio_indicator == NULL
|
||||
|| !verify_integrity(bio_indicator, st->bio_read_ex_cb,
|
||||
indicator_checksum, checksum_len,
|
||||
st->libctx))
|
||||
goto end;
|
||||
else
|
||||
kats_already_passed = 1;
|
||||
}
|
||||
|
||||
/* Only runs the KAT's during installation OR on_demand() */
|
||||
if (on_demand_test || kats_already_passed == 0) {
|
||||
/*TODO (3.0) Add self test KATS */
|
||||
}
|
||||
ok = 1;
|
||||
end:
|
||||
OPENSSL_free(module_checksum);
|
||||
OPENSSL_free(indicator_checksum);
|
||||
|
||||
(*st->bio_free_cb)(bio_indicator);
|
||||
(*st->bio_free_cb)(bio_module);
|
||||
|
||||
FIPS_state = ok ? FIPS_STATE_RUNNING : FIPS_STATE_ERROR;
|
||||
|
||||
return ok;
|
||||
}
|
@ -7,8 +7,8 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/core_numbers.h>
|
||||
#include <openssl/ossl_typ.h>
|
||||
|
||||
typedef struct self_test_post_params_st {
|
||||
/* FIPS module integrity check parameters */
|
||||
@ -23,7 +23,10 @@ typedef struct self_test_post_params_st {
|
||||
/* BIO callbacks supplied to the FIPS provider */
|
||||
OSSL_BIO_new_file_fn *bio_new_file_cb;
|
||||
OSSL_BIO_new_membuf_fn *bio_new_buffer_cb;
|
||||
OSSL_BIO_read_fn *bio_read_cb;
|
||||
OSSL_BIO_read_ex_fn *bio_read_ex_cb;
|
||||
OSSL_BIO_free_fn *bio_free_cb;
|
||||
OPENSSL_CTX *libctx;
|
||||
|
||||
} SELF_TEST_POST_PARAMS;
|
||||
|
||||
int SELF_TEST_post(SELF_TEST_POST_PARAMS *st);
|
||||
|
@ -38,7 +38,7 @@ IF[{- !$disabled{tests} -}]
|
||||
destest mdc2test \
|
||||
dhtest enginetest casttest \
|
||||
bftest ssltest_old dsatest dsa_no_digest_size_test exptest rsa_test \
|
||||
evp_test evp_extra_test igetest v3nametest v3ext \
|
||||
evp_test evp_extra_test evp_fetch_prov_test igetest v3nametest v3ext \
|
||||
crltest danetest bad_dtls_test lhash_test sparse_array_test \
|
||||
conf_include_test params_api_test params_conversion_test \
|
||||
constant_time_test verify_extra_test clienthellotest \
|
||||
@ -195,6 +195,10 @@ IF[{- !$disabled{tests} -}]
|
||||
SOURCE[evp_extra_test]=evp_extra_test.c
|
||||
INCLUDE[evp_extra_test]=../include ../apps/include ../crypto/include
|
||||
DEPEND[evp_extra_test]=../libcrypto libtestutil.a
|
||||
|
||||
SOURCE[evp_fetch_prov_test]=evp_fetch_prov_test.c
|
||||
INCLUDE[evp_fetch_prov_test]=../include ../apps/include ../crypto/include
|
||||
DEPEND[evp_fetch_prov_test]=../libcrypto libtestutil.a
|
||||
IF[{- $disabled{fips} || !$target{dso_scheme} -}]
|
||||
DEFINE[evp_extra_test]=NO_FIPS_MODULE
|
||||
ENDIF
|
||||
|
13
test/default-and-fips.cnf
Normal file
13
test/default-and-fips.cnf
Normal file
@ -0,0 +1,13 @@
|
||||
openssl_conf = openssl_init
|
||||
|
||||
.include fipsinstall.conf
|
||||
|
||||
[openssl_init]
|
||||
providers = provider_sect
|
||||
|
||||
[provider_sect]
|
||||
default = default_sect
|
||||
fips = fips_sect
|
||||
|
||||
[default_sect]
|
||||
activate = 1
|
@ -11,6 +11,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
@ -1070,333 +1071,7 @@ done:
|
||||
X509_PUBKEY_free(xp);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int calculate_digest(const EVP_MD *md, const char *msg, size_t len,
|
||||
const unsigned char *exptd)
|
||||
{
|
||||
unsigned char out[SHA256_DIGEST_LENGTH];
|
||||
EVP_MD_CTX *ctx;
|
||||
int ret = 0;
|
||||
|
||||
if (!TEST_ptr(ctx = EVP_MD_CTX_new())
|
||||
|| !TEST_true(EVP_DigestInit_ex(ctx, md, NULL))
|
||||
|| !TEST_true(EVP_DigestUpdate(ctx, msg, len))
|
||||
|| !TEST_true(EVP_DigestFinal_ex(ctx, out, NULL))
|
||||
|| !TEST_mem_eq(out, SHA256_DIGEST_LENGTH, exptd,
|
||||
SHA256_DIGEST_LENGTH)
|
||||
|| !TEST_true(md == EVP_MD_CTX_md(ctx)))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_MD_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* Test EVP_MD_fetch()
|
||||
*
|
||||
* Test 0: Test with the default OPENSSL_CTX
|
||||
* Test 1: Test with an explicit OPENSSL_CTX
|
||||
* Test 2: Explicit OPENSSL_CTX with explicit load of default provider
|
||||
* Test 3: Explicit OPENSSL_CTX with explicit load of default and fips provider
|
||||
* Test 4: Explicit OPENSSL_CTX with explicit load of fips provider
|
||||
*/
|
||||
static int test_EVP_MD_fetch(int tst)
|
||||
{
|
||||
OPENSSL_CTX *ctx = NULL;
|
||||
EVP_MD *md = NULL;
|
||||
OSSL_PROVIDER *defltprov = NULL, *fipsprov = NULL;
|
||||
int ret = 0;
|
||||
const char testmsg[] = "Hello world";
|
||||
const unsigned char exptd[] = {
|
||||
0x27, 0x51, 0x8b, 0xa9, 0x68, 0x30, 0x11, 0xf6, 0xb3, 0x96, 0x07, 0x2c,
|
||||
0x05, 0xf6, 0x65, 0x6d, 0x04, 0xf5, 0xfb, 0xc3, 0x78, 0x7c, 0xf9, 0x24,
|
||||
0x90, 0xec, 0x60, 0x6e, 0x50, 0x92, 0xe3, 0x26
|
||||
};
|
||||
|
||||
if (tst > 0) {
|
||||
ctx = OPENSSL_CTX_new();
|
||||
if (!TEST_ptr(ctx))
|
||||
goto err;
|
||||
|
||||
if (tst == 2 || tst == 3) {
|
||||
defltprov = OSSL_PROVIDER_load(ctx, "default");
|
||||
if (!TEST_ptr(defltprov))
|
||||
goto err;
|
||||
}
|
||||
if (tst == 3 || tst == 4) {
|
||||
fipsprov = OSSL_PROVIDER_load(ctx, "fips");
|
||||
if (!TEST_ptr(fipsprov))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Implicit fetching of the MD should produce the expected result */
|
||||
if (!TEST_true(calculate_digest(EVP_sha256(), testmsg, sizeof(testmsg),
|
||||
exptd))
|
||||
|| !TEST_int_eq(EVP_MD_size(EVP_sha256()), SHA256_DIGEST_LENGTH)
|
||||
|| !TEST_int_eq(EVP_MD_block_size(EVP_sha256()), SHA256_CBLOCK))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Test that without specifying any properties we can get a sha256 md from a
|
||||
* provider.
|
||||
*/
|
||||
if (!TEST_ptr(md = EVP_MD_fetch(ctx, "SHA256", NULL))
|
||||
|| !TEST_ptr(md)
|
||||
|| !TEST_int_eq(EVP_MD_nid(md), NID_sha256)
|
||||
|| !TEST_true(calculate_digest(md, testmsg, sizeof(testmsg), exptd))
|
||||
|| !TEST_int_eq(EVP_MD_size(md), SHA256_DIGEST_LENGTH)
|
||||
|| !TEST_int_eq(EVP_MD_block_size(md), SHA256_CBLOCK))
|
||||
goto err;
|
||||
|
||||
/* Also test EVP_MD_up_ref() while we're doing this */
|
||||
if (!TEST_true(EVP_MD_up_ref(md)))
|
||||
goto err;
|
||||
/* Ref count should now be 2. Release both */
|
||||
EVP_MD_free(md);
|
||||
EVP_MD_free(md);
|
||||
md = NULL;
|
||||
|
||||
/*
|
||||
* In tests 0 - 2 we've only loaded the default provider so explicitly
|
||||
* asking for a non-default implementation should fail. In tests 3 and 4 we
|
||||
* have the FIPS provider loaded so we should succeed in that case.
|
||||
*/
|
||||
md = EVP_MD_fetch(ctx, "SHA256", "default=no");
|
||||
if (tst == 3 || tst == 4) {
|
||||
if (!TEST_ptr(md)
|
||||
|| !TEST_true(calculate_digest(md, testmsg, sizeof(testmsg),
|
||||
exptd)))
|
||||
goto err;
|
||||
} else {
|
||||
if (!TEST_ptr_null(md))
|
||||
goto err;
|
||||
}
|
||||
|
||||
EVP_MD_free(md);
|
||||
md = NULL;
|
||||
|
||||
/*
|
||||
* Explicitly asking for the default implementation should succeed except
|
||||
* in test 4 where the default provider is not loaded.
|
||||
*/
|
||||
md = EVP_MD_fetch(ctx, "SHA256", "default=yes");
|
||||
if (tst != 4) {
|
||||
if (!TEST_ptr(md)
|
||||
|| !TEST_int_eq(EVP_MD_nid(md), NID_sha256)
|
||||
|| !TEST_true(calculate_digest(md, testmsg, sizeof(testmsg),
|
||||
exptd))
|
||||
|| !TEST_int_eq(EVP_MD_size(md), SHA256_DIGEST_LENGTH)
|
||||
|| !TEST_int_eq(EVP_MD_block_size(md), SHA256_CBLOCK))
|
||||
goto err;
|
||||
} else {
|
||||
if (!TEST_ptr_null(md))
|
||||
goto err;
|
||||
}
|
||||
|
||||
EVP_MD_free(md);
|
||||
md = NULL;
|
||||
|
||||
/*
|
||||
* Explicitly asking for a fips implementation should succeed if we have
|
||||
* the FIPS provider loaded and fail otherwise
|
||||
*/
|
||||
md = EVP_MD_fetch(ctx, "SHA256", "fips=yes");
|
||||
if (tst == 3 || tst == 4) {
|
||||
if (!TEST_ptr(md)
|
||||
|| !TEST_true(calculate_digest(md, testmsg, sizeof(testmsg),
|
||||
exptd)))
|
||||
goto err;
|
||||
} else {
|
||||
if (!TEST_ptr_null(md))
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EVP_MD_free(md);
|
||||
OSSL_PROVIDER_unload(defltprov);
|
||||
OSSL_PROVIDER_unload(fipsprov);
|
||||
/* Not normally needed, but we would like to test that
|
||||
* OPENSSL_thread_stop_ex() behaves as expected.
|
||||
*/
|
||||
if (ctx != NULL)
|
||||
OPENSSL_thread_stop_ex(ctx);
|
||||
OPENSSL_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int encrypt_decrypt(const EVP_CIPHER *cipher, const unsigned char *msg,
|
||||
size_t len)
|
||||
{
|
||||
int ret = 0, ctlen, ptlen;
|
||||
EVP_CIPHER_CTX *ctx = NULL;
|
||||
unsigned char key[128 / 8];
|
||||
unsigned char ct[64], pt[64];
|
||||
|
||||
memset(key, 0, sizeof(key));
|
||||
if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
|
||||
|| !TEST_int_eq(EVP_CIPHER_CTX_tag_length(ctx), 0)
|
||||
|| !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 1))
|
||||
|| !TEST_int_eq(EVP_CIPHER_CTX_tag_length(ctx), 0)
|
||||
|| !TEST_true(EVP_CipherUpdate(ctx, ct, &ctlen, msg, len))
|
||||
|| !TEST_true(EVP_CipherFinal_ex(ctx, ct, &ctlen))
|
||||
|| !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 0))
|
||||
|| !TEST_int_eq(EVP_CIPHER_CTX_tag_length(ctx), 0)
|
||||
|| !TEST_true(EVP_CipherUpdate(ctx, pt, &ptlen, ct, ctlen))
|
||||
|| !TEST_true(EVP_CipherFinal_ex(ctx, pt, &ptlen))
|
||||
|| !TEST_mem_eq(pt, ptlen, msg, len))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_num_params(const OSSL_PARAM *params)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (params != NULL) {
|
||||
while (params[i].key != NULL)
|
||||
++i;
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test EVP_CIPHER_fetch()
|
||||
*
|
||||
* Test 0: Test with the default OPENSSL_CTX
|
||||
* Test 1: Test with an explicit OPENSSL_CTX
|
||||
* Test 2: Explicit OPENSSL_CTX with explicit load of default provider
|
||||
* Test 3: Explicit OPENSSL_CTX with explicit load of default and fips provider
|
||||
* Test 4: Explicit OPENSSL_CTX with explicit load of fips provider
|
||||
*/
|
||||
static int test_EVP_CIPHER_fetch(int tst)
|
||||
{
|
||||
OPENSSL_CTX *ctx = NULL;
|
||||
EVP_CIPHER *cipher = NULL;
|
||||
OSSL_PROVIDER *defltprov = NULL, *fipsprov = NULL;
|
||||
int ret = 0;
|
||||
const unsigned char testmsg[] = "Hello world";
|
||||
const OSSL_PARAM *params;
|
||||
|
||||
if (tst > 0) {
|
||||
ctx = OPENSSL_CTX_new();
|
||||
if (!TEST_ptr(ctx))
|
||||
goto err;
|
||||
|
||||
if (tst == 2 || tst == 3) {
|
||||
defltprov = OSSL_PROVIDER_load(ctx, "default");
|
||||
if (!TEST_ptr(defltprov))
|
||||
goto err;
|
||||
}
|
||||
if (tst == 3 || tst == 4) {
|
||||
fipsprov = OSSL_PROVIDER_load(ctx, "fips");
|
||||
if (!TEST_ptr(fipsprov))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Implicit fetching of the cipher should produce the expected result */
|
||||
if (!TEST_true(encrypt_decrypt(EVP_aes_128_cbc(), testmsg, sizeof(testmsg))))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Test that without specifying any properties we can get a cipher from a
|
||||
* provider.
|
||||
*/
|
||||
if (!TEST_ptr(cipher = EVP_CIPHER_fetch(ctx, "AES-128-CBC", NULL))
|
||||
|| !TEST_true(encrypt_decrypt(cipher, testmsg, sizeof(testmsg))))
|
||||
goto err;
|
||||
|
||||
/* Also test EVP_CIPHER_up_ref() while we're doing this */
|
||||
if (!TEST_true(EVP_CIPHER_up_ref(cipher)))
|
||||
goto err;
|
||||
/* Ref count should now be 2. Release both */
|
||||
EVP_CIPHER_free(cipher);
|
||||
EVP_CIPHER_free(cipher);
|
||||
cipher = NULL;
|
||||
|
||||
/*
|
||||
* In tests 0 - 2 we've only loaded the default provider so explicitly
|
||||
* asking for a non-default implementation should fail. In tests 3 and 4 we
|
||||
* have the FIPS provider loaded so we should succeed in that case.
|
||||
*/
|
||||
cipher = EVP_CIPHER_fetch(ctx, "AES-128-CBC", "default=no");
|
||||
if (tst == 3 || tst == 4) {
|
||||
if (!TEST_ptr(cipher)
|
||||
|| !TEST_true(encrypt_decrypt(cipher, testmsg, sizeof(testmsg))))
|
||||
goto err;
|
||||
} else {
|
||||
if (!TEST_ptr_null(cipher))
|
||||
goto err;
|
||||
}
|
||||
|
||||
EVP_CIPHER_free(cipher);
|
||||
cipher = NULL;
|
||||
|
||||
/*
|
||||
* Explicitly asking for the default implementation should succeed except
|
||||
* in test 4 where the default provider is not loaded.
|
||||
*/
|
||||
cipher = EVP_CIPHER_fetch(ctx, "AES-128-CBC", "default=yes");
|
||||
if (tst != 4) {
|
||||
if (!TEST_ptr(cipher)
|
||||
|| !TEST_int_eq(EVP_CIPHER_nid(cipher), NID_aes_128_cbc)
|
||||
|| !TEST_true(encrypt_decrypt(cipher, testmsg, sizeof(testmsg)))
|
||||
|| !TEST_int_eq(EVP_CIPHER_block_size(cipher), 128/8))
|
||||
goto err;
|
||||
} else {
|
||||
if (!TEST_ptr_null(cipher))
|
||||
goto err;
|
||||
}
|
||||
|
||||
EVP_CIPHER_free(cipher);
|
||||
cipher = NULL;
|
||||
|
||||
/*
|
||||
* Explicitly asking for a fips implementation should succeed if we have
|
||||
* the FIPS provider loaded and fail otherwise
|
||||
*/
|
||||
cipher = EVP_CIPHER_fetch(ctx, "AES-128-CBC", "fips=yes");
|
||||
if (tst == 3 || tst == 4) {
|
||||
if (!TEST_ptr(cipher)
|
||||
|| !TEST_true(encrypt_decrypt(cipher, testmsg, sizeof(testmsg)))
|
||||
|| !TEST_ptr(params = cipher->gettable_params())
|
||||
|| !TEST_int_gt(get_num_params(params), 1)
|
||||
|| !TEST_ptr(params = cipher->gettable_ctx_params())
|
||||
|| !TEST_int_gt(get_num_params(params), 1)
|
||||
|| !TEST_ptr(params = cipher->settable_ctx_params())
|
||||
|| !TEST_int_gt(get_num_params(params), 1))
|
||||
goto err;
|
||||
} else {
|
||||
if (!TEST_ptr_null(cipher))
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EVP_CIPHER_free(cipher);
|
||||
OSSL_PROVIDER_unload(defltprov);
|
||||
OSSL_PROVIDER_unload(fipsprov);
|
||||
/* Not normally needed, but we would like to test that
|
||||
* OPENSSL_thread_stop_ex() behaves as expected.
|
||||
*/
|
||||
if (ctx != NULL)
|
||||
OPENSSL_thread_stop_ex(ctx);
|
||||
OPENSSL_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
#endif /* OPENSSL_NO_EC */
|
||||
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
/* Test getting and setting parameters on an EVP_PKEY_CTX */
|
||||
@ -1540,13 +1215,6 @@ int setup_tests(void)
|
||||
ADD_ALL_TESTS(test_invalide_ec_char2_pub_range_decode,
|
||||
OSSL_NELEM(ec_der_pub_keys));
|
||||
#endif
|
||||
#ifdef NO_FIPS_MODULE
|
||||
ADD_ALL_TESTS(test_EVP_MD_fetch, 3);
|
||||
ADD_ALL_TESTS(test_EVP_CIPHER_fetch, 3);
|
||||
#else
|
||||
ADD_ALL_TESTS(test_EVP_MD_fetch, 5);
|
||||
ADD_ALL_TESTS(test_EVP_CIPHER_fetch, 5);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
ADD_TEST(test_EVP_PKEY_CTX_get_set_params);
|
||||
#endif
|
||||
|
251
test/evp_fetch_prov_test.c
Normal file
251
test/evp_fetch_prov_test.c
Normal file
@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/provider.h>
|
||||
#include "testutil.h"
|
||||
|
||||
static char *alg = "digest";
|
||||
static int use_default_ctx = 0;
|
||||
static char *fetch_property = NULL;
|
||||
static int expected_fetch_result = 1;
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1,
|
||||
OPT_EOF = 0,
|
||||
OPT_ALG_FETCH_TYPE,
|
||||
OPT_FETCH_PROPERTY,
|
||||
OPT_FETCH_FAILURE,
|
||||
OPT_USE_DEFAULTCTX,
|
||||
OPT_TEST_ENUM
|
||||
} OPTION_CHOICE;
|
||||
|
||||
const OPTIONS *test_get_options(void)
|
||||
{
|
||||
static const OPTIONS test_options[] = {
|
||||
OPT_TEST_OPTIONS_WITH_EXTRA_USAGE("[provname...]\n"),
|
||||
{ "type", OPT_ALG_FETCH_TYPE, 's', "The fetch type to test" },
|
||||
{ "property", OPT_FETCH_PROPERTY, 's', "The fetch property e.g. fips=yes" },
|
||||
{ "fetchfail", OPT_FETCH_FAILURE, '-', "fetch is expected to fail" },
|
||||
{ "defaultctx", OPT_USE_DEFAULTCTX, '-',
|
||||
"Use the default context if this is set" },
|
||||
{ OPT_HELP_STR, 1, '-',
|
||||
"file\tProvider names to explicitly load\n" },
|
||||
{ NULL }
|
||||
};
|
||||
return test_options;
|
||||
}
|
||||
|
||||
static int calculate_digest(const EVP_MD *md, const char *msg, size_t len,
|
||||
const unsigned char *exptd)
|
||||
{
|
||||
unsigned char out[SHA256_DIGEST_LENGTH];
|
||||
EVP_MD_CTX *ctx;
|
||||
int ret = 0;
|
||||
|
||||
if (!TEST_ptr(ctx = EVP_MD_CTX_new())
|
||||
|| !TEST_true(EVP_DigestInit_ex(ctx, md, NULL))
|
||||
|| !TEST_true(EVP_DigestUpdate(ctx, msg, len))
|
||||
|| !TEST_true(EVP_DigestFinal_ex(ctx, out, NULL))
|
||||
|| !TEST_mem_eq(out, SHA256_DIGEST_LENGTH, exptd,
|
||||
SHA256_DIGEST_LENGTH)
|
||||
|| !TEST_true(md == EVP_MD_CTX_md(ctx)))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_MD_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int load_providers(OPENSSL_CTX **libctx, OSSL_PROVIDER *prov[])
|
||||
{
|
||||
OPENSSL_CTX *ctx;
|
||||
int ret = 0;
|
||||
size_t i;
|
||||
|
||||
ctx = OPENSSL_CTX_new();
|
||||
if (!TEST_ptr(ctx))
|
||||
goto err;
|
||||
|
||||
if (test_get_argument_count() > 2)
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < test_get_argument_count(); ++i) {
|
||||
char *provname = test_get_argument(i);
|
||||
prov[i] = OSSL_PROVIDER_load(ctx, provname);
|
||||
if (!TEST_ptr(prov[i]))
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
*libctx = ctx;
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test EVP_MD_fetch()
|
||||
*/
|
||||
static int test_EVP_MD_fetch(void)
|
||||
{
|
||||
OPENSSL_CTX *ctx = NULL;
|
||||
EVP_MD *md = NULL;
|
||||
OSSL_PROVIDER *prov[2] = {NULL, NULL};
|
||||
int ret = 0;
|
||||
const char testmsg[] = "Hello world";
|
||||
const unsigned char exptd[] = {
|
||||
0x27, 0x51, 0x8b, 0xa9, 0x68, 0x30, 0x11, 0xf6, 0xb3, 0x96, 0x07, 0x2c,
|
||||
0x05, 0xf6, 0x65, 0x6d, 0x04, 0xf5, 0xfb, 0xc3, 0x78, 0x7c, 0xf9, 0x24,
|
||||
0x90, 0xec, 0x60, 0x6e, 0x50, 0x92, 0xe3, 0x26
|
||||
};
|
||||
|
||||
if (use_default_ctx == 0 && !load_providers(&ctx, prov))
|
||||
goto err;
|
||||
|
||||
/* Implicit fetching of the MD should produce the expected result */
|
||||
if (!TEST_true(calculate_digest(EVP_sha256(), testmsg, sizeof(testmsg),
|
||||
exptd))
|
||||
|| !TEST_int_eq(EVP_MD_size(EVP_sha256()), SHA256_DIGEST_LENGTH)
|
||||
|| !TEST_int_eq(EVP_MD_block_size(EVP_sha256()), SHA256_CBLOCK))
|
||||
goto err;
|
||||
|
||||
/* Fetch the digest from a provider using properties. */
|
||||
md = EVP_MD_fetch(ctx, "SHA256", fetch_property);
|
||||
if (expected_fetch_result != 0) {
|
||||
if (!TEST_ptr(md)
|
||||
|| !TEST_int_eq(EVP_MD_nid(md), NID_sha256)
|
||||
|| !TEST_true(calculate_digest(md, testmsg, sizeof(testmsg), exptd))
|
||||
|| !TEST_int_eq(EVP_MD_size(md), SHA256_DIGEST_LENGTH)
|
||||
|| !TEST_int_eq(EVP_MD_block_size(md), SHA256_CBLOCK))
|
||||
goto err;
|
||||
|
||||
/* Also test EVP_MD_up_ref() while we're doing this */
|
||||
if (!TEST_true(EVP_MD_up_ref(md)))
|
||||
goto err;
|
||||
/* Ref count should now be 2. Release first one here */
|
||||
EVP_MD_meth_free(md);
|
||||
} else {
|
||||
if (!TEST_ptr_null(md))
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EVP_MD_meth_free(md);
|
||||
OSSL_PROVIDER_unload(prov[0]);
|
||||
OSSL_PROVIDER_unload(prov[1]);
|
||||
/* Not normally needed, but we would like to test that
|
||||
* OPENSSL_thread_stop_ex() behaves as expected.
|
||||
*/
|
||||
if (ctx != NULL) {
|
||||
OPENSSL_thread_stop_ex(ctx);
|
||||
OPENSSL_CTX_free(ctx);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int encrypt_decrypt(const EVP_CIPHER *cipher, const unsigned char *msg,
|
||||
size_t len)
|
||||
{
|
||||
int ret = 0, ctlen, ptlen;
|
||||
EVP_CIPHER_CTX *ctx = NULL;
|
||||
unsigned char key[128 / 8];
|
||||
unsigned char ct[64], pt[64];
|
||||
|
||||
memset(key, 0, sizeof(key));
|
||||
if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
|
||||
|| !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 1))
|
||||
|| !TEST_true(EVP_CipherUpdate(ctx, ct, &ctlen, msg, len))
|
||||
|| !TEST_true(EVP_CipherFinal_ex(ctx, ct, &ctlen))
|
||||
|| !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 0))
|
||||
|| !TEST_true(EVP_CipherUpdate(ctx, pt, &ptlen, ct, ctlen))
|
||||
|| !TEST_true(EVP_CipherFinal_ex(ctx, pt, &ptlen))
|
||||
|| !TEST_mem_eq(pt, ptlen, msg, len))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test EVP_CIPHER_fetch()
|
||||
*/
|
||||
static int test_EVP_CIPHER_fetch(void)
|
||||
{
|
||||
OPENSSL_CTX *ctx = NULL;
|
||||
EVP_CIPHER *cipher = NULL;
|
||||
OSSL_PROVIDER *prov[2] = {NULL, NULL};
|
||||
int ret = 0;
|
||||
const unsigned char testmsg[] = "Hello world";
|
||||
|
||||
if (use_default_ctx == 0 && !load_providers(&ctx, prov))
|
||||
goto err;
|
||||
|
||||
/* Implicit fetching of the cipher should produce the expected result */
|
||||
if (!TEST_true(encrypt_decrypt(EVP_aes_128_cbc(), testmsg, sizeof(testmsg))))
|
||||
goto err;
|
||||
|
||||
/* Fetch the cipher from a provider using properties. */
|
||||
cipher = EVP_CIPHER_fetch(ctx, "AES-128-CBC", fetch_property);
|
||||
if (expected_fetch_result != 0) {
|
||||
if (!TEST_ptr(cipher)
|
||||
|| !TEST_true(encrypt_decrypt(cipher, testmsg, sizeof(testmsg)))) {
|
||||
if (!TEST_true(EVP_CIPHER_up_ref(cipher)))
|
||||
goto err;
|
||||
/* Ref count should now be 2. Release first one here */
|
||||
EVP_CIPHER_meth_free(cipher);
|
||||
}
|
||||
} else {
|
||||
if (!TEST_ptr_null(cipher))
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_CIPHER_meth_free(cipher);
|
||||
OSSL_PROVIDER_unload(prov[0]);
|
||||
OSSL_PROVIDER_unload(prov[1]);
|
||||
OPENSSL_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int setup_tests(void)
|
||||
{
|
||||
OPTION_CHOICE o;
|
||||
|
||||
while ((o = opt_next()) != OPT_EOF) {
|
||||
switch (o) {
|
||||
case OPT_ALG_FETCH_TYPE:
|
||||
alg = opt_arg();
|
||||
break;
|
||||
case OPT_FETCH_PROPERTY:
|
||||
fetch_property = opt_arg();
|
||||
break;
|
||||
case OPT_FETCH_FAILURE:
|
||||
expected_fetch_result = 0;
|
||||
break;
|
||||
case OPT_USE_DEFAULTCTX:
|
||||
use_default_ctx = 1;
|
||||
break;
|
||||
case OPT_TEST_CASES:
|
||||
break;
|
||||
default:
|
||||
case OPT_ERR:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (strcmp(alg, "digest") == 0)
|
||||
ADD_TEST(test_EVP_MD_fetch);
|
||||
else
|
||||
ADD_TEST(test_EVP_CIPHER_fetch);
|
||||
return 1;
|
||||
}
|
@ -1,10 +1,9 @@
|
||||
openssl_conf = openssl_init
|
||||
|
||||
.include fipsinstall.conf
|
||||
|
||||
[openssl_init]
|
||||
providers = provider_sect
|
||||
|
||||
[provider_sect]
|
||||
fips = fips_sect
|
||||
|
||||
[fips_sect]
|
||||
activate = 1
|
||||
|
@ -10,10 +10,16 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use OpenSSL::Test qw(:DEFAULT data_file bldtop_dir srctop_file);
|
||||
use OpenSSL::Test qw(:DEFAULT data_file bldtop_dir srctop_file srctop_dir bldtop_file);
|
||||
use OpenSSL::Test::Utils;
|
||||
|
||||
BEGIN {
|
||||
setup("test_evp");
|
||||
}
|
||||
|
||||
use lib srctop_dir('Configurations');
|
||||
use lib bldtop_dir('.');
|
||||
use platform;
|
||||
|
||||
# Default config depends on if the legacy module is built or not
|
||||
my $defaultcnf = disabled('legacy') ? 'default.cnf' : 'default-and-legacy.cnf';
|
||||
@ -27,7 +33,17 @@ my @defltfiles = qw( evpencod.txt evpkdf.txt evppkey_kdf.txt evpmac.txt
|
||||
evppbe.txt evppkey.txt evppkey_ecc.txt evpcase.txt evpaessiv.txt
|
||||
evpccmcavs.txt );
|
||||
|
||||
plan tests => (scalar(@configs) * scalar(@files)) + scalar(@defltfiles);
|
||||
plan tests => (scalar(@configs) * scalar(@files)) + scalar(@defltfiles) + 1;
|
||||
|
||||
my $infile = bldtop_file('providers', platform->dso('fips'));
|
||||
$ENV{OPENSSL_MODULES} = bldtop_dir("providers");
|
||||
$ENV{OPENSSL_CONF_INCLUDE} = bldtop_dir("providers");
|
||||
|
||||
ok(run(app(['openssl', 'fipsinstall', '-out', bldtop_file('providers', 'fipsinstall.conf'),
|
||||
'-module', $infile,
|
||||
'-provider_name', 'fips', '-mac_name', 'HMAC',
|
||||
'-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
|
||||
'-section_name', 'fips_sect'])), "fipinstall");
|
||||
|
||||
foreach (@configs) {
|
||||
$ENV{OPENSSL_CONF} = srctop_file("test", $_);
|
||||
|
79
test/recipes/30-test_evp_fetch_prov.t
Normal file
79
test/recipes/30-test_evp_fetch_prov.t
Normal file
@ -0,0 +1,79 @@
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2015-2016 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
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use OpenSSL::Test qw(:DEFAULT bldtop_dir srctop_file srctop_dir bldtop_file);
|
||||
use OpenSSL::Test::Utils;
|
||||
|
||||
BEGIN {
|
||||
setup("test_evp_fetch_prov");
|
||||
}
|
||||
|
||||
use lib srctop_dir('Configurations');
|
||||
use lib bldtop_dir('.');
|
||||
use platform;
|
||||
|
||||
my @types = ( "digest", "cipher" );
|
||||
|
||||
plan tests => 2 + 16 * scalar(@types);
|
||||
|
||||
$ENV{OPENSSL_MODULES} = bldtop_dir("providers");
|
||||
$ENV{OPENSSL_CONF_INCLUDE} = bldtop_dir("providers");
|
||||
|
||||
my $infile = bldtop_file('providers', platform->dso('fips'));
|
||||
ok(run(app(['openssl', 'fipsinstall', '-out', bldtop_file('providers', 'fipsinstall.conf'),
|
||||
'-module', $infile,
|
||||
'-provider_name', 'fips', '-mac_name', 'HMAC',
|
||||
'-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
|
||||
'-section_name', 'fips_sect'])), "fipinstall");
|
||||
|
||||
# Do implicit fetch using the default context
|
||||
ok(run(test(["evp_fetch_prov_test", "-defaultctx"])),
|
||||
"running evp_fetch_prov_test using implicit fetch using the default libctx");
|
||||
|
||||
foreach my $alg(@types) {
|
||||
$ENV{OPENSSL_CONF} = srctop_file("test", "default.cnf");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg"])),
|
||||
"running evp_fetch_prov_test using implicit fetch using a created libctx");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "default"])),
|
||||
"running evp_fetch_prov_test with implicit fetch using default provider loaded");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "-property", "default=yes", "default"])),
|
||||
"running evp_fetch_prov_test with $alg fetch 'default=yes' using default provider loaded");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "-property", "fips=no", "default"])),
|
||||
"running evp_fetch_prov_test with $alg fetch 'fips=no' using default provider loaded");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "-property", "default=no", "-fetchfail", "default"])),
|
||||
"running evp_fetch_prov_test with $alg fetch 'default=no' using default provider loaded should fail");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "-property", "fips=yes", "-fetchfail", "default"])),
|
||||
"running evp_fetch_prov_test with $alg fetch 'fips=yes' using default provider loaded should fail");
|
||||
|
||||
$ENV{OPENSSL_CONF} = srctop_file("test", "fips.cnf");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "-property", "", "fips"])),
|
||||
"running evp_fetch_prov_test with $alg fetch '' using loaded fips provider");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "-property", "fips=yes", "fips"])),
|
||||
"running evp_fetch_prov_test with $alg fetch 'fips=yes' using loaded fips provider");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "-property", "default=no", "fips"])),
|
||||
"running evp_fetch_prov_test with $alg fetch 'default=no' using loaded fips provider");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "-property", "default=yes", "-fetchfail", "fips"])),
|
||||
"running evp_fetch_prov_test with $alg fetch 'default=yes' using loaded fips provider should fail");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "-property", "fips=no", "-fetchfail", "fips"])),
|
||||
"running evp_fetch_prov_test with $alg fetch 'fips=no' using loaded fips provider should fail");
|
||||
|
||||
$ENV{OPENSSL_CONF} = srctop_file("test", "default-and-fips.cnf");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "-property", "", "default", "fips"])),
|
||||
"running evp_fetch_prov_test with $alg fetch '' using loaded default & fips provider");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "-property", "default=no", "default", "fips"])),
|
||||
"running evp_fetch_prov_test with $alg fetch 'default=no' using loaded default & fips provider");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "-property", "default=yes", "default", "fips"])),
|
||||
"running evp_fetch_prov_test with $alg fetch 'default=yes' using loaded default & fips provider");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "-property", "fips=no", "default", "fips"])),
|
||||
"running evp_fetch_prov_test with $alg fetch 'fips=no' using loaded default & fips provider");
|
||||
ok(run(test(["evp_fetch_prov_test", "-type", "$alg", "-property", "fips=yes", "default", "fips"])),
|
||||
"running evp_fetch_prov_test with $alg fetch 'fips=yes' using loaded default & fips provider");
|
||||
}
|
Loading…
Reference in New Issue
Block a user