Latest update.

This commit is contained in:
2019-05-23 12:02:56 +09:00
parent a7bf77581f
commit 64d458de91
185 changed files with 5859 additions and 2853 deletions
+7 -2
View File
@@ -217,7 +217,7 @@ int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
uint64_t p, r, N;
size_t saltlen;
size_t keylen = 0;
int rv = 0;
int t, rv = 0;
SCRYPT_PARAMS *sparam = NULL;
if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
@@ -234,7 +234,12 @@ int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
goto err;
}
keylen = EVP_CIPHER_CTX_key_length(ctx);
t = EVP_CIPHER_CTX_key_length(ctx);
if (t < 0) {
EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, EVP_R_INVALID_KEY_LENGTH);
goto err;
}
keylen = t;
/* Now check the parameters of sparam */
+44
View File
@@ -0,0 +1,44 @@
/*
* 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 <stddef.h>
#include "internal/cryptlib.h"
const void *ossl_bsearch(const void *key, const void *base, int num,
int size, int (*cmp) (const void *, const void *),
int flags)
{
const char *base_ = base;
int l, h, i = 0, c = 0;
const char *p = NULL;
if (num == 0)
return NULL;
l = 0;
h = num;
while (l < h) {
i = (l + h) / 2;
p = &(base_[i * size]);
c = (*cmp) (key, p);
if (c < 0)
h = i;
else if (c > 0)
l = i + 1;
else
break;
}
if (c != 0 && !(flags & OSSL_BSEARCH_VALUE_ON_NOMATCH))
p = NULL;
else if (c == 0 && (flags & OSSL_BSEARCH_FIRST_VALUE_ON_MATCH)) {
while (i > 0 && (*cmp) (key, &(base_[(i - 1) * size])) == 0)
i--;
p = &(base_[i * size]);
}
return p;
}
+3 -3
View File
@@ -10,7 +10,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 x509v3 conf \
LIBS=../libcrypto
# The Core
SOURCE[../libcrypto]=provider_core.c provider_predefined.c provider_conf.c \
core_fetch.c
core_fetch.c core_namemap.c
# Central utilities
SOURCE[../libcrypto]=\
@@ -18,12 +18,12 @@ SOURCE[../libcrypto]=\
ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fopen.c ctype.c \
threads_pthread.c threads_win.c threads_none.c getenv.c \
o_init.c o_fips.c mem_sec.c init.c context.c sparse_array.c \
trace.c provider.c params.c \
trace.c provider.c params.c bsearch.c \
{- $target{cpuid_asm_src} -} {- $target{uplink_aux_src} -}
# FIPS module
SOURCE[../providers/fips]=\
cryptlib.c mem.c mem_clr.c params.c
cryptlib.c mem.c mem_clr.c params.c bsearch.c
DEPEND[cversion.o]=buildinf.h
+194 -22
View File
@@ -10,38 +10,106 @@
#include "internal/cryptlib.h"
#include "internal/thread_once.h"
struct openssl_ctx_onfree_list_st {
openssl_ctx_onfree_fn *fn;
struct openssl_ctx_onfree_list_st *next;
};
struct openssl_ctx_st {
CRYPTO_RWLOCK *lock;
CRYPTO_EX_DATA data;
/*
* For most data in the OPENSSL_CTX we just use ex_data to store it. But
* that doesn't work for ex_data itself - so we store that directly.
*/
OSSL_EX_DATA_GLOBAL global;
/* Map internal static indexes to dynamically created indexes */
int dyn_indexes[OPENSSL_CTX_MAX_INDEXES];
CRYPTO_RWLOCK *oncelock;
int run_once_done[OPENSSL_CTX_MAX_RUN_ONCE];
int run_once_ret[OPENSSL_CTX_MAX_RUN_ONCE];
struct openssl_ctx_onfree_list_st *onfreelist;
};
static OPENSSL_CTX default_context;
#ifndef FIPS_MODE
static OPENSSL_CTX default_context_int;
#endif
/* Always points at default_context_int if it has been initialised */
static OPENSSL_CTX *default_context = NULL;
static int context_init(OPENSSL_CTX *ctx)
{
return (ctx->lock = CRYPTO_THREAD_lock_new()) != NULL
&& CRYPTO_new_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL,
&ctx->data);
size_t i;
ctx->lock = CRYPTO_THREAD_lock_new();
if (ctx->lock == NULL)
return 0;
ctx->oncelock = CRYPTO_THREAD_lock_new();
if (ctx->oncelock == NULL)
goto err;
for (i = 0; i < OPENSSL_CTX_MAX_INDEXES; i++)
ctx->dyn_indexes[i] = -1;
if (!do_ex_data_init(ctx))
goto err;
if (!crypto_new_ex_data_ex(ctx, CRYPTO_EX_INDEX_OPENSSL_CTX, NULL,
&ctx->data)) {
crypto_cleanup_all_ex_data_int(ctx);
goto err;
}
return 1;
err:
CRYPTO_THREAD_lock_free(ctx->oncelock);
CRYPTO_THREAD_lock_free(ctx->lock);
ctx->lock = NULL;
return 0;
}
static int context_deinit(OPENSSL_CTX *ctx)
{
struct openssl_ctx_onfree_list_st *tmp, *onfree;
if (ctx == NULL)
return 1;
onfree = ctx->onfreelist;
while (onfree != NULL) {
onfree->fn(ctx);
tmp = onfree;
onfree = onfree->next;
OPENSSL_free(tmp);
}
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL, &ctx->data);
crypto_cleanup_all_ex_data_int(ctx);
CRYPTO_THREAD_lock_free(ctx->oncelock);
CRYPTO_THREAD_lock_free(ctx->lock);
ctx->lock = NULL;
return 1;
}
static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT;
static void do_default_context_deinit(void)
#ifndef FIPS_MODE
void openssl_ctx_default_deinit(void)
{
context_deinit(&default_context);
context_deinit(default_context);
}
static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(do_default_context_init)
{
return OPENSSL_init_crypto(0, NULL)
&& context_init(&default_context)
&& OPENSSL_atexit(do_default_context_deinit);
if (context_init(&default_context_int))
default_context = &default_context_int;
return 1;
}
#endif
OPENSSL_CTX *OPENSSL_CTX_new(void)
{
@@ -66,7 +134,7 @@ static void openssl_ctx_generic_new(void *parent_ign, void *ptr_ign,
long argl_ign, void *argp)
{
const OPENSSL_CTX_METHOD *meth = argp;
void *ptr = meth->new_func();
void *ptr = meth->new_func(crypto_ex_data_get_openssl_ctx(ad));
if (ptr != NULL)
CRYPTO_set_ex_data(ad, index, ptr);
@@ -79,32 +147,136 @@ static void openssl_ctx_generic_free(void *parent_ign, void *ptr,
meth->free_func(ptr);
}
int openssl_ctx_new_index(const OPENSSL_CTX_METHOD *meth)
{
return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_OPENSSL_CTX, 0, (void *)meth,
openssl_ctx_generic_new, NULL,
openssl_ctx_generic_free);
}
void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index)
/* Non-static so we can use it in context_internal_test */
static int openssl_ctx_init_index(OPENSSL_CTX *ctx, int static_index,
const OPENSSL_CTX_METHOD *meth)
{
void *data = NULL;
int idx;
#ifndef FIPS_MODE
if (ctx == NULL) {
if (!RUN_ONCE(&default_context_init, do_default_context_init))
return 0;
ctx = &default_context;
ctx = default_context;
}
#endif
if (ctx == NULL)
return 0;
idx = crypto_get_ex_new_index_ex(ctx, CRYPTO_EX_INDEX_OPENSSL_CTX, 0,
(void *)meth,
openssl_ctx_generic_new,
NULL, openssl_ctx_generic_free);
if (idx < 0)
return 0;
ctx->dyn_indexes[static_index] = idx;
return 1;
}
void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index,
const OPENSSL_CTX_METHOD *meth)
{
void *data = NULL;
#ifndef FIPS_MODE
if (ctx == NULL) {
if (!RUN_ONCE(&default_context_init, do_default_context_init))
return NULL;
ctx = default_context;
}
#endif
if (ctx == NULL)
return NULL;
CRYPTO_THREAD_read_lock(ctx->lock);
if (ctx->dyn_indexes[index] == -1
&& !openssl_ctx_init_index(ctx, index, meth)) {
CRYPTO_THREAD_unlock(ctx->lock);
return NULL;
}
/* The alloc call ensures there's a value there */
if (CRYPTO_alloc_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL,
&ctx->data, index))
data = CRYPTO_get_ex_data(&ctx->data, index);
&ctx->data, ctx->dyn_indexes[index]))
data = CRYPTO_get_ex_data(&ctx->data, ctx->dyn_indexes[index]);
CRYPTO_THREAD_unlock(ctx->lock);
return data;
}
OSSL_EX_DATA_GLOBAL *openssl_ctx_get_ex_data_global(OPENSSL_CTX *ctx)
{
/*
* The default context code is not needed in FIPS_MODE and ctx should never
* be NULL in the FIPS provider. However we compile this code out to ensure
* we fail immediately if ctx == NULL in FIPS_MODE
*/
#ifndef FIPS_MODE
if (ctx == NULL) {
if (!RUN_ONCE(&default_context_init, do_default_context_init))
return NULL;
ctx = default_context;
}
#endif
if (ctx == NULL)
return NULL;
return &ctx->global;
}
int openssl_ctx_run_once(OPENSSL_CTX *ctx, unsigned int idx,
openssl_ctx_run_once_fn run_once_fn)
{
int done = 0, ret = 0;
#ifndef FIPS_MODE
if (ctx == NULL) {
if (!RUN_ONCE(&default_context_init, do_default_context_init))
return 0;
ctx = default_context;
}
#endif
if (ctx == NULL)
return 0;
CRYPTO_THREAD_read_lock(ctx->oncelock);
done = ctx->run_once_done[idx];
if (done)
ret = ctx->run_once_ret[idx];
CRYPTO_THREAD_unlock(ctx->oncelock);
if (done)
return ret;
CRYPTO_THREAD_write_lock(ctx->oncelock);
if (ctx->run_once_done[idx]) {
ret = ctx->run_once_ret[idx];
CRYPTO_THREAD_unlock(ctx->oncelock);
return ret;
}
ret = run_once_fn(ctx);
ctx->run_once_done[idx] = 1;
ctx->run_once_ret[idx] = ret;
CRYPTO_THREAD_unlock(ctx->oncelock);
return ret;
}
int openssl_ctx_onfree(OPENSSL_CTX *ctx, openssl_ctx_onfree_fn onfreefn)
{
struct openssl_ctx_onfree_list_st *newonfree
= OPENSSL_malloc(sizeof(*newonfree));
if (newonfree == NULL)
return 0;
newonfree->fn = onfreefn;
newonfree->next = ctx->onfreelist;
ctx->onfreelist = newonfree;
return 1;
}
+10 -9
View File
@@ -56,14 +56,14 @@ static int ossl_method_construct_this(OSSL_PROVIDER *provider, void *cbdata)
* If we haven't been told not to store,
* add to the global store
*/
data->mcm->put(data->libctx, NULL,
thismap->property_definition,
method, data->mcm_data);
data->mcm->put(data->libctx, NULL, method,
thismap->algorithm_name,
thismap->property_definition, data->mcm_data);
}
data->mcm->put(data->libctx, data->store,
thismap->property_definition,
method, data->mcm_data);
data->mcm->put(data->libctx, data->store, method,
thismap->algorithm_name, thismap->property_definition,
data->mcm_data);
/* refcnt-- because we're dropping the reference */
data->mcm->destruct(method, data->mcm_data);
@@ -79,14 +79,15 @@ void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id,
{
void *method = NULL;
if ((method = mcm->get(libctx, NULL, propquery, mcm_data)) == NULL) {
if ((method =
mcm->get(libctx, NULL, name, propquery, mcm_data)) == NULL) {
struct construct_data_st cbdata;
/*
* We have a temporary store to be able to easily search among new
* items, or items that should find themselves in the global store.
*/
if ((cbdata.store = mcm->alloc_tmp_store()) == NULL)
if ((cbdata.store = mcm->alloc_tmp_store(libctx)) == NULL)
goto fin;
cbdata.libctx = libctx;
@@ -97,7 +98,7 @@ void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id,
ossl_provider_forall_loaded(libctx, ossl_method_construct_this,
&cbdata);
method = mcm->get(libctx, cbdata.store, propquery, mcm_data);
method = mcm->get(libctx, cbdata.store, name, propquery, mcm_data);
mcm->dealloc_tmp_store(cbdata.store);
}
+211
View File
@@ -0,0 +1,211 @@
/*
* 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 "internal/namemap.h"
#include <openssl/lhash.h>
#include <openssl/safestack.h>
/* The namemap entry */
typedef struct {
int number;
const char *name;
char body[1]; /* Sized appropriately to contain the name */
} NAMEMAP_ENTRY;
DEFINE_LHASH_OF(NAMEMAP_ENTRY);
DEFINE_STACK_OF(NAMEMAP_ENTRY)
/* The namemap, which provides for bidirectional indexing */
struct ossl_namemap_st {
/* Flags */
unsigned int stored:1; /* If 1, it's stored in a library context */
CRYPTO_RWLOCK *lock;
LHASH_OF(NAMEMAP_ENTRY) *namenum; /* Name->number mapping */
STACK_OF(NAMEMAP_ENTRY) *numname; /* Number->name mapping */
};
/* LHASH callbacks */
static unsigned long namemap_hash(const NAMEMAP_ENTRY *n)
{
return OPENSSL_LH_strhash(n->name);
}
static int namemap_cmp(const NAMEMAP_ENTRY *a, const NAMEMAP_ENTRY *b)
{
return strcmp(a->name, b->name);
}
static void namemap_free(NAMEMAP_ENTRY *n)
{
OPENSSL_free(n);
}
/* OPENSSL_CTX_METHOD functions for a namemap stored in a library context */
static void *stored_namemap_new(OPENSSL_CTX *libctx)
{
OSSL_NAMEMAP *namemap = ossl_namemap_new();
if (namemap != NULL)
namemap->stored = 1;
return namemap;
}
static void stored_namemap_free(void *vnamemap)
{
OSSL_NAMEMAP *namemap = vnamemap;
/* Pretend it isn't stored, or ossl_namemap_free() will do nothing */
namemap->stored = 0;
ossl_namemap_free(namemap);
}
static const OPENSSL_CTX_METHOD stored_namemap_method = {
stored_namemap_new,
stored_namemap_free,
};
/* API functions */
OSSL_NAMEMAP *ossl_namemap_stored(OPENSSL_CTX *libctx)
{
return openssl_ctx_get_data(libctx, OPENSSL_CTX_NAMEMAP_INDEX,
&stored_namemap_method);
}
OSSL_NAMEMAP *ossl_namemap_new(void)
{
OSSL_NAMEMAP *namemap;
if ((namemap = OPENSSL_zalloc(sizeof(*namemap))) != NULL
&& (namemap->lock = CRYPTO_THREAD_lock_new()) != NULL
&& (namemap->numname = sk_NAMEMAP_ENTRY_new_null()) != NULL
&& (namemap->namenum =
lh_NAMEMAP_ENTRY_new(namemap_hash, namemap_cmp)) != NULL) {
return namemap;
}
ossl_namemap_free(namemap);
return NULL;
}
void ossl_namemap_free(OSSL_NAMEMAP *namemap)
{
if (namemap == NULL || namemap->stored)
return;
/* The elements will be freed by sk_NAMEMAP_ENTRY_pop_free() */
lh_NAMEMAP_ENTRY_free(namemap->namenum);
sk_NAMEMAP_ENTRY_pop_free(namemap->numname, namemap_free);
CRYPTO_THREAD_lock_free(namemap->lock);
OPENSSL_free(namemap);
}
/*
* TODO(3.0) It isn't currently possible to have a default namemap in the
* FIPS module because if init and cleanup constraints, so we currently
* disable the code that would allow it when FIPS_MODE is defined.
*/
const char *ossl_namemap_name(const OSSL_NAMEMAP *namemap, int number)
{
NAMEMAP_ENTRY *entry;
#ifndef FIPS_MODE
if (namemap == NULL)
namemap = ossl_namemap_stored(NULL);
#endif
if (namemap == NULL || number == 0)
return NULL;
CRYPTO_THREAD_read_lock(namemap->lock);
entry = sk_NAMEMAP_ENTRY_value(namemap->numname, number);
CRYPTO_THREAD_unlock(namemap->lock);
if (entry != NULL)
return entry->name;
return NULL;
}
int ossl_namemap_number(const OSSL_NAMEMAP *namemap, const char *name)
{
NAMEMAP_ENTRY *entry, template;
#ifndef FIPS_MODE
if (namemap == NULL)
namemap = ossl_namemap_stored(NULL);
#endif
if (namemap == NULL)
return 0;
template.name = name;
CRYPTO_THREAD_read_lock(namemap->lock);
entry = lh_NAMEMAP_ENTRY_retrieve(namemap->namenum, &template);
CRYPTO_THREAD_unlock(namemap->lock);
if (entry == NULL)
return 0;
return entry->number;
}
int ossl_namemap_add(OSSL_NAMEMAP *namemap, const char *name)
{
NAMEMAP_ENTRY *entry;
int number;
#ifndef FIPS_MODE
if (namemap == NULL)
namemap = ossl_namemap_stored(NULL);
#endif
if (name == NULL || namemap == NULL)
return 0;
if ((number = ossl_namemap_number(namemap, name)) != 0)
return number; /* Pretend success */
if ((entry = OPENSSL_zalloc(sizeof(*entry) + strlen(name))) == NULL)
goto err;
strcpy(entry->body, name);
entry->name = entry->body;
CRYPTO_THREAD_write_lock(namemap->lock);
entry->number = sk_NAMEMAP_ENTRY_push(namemap->numname, entry);
if (entry->number == 0)
goto err;
(void)lh_NAMEMAP_ENTRY_insert(namemap->namenum, entry);
if (lh_NAMEMAP_ENTRY_error(namemap->namenum))
goto err;
CRYPTO_THREAD_unlock(namemap->lock);
return entry->number;
err:
if (entry != NULL) {
if (entry->number != 0)
(void)sk_NAMEMAP_ENTRY_pop(namemap->numname);
lh_NAMEMAP_ENTRY_delete(namemap->namenum, entry);
CRYPTO_THREAD_unlock(namemap->lock);
}
return 0;
}
+6 -2
View File
@@ -21,9 +21,13 @@ static const ERR_STRING_DATA CRYPTO_str_functs[] = {
"CRYPTO_free_ex_data"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, 0),
"CRYPTO_get_ex_new_index"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX, 0),
"CRYPTO_get_ex_new_index_ex"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_MEMDUP, 0), "CRYPTO_memdup"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_NEW_EX_DATA, 0),
"CRYPTO_new_ex_data"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_NEW_EX_DATA_EX, 0),
"crypto_new_ex_data_ex"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_OCB128_COPY_CTX, 0),
"CRYPTO_ocb128_copy_ctx"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_OCB128_INIT, 0),
@@ -46,10 +50,10 @@ static const ERR_STRING_DATA CRYPTO_str_functs[] = {
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_SK_DEEP_COPY, 0),
"OPENSSL_sk_deep_copy"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_SK_DUP, 0), "OPENSSL_sk_dup"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ADD_BUILTIN, 0),
"OSSL_PROVIDER_add_builtin"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ACTIVATE, 0),
"ossl_provider_activate"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ADD_BUILTIN, 0),
"OSSL_PROVIDER_add_builtin"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER, 0),
"ossl_provider_add_parameter"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_NEW, 0),
+1 -1
View File
@@ -54,7 +54,7 @@ static int pkey_dh_init(EVP_PKEY_CTX *ctx)
DHerr(DH_F_PKEY_DH_INIT, ERR_R_MALLOC_FAILURE);
return 0;
}
dctx->prime_len = 1024;
dctx->prime_len = 2048;
dctx->subprime_len = -1;
dctx->generator = 2;
dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
+6
View File
@@ -190,6 +190,12 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
return 0;
}
/* Reject obviously invalid parameters */
if (BN_is_zero(dsa->p) || BN_is_zero(dsa->q) || BN_is_zero(dsa->g)) {
DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_INVALID_PARAMETERS);
return 0;
}
k = BN_new();
l = BN_new();
if (k == NULL || l == NULL)
+9 -5
View File
@@ -20,8 +20,8 @@
typedef struct {
/* Parameter gen parameters */
int nbits; /* size of p in bits (default: 1024) */
int qbits; /* size of q in bits (default: 160) */
int nbits; /* size of p in bits (default: 2048) */
int qbits; /* size of q in bits (default: 224) */
const EVP_MD *pmd; /* MD for parameter generation */
/* Keygen callback info */
int gentmp[2];
@@ -35,8 +35,8 @@ static int pkey_dsa_init(EVP_PKEY_CTX *ctx)
if (dctx == NULL)
return 0;
dctx->nbits = 1024;
dctx->qbits = 160;
dctx->nbits = 2048;
dctx->qbits = 224;
dctx->pmd = NULL;
dctx->md = NULL;
@@ -138,7 +138,11 @@ static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
EVP_MD_type((const EVP_MD *)p2) != NID_sha512 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_224 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_256 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_384 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512) {
DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
return 0;
}
+5 -1
View File
@@ -323,7 +323,11 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
EVP_MD_type((const EVP_MD *)p2) != NID_sha512 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_224 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_256 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_384 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512) {
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
return 0;
}
+15 -49
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015-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
@@ -10,62 +10,28 @@
#include <string.h>
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/kdf.h>
#include "ec_lcl.h"
/* Key derivation function from X9.63/SECG */
/* Way more than we will ever need */
#define ECDH_KDF_MAX (1 << 30)
int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
const unsigned char *Z, size_t Zlen,
const unsigned char *sinfo, size_t sinfolen,
const EVP_MD *md)
{
EVP_MD_CTX *mctx = NULL;
int rv = 0;
unsigned int i;
size_t mdlen;
unsigned char ctr[4];
if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX
|| Zlen > ECDH_KDF_MAX)
return 0;
mctx = EVP_MD_CTX_new();
if (mctx == NULL)
return 0;
mdlen = EVP_MD_size(md);
for (i = 1;; i++) {
unsigned char mtmp[EVP_MAX_MD_SIZE];
if (!EVP_DigestInit_ex(mctx, md, NULL))
goto err;
ctr[3] = i & 0xFF;
ctr[2] = (i >> 8) & 0xFF;
ctr[1] = (i >> 16) & 0xFF;
ctr[0] = (i >> 24) & 0xFF;
if (!EVP_DigestUpdate(mctx, Z, Zlen))
goto err;
if (!EVP_DigestUpdate(mctx, ctr, sizeof(ctr)))
goto err;
if (!EVP_DigestUpdate(mctx, sinfo, sinfolen))
goto err;
if (outlen >= mdlen) {
if (!EVP_DigestFinal(mctx, out, NULL))
goto err;
outlen -= mdlen;
if (outlen == 0)
break;
out += mdlen;
} else {
if (!EVP_DigestFinal(mctx, mtmp, NULL))
goto err;
memcpy(out, mtmp, outlen);
OPENSSL_cleanse(mtmp, mdlen);
break;
}
}
rv = 1;
err:
EVP_MD_CTX_free(mctx);
return rv;
int ret;
EVP_KDF_CTX *kctx = NULL;
kctx = EVP_KDF_CTX_new(EVP_get_kdfbyname(SN_x963kdf));
ret =
kctx != NULL
&& EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, md) > 0
&& EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, Z, Zlen) > 0
&& EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SHARED_INFO, sinfo, sinfolen) > 0
&& EVP_KDF_derive(kctx, out, outlen) > 0;
EVP_KDF_CTX_free(kctx);
return ret;
}
/*-
+6 -3
View File
@@ -189,12 +189,15 @@ typedef struct {
static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
const int n = EVP_CIPHER_CTX_key_length(ctx);
# ifdef TEST_ENG_OPENSSL_RC4_P_INIT
fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
# endif
memcpy(&test(ctx)->key[0], key, EVP_CIPHER_CTX_key_length(ctx));
RC4_set_key(&test(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
test(ctx)->key);
if (n <= 0)
return n;
memcpy(&test(ctx)->key[0], key, n);
RC4_set_key(&test(ctx)->ks, n, test(ctx)->key);
return 1;
}
+1 -1
View File
@@ -92,7 +92,7 @@ int err_load_crypto_strings_int(void)
# ifndef OPENSSL_NO_CMS
ERR_load_CMS_strings() == 0 ||
# endif
# ifndef OPENSSL_NO_CMP
# ifndef OPENSSL_NO_CRMF
ERR_load_CRMF_strings() == 0 ||
# endif
# ifndef OPENSSL_NO_CT
+7
View File
@@ -374,8 +374,10 @@ CRYPTO_F_CMAC_CTX_NEW:120:CMAC_CTX_new
CRYPTO_F_CRYPTO_DUP_EX_DATA:110:CRYPTO_dup_ex_data
CRYPTO_F_CRYPTO_FREE_EX_DATA:111:CRYPTO_free_ex_data
CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX:100:CRYPTO_get_ex_new_index
CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX:141:crypto_get_ex_new_index_ex
CRYPTO_F_CRYPTO_MEMDUP:115:CRYPTO_memdup
CRYPTO_F_CRYPTO_NEW_EX_DATA:112:CRYPTO_new_ex_data
CRYPTO_F_CRYPTO_NEW_EX_DATA_EX:142:crypto_new_ex_data_ex
CRYPTO_F_CRYPTO_OCB128_COPY_CTX:121:CRYPTO_ocb128_copy_ctx
CRYPTO_F_CRYPTO_OCB128_INIT:122:CRYPTO_ocb128_init
CRYPTO_F_CRYPTO_SET_EX_DATA:102:CRYPTO_set_ex_data
@@ -800,6 +802,7 @@ EVP_F_EVP_ENCRYPTFINAL_EX:127:EVP_EncryptFinal_ex
EVP_F_EVP_ENCRYPTUPDATE:167:EVP_EncryptUpdate
EVP_F_EVP_KDF_CTRL:224:EVP_KDF_ctrl
EVP_F_EVP_KDF_CTRL_STR:225:EVP_KDF_ctrl_str
EVP_F_EVP_KDF_CTX_NEW:240:EVP_KDF_CTX_new
EVP_F_EVP_KDF_CTX_NEW_ID:226:EVP_KDF_CTX_new_id
EVP_F_EVP_MAC_CTRL:209:EVP_MAC_ctrl
EVP_F_EVP_MAC_CTRL_STR:210:EVP_MAC_ctrl_str
@@ -922,6 +925,7 @@ KDF_F_SSKDF_MAC2CTRL:136:sskdf_mac2ctrl
KDF_F_SSKDF_NEW:137:sskdf_new
KDF_F_SSKDF_SIZE:138:sskdf_size
KDF_F_TLS1_PRF_ALG:111:tls1_prf_alg
KDF_F_X963KDF_DERIVE:139:x963kdf_derive
OBJ_F_OBJ_ADD_OBJECT:105:OBJ_add_object
OBJ_F_OBJ_ADD_SIGID:107:OBJ_add_sigid
OBJ_F_OBJ_CREATE:100:OBJ_create
@@ -1434,6 +1438,7 @@ SSL_F_SSL_RENEGOTIATE:516:SSL_renegotiate
SSL_F_SSL_RENEGOTIATE_ABBREVIATED:546:SSL_renegotiate_abbreviated
SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT:320:*
SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT:321:*
SSL_F_SSL_SENDFILE:639:SSL_sendfile
SSL_F_SSL_SESSION_DUP:348:ssl_session_dup
SSL_F_SSL_SESSION_NEW:189:SSL_SESSION_new
SSL_F_SSL_SESSION_PRINT_FP:190:SSL_SESSION_print_fp
@@ -2396,6 +2401,7 @@ EVP_R_INPUT_NOT_INITIALIZED:111:input not initialized
EVP_R_INVALID_CUSTOM_LENGTH:185:invalid custom length
EVP_R_INVALID_DIGEST:152:invalid digest
EVP_R_INVALID_FIPS_MODE:168:invalid fips mode
EVP_R_INVALID_IV_LENGTH:194:invalid iv length
EVP_R_INVALID_KEY:163:invalid key
EVP_R_INVALID_KEY_LENGTH:130:invalid key length
EVP_R_INVALID_OPERATION:148:invalid operation
@@ -2459,6 +2465,7 @@ KDF_R_MISSING_SEED:106:missing seed
KDF_R_MISSING_SESSION_ID:113:missing session id
KDF_R_MISSING_TYPE:114:missing type
KDF_R_MISSING_XCGHASH:115:missing xcghash
KDF_R_NOT_SUPPORTED:118:not supported
KDF_R_UNKNOWN_PARAMETER_TYPE:103:unknown parameter type
KDF_R_UNSUPPORTED_MAC_TYPE:117:unsupported mac type
KDF_R_VALUE_ERROR:108:value error
+1 -1
View File
@@ -10,7 +10,7 @@ SOURCE[../../libcrypto]=\
bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
c_allc.c c_alld.c evp_lib.c bio_ok.c \
evp_pkey.c kdf_lib.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \
pkey_kdf.c \
pkey_kdf.c c_allkdf.c \
e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \
e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
e_chacha20_poly1305.c cmeth_lib.c \
+24
View File
@@ -0,0 +1,24 @@
/*
* 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 <openssl/evp.h>
#include "internal/evp_int.h"
void openssl_add_all_kdfs_int(void)
{
EVP_add_kdf(&pbkdf2_kdf_meth);
#ifndef OPENSSL_NO_SCRYPT
EVP_add_kdf(&scrypt_kdf_meth);
#endif
EVP_add_kdf(&tls1_prf_kdf_meth);
EVP_add_kdf(&hkdf_kdf_meth);
EVP_add_kdf(&sshkdf_kdf_meth);
EVP_add_kdf(&ss_kdf_meth);
EVP_add_kdf(&x963_kdf_meth);
}
+23 -14
View File
@@ -172,7 +172,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
ctx->digest = type;
if (ctx->provctx == NULL) {
ctx->provctx = ctx->digest->newctx();
ctx->provctx = ctx->digest->newctx(ossl_provider_ctx(type->prov));
if (ctx->provctx == NULL) {
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
return 0;
@@ -494,13 +494,14 @@ int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
return 0;
}
static void *evp_md_from_dispatch(int mdtype, const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov)
static void *evp_md_from_dispatch(const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov)
{
EVP_MD *md = NULL;
int fncnt = 0;
if ((md = EVP_MD_meth_new(mdtype, NID_undef)) == NULL)
/* EVP_MD_fetch() will set the legacy NID if available */
if ((md = EVP_MD_meth_new(NID_undef, NID_undef)) == NULL)
return NULL;
for (; fns->function_id != 0; fns++) {
@@ -587,17 +588,25 @@ static void evp_md_free(void *md)
EVP_MD_meth_free(md);
}
static int evp_md_nid(void *vmd)
{
EVP_MD *md = vmd;
return md->type;
}
EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm,
const char *properties)
{
return evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties,
evp_md_from_dispatch, evp_md_upref,
evp_md_free, evp_md_nid);
EVP_MD *md =
evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties,
evp_md_from_dispatch, evp_md_upref,
evp_md_free);
#ifndef FIPS_MODE
/* TODO(3.x) get rid of the need for legacy NIDs */
if (md != NULL) {
/*
* FIPS module note: since internal fetches will be entirely
* provider based, we know that none of its code depends on legacy
* NIDs or any functionality that use them.
*/
md->type = OBJ_sn2nid(algorithm);
}
#endif
return md;
}
+22 -17
View File
@@ -15,6 +15,7 @@
#include <assert.h>
#include <openssl/aes.h>
#include "internal/evp_int.h"
#include "internal/cryptlib.h"
#include "modes_lcl.h"
#include <openssl/rand.h>
#include <openssl/cmac.h>
@@ -22,7 +23,7 @@
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
AES_KEY ks;
} ks;
block128_f block;
@@ -34,7 +35,7 @@ typedef struct {
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
AES_KEY ks;
} ks; /* AES key schedule to use */
int key_set; /* Set if key initialised */
@@ -52,7 +53,7 @@ typedef struct {
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
AES_KEY ks;
} ks1, ks2; /* AES key schedules to use */
XTS128_CONTEXT xts;
@@ -64,7 +65,7 @@ typedef struct {
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
AES_KEY ks;
} ks; /* AES key schedule to use */
int key_set; /* Set if key initialised */
@@ -80,11 +81,11 @@ typedef struct {
#ifndef OPENSSL_NO_OCB
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
AES_KEY ks;
} ksenc; /* AES key schedule to use for encryption */
union {
double align;
OSSL_UNION_ALIGN;
AES_KEY ks;
} ksdec; /* AES key schedule to use for decryption */
int key_set; /* Set if key initialised */
@@ -1008,7 +1009,7 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
/*-
* KM-AES parameter block - begin
* (see z/Architecture Principles of Operation >= SA22-7832-06)
@@ -1023,7 +1024,7 @@ typedef struct {
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
/*-
* KMO-AES parameter block - begin
* (see z/Architecture Principles of Operation >= SA22-7832-08)
@@ -1041,7 +1042,7 @@ typedef struct {
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
/*-
* KMF-AES parameter block - begin
* (see z/Architecture Principles of Operation >= SA22-7832-08)
@@ -1059,7 +1060,7 @@ typedef struct {
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
/*-
* KMA-GCM-AES parameter block - begin
* (see z/Architecture Principles of Operation >= SA22-7832-11)
@@ -1108,7 +1109,7 @@ typedef struct {
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
/*-
* Padding is chosen so that ccm.kmac_param.k overlaps with key.k and
* ccm.fc with key.k.rounds. Remember that on s390x, an AES_KEY's
@@ -2263,9 +2264,6 @@ static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
if (!cctx->aes.ccm.iv_set)
return -1;
if (!enc && !cctx->aes.ccm.tag_set)
return -1;
if (out == NULL) {
/* Update(): Pass message length. */
if (in == NULL) {
@@ -2284,6 +2282,10 @@ static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
return len;
}
/* The tag must be set before actually decrypting data */
if (!enc && !cctx->aes.ccm.tag_set)
return -1;
/* Update(): Process message. */
if (!cctx->aes.ccm.len_set) {
@@ -3791,8 +3793,6 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
if (!cctx->iv_set)
return -1;
if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set)
return -1;
if (!out) {
if (!in) {
if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
@@ -3807,6 +3807,11 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
CRYPTO_ccm128_aad(ccm, in, len);
return len;
}
/* The tag must be set before actually decrypting data */
if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set)
return -1;
/* If not set length yet do it */
if (!cctx->len_set) {
if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
@@ -3853,7 +3858,7 @@ BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM,
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
AES_KEY ks;
} ks;
/* Indicates if IV has been set */
+3 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -27,7 +27,7 @@ typedef struct {
/* ARIA GCM context */
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
ARIA_KEY ks;
} ks; /* ARIA subkey to use */
int key_set; /* Set if key initialised */
@@ -43,7 +43,7 @@ typedef struct {
/* ARIA CCM context */
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
ARIA_KEY ks;
} ks; /* ARIA key schedule to use */
int key_set; /* Set if key initialised */
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015-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
@@ -20,7 +20,7 @@
typedef struct {
union {
double align; /* this ensures even sizeof(EVP_CHACHA_KEY)%8==0 */
OSSL_UNION_ALIGN; /* this ensures even sizeof(EVP_CHACHA_KEY)%8==0 */
unsigned int d[CHACHA_KEY_SIZE / 4];
} key;
unsigned int counter[CHACHA_CTR_SIZE / 4];
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-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
@@ -18,7 +18,7 @@
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
DES_key_schedule ks;
} ks;
union {
+7 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-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
@@ -19,7 +19,7 @@
typedef struct {
union {
double align;
OSSL_UNION_ALIGN;
DES_key_schedule ks[3];
} ks;
union {
@@ -280,15 +280,17 @@ static int des3_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
{
DES_cblock *deskey = ptr;
int kl;
switch (type) {
case EVP_CTRL_RAND_KEY:
if (RAND_priv_bytes(ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0)
kl = EVP_CIPHER_CTX_key_length(ctx);
if (kl < 0 || RAND_priv_bytes(ptr, kl) <= 0)
return 0;
DES_set_odd_parity(deskey);
if (EVP_CIPHER_CTX_key_length(ctx) >= 16)
if (kl >= 16)
DES_set_odd_parity(deskey + 1);
if (EVP_CIPHER_CTX_key_length(ctx) >= 24)
if (kl >= 24)
DES_set_odd_parity(deskey + 2);
return 1;
+67 -34
View File
@@ -206,7 +206,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
ctx->cipher = cipher;
if (ctx->provctx == NULL) {
ctx->provctx = ctx->cipher->newctx();
ctx->provctx = ctx->cipher->newctx(ossl_provider_ctx(cipher->prov));
if (ctx->provctx == NULL) {
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
return 0;
@@ -338,6 +338,9 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
#ifndef OPENSSL_NO_ENGINE
skip_to_init:
#endif
if (ctx->cipher == NULL)
return 0;
/* we assume block size is a power of 2 in *cryptUpdate */
OPENSSL_assert(ctx->cipher->block_size == 1
|| ctx->cipher->block_size == 8
@@ -492,11 +495,6 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx,
bl = ctx->cipher->block_size;
if (inl <= 0) {
*outl = 0;
return inl == 0;
}
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
/* If block size > 1 then the cipher will have to do this check */
if (bl == 1 && is_partially_overlapping(out, in, cmpl)) {
@@ -512,6 +510,10 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx,
return 1;
}
if (inl <= 0) {
*outl = 0;
return inl == 0;
}
if (is_partially_overlapping(out + ctx->buf_len, in, cmpl)) {
EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
return 0;
@@ -587,11 +589,14 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
inl + (blocksize == 1 ? 0 : blocksize), in,
(size_t)inl);
if (soutl > INT_MAX) {
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_UPDATE_ERROR);
return 0;
if (ret) {
if (soutl > INT_MAX) {
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_UPDATE_ERROR);
return 0;
}
*outl = soutl;
}
*outl = soutl;
return ret;
/* TODO(3.0): Remove legacy code below */
@@ -620,7 +625,11 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
return 0;
}
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
if (ctx->cipher == NULL) {
EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_NO_CIPHER_SET);
return 0;
}
if (ctx->cipher->prov == NULL)
goto legacy;
blocksize = EVP_CIPHER_CTX_block_size(ctx);
@@ -633,11 +642,13 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
ret = ctx->cipher->cfinal(ctx->provctx, out, &soutl,
blocksize == 1 ? 0 : blocksize);
if (soutl > INT_MAX) {
EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_FINAL_ERROR);
return 0;
if (ret) {
if (soutl > INT_MAX) {
EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_FINAL_ERROR);
return 0;
}
*outl = soutl;
}
*outl = soutl;
return ret;
@@ -695,7 +706,11 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
return 0;
}
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
if (ctx->cipher == NULL) {
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_NO_CIPHER_SET);
return 0;
}
if (ctx->cipher->prov == NULL)
goto legacy;
blocksize = EVP_CIPHER_CTX_block_size(ctx);
@@ -726,11 +741,6 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
cmpl = (cmpl + 7) / 8;
if (inl <= 0) {
*outl = 0;
return inl == 0;
}
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
if (b == 1 && is_partially_overlapping(out, in, cmpl)) {
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
@@ -746,6 +756,11 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
return 1;
}
if (inl <= 0) {
*outl = 0;
return inl == 0;
}
if (ctx->flags & EVP_CIPH_NO_PADDING)
return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl);
@@ -832,6 +847,10 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
legacy:
*outl = 0;
if (ctx->cipher == NULL) {
EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_NO_CIPHER_SET);
return 0;
}
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
i = ctx->cipher->do_cipher(ctx, out, NULL, 0);
@@ -949,9 +968,11 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
{
int kl;
if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
if (RAND_priv_bytes(key, EVP_CIPHER_CTX_key_length(ctx)) <= 0)
kl = EVP_CIPHER_CTX_key_length(ctx);
if (kl <= 0 || RAND_priv_bytes(key, kl) <= 0)
return 0;
return 1;
}
@@ -1022,13 +1043,17 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
return 1;
}
static void *evp_cipher_from_dispatch(int nid, const OSSL_DISPATCH *fns,
static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov)
{
EVP_CIPHER *cipher = NULL;
int fnciphcnt = 0, fnctxcnt = 0;
if ((cipher = EVP_CIPHER_meth_new(nid, 0, 0)) == NULL)
/*
* The legacy NID is set by EVP_CIPHER_fetch() if the name exists in
* the object database.
*/
if ((cipher = EVP_CIPHER_meth_new(0, 0, 0)) == NULL)
return NULL;
for (; fns->function_id != 0; fns++) {
@@ -1145,17 +1170,25 @@ static void evp_cipher_free(void *cipher)
EVP_CIPHER_meth_free(cipher);
}
static int evp_cipher_nid(void *vcipher)
{
EVP_CIPHER *cipher = vcipher;
return cipher->nid;
}
EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
const char *properties)
{
return evp_generic_fetch(ctx, OSSL_OP_CIPHER, algorithm, properties,
evp_cipher_from_dispatch, evp_cipher_upref,
evp_cipher_free, evp_cipher_nid);
EVP_CIPHER *cipher =
evp_generic_fetch(ctx, OSSL_OP_CIPHER, algorithm, properties,
evp_cipher_from_dispatch, evp_cipher_upref,
evp_cipher_free);
#ifndef FIPS_MODE
/* TODO(3.x) get rid of the need for legacy NIDs */
if (cipher != NULL) {
/*
* FIPS module note: since internal fetches will be entirely
* provider based, we know that none of its code depends on legacy
* NIDs or any functionality that use them.
*/
cipher->nid = OBJ_sn2nid(algorithm);
}
#endif
return cipher;
}
+2
View File
@@ -74,6 +74,7 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTUPDATE, 0), "EVP_EncryptUpdate"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTRL, 0), "EVP_KDF_ctrl"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTRL_STR, 0), "EVP_KDF_ctrl_str"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTX_NEW, 0), "EVP_KDF_CTX_new"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTX_NEW_ID, 0), "EVP_KDF_CTX_new_id"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL, 0), "EVP_MAC_ctrl"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL_STR, 0), "EVP_MAC_ctrl_str"},
@@ -248,6 +249,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
"invalid custom length"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_DIGEST), "invalid digest"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_FIPS_MODE), "invalid fips mode"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_IV_LENGTH), "invalid iv length"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY), "invalid key"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY_LENGTH), "invalid key length"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION), "invalid operation"},
+40 -76
View File
@@ -13,23 +13,20 @@
#include <openssl/core.h>
#include "internal/cryptlib.h"
#include "internal/thread_once.h"
#include "internal/asn1_int.h"
#include "internal/property.h"
#include "internal/core.h"
#include "internal/namemap.h"
#include "internal/evp_int.h" /* evp_locl.h needs it */
#include "evp_locl.h"
/* The OpenSSL library context index for the default method store */
static int default_method_store_index = -1;
static void default_method_store_free(void *vstore)
{
ossl_method_store_free(vstore);
}
static void *default_method_store_new(void)
static void *default_method_store_new(OPENSSL_CTX *ctx)
{
return ossl_method_store_new();
return ossl_method_store_new(ctx);
}
@@ -38,39 +35,23 @@ static const OPENSSL_CTX_METHOD default_method_store_method = {
default_method_store_free,
};
static int default_method_store_init(void)
{
default_method_store_index =
openssl_ctx_new_index(&default_method_store_method);
return default_method_store_index != -1;
}
static CRYPTO_ONCE default_method_store_init_flag = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(do_default_method_store_init)
{
return OPENSSL_init_crypto(0, NULL)
&& default_method_store_init();
}
/* Data to be passed through ossl_method_construct() */
struct method_data_st {
OPENSSL_CTX *libctx;
const char *name;
int nid;
int id;
OSSL_METHOD_CONSTRUCT_METHOD *mcm;
void *(*method_from_dispatch)(int nid, const OSSL_DISPATCH *,
OSSL_PROVIDER *);
void *(*method_from_dispatch)(const OSSL_DISPATCH *, OSSL_PROVIDER *);
int (*refcnt_up_method)(void *method);
void (*destruct_method)(void *method);
int (*nid_method)(void *method);
};
/*
* Generic routines to fetch / create EVP methods with ossl_method_construct()
*/
static void *alloc_tmp_method_store(void)
static void *alloc_tmp_method_store(OPENSSL_CTX *ctx)
{
return ossl_method_store_new();
return ossl_method_store_new(ctx);
}
static void dealloc_tmp_method_store(void *store)
@@ -81,23 +62,28 @@ static void *alloc_tmp_method_store(void)
static OSSL_METHOD_STORE *get_default_method_store(OPENSSL_CTX *libctx)
{
if (!RUN_ONCE(&default_method_store_init_flag,
do_default_method_store_init))
return NULL;
return openssl_ctx_get_data(libctx, default_method_store_index);
return openssl_ctx_get_data(libctx, OPENSSL_CTX_DEFAULT_METHOD_STORE_INDEX,
&default_method_store_method);
}
static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
const char *propquery, void *data)
const char *name, const char *propquery,
void *data)
{
struct method_data_st *methdata = data;
void *method = NULL;
OSSL_NAMEMAP *namemap;
int id;
if (store == NULL
&& (store = get_default_method_store(libctx)) == NULL)
return NULL;
(void)ossl_method_store_fetch(store, methdata->nid, propquery, &method);
if ((namemap = ossl_namemap_stored(libctx)) == NULL
|| (id = ossl_namemap_add(namemap, name)) == 0)
return NULL;
(void)ossl_method_store_fetch(store, id, propquery, &method);
if (method != NULL
&& !methdata->refcnt_up_method(method)) {
@@ -107,13 +93,15 @@ static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
}
static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
const char *propdef,
void *method, void *data)
void *method, const char *name,
const char *propdef, void *data)
{
struct method_data_st *methdata = data;
int nid = methdata->nid_method(method);
OSSL_NAMEMAP *namemap;
int id;
if (nid == NID_undef)
if ((namemap = ossl_namemap_stored(methdata->libctx)) == NULL
|| (id = ossl_namemap_add(namemap, name)) == 0)
return 0;
if (store == NULL
@@ -121,41 +109,18 @@ static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
return 0;
if (methdata->refcnt_up_method(method)
&& ossl_method_store_add(store, nid, propdef, method,
&& ossl_method_store_add(store, id, propdef, method,
methdata->destruct_method))
return 1;
return 0;
}
static void *construct_method(const char *algorithm_name,
const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov,
void *data)
static void *construct_method(const char *name, const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov, void *data)
{
struct method_data_st *methdata = data;
void *method = NULL;
int nid = OBJ_sn2nid(algorithm_name);
if (nid == NID_undef) {
/* Create a new NID for that name on the fly */
ASN1_OBJECT tmpobj;
/* This is the same as OBJ_create() but without requiring a OID */
tmpobj.nid = OBJ_new_nid(1);
tmpobj.sn = tmpobj.ln = methdata->name;
tmpobj.flags = ASN1_OBJECT_FLAG_DYNAMIC;
tmpobj.length = 0;
tmpobj.data = NULL;
nid = OBJ_add_object(&tmpobj);
}
if (nid == NID_undef)
return NULL;
method = methdata->method_from_dispatch(nid, fns, prov);
if (method == NULL)
return NULL;
return method;
return methdata->method_from_dispatch(fns, prov);
}
static void destruct_method(void *method, void *data)
@@ -166,22 +131,22 @@ static void destruct_method(void *method, void *data)
}
void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
const char *algorithm, const char *properties,
void *(*new_method)(int nid, const OSSL_DISPATCH *fns,
const char *name, const char *properties,
void *(*new_method)(const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov),
int (*upref_method)(void *),
void (*free_method)(void *),
int (*nid_method)(void *))
void (*free_method)(void *))
{
OSSL_METHOD_STORE *store = get_default_method_store(libctx);
int nid = OBJ_sn2nid(algorithm);
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
int id;
void *method = NULL;
if (store == NULL)
if (store == NULL || namemap == NULL)
return NULL;
if (nid == NID_undef
|| !ossl_method_store_cache_get(store, nid, properties, &method)) {
if ((id = ossl_namemap_number(namemap, name)) == 0
|| !ossl_method_store_cache_get(store, id, properties, &method)) {
OSSL_METHOD_CONSTRUCT_METHOD mcm = {
alloc_tmp_method_store,
dealloc_tmp_method_store,
@@ -192,17 +157,16 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
};
struct method_data_st mcmdata;
mcmdata.nid = nid;
mcmdata.mcm = &mcm;
mcmdata.libctx = libctx;
mcmdata.method_from_dispatch = new_method;
mcmdata.destruct_method = free_method;
mcmdata.refcnt_up_method = upref_method;
mcmdata.destruct_method = free_method;
mcmdata.nid_method = nid_method;
method = ossl_method_construct(libctx, operation_id, algorithm,
method = ossl_method_construct(libctx, operation_id, name,
properties, 0 /* !force_cache */,
&mcm, &mcmdata);
ossl_method_store_cache_set(store, nid, properties, method);
ossl_method_store_cache_set(store, id, properties, method);
} else {
upref_method(method);
}
+7 -1
View File
@@ -232,8 +232,14 @@ int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, unsigned int inl)
{
if (ctx->cipher->prov != NULL) {
size_t outl = 0; /* ignored */
int blocksize = EVP_CIPHER_CTX_block_size(ctx);
if (ctx->cipher->ccipher != NULL)
return ctx->cipher->ccipher(ctx->provctx, out, in, (size_t)inl);
return
ctx->cipher->ccipher(ctx->provctx, out, &outl,
inl + (blocksize == 1 ? 0 : blocksize),
in, (size_t)inl);
return 0;
}
+3 -4
View File
@@ -56,7 +56,7 @@ struct evp_mac_ctx_st {
} /* EVP_MAC_CTX */;
struct evp_kdf_ctx_st {
const EVP_KDF_METHOD *kmeth;
const EVP_KDF *meth; /* Method structure */
EVP_KDF_IMPL *impl; /* Algorithm-specific data */
} /* EVP_KDF_CTX */ ;
@@ -91,8 +91,7 @@ int is_partially_overlapping(const void *ptr1, const void *ptr2, int len);
void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id,
const char *algorithm, const char *properties,
void *(*new_method)(int nid, const OSSL_DISPATCH *fns,
void *(*new_method)(const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov),
int (*upref_method)(void *),
void (*free_method)(void *),
int (*nid_method)(void *));
void (*free_method)(void *));
+33 -65
View File
@@ -1,6 +1,6 @@
/*
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2018-2019, Oracle and/or its affiliates. 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
@@ -20,70 +20,39 @@
#include "internal/numbers.h"
#include "evp_locl.h"
typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
/* This array needs to be in order of NIDs */
static const EVP_KDF_METHOD *standard_methods[] = {
&pbkdf2_kdf_meth,
#ifndef OPENSSL_NO_SCRYPT
&scrypt_kdf_meth,
#endif
&tls1_prf_kdf_meth,
&hkdf_kdf_meth,
&sshkdf_kdf_meth,
&ss_kdf_meth
};
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_KDF_METHOD *, const EVP_KDF_METHOD *,
kmeth);
static int kmeth_cmp(const EVP_KDF_METHOD *const *a,
const EVP_KDF_METHOD *const *b)
EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf)
{
return ((*a)->type - (*b)->type);
}
EVP_KDF_CTX *ctx = NULL;
IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_KDF_METHOD *, const EVP_KDF_METHOD *,
kmeth);
static const EVP_KDF_METHOD *kdf_meth_find(int type)
{
EVP_KDF_METHOD tmp;
const EVP_KDF_METHOD *t = &tmp, **ret;
tmp.type = type;
ret = OBJ_bsearch_kmeth(&t, standard_methods,
OSSL_NELEM(standard_methods));
if (ret == NULL || *ret == NULL)
if (kdf == NULL)
return NULL;
return *ret;
ctx = OPENSSL_zalloc(sizeof(EVP_KDF_CTX));
if (ctx == NULL || (ctx->impl = kdf->new()) == NULL) {
EVPerr(EVP_F_EVP_KDF_CTX_NEW, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ctx);
ctx = NULL;
} else {
ctx->meth = kdf;
}
return ctx;
}
EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id)
{
EVP_KDF_CTX *ret;
const EVP_KDF_METHOD *kmeth;
const EVP_KDF *kdf = EVP_get_kdfbynid(id);
kmeth = kdf_meth_find(id);
if (kmeth == NULL) {
EVPerr(EVP_F_EVP_KDF_CTX_NEW_ID, EVP_R_UNSUPPORTED_ALGORITHM);
return NULL;
}
return EVP_KDF_CTX_new(kdf);
}
ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
EVPerr(EVP_F_EVP_KDF_CTX_NEW_ID, ERR_R_MALLOC_FAILURE);
return NULL;
}
int EVP_KDF_nid(const EVP_KDF *kdf)
{
return kdf->type;
}
if (kmeth->new != NULL && (ret->impl = kmeth->new()) == NULL) {
EVP_KDF_CTX_free(ret);
return NULL;
}
ret->kmeth = kmeth;
return ret;
const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx)
{
return ctx->meth;
}
void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx)
@@ -91,7 +60,7 @@ void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx)
if (ctx == NULL)
return;
ctx->kmeth->free(ctx->impl);
ctx->meth->free(ctx->impl);
OPENSSL_free(ctx);
}
@@ -100,8 +69,8 @@ void EVP_KDF_reset(EVP_KDF_CTX *ctx)
if (ctx == NULL)
return;
if (ctx->kmeth->reset != NULL)
ctx->kmeth->reset(ctx->impl);
if (ctx->meth->reset != NULL)
ctx->meth->reset(ctx->impl);
}
int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...)
@@ -124,7 +93,7 @@ int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args)
if (ctx == NULL)
return 0;
return ctx->kmeth->ctrl(ctx->impl, cmd, args);
return ctx->meth->ctrl(ctx->impl, cmd, args);
}
int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value)
@@ -134,12 +103,12 @@ int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value)
if (ctx == NULL)
return 0;
if (ctx->kmeth->ctrl_str == NULL) {
if (ctx->meth->ctrl_str == NULL) {
EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
return -2;
}
ret = ctx->kmeth->ctrl_str(ctx->impl, type, value);
ret = ctx->meth->ctrl_str(ctx->impl, type, value);
if (ret == -2)
EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
@@ -151,10 +120,10 @@ size_t EVP_KDF_size(EVP_KDF_CTX *ctx)
if (ctx == NULL)
return 0;
if (ctx->kmeth->size == NULL)
if (ctx->meth->size == NULL)
return SIZE_MAX;
return ctx->kmeth->size(ctx->impl);
return ctx->meth->size(ctx->impl);
}
int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen)
@@ -162,6 +131,5 @@ int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen)
if (ctx == NULL)
return 0;
return ctx->kmeth->derive(ctx->impl, key, keylen);
return ctx->meth->derive(ctx->impl, key, keylen);
}
+32 -1
View File
@@ -10,6 +10,7 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/evp.h>
#include <openssl/kdf.h>
#include "internal/objects.h"
#include <openssl/x509.h>
#include "internal/evp_int.h"
@@ -71,6 +72,23 @@ int EVP_add_mac(const EVP_MAC *m)
return r;
}
/* TODO(3.0) Is this needed after changing to providers? */
int EVP_add_kdf(const EVP_KDF *k)
{
int r;
if (k == NULL)
return 0;
r = OBJ_NAME_add(OBJ_nid2sn(k->type), OBJ_NAME_TYPE_KDF_METH,
(const char *)k);
if (r == 0)
return 0;
r = OBJ_NAME_add(OBJ_nid2ln(k->type), OBJ_NAME_TYPE_KDF_METH,
(const char *)k);
return r;
}
const EVP_CIPHER *EVP_get_cipherbyname(const char *name)
{
const EVP_CIPHER *cp;
@@ -104,9 +122,22 @@ const EVP_MAC *EVP_get_macbyname(const char *name)
return mp;
}
/* TODO(3.0) Is this API needed after implementing providers? */
const EVP_KDF *EVP_get_kdfbyname(const char *name)
{
const EVP_KDF *kdf;
if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_KDFS, NULL))
return NULL;
kdf = (const EVP_KDF *)OBJ_NAME_get(name, OBJ_NAME_TYPE_KDF_METH);
return kdf;
}
void evp_cleanup_int(void)
{
OBJ_NAME_cleanup(OBJ_NAME_TYPE_MAC_METH);
OBJ_NAME_cleanup(OBJ_NAME_TYPE_KDF_METH);
OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
/*
@@ -207,6 +238,7 @@ void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *md,
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
}
/* TODO(3.0) Are these do_all API's needed for MAC? */
struct doall_mac {
void *arg;
void (*fn) (const EVP_MAC *ciph,
@@ -250,4 +282,3 @@ void EVP_MAC_do_all_sorted(void (*fn)
dc.arg = arg;
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MAC_METH, do_all_mac_fn, &dc);
}
+14 -6
View File
@@ -28,7 +28,7 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
EVP_MD_CTX *ctx;
unsigned char md_tmp[EVP_MAX_MD_SIZE];
unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
int i;
int i, ivl, kl;
PBEPARAM *pbe;
int saltlen, iter;
unsigned char *salt;
@@ -48,6 +48,17 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
return 0;
}
ivl = EVP_CIPHER_iv_length(cipher);
if (ivl < 0 || ivl > 16) {
EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_INVALID_IV_LENGTH);
return 0;
}
kl = EVP_CIPHER_key_length(cipher);
if (kl < 0 || kl > (int)sizeof(md_tmp)) {
EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_INVALID_KEY_LENGTH);
return 0;
}
if (!pbe->iter)
iter = 1;
else
@@ -86,11 +97,8 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL))
goto err;
}
OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp));
memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher));
OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16);
memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)),
EVP_CIPHER_iv_length(cipher));
memcpy(key, md_tmp, kl);
memcpy(iv, md_tmp + (16 - ivl), ivl);
if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de))
goto err;
OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE);
+7 -2
View File
@@ -134,7 +134,7 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
const EVP_CIPHER *c, const EVP_MD *md, int en_de)
{
unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
int saltlen, iter;
int saltlen, iter, t;
int rv = 0;
unsigned int keylen = 0;
int prf_nid, hmac_md_nid;
@@ -157,7 +157,12 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
goto err;
}
keylen = EVP_CIPHER_CTX_key_length(ctx);
t = EVP_CIPHER_CTX_key_length(ctx);
if (t < 0) {
EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_INVALID_KEY_LENGTH);
goto err;
}
keylen = t;
/* Now check the parameters of the kdf */
+99 -65
View File
@@ -10,58 +10,33 @@
#include "internal/cryptlib_int.h"
#include "internal/thread_once.h"
/*
* Each structure type (sometimes called a class), that supports
* exdata has a stack of callbacks for each instance.
*/
struct ex_callback_st {
long argl; /* Arbitrary long */
void *argp; /* Arbitrary void * */
CRYPTO_EX_new *new_func;
CRYPTO_EX_free *free_func;
CRYPTO_EX_dup *dup_func;
};
/*
* The state for each class. This could just be a typedef, but
* a structure allows future changes.
*/
typedef struct ex_callbacks_st {
STACK_OF(EX_CALLBACK) *meth;
} EX_CALLBACKS;
static EX_CALLBACKS ex_data[CRYPTO_EX_INDEX__COUNT];
static CRYPTO_RWLOCK *ex_data_lock = NULL;
static CRYPTO_ONCE ex_data_init = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(do_ex_data_init)
int do_ex_data_init(OPENSSL_CTX *ctx)
{
if (!OPENSSL_init_crypto(0, NULL))
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
if (global == NULL)
return 0;
ex_data_lock = CRYPTO_THREAD_lock_new();
return ex_data_lock != NULL;
global->ex_data_lock = CRYPTO_THREAD_lock_new();
return global->ex_data_lock != NULL;
}
/*
* Return the EX_CALLBACKS from the |ex_data| array that corresponds to
* a given class. On success, *holds the lock.*
*/
static EX_CALLBACKS *get_and_lock(int class_index)
static EX_CALLBACKS *get_and_lock(OPENSSL_CTX *ctx, int class_index)
{
EX_CALLBACKS *ip;
OSSL_EX_DATA_GLOBAL *global = NULL;
if (class_index < 0 || class_index >= CRYPTO_EX_INDEX__COUNT) {
CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_PASSED_INVALID_ARGUMENT);
return NULL;
}
if (!RUN_ONCE(&ex_data_init, do_ex_data_init)) {
CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (ex_data_lock == NULL) {
global = openssl_ctx_get_ex_data_global(ctx);
if (global->ex_data_lock == NULL) {
/*
* This can happen in normal operation when using CRYPTO_mem_leaks().
* The CRYPTO_mem_leaks() function calls OPENSSL_cleanup() which cleans
@@ -74,8 +49,8 @@ static EX_CALLBACKS *get_and_lock(int class_index)
return NULL;
}
ip = &ex_data[class_index];
CRYPTO_THREAD_write_lock(ex_data_lock);
ip = &global->ex_data[class_index];
CRYPTO_THREAD_write_lock(global->ex_data_lock);
return ip;
}
@@ -90,19 +65,23 @@ static void cleanup_cb(EX_CALLBACK *funcs)
* called under potential race-conditions anyway (it's for program shutdown
* after all).
*/
void crypto_cleanup_all_ex_data_int(void)
void crypto_cleanup_all_ex_data_int(OPENSSL_CTX *ctx)
{
int i;
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
if (global == NULL)
return;
for (i = 0; i < CRYPTO_EX_INDEX__COUNT; ++i) {
EX_CALLBACKS *ip = &ex_data[i];
EX_CALLBACKS *ip = &global->ex_data[i];
sk_EX_CALLBACK_pop_free(ip->meth, cleanup_cb);
ip->meth = NULL;
}
CRYPTO_THREAD_lock_free(ex_data_lock);
ex_data_lock = NULL;
CRYPTO_THREAD_lock_free(global->ex_data_lock);
global->ex_data_lock = NULL;
}
@@ -127,12 +106,17 @@ static int dummy_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
return 1;
}
int CRYPTO_free_ex_index(int class_index, int idx)
int crypto_free_ex_index_ex(OPENSSL_CTX *ctx, int class_index, int idx)
{
EX_CALLBACKS *ip = get_and_lock(class_index);
EX_CALLBACKS *ip = get_and_lock(ctx, class_index);
EX_CALLBACK *a;
int toret = 0;
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
if (global == NULL)
return 0;
ip = get_and_lock(ctx, class_index);
if (ip == NULL)
return 0;
if (idx < 0 || idx >= sk_EX_CALLBACK_num(ip->meth))
@@ -145,21 +129,32 @@ int CRYPTO_free_ex_index(int class_index, int idx)
a->free_func = dummy_free;
toret = 1;
err:
CRYPTO_THREAD_unlock(ex_data_lock);
CRYPTO_THREAD_unlock(global->ex_data_lock);
return toret;
}
int CRYPTO_free_ex_index(int class_index, int idx)
{
return crypto_free_ex_index_ex(NULL, class_index, idx);
}
/*
* Register a new index.
*/
int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func)
int crypto_get_ex_new_index_ex(OPENSSL_CTX *ctx, int class_index, long argl,
void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func)
{
int toret = -1;
EX_CALLBACK *a;
EX_CALLBACKS *ip = get_and_lock(class_index);
EX_CALLBACKS *ip;
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
if (global == NULL)
return -1;
ip = get_and_lock(ctx, class_index);
if (ip == NULL)
return -1;
@@ -169,14 +164,14 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
* "app_data" routines use ex_data index zero. See RT 3710. */
if (ip->meth == NULL
|| !sk_EX_CALLBACK_push(ip->meth, NULL)) {
CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX, ERR_R_MALLOC_FAILURE);
goto err;
}
}
a = (EX_CALLBACK *)OPENSSL_malloc(sizeof(*a));
if (a == NULL) {
CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX, ERR_R_MALLOC_FAILURE);
goto err;
}
a->argl = argl;
@@ -186,7 +181,7 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
a->free_func = free_func;
if (!sk_EX_CALLBACK_push(ip->meth, NULL)) {
CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX, ERR_R_MALLOC_FAILURE);
OPENSSL_free(a);
goto err;
}
@@ -194,10 +189,18 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
(void)sk_EX_CALLBACK_set(ip->meth, toret, a);
err:
CRYPTO_THREAD_unlock(ex_data_lock);
CRYPTO_THREAD_unlock(global->ex_data_lock);
return toret;
}
int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func)
{
return crypto_get_ex_new_index_ex(NULL, class_index, argl, argp, new_func,
dup_func, free_func);
}
/*
* Initialise a new CRYPTO_EX_DATA for use in a particular class - including
* calling new() callbacks for each index in the class used by this variable
@@ -205,17 +208,24 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
* in the lock, then using them outside the lock. Note this only applies
* to the global "ex_data" state (ie. class definitions), not 'ad' itself.
*/
int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
int crypto_new_ex_data_ex(OPENSSL_CTX *ctx, int class_index, void *obj,
CRYPTO_EX_DATA *ad)
{
int mx, i;
void *ptr;
EX_CALLBACK **storage = NULL;
EX_CALLBACK *stack[10];
EX_CALLBACKS *ip = get_and_lock(class_index);
EX_CALLBACKS *ip;
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
if (global == NULL)
return 0;
ip = get_and_lock(ctx, class_index);
if (ip == NULL)
return 0;
ad->ctx = ctx;
ad->sk = NULL;
mx = sk_EX_CALLBACK_num(ip->meth);
@@ -228,10 +238,10 @@ int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
for (i = 0; i < mx; i++)
storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
}
CRYPTO_THREAD_unlock(ex_data_lock);
CRYPTO_THREAD_unlock(global->ex_data_lock);
if (mx > 0 && storage == NULL) {
CRYPTOerr(CRYPTO_F_CRYPTO_NEW_EX_DATA, ERR_R_MALLOC_FAILURE);
CRYPTOerr(CRYPTO_F_CRYPTO_NEW_EX_DATA_EX, ERR_R_MALLOC_FAILURE);
return 0;
}
for (i = 0; i < mx; i++) {
@@ -246,6 +256,11 @@ int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
return 1;
}
int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
{
return crypto_new_ex_data_ex(NULL, class_index, obj, ad);
}
/*
* Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks
* for each index in the class used by this variable
@@ -259,11 +274,16 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
EX_CALLBACK **storage = NULL;
EX_CALLBACKS *ip;
int toret = 0;
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(from->ctx);
if (global == NULL)
return 0;
to->ctx = from->ctx;
if (from->sk == NULL)
/* Nothing to copy over */
return 1;
if ((ip = get_and_lock(class_index)) == NULL)
if ((ip = get_and_lock(from->ctx, class_index)) == NULL)
return 0;
mx = sk_EX_CALLBACK_num(ip->meth);
@@ -279,7 +299,7 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
for (i = 0; i < mx; i++)
storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
}
CRYPTO_THREAD_unlock(ex_data_lock);
CRYPTO_THREAD_unlock(global->ex_data_lock);
if (mx == 0)
return 1;
@@ -325,8 +345,12 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
EX_CALLBACK *f;
EX_CALLBACK *stack[10];
EX_CALLBACK **storage = NULL;
OSSL_EX_DATA_GLOBAL *global;
if ((ip = get_and_lock(class_index)) == NULL)
if ((ip = get_and_lock(ad->ctx, class_index)) == NULL)
goto err;
global = openssl_ctx_get_ex_data_global(ad->ctx);
if (global == NULL)
goto err;
mx = sk_EX_CALLBACK_num(ip->meth);
@@ -339,15 +363,15 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
for (i = 0; i < mx; i++)
storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
}
CRYPTO_THREAD_unlock(ex_data_lock);
CRYPTO_THREAD_unlock(global->ex_data_lock);
for (i = 0; i < mx; i++) {
if (storage != NULL)
f = storage[i];
else {
CRYPTO_THREAD_write_lock(ex_data_lock);
CRYPTO_THREAD_write_lock(global->ex_data_lock);
f = sk_EX_CALLBACK_value(ip->meth, i);
CRYPTO_THREAD_unlock(ex_data_lock);
CRYPTO_THREAD_unlock(global->ex_data_lock);
}
if (f != NULL && f->free_func != NULL) {
ptr = CRYPTO_get_ex_data(ad, i);
@@ -360,6 +384,7 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
err:
sk_void_free(ad->sk);
ad->sk = NULL;
ad->ctx = NULL;
}
/*
@@ -372,6 +397,10 @@ int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad,
EX_CALLBACK *f;
EX_CALLBACKS *ip;
void *curval;
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ad->ctx);
if (global == NULL)
return 0;
curval = CRYPTO_get_ex_data(ad, idx);
@@ -379,11 +408,11 @@ int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad,
if (curval != NULL)
return 1;
ip = get_and_lock(class_index);
ip = get_and_lock(ad->ctx, class_index);
if (ip == NULL)
return 0;
f = sk_EX_CALLBACK_value(ip->meth, idx);
CRYPTO_THREAD_unlock(ex_data_lock);
CRYPTO_THREAD_unlock(global->ex_data_lock);
/*
* This should end up calling CRYPTO_set_ex_data(), which allocates
@@ -432,3 +461,8 @@ void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
return NULL;
return sk_void_value(ad->sk, idx);
}
OPENSSL_CTX *crypto_ex_data_get_openssl_ctx(const CRYPTO_EX_DATA *ad)
{
return ad->ctx;
}
+11 -8
View File
@@ -151,10 +151,11 @@ const EVP_MD *evp_keccak_kmac256(void);
* object database.
*/
int EVP_add_mac(const EVP_MAC *mac);
int EVP_add_kdf(const EVP_KDF *kdf);
/* struct evp_kdf_impl_st is defined by the implementation */
typedef struct evp_kdf_impl_st EVP_KDF_IMPL;
typedef struct {
struct evp_kdf_st {
int type;
EVP_KDF_IMPL *(*new) (void);
void (*free) (EVP_KDF_IMPL *impl);
@@ -163,14 +164,15 @@ typedef struct {
int (*ctrl_str) (EVP_KDF_IMPL *impl, const char *type, const char *value);
size_t (*size) (EVP_KDF_IMPL *impl);
int (*derive) (EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen);
} EVP_KDF_METHOD;
};
extern const EVP_KDF_METHOD pbkdf2_kdf_meth;
extern const EVP_KDF_METHOD scrypt_kdf_meth;
extern const EVP_KDF_METHOD tls1_prf_kdf_meth;
extern const EVP_KDF_METHOD hkdf_kdf_meth;
extern const EVP_KDF_METHOD sshkdf_kdf_meth;
extern const EVP_KDF_METHOD ss_kdf_meth;
extern const EVP_KDF pbkdf2_kdf_meth;
extern const EVP_KDF scrypt_kdf_meth;
extern const EVP_KDF tls1_prf_kdf_meth;
extern const EVP_KDF hkdf_kdf_meth;
extern const EVP_KDF sshkdf_kdf_meth;
extern const EVP_KDF ss_kdf_meth;
extern const EVP_KDF x963_kdf_meth;
struct evp_md_st {
/* nid */
@@ -528,6 +530,7 @@ struct evp_pkey_st {
void openssl_add_all_ciphers_int(void);
void openssl_add_all_digests_int(void);
void openssl_add_all_macs_int(void);
void openssl_add_all_kdfs_int(void);
void evp_cleanup_int(void);
void evp_app_cleanup_int(void);
+43 -3
View File
@@ -293,6 +293,26 @@ DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_macs, ossl_init_add_all_macs)
return 1;
}
static CRYPTO_ONCE add_all_kdfs = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_kdfs)
{
/*
* OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
* pulling in all the macs during static linking
*/
#ifndef OPENSSL_NO_AUTOALGINIT
OSSL_TRACE(INIT, "openssl_add_all_kdfs_int()\n");
openssl_add_all_kdfs_int();
#endif
return 1;
}
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_kdfs, ossl_init_add_all_kdfs)
{
/* Do nothing */
return 1;
}
static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
static int config_inited = 0;
static const OPENSSL_INIT_SETTINGS *conf_settings = NULL;
@@ -468,6 +488,11 @@ void OPENSSL_cleanup(void)
OPENSSL_INIT_STOP *currhandler, *lasthandler;
CRYPTO_THREAD_LOCAL key;
/*
* TODO(3.0): This function needs looking at with a view to moving most/all
* of this into onfree handlers in OPENSSL_CTX.
*/
/* If we've not been inited then no need to deinit */
if (!base_inited)
return;
@@ -526,7 +551,7 @@ void OPENSSL_cleanup(void)
* - rand_cleanup_int could call an ENGINE's RAND cleanup function so
* must be called before engine_cleanup_int()
* - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
* before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data().
* before the ex data handlers are wiped during default openssl_ctx deinit.
* - conf_modules_free_int() can end up in ENGINE code so must be called
* before engine_cleanup_int()
* - ENGINEs and additional EVP algorithms might use added OIDs names so
@@ -540,6 +565,7 @@ void OPENSSL_cleanup(void)
OSSL_TRACE(INIT, "OPENSSL_cleanup: conf_modules_free_int()\n");
conf_modules_free_int();
#ifndef OPENSSL_NO_ENGINE
OSSL_TRACE(INIT, "OPENSSL_cleanup: engine_cleanup_int()\n");
engine_cleanup_int();
@@ -547,8 +573,8 @@ void OPENSSL_cleanup(void)
OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_store_cleanup_int()\n");
ossl_store_cleanup_int();
OSSL_TRACE(INIT, "OPENSSL_cleanup: crypto_cleanup_all_ex_data_int()\n");
crypto_cleanup_all_ex_data_int();
OSSL_TRACE(INIT, "OPENSSL_cleanup: openssl_ctx_default_deinit()\n");
openssl_ctx_default_deinit();
OSSL_TRACE(INIT, "OPENSSL_cleanup: bio_cleanup()\n");
bio_cleanup();
@@ -578,6 +604,11 @@ void OPENSSL_cleanup(void)
*/
int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
{
/*
* TODO(3.0): This function needs looking at with a view to moving most/all
* of this into OPENSSL_CTX.
*/
if (stopped) {
if (!(opts & OPENSSL_INIT_BASE_ONLY))
CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL);
@@ -655,6 +686,15 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
&& !RUN_ONCE(&add_all_macs, ossl_init_add_all_macs))
return 0;
if ((opts & OPENSSL_INIT_NO_ADD_ALL_KDFS)
&& !RUN_ONCE_ALT(&add_all_kdfs, ossl_init_no_add_all_kdfs,
ossl_init_add_all_kdfs))
return 0;
if ((opts & OPENSSL_INIT_ADD_ALL_KDFS)
&& !RUN_ONCE(&add_all_kdfs, ossl_init_add_all_kdfs))
return 0;
if ((opts & OPENSSL_INIT_ATFORK)
&& !openssl_init_fork_handlers())
return 0;
+1 -1
View File
@@ -229,7 +229,7 @@ static int kdf_hkdf_derive(EVP_KDF_IMPL *impl, unsigned char *key,
}
}
const EVP_KDF_METHOD hkdf_kdf_meth = {
const EVP_KDF hkdf_kdf_meth = {
EVP_KDF_HKDF,
kdf_hkdf_new,
kdf_hkdf_free,
+2
View File
@@ -65,6 +65,7 @@ static const ERR_STRING_DATA KDF_str_functs[] = {
{ERR_PACK(ERR_LIB_KDF, KDF_F_SSKDF_NEW, 0), "sskdf_new"},
{ERR_PACK(ERR_LIB_KDF, KDF_F_SSKDF_SIZE, 0), "sskdf_size"},
{ERR_PACK(ERR_LIB_KDF, KDF_F_TLS1_PRF_ALG, 0), "tls1_prf_alg"},
{ERR_PACK(ERR_LIB_KDF, KDF_F_X963KDF_DERIVE, 0), "x963kdf_derive"},
{0, NULL}
};
@@ -84,6 +85,7 @@ static const ERR_STRING_DATA KDF_str_reasons[] = {
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_SESSION_ID), "missing session id"},
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_TYPE), "missing type"},
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_XCGHASH), "missing xcghash"},
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_NOT_SUPPORTED), "not supported"},
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_UNKNOWN_PARAMETER_TYPE),
"unknown parameter type"},
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_UNSUPPORTED_MAC_TYPE),
+1 -1
View File
@@ -180,7 +180,7 @@ static int kdf_pbkdf2_derive(EVP_KDF_IMPL *impl, unsigned char *key,
impl->md, key, keylen);
}
const EVP_KDF_METHOD pbkdf2_kdf_meth = {
const EVP_KDF pbkdf2_kdf_meth = {
EVP_KDF_PBKDF2,
kdf_pbkdf2_new,
kdf_pbkdf2_free,
+1 -1
View File
@@ -266,7 +266,7 @@ static int kdf_scrypt_derive(EVP_KDF_IMPL *impl, unsigned char *key,
impl->maxmem_bytes, key, keylen);
}
const EVP_KDF_METHOD scrypt_kdf_meth = {
const EVP_KDF scrypt_kdf_meth = {
EVP_KDF_SCRYPT,
kdf_scrypt_new,
kdf_scrypt_free,
+4 -1
View File
@@ -125,6 +125,9 @@ static int kdf_sshkdf_ctrl_str(EVP_KDF_IMPL *impl, const char *type,
return 0;
}
if (strcmp(type, "digest") == 0)
return kdf_md2ctrl(impl, kdf_sshkdf_ctrl, EVP_KDF_CTRL_SET_MD, value);
/* alias, for historical reasons */
if (strcmp(type, "md") == 0)
return kdf_md2ctrl(impl, kdf_sshkdf_ctrl, EVP_KDF_CTRL_SET_MD, value);
@@ -200,7 +203,7 @@ static int kdf_sshkdf_derive(EVP_KDF_IMPL *impl, unsigned char *key,
impl->type, key, keylen);
}
const EVP_KDF_METHOD sshkdf_kdf_meth = {
const EVP_KDF sshkdf_kdf_meth = {
EVP_KDF_SSHKDF,
kdf_sshkdf_new,
kdf_sshkdf_free,
+42 -3
View File
@@ -66,10 +66,16 @@ static const unsigned char kmac_custom_str[] = { 0x4B, 0x44, 0x46 };
/*
* Refer to https://csrc.nist.gov/publications/detail/sp/800-56c/rev-1/final
* Section 4. One-Step Key Derivation using H(x) = hash(x)
* Note: X9.63 also uses this code with the only difference being that the
* counter is appended to the secret 'z'.
* i.e.
* result[i] = Hash(counter || z || info) for One Step OR
* result[i] = Hash(z || counter || info) for X9.63.
*/
static int SSKDF_hash_kdm(const EVP_MD *kdf_md,
const unsigned char *z, size_t z_len,
const unsigned char *info, size_t info_len,
unsigned int append_ctr,
unsigned char *derived_key, size_t derived_key_len)
{
int ret = 0, hlen;
@@ -104,8 +110,9 @@ static int SSKDF_hash_kdm(const EVP_MD *kdf_md,
c[3] = (unsigned char)(counter & 0xff);
if (!(EVP_MD_CTX_copy_ex(ctx, ctx_init)
&& EVP_DigestUpdate(ctx, c, sizeof(c))
&& (append_ctr || EVP_DigestUpdate(ctx, c, sizeof(c)))
&& EVP_DigestUpdate(ctx, z, z_len)
&& (!append_ctr || EVP_DigestUpdate(ctx, c, sizeof(c)))
&& EVP_DigestUpdate(ctx, info, info_len)))
goto end;
if (len >= out_len) {
@@ -468,11 +475,32 @@ static int sskdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen)
return 0;
}
return SSKDF_hash_kdm(impl->md, impl->secret, impl->secret_len,
impl->info, impl->info_len, key, keylen);
impl->info, impl->info_len, 0, key, keylen);
}
}
const EVP_KDF_METHOD ss_kdf_meth = {
static int x963kdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen)
{
if (impl->secret == NULL) {
KDFerr(KDF_F_X963KDF_DERIVE, KDF_R_MISSING_SECRET);
return 0;
}
if (impl->mac != NULL) {
KDFerr(KDF_F_X963KDF_DERIVE, KDF_R_NOT_SUPPORTED);
return 0;
} else {
/* H(x) = hash */
if (impl->md == NULL) {
KDFerr(KDF_F_X963KDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
return 0;
}
return SSKDF_hash_kdm(impl->md, impl->secret, impl->secret_len,
impl->info, impl->info_len, 1, key, keylen);
}
}
const EVP_KDF ss_kdf_meth = {
EVP_KDF_SS,
sskdf_new,
sskdf_free,
@@ -482,3 +510,14 @@ const EVP_KDF_METHOD ss_kdf_meth = {
sskdf_size,
sskdf_derive
};
const EVP_KDF x963_kdf_meth = {
EVP_KDF_X963,
sskdf_new,
sskdf_free,
sskdf_reset,
sskdf_ctrl,
sskdf_ctrl_str,
sskdf_size,
x963kdf_derive
};
+1 -1
View File
@@ -157,7 +157,7 @@ static int kdf_tls1_prf_derive(EVP_KDF_IMPL *impl, unsigned char *key,
key, keylen);
}
const EVP_KDF_METHOD tls1_prf_kdf_meth = {
const EVP_KDF tls1_prf_kdf_meth = {
EVP_KDF_TLS1_PRF,
kdf_tls1_prf_new,
kdf_tls1_prf_free,
+1 -1
View File
@@ -33,8 +33,8 @@
# include <linux/mman.h>
# include <errno.h>
# endif
# include <sys/param.h>
# endif
# include <sys/param.h>
# include <sys/stat.h>
# include <fcntl.h>
#endif
+9 -29
View File
@@ -585,52 +585,32 @@ const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
}
const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num,
const void *OBJ_bsearch_ex_(const void *key, const void *base, int num,
int size,
int (*cmp) (const void *, const void *),
int flags)
{
const char *base = base_;
int l, h, i = 0, c = 0;
const char *p = NULL;
const char *p = ossl_bsearch(key, base, num, size, cmp, flags);
if (num == 0)
return NULL;
l = 0;
h = num;
while (l < h) {
i = (l + h) / 2;
p = &(base[i * size]);
c = (*cmp) (key, p);
if (c < 0)
h = i;
else if (c > 0)
l = i + 1;
else
break;
}
#ifdef CHARSET_EBCDIC
/*
* THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I
* don't have perl (yet), we revert to a *LINEAR* search when the object
* wasn't found in the binary search.
*/
if (c != 0) {
if (p == NULL) {
const char *base_ = base;
int l, h, i = 0, c = 0;
for (i = 0; i < num; ++i) {
p = &(base[i * size]);
p = &(base_[i * size]);
c = (*cmp) (key, p);
if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
if (c == 0
|| (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
return p;
}
}
#endif
if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
p = NULL;
else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) {
while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0)
i--;
p = &(base[i * size]);
}
return p;
}
+10 -7
View File
@@ -1070,7 +1070,7 @@ static const unsigned char so[7775] = {
0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x01, /* [ 7684] OBJ_id_tc26_wrap_gostr3412_2015_magma */
0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x01,0x01, /* [ 7692] OBJ_id_tc26_wrap_gostr3412_2015_magma_kexp15 */
0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x02, /* [ 7701] OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik */
0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x01,0x01, /* [ 7709] OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 */
0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x02,0x01, /* [ 7709] OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 */
0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x02, /* [ 7718] OBJ_id_tc26_gost_3410_2012_256_paramSetB */
0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x03, /* [ 7727] OBJ_id_tc26_gost_3410_2012_256_paramSetC */
0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x04, /* [ 7736] OBJ_id_tc26_gost_3410_2012_256_paramSetD */
@@ -1080,7 +1080,7 @@ static const unsigned char so[7775] = {
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75, /* [ 7766] OBJ_SM2_with_SM3 */
};
#define NUM_NID 1207
#define NUM_NID 1208
static const ASN1_OBJECT nid_objs[NUM_NID] = {
{"UNDEF", "undefined", NID_undef},
{"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
@@ -2288,10 +2288,11 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
{"SSHKDF", "sshkdf", NID_sshkdf},
{"SM2-SM3", "SM2-with-SM3", NID_SM2_with_SM3, 8, &so[7766]},
{"SSKDF", "sskdf", NID_sskdf},
{"X963KDF", "x963kdf", NID_x963kdf},
{"ChaCha20-Poly1305-D", "chacha20-poly1305-draft", NID_chacha20_poly1305_draft},
};
#define NUM_SN 1198
#define NUM_SN 1199
static const unsigned int sn_objs[NUM_SN] = {
364, /* "AD_DVCS" */
419, /* "AES-128-CBC" */
@@ -2414,7 +2415,7 @@ static const unsigned int sn_objs[NUM_SN] = {
417, /* "CSPName" */
1019, /* "ChaCha20" */
1018, /* "ChaCha20-Poly1305" */
1206, /* "ChaCha20-Poly1305-D" */
1207, /* "ChaCha20-Poly1305-D" */
367, /* "CrlID" */
391, /* "DC" */
31, /* "DES-CBC" */
@@ -2593,6 +2594,7 @@ static const unsigned int sn_objs[NUM_SN] = {
378, /* "X500algorithms" */
12, /* "X509" */
184, /* "X9-57" */
1206, /* "X963KDF" */
185, /* "X9cm" */
125, /* "ZLIB" */
478, /* "aRecord" */
@@ -3493,7 +3495,7 @@ static const unsigned int sn_objs[NUM_SN] = {
1093, /* "x509ExtAdmission" */
};
#define NUM_LN 1198
#define NUM_LN 1199
static const unsigned int ln_objs[NUM_LN] = {
363, /* "AD Time Stamping" */
405, /* "ANSI X9.62" */
@@ -3878,7 +3880,7 @@ static const unsigned int ln_objs[NUM_LN] = {
883, /* "certificateRevocationList" */
1019, /* "chacha20" */
1018, /* "chacha20-poly1305" */
1206, /* "chacha20-poly1305-draft" */
1207, /* "chacha20-poly1305-draft" */
54, /* "challengePassword" */
407, /* "characteristic-two-field" */
395, /* "clearance" */
@@ -4692,6 +4694,7 @@ static const unsigned int ln_objs[NUM_LN] = {
503, /* "x500UniqueIdentifier" */
158, /* "x509Certificate" */
160, /* "x509Crl" */
1206, /* "x963kdf" */
125, /* "zlib compression" */
};
@@ -5404,7 +5407,7 @@ static const unsigned int obj_objs[NUM_OBJ] = {
1177, /* OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm 1 2 643 7 1 1 5 2 1 */
1178, /* OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac 1 2 643 7 1 1 5 2 2 */
1181, /* OBJ_id_tc26_wrap_gostr3412_2015_magma_kexp15 1 2 643 7 1 1 7 1 1 */
1183, /* OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 1 2 643 7 1 1 7 1 1 */
1183, /* OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 1 2 643 7 1 1 7 2 1 */
1148, /* OBJ_id_tc26_gost_3410_2012_256_paramSetA 1 2 643 7 1 2 1 1 1 */
1184, /* OBJ_id_tc26_gost_3410_2012_256_paramSetB 1 2 643 7 1 2 1 1 2 */
1185, /* OBJ_id_tc26_gost_3410_2012_256_paramSetC 1 2 643 7 1 2 1 1 3 */
+2 -1
View File
@@ -1203,4 +1203,5 @@ blake2smac 1202
sshkdf 1203
SM2_with_SM3 1204
sskdf 1205
chacha20_poly1305_draft 1206
x963kdf 1206
chacha20_poly1305_draft 1207
+4 -1
View File
@@ -1369,7 +1369,7 @@ id-tc26-algorithms 7 : id-tc26-wrap
id-tc26-wrap 1 : id-tc26-wrap-gostr3412-2015-magma
id-tc26-wrap-gostr3412-2015-magma 1 : id-tc26-wrap-gostr3412-2015-magma-kexp15
id-tc26-wrap 2 : id-tc26-wrap-gostr3412-2015-kuznyechik
id-tc26-wrap-gostr3412-2015-magma 1 : id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15
id-tc26-wrap-gostr3412-2015-kuznyechik 1 : id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15
id-tc26 2 : id-tc26-constants
@@ -1618,6 +1618,9 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme
# NID for SSKDF
: SSKDF : sskdf
# NID for X963-2001 KDF
: X963KDF : x963kdf
# RFC 4556
1 3 6 1 5 2 3 : id-pkinit
id-pkinit 4 : pkInitClientAuth : PKINIT Client Auth
+393 -82
View File
@@ -156,12 +156,54 @@ OSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf,
int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val)
{
if (val == NULL || p == NULL || (p->data_type != OSSL_PARAM_INTEGER))
int64_t i64;
uint32_t u32;
uint64_t u64;
double d;
if (val == NULL || p == NULL )
return 0;
if (p->data_size == sizeof(int32_t)) {
*val = *(const int32_t *)p->data;
return 1;
if (p->data_type == OSSL_PARAM_INTEGER) {
switch (p->data_size) {
case sizeof(int32_t):
*val = *(const int32_t *)p->data;
return 1;
case sizeof(int64_t):
i64 = *(const int64_t *)p->data;
if (i64 >= INT32_MIN && i64 <= INT32_MAX) {
*val = (int32_t)i64;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
switch (p->data_size) {
case sizeof(uint32_t):
u32 = *(const uint32_t *)p->data;
if (u32 <= INT32_MAX) {
*val = (int32_t)u32;
return 1;
}
break;
case sizeof(uint64_t):
u64 = *(const uint64_t *)p->data;
if (u64 <= INT32_MAX) {
*val = (int32_t)u64;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
switch (p->data_size) {
case sizeof(double):
d = *(const double *)p->data;
if (d >= INT32_MIN && d <= INT32_MAX && d == (int32_t)d) {
*val = (int32_t)d;
return 1;
}
break;
}
}
return 0;
}
@@ -171,19 +213,35 @@ int OSSL_PARAM_set_int32(const OSSL_PARAM *p, int32_t val)
if (p == NULL)
return 0;
SET_RETURN_SIZE(p, 0);
if (p->data_type != OSSL_PARAM_INTEGER)
return 0;
SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(int32_t):
SET_RETURN_SIZE(p, sizeof(int32_t));
*(int32_t *)p->data = val;
return 1;
case sizeof(int64_t):
SET_RETURN_SIZE(p, sizeof(int64_t));
*(int64_t *)p->data = (int64_t)val;
return 1;
if (p->data_type == OSSL_PARAM_INTEGER) {
SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(int32_t):
*(int32_t *)p->data = val;
return 1;
case sizeof(int64_t):
SET_RETURN_SIZE(p, sizeof(int64_t));
*(int64_t *)p->data = (int64_t)val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(uint32_t):
*(uint32_t *)p->data = (uint32_t)val;
return 1;
case sizeof(uint64_t):
SET_RETURN_SIZE(p, sizeof(uint64_t));
*(uint64_t *)p->data = (uint64_t)val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
SET_RETURN_SIZE(p, sizeof(double));
switch (p->data_size) {
case sizeof(double):
*(double *)p->data = (double)val;
return 1;
}
}
return 0;
}
@@ -197,35 +255,96 @@ OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf,
int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val)
{
if (val == NULL
|| p == NULL
|| (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
int32_t i32;
int64_t i64;
uint64_t u64;
double d;
if (val == NULL || p == NULL)
return 0;
if (p->data_size == sizeof(uint32_t)) {
*val = *(const uint32_t *)p->data;
return 1;
if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
switch (p->data_size) {
case sizeof(uint32_t):
*val = *(const uint32_t *)p->data;
return 1;
case sizeof(uint64_t):
u64 = *(const uint64_t *)p->data;
if (u64 <= UINT32_MAX) {
*val = (uint32_t)u64;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_INTEGER) {
switch (p->data_size) {
case sizeof(int32_t):
i32 = *(const int32_t *)p->data;
if (i32 >= 0) {
*val = i32;
return 1;
}
break;
case sizeof(int64_t):
i64 = *(const int64_t *)p->data;
if (i64 >= 0 && i64 <= UINT32_MAX) {
*val = (uint32_t)i64;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
switch (p->data_size) {
case sizeof(double):
d = *(const double *)p->data;
if (d >= 0 && d <= UINT32_MAX && d == (uint32_t)d) {
*val = (uint32_t)d;
return 1;
}
break;
}
}
return 0;
}
int OSSL_PARAM_set_uint32(const OSSL_PARAM *p, uint32_t val)
{
if (p == NULL) return 0;
SET_RETURN_SIZE(p, 0);
if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
if (p == NULL)
return 0;
SET_RETURN_SIZE(p, 0);
SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(uint32_t):
SET_RETURN_SIZE(p, sizeof(uint32_t));
*(uint32_t *)p->data = val;
return 1;
case sizeof(uint64_t):
SET_RETURN_SIZE(p, sizeof(uint64_t));
*(uint64_t *)p->data = (uint64_t)val;
return 1;
if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(uint32_t):
*(uint32_t *)p->data = val;
return 1;
case sizeof(uint64_t):
SET_RETURN_SIZE(p, sizeof(uint64_t));
*(uint64_t *)p->data = val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_INTEGER) {
SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(int32_t):
if (val <= INT32_MAX) {
*(int32_t *)p->data = (int32_t)val;
return 1;
}
break;
case sizeof(int64_t):
SET_RETURN_SIZE(p, sizeof(int64_t));
*(int64_t *)p->data = (int64_t)val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
SET_RETURN_SIZE(p, sizeof(double));
switch (p->data_size) {
case sizeof(double):
*(double *)p->data = (double)val;
return 1;
}
}
return 0;
}
@@ -239,34 +358,94 @@ OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf,
int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val)
{
if (val == NULL || p == NULL || (p->data_type != OSSL_PARAM_INTEGER))
uint64_t u64;
double d;
if (val == NULL || p == NULL )
return 0;
switch (p->data_size) {
case sizeof(int32_t):
*val = (int64_t)*(const int32_t *)p->data;
return 1;
case sizeof(int64_t):
*val = *(const int64_t *)p->data;
return 1;
if (p->data_type == OSSL_PARAM_INTEGER) {
switch (p->data_size) {
case sizeof(int32_t):
*val = *(const int32_t *)p->data;
return 1;
case sizeof(int64_t):
*val = *(const int64_t *)p->data;
return 1;
}
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
switch (p->data_size) {
case sizeof(uint32_t):
*val = *(const uint32_t *)p->data;
return 1;
case sizeof(uint64_t):
u64 = *(const uint64_t *)p->data;
if (u64 <= INT64_MAX) {
*val = (int64_t)u64;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
switch (p->data_size) {
case sizeof(double):
d = *(const double *)p->data;
if (d >= INT64_MIN && d <= INT64_MAX && d == (int64_t)d) {
*val = (int64_t)d;
return 1;
}
break;
}
}
return 0;
}
int OSSL_PARAM_set_int64(const OSSL_PARAM *p, int64_t val)
{
uint64_t u64;
if (p == NULL)
return 0;
SET_RETURN_SIZE(p, 0);
if (p->data_type != OSSL_PARAM_INTEGER)
return 0;
SET_RETURN_SIZE(p, sizeof(int64_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(int64_t):
SET_RETURN_SIZE(p, sizeof(int64_t));
*(int64_t *)p->data = val;
return 1;
if (p->data_type == OSSL_PARAM_INTEGER) {
SET_RETURN_SIZE(p, sizeof(int64_t)); /* Expected size */
switch (p->data_size) {
case sizeof(int32_t):
if (val >= INT32_MIN && val <= INT32_MAX) {
SET_RETURN_SIZE(p, sizeof(int32_t));
*(int32_t *)p->data = (int32_t)val;
return 1;
}
break;
case sizeof(int64_t):
*(int64_t *)p->data = val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Expected size */
switch (p->data_size) {
case sizeof(uint32_t):
if (val <= UINT32_MAX) {
SET_RETURN_SIZE(p, sizeof(uint32_t));
*(uint32_t *)p->data = (uint32_t)val;
return 1;
}
break;
case sizeof(uint64_t):
*(uint64_t *)p->data = (uint64_t)val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
SET_RETURN_SIZE(p, sizeof(double));
switch (p->data_size) {
case sizeof(double):
u64 = val < 0 ? -val : val;
if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
*(double *)p->data = (double)val;
return 1;
}
break;
}
}
return 0;
}
@@ -280,18 +459,49 @@ OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf,
int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val)
{
if (val == NULL
|| p == NULL
|| (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
int32_t i32;
int64_t i64;
double d;
if (val == NULL || p == NULL)
return 0;
switch (p->data_size) {
case sizeof(uint32_t):
*val = (uint64_t)*(const uint32_t *)p->data;
return 1;
case sizeof(uint64_t):
*val = *(const uint64_t *)p->data;
return 1;
if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
switch (p->data_size) {
case sizeof(uint32_t):
*val = *(const uint32_t *)p->data;
return 1;
case sizeof(uint64_t):
*val = *(const uint64_t *)p->data;
return 1;
}
} else if (p->data_type == OSSL_PARAM_INTEGER) {
switch (p->data_size) {
case sizeof(int32_t):
i32 = *(const int32_t *)p->data;
if (i32 >= 0) {
*val = (uint64_t)i32;
return 1;
}
break;
case sizeof(int64_t):
i64 = *(const int64_t *)p->data;
if (i64 >= 0) {
*val = (uint64_t)i64;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
switch (p->data_size) {
case sizeof(double):
d = *(const double *)p->data;
if (d >= 0 && d <= INT64_MAX && d == (uint64_t)d) {
*val = (uint64_t)d;
return 1;
}
break;
}
}
return 0;
}
@@ -301,15 +511,48 @@ int OSSL_PARAM_set_uint64(const OSSL_PARAM *p, uint64_t val)
if (p == NULL)
return 0;
SET_RETURN_SIZE(p, 0);
if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
return 0;
SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Minimum expected size */
switch (p->data_size) {
case sizeof(uint64_t):
SET_RETURN_SIZE(p, sizeof(uint64_t));
*(uint64_t *)p->data = val;
return 1;
if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Expected size */
switch (p->data_size) {
case sizeof(uint32_t):
if (val <= UINT32_MAX) {
SET_RETURN_SIZE(p, sizeof(uint32_t));
*(uint32_t *)p->data = (uint32_t)val;
return 1;
}
break;
case sizeof(uint64_t):
*(uint64_t *)p->data = val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_INTEGER) {
SET_RETURN_SIZE(p, sizeof(int64_t)); /* Expected size */
switch (p->data_size) {
case sizeof(int32_t):
if (val <= INT32_MAX) {
SET_RETURN_SIZE(p, sizeof(int32_t));
*(int32_t *)p->data = (int32_t)val;
return 1;
}
break;
case sizeof(int64_t):
if (val <= INT64_MAX) {
*(int64_t *)p->data = (int64_t)val;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_REAL) {
SET_RETURN_SIZE(p, sizeof(double));
switch (p->data_size) {
case sizeof(double):
if ((val >> 53) == 0) { /* 53 significant bits in the mantissa */
*(double *)p->data = (double)val;
return 1;
}
break;
}
}
return 0;
}
@@ -402,13 +645,45 @@ OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
{
if (val == NULL || p == NULL || p->data_type != OSSL_PARAM_REAL)
int64_t i64;
uint64_t u64;
if (val == NULL || p == NULL)
return 0;
switch (p->data_size) {
case sizeof(double):
*val = *(const double *)p->data;
return 1;
if (p->data_type == OSSL_PARAM_REAL) {
switch (p->data_size) {
case sizeof(double):
*val = *(const double *)p->data;
return 1;
}
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
switch (p->data_size) {
case sizeof(uint32_t):
*val = *(const uint32_t *)p->data;
return 1;
case sizeof(uint64_t):
u64 = *(const uint64_t *)p->data;
if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
*val = (double)u64;
return 1;
}
break;
}
} else if (p->data_type == OSSL_PARAM_INTEGER) {
switch (p->data_size) {
case sizeof(int32_t):
*val = *(const int32_t *)p->data;
return 1;
case sizeof(int64_t):
i64 = *(const int64_t *)p->data;
u64 = i64 < 0 ? -i64 : i64;
if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
*val = 0.0 + i64;
return 1;
}
break;
}
}
return 0;
}
@@ -418,14 +693,50 @@ int OSSL_PARAM_set_double(const OSSL_PARAM *p, double val)
if (p == NULL)
return 0;
SET_RETURN_SIZE(p, 0);
if (p->data_type != OSSL_PARAM_REAL)
return 0;
switch (p->data_size) {
case sizeof(double):
if (p->data_type == OSSL_PARAM_REAL) {
SET_RETURN_SIZE(p, sizeof(double));
*(double *)p->data = val;
return 1;
switch (p->data_size) {
case sizeof(double):
*(double *)p->data = val;
return 1;
}
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER
&& val == (uintmax_t)val) {
SET_RETURN_SIZE(p, sizeof(double));
switch (p->data_size) {
case sizeof(uint32_t):
if (val >= 0 && val <= UINT32_MAX) {
SET_RETURN_SIZE(p, sizeof(uint32_t));
*(uint32_t *)p->data = (uint32_t)val;
return 1;
}
break;
case sizeof(uint64_t):
if (val >= 0 && val <= UINT64_MAX) {
SET_RETURN_SIZE(p, sizeof(uint64_t));
*(uint64_t *)p->data = (uint64_t)val;
return 1;
}
break; }
} else if (p->data_type == OSSL_PARAM_INTEGER && val == (intmax_t)val) {
SET_RETURN_SIZE(p, sizeof(double));
switch (p->data_size) {
case sizeof(int32_t):
if (val >= INT32_MIN && val <= INT32_MAX) {
SET_RETURN_SIZE(p, sizeof(int32_t));
*(int32_t *)p->data = (int32_t)val;
return 1;
}
break;
case sizeof(int64_t):
if (val >= INT64_MIN && val <= INT64_MAX) {
SET_RETURN_SIZE(p, sizeof(int64_t));
*(int64_t *)p->data = (int64_t)val;
return 1;
}
break;
}
}
return 0;
}
+3 -2
View File
@@ -323,6 +323,7 @@ void OPENSSL_cpuid_setup(void)
#ifdef OSSL_IMPLEMENT_GETAUXVAL
{
unsigned long hwcap = getauxval(HWCAP);
unsigned long hwcap2 = getauxval(HWCAP2);
if (hwcap & HWCAP_FPU) {
OPENSSL_ppccap_P |= PPC_FPU;
@@ -341,11 +342,11 @@ void OPENSSL_cpuid_setup(void)
if (hwcap & HWCAP_ALTIVEC) {
OPENSSL_ppccap_P |= PPC_ALTIVEC;
if ((hwcap & HWCAP_VSX) && (getauxval(HWCAP2) & HWCAP_VEC_CRYPTO))
if ((hwcap & HWCAP_VSX) && (hwcap2 & HWCAP_VEC_CRYPTO))
OPENSSL_ppccap_P |= PPC_CRYPTO207;
}
if (hwcap & HWCAP_ARCH_3_00) {
if (hwcap2 & HWCAP_ARCH_3_00) {
OPENSSL_ppccap_P |= PPC_MADD300;
}
}
+28 -13
View File
@@ -29,8 +29,6 @@ typedef struct {
DEFINE_LHASH_OF(PROPERTY_DEFN_ELEM);
static LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns = NULL;
static unsigned long property_defn_hash(const PROPERTY_DEFN_ELEM *a)
{
return OPENSSL_LH_strhash(a->prop);
@@ -48,35 +46,52 @@ static void property_defn_free(PROPERTY_DEFN_ELEM *elem)
OPENSSL_free(elem);
}
int ossl_prop_defn_init(void)
static void property_defns_free(void *vproperty_defns)
{
property_defns = lh_PROPERTY_DEFN_ELEM_new(&property_defn_hash,
&property_defn_cmp);
return property_defns != NULL;
}
LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns = vproperty_defns;
void ossl_prop_defn_cleanup(void)
{
if (property_defns != NULL) {
lh_PROPERTY_DEFN_ELEM_doall(property_defns, &property_defn_free);
lh_PROPERTY_DEFN_ELEM_doall(property_defns,
&property_defn_free);
lh_PROPERTY_DEFN_ELEM_free(property_defns);
property_defns = NULL;
}
}
OSSL_PROPERTY_LIST *ossl_prop_defn_get(const char *prop)
static void *property_defns_new(OPENSSL_CTX *ctx) {
return lh_PROPERTY_DEFN_ELEM_new(&property_defn_hash, &property_defn_cmp);
}
static const OPENSSL_CTX_METHOD property_defns_method = {
property_defns_new,
property_defns_free,
};
OSSL_PROPERTY_LIST *ossl_prop_defn_get(OPENSSL_CTX *ctx, const char *prop)
{
PROPERTY_DEFN_ELEM elem, *r;
LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns;
property_defns = openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_DEFN_INDEX,
&property_defns_method);
if (property_defns == NULL)
return NULL;
elem.prop = prop;
r = lh_PROPERTY_DEFN_ELEM_retrieve(property_defns, &elem);
return r != NULL ? r->defn : NULL;
}
int ossl_prop_defn_set(const char *prop, OSSL_PROPERTY_LIST *pl)
int ossl_prop_defn_set(OPENSSL_CTX *ctx, const char *prop,
OSSL_PROPERTY_LIST *pl)
{
PROPERTY_DEFN_ELEM elem, *old, *p = NULL;
size_t len;
LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns;
property_defns = openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_DEFN_INDEX,
&property_defns_method);
if (property_defns == NULL)
return 0;
if (prop == NULL)
return 1;
+5 -4
View File
@@ -2,16 +2,17 @@
Definition
::= PropertyName ( '=' Value )? ( ',' PropertyName ( '=' Value )? )*
Query ::= ( '-'? PropertyName | PropertyName ( '=' | '!=' ) Value )
( ',' ( '-'? PropertyName | PropertyName ( '=' | '!=' ) Value ) )*
Query ::= PropertyQuery ( ',' PropertyQuery )*
PropertyQuery ::= '-'? PropertyName
| '?' ( PropertyName (( '=' | '!=' ) Value)?)
Value ::= NumberLiteral
| StringLiteral
StringLiteral ::= QuotedString | UnquotedString
QuotedString ::= '"' [^"]* '"'
| "'" [^']* "'"
| "'" [^']* "'"
UnquotedString ::= [^{space},]+
NumberLiteral
::= '0' ( [0-7]* | 'x' [0-9A-Fa-f]+ )
| '-'? [1-9] [0-9]+
| '-'? [1-9] [0-9]+
PropertyName
::= [A-Z] [A-Z0-9_]* ( '.' [A-Z] [A-Z0-9_]* )*
Regular → Executable
+76 -28
View File
@@ -2,7 +2,7 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
<meta name="generator" content="Railroad Diagram Generator 1.56.1774" />
<meta name="generator" content="Railroad Diagram Generator 1.59.1797" />
<style type="text/css">
::-moz-selection
{
@@ -133,7 +133,7 @@
display: block;
padding: 10px;
background: #FFF6D1;
width: 1000px;
width: 992px;
}
#divs div.grammar
{
@@ -268,7 +268,7 @@
<div><a href="#Definition" title="Definition">Definition</a></div>
<div>         ::= <a href="#PropertyName" title="PropertyName">PropertyName</a> ( '=' <a href="#Value" title="Value">Value</a> )? ( ',' <a href="#PropertyName" title="PropertyName">PropertyName</a> ( '=' <a href="#Value" title="Value">Value</a> )? )*</div></xhtml:code></xhtml:div>
</xhtml:p>
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">no references</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="Query">Query:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="419" height="201">
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">no references</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="Query">Query:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="211" height="81">
<defs>
<style type="text/css">
@namespace "http://www.w3.org/2000/svg";
@@ -299,33 +299,81 @@
</style>
</defs>
<polygon points="9 61 1 57 1 65"/>
<polygon points="17 61 9 57 9 65"/>
<rect x="91" y="79" width="26" height="32" rx="10"/>
<rect x="89" y="77" width="26" height="32" class="terminal" rx="10"/>
<text class="terminal" x="99" y="97">-</text><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#PropertyName" xlink:title="PropertyName">
<rect x="157" y="47" width="110" height="32"/>
<rect x="155" y="45" width="110" height="32" class="nonterminal"/>
<text class="nonterminal" x="165" y="65">PropertyName</text></a><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#PropertyName" xlink:title="PropertyName">
<rect x="71" y="123" width="110" height="32"/>
<rect x="69" y="121" width="110" height="32" class="nonterminal"/>
<text class="nonterminal" x="79" y="141">PropertyName</text></a><rect x="221" y="123" width="30" height="32" rx="10"/>
<rect x="219" y="121" width="30" height="32" class="terminal" rx="10"/>
<text class="terminal" x="229" y="141">=</text>
<rect x="221" y="167" width="34" height="32" rx="10"/>
<rect x="219" y="165" width="34" height="32" class="terminal" rx="10"/>
<text class="terminal" x="229" y="185">!=</text><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#Value" xlink:title="Value">
<rect x="295" y="123" width="56" height="32"/>
<rect x="293" y="121" width="56" height="32" class="nonterminal"/>
<text class="nonterminal" x="303" y="141">Value</text></a><rect x="51" y="3" width="24" height="32" rx="10"/>
<polygon points="17 61 9 57 9 65"/><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#PropertyQuery" xlink:title="PropertyQuery">
<rect x="51" y="47" width="112" height="32"/>
<rect x="49" y="45" width="112" height="32" class="nonterminal"/>
<text class="nonterminal" x="59" y="65">PropertyQuery</text></a><rect x="51" y="3" width="24" height="32" rx="10"/>
<rect x="49" y="1" width="24" height="32" class="terminal" rx="10"/>
<text class="terminal" x="59" y="21">,</text>
<svg:path xmlns:svg="http://www.w3.org/2000/svg" class="line" d="m17 61 h2 m60 0 h10 m0 0 h36 m-66 0 h20 m46 0 h20 m-86 0 q10 0 10 10 m66 0 q0 -10 10 -10 m-76 10 v12 m66 0 v-12 m-66 12 q0 10 10 10 m46 0 q10 0 10 -10 m-56 10 h10 m26 0 h10 m20 -32 h10 m110 0 h10 m0 0 h84 m-320 0 h20 m300 0 h20 m-340 0 q10 0 10 10 m320 0 q0 -10 10 -10 m-330 10 v56 m320 0 v-56 m-320 56 q0 10 10 10 m300 0 q10 0 10 -10 m-310 10 h10 m110 0 h10 m20 0 h10 m30 0 h10 m0 0 h4 m-74 0 h20 m54 0 h20 m-94 0 q10 0 10 10 m74 0 q0 -10 10 -10 m-84 10 v24 m74 0 v-24 m-74 24 q0 10 10 10 m54 0 q10 0 10 -10 m-64 10 h10 m34 0 h10 m20 -44 h10 m56 0 h10 m-340 -76 l20 0 m-1 0 q-9 0 -9 -10 l0 -24 q0 -10 10 -10 m340 44 l20 0 m-20 0 q10 0 10 -10 l0 -24 q0 -10 -10 -10 m-340 0 h10 m24 0 h10 m0 0 h296 m23 44 h-3"/>
<polygon points="409 61 417 57 417 65"/>
<polygon points="409 61 401 57 401 65"/></svg><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
<svg:path xmlns:svg="http://www.w3.org/2000/svg" class="line" d="m17 61 h2 m20 0 h10 m112 0 h10 m-152 0 l20 0 m-1 0 q-9 0 -9 -10 l0 -24 q0 -10 10 -10 m132 44 l20 0 m-20 0 q10 0 10 -10 l0 -24 q0 -10 -10 -10 m-132 0 h10 m24 0 h10 m0 0 h88 m23 44 h-3"/>
<polygon points="201 61 209 57 209 65"/>
<polygon points="201 61 193 57 193 65"/></svg><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xhtml:div class="ebnf"><xhtml:code>
<div><a href="#Query" title="Query">Query</a>    ::= ( '-'? <a href="#PropertyName" title="PropertyName">PropertyName</a> | <a href="#PropertyName" title="PropertyName">PropertyName</a> ( '=' | '!=' ) <a href="#Value" title="Value">Value</a> ) ( ',' ( '-'? <a href="#PropertyName" title="PropertyName">PropertyName</a> | <a href="#PropertyName" title="PropertyName">PropertyName</a> ( '=' | '!=' ) <a href="#Value" title="Value">Value</a> ) )*</div></xhtml:code></xhtml:div>
<div><a href="#Query" title="Query">Query</a>    ::= <a href="#PropertyQuery" title="PropertyQuery">PropertyQuery</a> ( ',' <a href="#PropertyQuery" title="PropertyQuery">PropertyQuery</a> )*</div></xhtml:code></xhtml:div>
</xhtml:p>
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">no references</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="Value">Value:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="207" height="81">
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">no references</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="PropertyQuery">PropertyQuery:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="465" height="189">
<defs>
<style type="text/css">
@namespace "http://www.w3.org/2000/svg";
.line {fill: none; stroke: #332900;}
.bold-line {stroke: #141000; shape-rendering: crispEdges; stroke-width: 2; }
.thin-line {stroke: #1F1800; shape-rendering: crispEdges}
.filled {fill: #332900; stroke: none;}
text.terminal {font-family: Verdana, Sans-serif;
font-size: 12px;
fill: #141000;
font-weight: bold;
}
text.nonterminal {font-family: Verdana, Sans-serif;
font-size: 12px;
fill: #1A1400;
font-weight: normal;
}
text.regexp {font-family: Verdana, Sans-serif;
font-size: 12px;
fill: #1F1800;
font-weight: normal;
}
rect, circle, polygon {fill: #332900; stroke: #332900;}
rect.terminal {fill: #FFDB4D; stroke: #332900;}
rect.nonterminal {fill: #FFEC9E; stroke: #332900;}
rect.text {fill: none; stroke: none;}
polygon.regexp {fill: #FFF4C7; stroke: #332900;}
</style>
</defs>
<polygon points="9 17 1 13 1 21"/>
<polygon points="17 17 9 13 9 21"/>
<rect x="71" y="35" width="26" height="32" rx="10"/>
<rect x="69" y="33" width="26" height="32" class="terminal" rx="10"/>
<text class="terminal" x="79" y="53">-</text><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#PropertyName" xlink:title="PropertyName">
<rect x="137" y="3" width="110" height="32"/>
<rect x="135" y="1" width="110" height="32" class="nonterminal"/>
<text class="nonterminal" x="145" y="21">PropertyName</text></a><rect x="51" y="79" width="26" height="32" rx="10"/>
<rect x="49" y="77" width="26" height="32" class="terminal" rx="10"/>
<text class="terminal" x="59" y="97">?</text><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#PropertyName" xlink:title="PropertyName">
<rect x="97" y="79" width="110" height="32"/>
<rect x="95" y="77" width="110" height="32" class="nonterminal"/>
<text class="nonterminal" x="105" y="97">PropertyName</text></a><rect x="267" y="111" width="30" height="32" rx="10"/>
<rect x="265" y="109" width="30" height="32" class="terminal" rx="10"/>
<text class="terminal" x="275" y="129">=</text>
<rect x="267" y="155" width="34" height="32" rx="10"/>
<rect x="265" y="153" width="34" height="32" class="terminal" rx="10"/>
<text class="terminal" x="275" y="173">!=</text><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#Value" xlink:title="Value">
<rect x="341" y="111" width="56" height="32"/>
<rect x="339" y="109" width="56" height="32" class="nonterminal"/>
<text class="nonterminal" x="349" y="129">Value</text></a><svg:path xmlns:svg="http://www.w3.org/2000/svg" class="line" d="m17 17 h2 m40 0 h10 m0 0 h36 m-66 0 h20 m46 0 h20 m-86 0 q10 0 10 10 m66 0 q0 -10 10 -10 m-76 10 v12 m66 0 v-12 m-66 12 q0 10 10 10 m46 0 q10 0 10 -10 m-56 10 h10 m26 0 h10 m20 -32 h10 m110 0 h10 m0 0 h170 m-406 0 h20 m386 0 h20 m-426 0 q10 0 10 10 m406 0 q0 -10 10 -10 m-416 10 v56 m406 0 v-56 m-406 56 q0 10 10 10 m386 0 q10 0 10 -10 m-396 10 h10 m26 0 h10 m0 0 h10 m110 0 h10 m20 0 h10 m0 0 h160 m-190 0 h20 m170 0 h20 m-210 0 q10 0 10 10 m190 0 q0 -10 10 -10 m-200 10 v12 m190 0 v-12 m-190 12 q0 10 10 10 m170 0 q10 0 10 -10 m-160 10 h10 m30 0 h10 m0 0 h4 m-74 0 h20 m54 0 h20 m-94 0 q10 0 10 10 m74 0 q0 -10 10 -10 m-84 10 v24 m74 0 v-24 m-74 24 q0 10 10 10 m54 0 q10 0 10 -10 m-64 10 h10 m34 0 h10 m20 -44 h10 m56 0 h10 m43 -108 h-3"/>
<polygon points="455 17 463 13 463 21"/>
<polygon points="455 17 447 13 447 21"/></svg><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xhtml:div class="ebnf"><xhtml:code>
<div><a href="#PropertyQuery" title="PropertyQuery">PropertyQuery</a></div>
<div>         ::= '-'? <a href="#PropertyName" title="PropertyName">PropertyName</a></div>
<div>           | '?' <a href="#PropertyName" title="PropertyName">PropertyName</a> ( ( '=' | '!=' ) <a href="#Value" title="Value">Value</a> )?</div></xhtml:code></xhtml:div>
</xhtml:p>
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">referenced by:
<xhtml:ul>
<xhtml:li><xhtml:a href="#Query" title="Query">Query</xhtml:a></xhtml:li>
</xhtml:ul>
</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="Value">Value:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="207" height="81">
<defs>
<style type="text/css">
@namespace "http://www.w3.org/2000/svg";
@@ -372,7 +420,7 @@
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">referenced by:
<xhtml:ul>
<xhtml:li><xhtml:a href="#Definition" title="Definition">Definition</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="#Query" title="Query">Query</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="#PropertyQuery" title="PropertyQuery">PropertyQuery</xhtml:a></xhtml:li>
</xhtml:ul>
</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="StringLiteral">StringLiteral:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="219" height="81">
<defs>
@@ -659,7 +707,7 @@
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">referenced by:
<xhtml:ul>
<xhtml:li><xhtml:a href="#Definition" title="Definition">Definition</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="#Query" title="Query">Query</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="#PropertyQuery" title="PropertyQuery">PropertyQuery</xhtml:a></xhtml:li>
</xhtml:ul>
</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:hr xmlns:xhtml="http://www.w3.org/1999/xhtml" />
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
+27 -34
View File
@@ -47,6 +47,7 @@ typedef struct {
} ALGORITHM;
struct ossl_method_store_st {
OPENSSL_CTX *ctx;
size_t nelem;
SPARSE_ARRAY_OF(ALGORITHM) *algs;
OSSL_PROPERTY_LIST *global_properties;
@@ -82,29 +83,10 @@ int ossl_property_unlock(OSSL_METHOD_STORE *p)
return p != 0 ? CRYPTO_THREAD_unlock(p->lock) : 0;
}
int ossl_method_store_init(void)
static openssl_ctx_run_once_fn do_method_store_init;
int do_method_store_init(OPENSSL_CTX *ctx)
{
if (ossl_property_string_init()
&& ossl_prop_defn_init()
&& ossl_property_parse_init())
return 1;
ossl_method_store_cleanup();
return 0;
}
void ossl_method_store_cleanup(void)
{
ossl_property_string_cleanup();
ossl_prop_defn_cleanup();
}
static CRYPTO_ONCE method_store_init_flag = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(do_method_store_init)
{
return OPENSSL_init_crypto(0, NULL)
&& ossl_method_store_init()
&& OPENSSL_atexit(&ossl_method_store_cleanup);
return ossl_property_parse_init(ctx);
}
static unsigned long query_hash(const QUERY *a)
@@ -141,15 +123,22 @@ static void alg_cleanup(ossl_uintmax_t idx, ALGORITHM *a)
}
}
OSSL_METHOD_STORE *ossl_method_store_new(void)
/*
* The OPENSSL_CTX param here allows access to underlying property data needed
* for computation
*/
OSSL_METHOD_STORE *ossl_method_store_new(OPENSSL_CTX *ctx)
{
OSSL_METHOD_STORE *res;
if (!RUN_ONCE(&method_store_init_flag, do_method_store_init))
return 0;
if (!openssl_ctx_run_once(ctx,
OPENSSL_CTX_METHOD_STORE_RUN_ONCE_INDEX,
do_method_store_init))
return NULL;
res = OPENSSL_zalloc(sizeof(*res));
if (res != NULL) {
res->ctx = ctx;
if ((res->algs = ossl_sa_ALGORITHM_new()) == NULL) {
OPENSSL_free(res);
return NULL;
@@ -212,10 +201,11 @@ int ossl_method_store_add(OSSL_METHOD_STORE *store,
*/
ossl_property_write_lock(store);
ossl_method_cache_flush(store, nid);
if ((impl->properties = ossl_prop_defn_get(properties)) == NULL) {
if ((impl->properties = ossl_parse_property(properties)) == NULL)
if ((impl->properties = ossl_prop_defn_get(store->ctx, properties)) == NULL) {
impl->properties = ossl_parse_property(store->ctx, properties);
if (impl->properties == NULL)
goto err;
ossl_prop_defn_set(properties, impl->properties);
ossl_prop_defn_set(store->ctx, properties, impl->properties);
}
alg = ossl_method_store_retrieve(store, nid);
@@ -287,7 +277,7 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid,
IMPLEMENTATION *impl;
OSSL_PROPERTY_LIST *pq = NULL, *p2;
int ret = 0;
int j;
int j, best = -1, score, optional;
if (nid <= 0 || method == NULL || store == NULL)
return 0;
@@ -310,7 +300,7 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid,
}
goto fin;
}
pq = ossl_parse_query(prop_query);
pq = ossl_parse_query(store->ctx, prop_query);
if (pq == NULL)
goto fin;
if (store->global_properties != NULL) {
@@ -320,13 +310,16 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid,
ossl_property_free(pq);
pq = p2;
}
optional = ossl_property_has_optional(pq);
for (j = 0; j < sk_IMPLEMENTATION_num(alg->impls); j++) {
impl = sk_IMPLEMENTATION_value(alg->impls, j);
if (ossl_property_match(pq, impl->properties)) {
score = ossl_property_match_count(pq, impl->properties);
if (score > best) {
*method = impl->method;
ret = 1;
goto fin;
if (!optional)
goto fin;
best = score;
}
}
fin:
@@ -350,7 +343,7 @@ int ossl_method_store_set_global_properties(OSSL_METHOD_STORE *store,
ossl_property_unlock(store);
return 1;
}
store->global_properties = ossl_parse_query(prop_query);
store->global_properties = ossl_parse_query(store->ctx, prop_query);
ret = store->global_properties != NULL;
ossl_property_unlock(store);
return ret;
+13 -17
View File
@@ -14,35 +14,31 @@
typedef struct ossl_property_list_st OSSL_PROPERTY_LIST;
typedef int OSSL_PROPERTY_IDX;
/* Initialisation and finalisation for subsystem */
int ossl_method_store_init(void);
void ossl_method_store_cleanup(void);
/* Property string functions */
OSSL_PROPERTY_IDX ossl_property_name(const char *s, int create);
OSSL_PROPERTY_IDX ossl_property_value(const char *s, int create);
int ossl_property_string_init(void);
void ossl_property_string_cleanup(void);
OSSL_PROPERTY_IDX ossl_property_name(OPENSSL_CTX *ctx, const char *s,
int create);
OSSL_PROPERTY_IDX ossl_property_value(OPENSSL_CTX *ctx, const char *s,
int create);
/* Property list functions */
int ossl_property_parse_init(void);
int ossl_property_parse_init(OPENSSL_CTX *ctx);
void ossl_property_free(OSSL_PROPERTY_LIST *p);
int ossl_property_match(const OSSL_PROPERTY_LIST *query,
const OSSL_PROPERTY_LIST *defn);
int ossl_property_has_optional(const OSSL_PROPERTY_LIST *query);
int ossl_property_match_count(const OSSL_PROPERTY_LIST *query,
const OSSL_PROPERTY_LIST *defn);
OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a,
const OSSL_PROPERTY_LIST *b);
/* Property definition functions */
OSSL_PROPERTY_LIST *ossl_parse_property(const char *s);
OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *s);
/* Property query functions */
OSSL_PROPERTY_LIST *ossl_parse_query(const char *s);
OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s);
/* Property definition cache functions */
int ossl_prop_defn_init(void);
void ossl_prop_defn_cleanup(void);
OSSL_PROPERTY_LIST *ossl_prop_defn_get(const char *prop);
int ossl_prop_defn_set(const char *prop, OSSL_PROPERTY_LIST *pl);
OSSL_PROPERTY_LIST *ossl_prop_defn_get(OPENSSL_CTX *ctx, const char *prop);
int ossl_prop_defn_set(OPENSSL_CTX *ctx, const char *prop,
OSSL_PROPERTY_LIST *pl);
/* Property cache lock / unlock */
int ossl_property_write_lock(OSSL_METHOD_STORE *);
+60 -33
View File
@@ -32,6 +32,7 @@ typedef struct {
OSSL_PROPERTY_IDX name_idx;
PROPERTY_TYPE type;
PROPERTY_OPER oper;
unsigned int optional : 1;
union {
int64_t int_val; /* Signed integer */
OSSL_PROPERTY_IDX str_val; /* String */
@@ -40,6 +41,7 @@ typedef struct {
struct ossl_property_list_st {
int n;
unsigned int has_optional : 1;
PROPERTY_DEFINITION properties[1];
};
@@ -78,7 +80,8 @@ static int match(const char *t[], const char m[], size_t m_len)
return 0;
}
static int parse_name(const char *t[], int create, OSSL_PROPERTY_IDX *idx)
static int parse_name(OPENSSL_CTX *ctx, const char *t[], int create,
OSSL_PROPERTY_IDX *idx)
{
char name[100];
int err = 0;
@@ -109,7 +112,7 @@ static int parse_name(const char *t[], int create, OSSL_PROPERTY_IDX *idx)
name[i] = '\0';
*t = skip_space(s);
if (!err) {
*idx = ossl_property_name(name, user_name && create);
*idx = ossl_property_name(ctx, name, user_name && create);
return 1;
}
PROPerr(PROP_F_PARSE_NAME, PROP_R_NAME_TOO_LONG);
@@ -180,8 +183,8 @@ static int parse_oct(const char *t[], PROPERTY_DEFINITION *res)
return 1;
}
static int parse_string(const char *t[], char delim, PROPERTY_DEFINITION *res,
const int create)
static int parse_string(OPENSSL_CTX *ctx, const char *t[], char delim,
PROPERTY_DEFINITION *res, const int create)
{
char v[1000];
const char *s = *t;
@@ -205,13 +208,13 @@ static int parse_string(const char *t[], char delim, PROPERTY_DEFINITION *res,
if (err)
PROPerr(PROP_F_PARSE_STRING, PROP_R_STRING_TOO_LONG);
else
res->v.str_val = ossl_property_value(v, create);
res->v.str_val = ossl_property_value(ctx, v, create);
res->type = PROPERTY_TYPE_STRING;
return !err;
}
static int parse_unquoted(const char *t[], PROPERTY_DEFINITION *res,
const int create)
static int parse_unquoted(OPENSSL_CTX *ctx, const char *t[],
PROPERTY_DEFINITION *res, const int create)
{
char v[1000];
const char *s = *t;
@@ -236,19 +239,20 @@ static int parse_unquoted(const char *t[], PROPERTY_DEFINITION *res,
if (err)
PROPerr(PROP_F_PARSE_UNQUOTED, PROP_R_STRING_TOO_LONG);
else
res->v.str_val = ossl_property_value(v, create);
res->v.str_val = ossl_property_value(ctx, v, create);
res->type = PROPERTY_TYPE_STRING;
return !err;
}
static int parse_value(const char *t[], PROPERTY_DEFINITION *res, int create)
static int parse_value(OPENSSL_CTX *ctx, const char *t[],
PROPERTY_DEFINITION *res, int create)
{
const char *s = *t;
int r = 0;
if (*s == '"' || *s == '\'') {
s++;
r = parse_string(&s, s[-1], res, create);
r = parse_string(ctx, &s, s[-1], res, create);
} else if (*s == '+') {
s++;
r = parse_number(&s, res);
@@ -265,7 +269,7 @@ static int parse_value(const char *t[], PROPERTY_DEFINITION *res, int create)
} else if (ossl_isdigit(*s)) {
return parse_number(t, res);
} else if (ossl_isalpha(*s))
return parse_unquoted(t, res, create);
return parse_unquoted(ctx, t, res, create);
if (r)
*t = s;
return r;
@@ -305,14 +309,17 @@ static OSSL_PROPERTY_LIST *stack_to_property_list(STACK_OF(PROPERTY_DEFINITION)
if (r != NULL) {
sk_PROPERTY_DEFINITION_sort(sk);
for (i = 0; i < n; i++)
r->has_optional = 0;
for (i = 0; i < n; i++) {
r->properties[i] = *sk_PROPERTY_DEFINITION_value(sk, i);
r->has_optional |= r->properties[i].optional;
}
r->n = n;
}
return r;
}
OSSL_PROPERTY_LIST *ossl_parse_property(const char *defn)
OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *defn)
{
PROPERTY_DEFINITION *prop = NULL;
OSSL_PROPERTY_LIST *res = NULL;
@@ -330,7 +337,8 @@ OSSL_PROPERTY_LIST *ossl_parse_property(const char *defn)
if (prop == NULL)
goto err;
memset(&prop->v, 0, sizeof(prop->v));
if (!parse_name(&s, 1, &prop->name_idx))
prop->optional = 0;
if (!parse_name(ctx, &s, 1, &prop->name_idx))
goto err;
prop->oper = PROPERTY_OPER_EQ;
if (prop->name_idx == 0) {
@@ -338,7 +346,7 @@ OSSL_PROPERTY_LIST *ossl_parse_property(const char *defn)
goto err;
}
if (match_ch(&s, '=')) {
if (!parse_value(&s, prop, 1)) {
if (!parse_value(ctx, &s, prop, 1)) {
PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_NO_VALUE);
goto err;
}
@@ -365,7 +373,7 @@ err:
return res;
}
OSSL_PROPERTY_LIST *ossl_parse_query(const char *s)
OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s)
{
STACK_OF(PROPERTY_DEFINITION) *sk;
OSSL_PROPERTY_LIST *res = NULL;
@@ -385,11 +393,13 @@ OSSL_PROPERTY_LIST *ossl_parse_query(const char *s)
if (match_ch(&s, '-')) {
prop->oper = PROPERTY_OVERRIDE;
if (!parse_name(&s, 0, &prop->name_idx))
prop->optional = 0;
if (!parse_name(ctx, &s, 0, &prop->name_idx))
goto err;
goto skip_value;
}
if (!parse_name(&s, 0, &prop->name_idx))
prop->optional = match_ch(&s, '?');
if (!parse_name(ctx, &s, 0, &prop->name_idx))
goto err;
if (match_ch(&s, '=')) {
@@ -403,7 +413,7 @@ OSSL_PROPERTY_LIST *ossl_parse_query(const char *s)
prop->v.str_val = ossl_property_true;
goto skip_value;
}
if (!parse_value(&s, prop, 0))
if (!parse_value(ctx, &s, prop, 0))
prop->type = PROPERTY_TYPE_VALUE_UNDEFINED;
skip_value:
@@ -424,12 +434,22 @@ err:
return res;
}
int ossl_property_match(const OSSL_PROPERTY_LIST *query,
const OSSL_PROPERTY_LIST *defn)
/* Does a property query have any optional clauses */
int ossl_property_has_optional(const OSSL_PROPERTY_LIST *query)
{
return query->has_optional ? 1 : 0;
}
/*
* Compare a query against a definition.
* Return the number of clauses matched or -1 if a mandatory clause is false.
*/
int ossl_property_match_count(const OSSL_PROPERTY_LIST *query,
const OSSL_PROPERTY_LIST *defn)
{
const PROPERTY_DEFINITION *const q = query->properties;
const PROPERTY_DEFINITION *const d = defn->properties;
int i = 0, j = 0;
int i = 0, j = 0, matches = 0;
PROPERTY_OPER oper;
while (i < query->n) {
@@ -446,9 +466,11 @@ int ossl_property_match(const OSSL_PROPERTY_LIST *query,
const int eq = q[i].type == d[j].type
&& memcmp(&q[i].v, &d[j].v, sizeof(q[i].v)) == 0;
if ((eq && oper != PROPERTY_OPER_EQ)
|| (!eq && oper != PROPERTY_OPER_NE))
return 0;
if ((eq && oper == PROPERTY_OPER_EQ)
|| (!eq && oper == PROPERTY_OPER_NE))
matches++;
else if (!q[i].optional)
return -1;
i++;
j++;
continue;
@@ -461,18 +483,23 @@ int ossl_property_match(const OSSL_PROPERTY_LIST *query,
* the latter is treated as a comparison against the Boolean false.
*/
if (q[i].type == PROPERTY_TYPE_VALUE_UNDEFINED) {
if (oper != PROPERTY_OPER_NE)
return 0;
if (oper == PROPERTY_OPER_NE)
matches++;
else if (!q[i].optional)
return -1;
} else if (q[i].type != PROPERTY_TYPE_STRING
|| (oper == PROPERTY_OPER_EQ
&& q[i].v.str_val != ossl_property_false)
|| (oper == PROPERTY_OPER_NE
&& q[i].v.str_val == ossl_property_false)) {
return 0;
if (!q[i].optional)
return -1;
} else {
matches++;
}
i++;
}
return 1;
return matches;
}
void ossl_property_free(OSSL_PROPERTY_LIST *p)
@@ -519,7 +546,7 @@ OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a,
return r;
}
int ossl_property_parse_init(void)
int ossl_property_parse_init(OPENSSL_CTX *ctx)
{
static const char *const predefined_names[] = {
"default", /* Being provided by the default built-in provider */
@@ -532,12 +559,12 @@ int ossl_property_parse_init(void)
size_t i;
for (i = 0; i < OSSL_NELEM(predefined_names); i++)
if (ossl_property_name(predefined_names[i], 1) == 0)
if (ossl_property_name(ctx, predefined_names[i], 1) == 0)
goto err;
/* Pre-populate the two Boolean values */
if ((ossl_property_true = ossl_property_value("yes", 1)) == 0
|| (ossl_property_false = ossl_property_value("no", 1)) == 0)
if ((ossl_property_true = ossl_property_value(ctx, "yes", 1)) == 0
|| (ossl_property_false = ossl_property_value(ctx, "no", 1)) == 0)
goto err;
return 1;
+68 -29
View File
@@ -34,10 +34,12 @@ typedef struct {
DEFINE_LHASH_OF(PROPERTY_STRING);
typedef LHASH_OF(PROPERTY_STRING) PROP_TABLE;
static PROP_TABLE *prop_names;
static PROP_TABLE *prop_values;
static OSSL_PROPERTY_IDX prop_name_idx = 0;
static OSSL_PROPERTY_IDX prop_value_idx = 0;
typedef struct {
PROP_TABLE *prop_names;
PROP_TABLE *prop_values;
OSSL_PROPERTY_IDX prop_name_idx;
OSSL_PROPERTY_IDX prop_value_idx;
} PROPERTY_STRING_DATA;
static unsigned long property_hash(const PROPERTY_STRING *a)
{
@@ -65,6 +67,48 @@ static void property_table_free(PROP_TABLE **pt)
}
}
static void property_string_data_free(void *vpropdata)
{
PROPERTY_STRING_DATA *propdata = vpropdata;
if (propdata == NULL)
return;
property_table_free(&propdata->prop_names);
property_table_free(&propdata->prop_values);
propdata->prop_name_idx = propdata->prop_value_idx = 0;
OPENSSL_free(propdata);
}
static void *property_string_data_new(OPENSSL_CTX *ctx) {
PROPERTY_STRING_DATA *propdata = OPENSSL_zalloc(sizeof(*propdata));
if (propdata == NULL)
return NULL;
propdata->prop_names = lh_PROPERTY_STRING_new(&property_hash,
&property_cmp);
if (propdata->prop_names == NULL)
goto err;
propdata->prop_values = lh_PROPERTY_STRING_new(&property_hash,
&property_cmp);
if (propdata->prop_values == NULL)
goto err;
return propdata;
err:
property_string_data_free(propdata);
return NULL;
}
static const OPENSSL_CTX_METHOD property_string_data_method = {
property_string_data_new,
property_string_data_free,
};
static PROPERTY_STRING *new_property_string(const char *s,
OSSL_PROPERTY_IDX *pidx)
{
@@ -103,35 +147,30 @@ static OSSL_PROPERTY_IDX ossl_property_string(PROP_TABLE *t,
return ps != NULL ? ps->idx : 0;
}
OSSL_PROPERTY_IDX ossl_property_name(const char *s, int create)
OSSL_PROPERTY_IDX ossl_property_name(OPENSSL_CTX *ctx, const char *s,
int create)
{
return ossl_property_string(prop_names, create ? &prop_name_idx : NULL, s);
}
PROPERTY_STRING_DATA *propdata
= openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_STRING_INDEX,
&property_string_data_method);
OSSL_PROPERTY_IDX ossl_property_value(const char *s, int create)
{
return ossl_property_string(prop_values, create ? &prop_value_idx : NULL, s);
}
int ossl_property_string_init(void)
{
prop_names = lh_PROPERTY_STRING_new(&property_hash, &property_cmp);
if (prop_names == NULL)
if (propdata == NULL)
return 0;
prop_values = lh_PROPERTY_STRING_new(&property_hash, &property_cmp);
if (prop_values == NULL)
goto err;
return 1;
err:
ossl_property_string_cleanup();
return 0;
return ossl_property_string(propdata->prop_names,
create ? &propdata->prop_name_idx : NULL,
s);
}
void ossl_property_string_cleanup(void)
OSSL_PROPERTY_IDX ossl_property_value(OPENSSL_CTX *ctx, const char *s,
int create)
{
property_table_free(&prop_names);
property_table_free(&prop_values);
prop_name_idx = prop_value_idx = 0;
PROPERTY_STRING_DATA *propdata
= openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_STRING_INDEX,
&property_string_data_method);
if (propdata == NULL)
return 0;
return ossl_property_string(propdata->prop_values,
create ? &propdata->prop_value_idx : NULL,
s);
}
+20 -21
View File
@@ -54,6 +54,9 @@ struct ossl_provider_st {
OSSL_provider_get_param_types_fn *get_param_types;
OSSL_provider_get_params_fn *get_params;
OSSL_provider_query_operation_fn *query_operation;
/* Provider side data */
void *provctx;
};
DEFINE_STACK_OF(OSSL_PROVIDER)
@@ -76,7 +79,6 @@ struct provider_store_st {
CRYPTO_RWLOCK *lock;
unsigned int use_fallbacks:1;
};
static int provider_store_index = -1;
static void provider_store_free(void *vstore)
{
@@ -89,7 +91,7 @@ static void provider_store_free(void *vstore)
OPENSSL_free(store);
}
static void *provider_store_new(void)
static void *provider_store_new(OPENSSL_CTX *ctx)
{
struct provider_store_st *store = OPENSSL_zalloc(sizeof(*store));
const struct predefined_providers_st *p = NULL;
@@ -131,23 +133,12 @@ static const OPENSSL_CTX_METHOD provider_store_method = {
provider_store_free,
};
static CRYPTO_ONCE provider_store_init_flag = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(do_provider_store_init)
{
return OPENSSL_init_crypto(0, NULL)
&& (provider_store_index =
openssl_ctx_new_index(&provider_store_method)) != -1;
}
static struct provider_store_st *get_provider_store(OPENSSL_CTX *libctx)
{
struct provider_store_st *store = NULL;
if (!RUN_ONCE(&provider_store_init_flag, do_provider_store_init))
return NULL;
store = openssl_ctx_get_data(libctx, provider_store_index);
store = openssl_ctx_get_data(libctx, OPENSSL_CTX_PROVIDER_STORE_INDEX,
&provider_store_method);
if (store == NULL)
CRYPTOerr(CRYPTO_F_GET_PROVIDER_STORE, ERR_R_INTERNAL_ERROR);
return store;
@@ -275,7 +266,7 @@ void ossl_provider_free(OSSL_PROVIDER *prov)
*/
if (ref < 2 && prov->flag_initialized) {
if (prov->teardown != NULL)
prov->teardown();
prov->teardown(prov->provctx);
prov->flag_initialized = 0;
}
@@ -401,7 +392,8 @@ static int provider_activate(OSSL_PROVIDER *prov)
}
if (prov->init_function == NULL
|| !prov->init_function(prov, core_dispatch, &provider_dispatch)) {
|| !prov->init_function(prov, core_dispatch, &provider_dispatch,
&prov->provctx)) {
CRYPTOerr(CRYPTO_F_PROVIDER_ACTIVATE, ERR_R_INIT_FAIL);
ERR_add_error_data(2, "name=", prov->name);
DSO_free(prov->module);
@@ -448,6 +440,11 @@ int ossl_provider_activate(OSSL_PROVIDER *prov)
return 0;
}
void *ossl_provider_ctx(const OSSL_PROVIDER *prov)
{
return prov->provctx;
}
static int provider_forall_loaded(struct provider_store_st *store,
int *found_activated,
@@ -573,18 +570,20 @@ const char *ossl_provider_module_path(OSSL_PROVIDER *prov)
void ossl_provider_teardown(const OSSL_PROVIDER *prov)
{
if (prov->teardown != NULL)
prov->teardown();
prov->teardown(prov->provctx);
}
const OSSL_ITEM *ossl_provider_get_param_types(const OSSL_PROVIDER *prov)
{
return prov->get_param_types == NULL ? NULL : prov->get_param_types(prov);
return prov->get_param_types == NULL
? NULL : prov->get_param_types(prov->provctx);
}
int ossl_provider_get_params(const OSSL_PROVIDER *prov,
const OSSL_PARAM params[])
{
return prov->get_params == NULL ? 0 : prov->get_params(prov, params);
return prov->get_params == NULL
? 0 : prov->get_params(prov->provctx, params);
}
@@ -592,7 +591,7 @@ const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov,
int operation_id,
int *no_cache)
{
return prov->query_operation(prov, operation_id, no_cache);
return prov->query_operation(prov->provctx, operation_id, no_cache);
}
/*-
+1 -2
View File
@@ -1,6 +1,5 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=\
randfile.c rand_lib.c rand_err.c rand_crng_test.c rand_egd.c \
rand_win.c rand_unix.c rand_vms.c drbg_lib.c drbg_ctr.c \
rand_win.c rand_unix.c rand_vms.c drbg_lib.c drbg_ctr.c rand_vxworks.c \
drbg_hash.c drbg_hmac.c
+12 -2
View File
@@ -1101,6 +1101,17 @@ static int drbg_add(const void *buf, int num, double randomness)
buflen = (size_t)num;
#ifdef FIPS_MODE
/*
* NIST SP-800-90A mandates that entropy *shall not* be provided
* by the consuming application. By setting the randomness to zero,
* we ensure that the buffer contents will be added to the internal
* state of the DRBG only as additional data.
*
* (NIST SP-800-90Ar1, Sections 9.1 and 9.2)
*/
randomness = 0.0;
#endif
if (buflen < seedlen || randomness < (double) seedlen) {
#if defined(OPENSSL_RAND_SEED_NONE)
/*
@@ -1117,7 +1128,7 @@ static int drbg_add(const void *buf, int num, double randomness)
return ret;
#else
/*
* If an os entropy source is avaible then we declare the buffer content
* If an os entropy source is available then we declare the buffer content
* as additional data by setting randomness to zero and trigger a regular
* reseeding.
*/
@@ -1125,7 +1136,6 @@ static int drbg_add(const void *buf, int num, double randomness)
#endif
}
if (randomness > (double)seedlen) {
/*
* The purpose of this check is to bound |randomness| by a
+27 -18
View File
@@ -13,45 +13,52 @@
*/
#include <string.h>
#include <openssl/evp.h>
#include "internal/rand_int.h"
#include "internal/thread_once.h"
#include "rand_lcl.h"
static RAND_POOL *crngt_pool;
static unsigned char *crngt_prev;
static unsigned char crngt_prev[EVP_MAX_MD_SIZE];
int (*crngt_get_entropy)(unsigned char *) = &rand_crngt_get_entropy_cb;
int (*crngt_get_entropy)(unsigned char *, unsigned char *, unsigned int *)
= &rand_crngt_get_entropy_cb;
int rand_crngt_get_entropy_cb(unsigned char *buf)
int rand_crngt_get_entropy_cb(unsigned char *buf, unsigned char *md,
unsigned int *md_size)
{
int r;
size_t n;
unsigned char *p;
while ((n = rand_pool_acquire_entropy(crngt_pool)) != 0)
if (n >= CRNGT_BUFSIZ) {
p = rand_pool_detach(crngt_pool);
n = rand_pool_acquire_entropy(crngt_pool);
if (n >= CRNGT_BUFSIZ) {
p = rand_pool_detach(crngt_pool);
r = EVP_Digest(p, CRNGT_BUFSIZ, md, md_size, EVP_sha256(), NULL);
if (r != 0)
memcpy(buf, p, CRNGT_BUFSIZ);
rand_pool_reattach(crngt_pool, p);
return 1;
}
rand_pool_reattach(crngt_pool, p);
return r;
}
return 0;
}
void rand_crngt_cleanup(void)
{
rand_pool_free(crngt_pool);
OPENSSL_secure_free(crngt_prev);
crngt_pool = NULL;
crngt_prev = NULL;
}
int rand_crngt_init(void)
{
unsigned char buf[CRNGT_BUFSIZ];
if ((crngt_pool = rand_pool_new(0, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL)
return 0;
if ((crngt_prev = OPENSSL_secure_malloc(CRNGT_BUFSIZ)) != NULL
&& crngt_get_entropy(crngt_prev))
if (crngt_get_entropy(buf, crngt_prev, NULL)) {
OPENSSL_cleanse(buf, sizeof(buf));
return 1;
}
rand_crngt_cleanup();
return 0;
}
@@ -74,7 +81,8 @@ size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
int entropy, size_t min_len, size_t max_len,
int prediction_resistance)
{
unsigned char buf[CRNGT_BUFSIZ];
unsigned char buf[CRNGT_BUFSIZ], md[EVP_MAX_MD_SIZE];
unsigned int sz;
RAND_POOL *pool;
size_t q, r = 0, s, t = 0;
int attempts = 3;
@@ -87,17 +95,18 @@ size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
while ((q = rand_pool_bytes_needed(pool, 1)) > 0 && attempts-- > 0) {
s = q > sizeof(buf) ? sizeof(buf) : q;
if (!crngt_get_entropy(buf)
|| memcmp(crngt_prev, buf, CRNGT_BUFSIZ) == 0
if (!crngt_get_entropy(buf, md, &sz)
|| memcmp(crngt_prev, md, sz) == 0
|| !rand_pool_add(pool, buf, s, s * 8))
goto err;
memcpy(crngt_prev, buf, CRNGT_BUFSIZ);
memcpy(crngt_prev, md, sz);
t += s;
attempts++;
}
r = t;
*pout = rand_pool_detach(pool);
err:
OPENSSL_cleanse(buf, sizeof(buf));
rand_pool_free(pool);
return r;
}
+4 -2
View File
@@ -334,8 +334,10 @@ int drbg_hmac_init(RAND_DRBG *drbg);
* Entropy call back for the FIPS 140-2 section 4.9.2 Conditional Tests.
* These need to be exposed for the unit tests.
*/
int rand_crngt_get_entropy_cb(unsigned char *buf);
extern int (*crngt_get_entropy)(unsigned char *);
int rand_crngt_get_entropy_cb(unsigned char *buf, unsigned char *md,
unsigned int *md_size);
extern int (*crngt_get_entropy)(unsigned char *buf, unsigned char *md,
unsigned int *md_size);
int rand_crngt_init(void);
void rand_crngt_cleanup(void);
+6 -26
View File
@@ -30,7 +30,8 @@
# include <sys/param.h>
#endif
#if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__)
#if (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) \
|| defined(__DJGPP__)
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
@@ -88,30 +89,8 @@ static uint64_t get_timer_bits(void);
# undef OPENSSL_RAND_SEED_EGD
#endif
#if (defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI)) && \
!defined(OPENSSL_RAND_SEED_NONE)
# error "UEFI and VXWorks only support seeding NONE"
#endif
#if defined(OPENSSL_SYS_VXWORKS)
/* empty implementation */
int rand_pool_init(void)
{
return 1;
}
void rand_pool_cleanup(void)
{
}
void rand_pool_keep_random_devices_open(int keep)
{
}
size_t rand_pool_acquire_entropy(RAND_POOL *pool)
{
return rand_pool_entropy_available(pool);
}
#if defined(OPENSSL_SYS_UEFI) && !defined(OPENSSL_RAND_SEED_NONE)
# error "UEFI only supports seeding NONE"
#endif
#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) \
@@ -608,7 +587,8 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
# endif
#endif
#if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__)
#if (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) \
|| defined(__DJGPP__)
int rand_pool_add_nonce_data(RAND_POOL *pool)
{
struct {
+171
View File
@@ -0,0 +1,171 @@
/*
* 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 <openssl/opensslconf.h>
#ifndef OPENSSL_SYS_VXWORKS
NON_EMPTY_TRANSLATION_UNIT
#else
# include <openssl/rand.h>
# include "rand_lcl.h"
# include "internal/rand_int.h"
# include "internal/cryptlib.h"
# include <version.h>
# include <taskLib.h>
# if defined(OPENSSL_RAND_SEED_NONE)
/* none means none */
# undef OPENSSL_RAND_SEED_OS
# endif
# if defined(OPENSSL_RAND_SEED_OS)
# if _WRS_VXWORKS_MAJOR >= 7
# define RAND_SEED_VXRANDLIB
# else
# error "VxWorks <7 only support RAND_SEED_NONE"
# endif
# endif
# if defined(RAND_SEED_VXRANDLIB)
# include <randomNumGen.h>
# endif
/* Macro to convert two thirty two bit values into a sixty four bit one */
# define TWO32TO64(a, b) ((((uint64_t)(a)) << 32) + (b))
static uint64_t get_time_stamp(void)
{
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
return TWO32TO64(ts.tv_sec, ts.tv_nsec);
return time(NULL);
}
static uint64_t get_timer_bits(void)
{
uint64_t res = OPENSSL_rdtsc();
struct timespec ts;
if (res != 0)
return res;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
return TWO32TO64(ts.tv_sec, ts.tv_nsec);
return time(NULL);
}
/*
* empty implementation
* vxworks does not need to init/cleanup or keep open the random lib
*/
int rand_pool_init(void)
{
return 1;
}
void rand_pool_cleanup(void)
{
}
void rand_pool_keep_random_devices_open(int keep)
{
}
int rand_pool_add_additional_data(RAND_POOL *pool)
{
struct {
CRYPTO_THREAD_ID tid;
uint64_t time;
} data;
memset(&data, 0, sizeof(data));
/*
* Add some noise from the thread id and a high resolution timer.
* The thread id adds a little randomness if the drbg is accessed
* concurrently (which is the case for the <master> drbg).
*/
data.tid = CRYPTO_THREAD_get_current_id();
data.time = get_timer_bits();
return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
}
int rand_pool_add_nonce_data(RAND_POOL *pool)
{
struct {
pid_t pid;
CRYPTO_THREAD_ID tid;
uint64_t time;
} data;
memset(&data, 0, sizeof(data));
/*
* Add process id, thread id, and a high resolution timestamp to
* ensure that the nonce is unique with high probability for
* different process instances.
*/
data.pid = getpid();
data.tid = CRYPTO_THREAD_get_current_id();
data.time = get_time_stamp();
return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
}
size_t rand_pool_acquire_entropy(RAND_POOL *pool)
{
# if defined(RAND_SEED_VXRANDLIB)
/* vxRandLib based entropy method */
size_t bytes_needed;
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
if (bytes_needed > 0)
{
int retryCount = 0;
STATUS result = ERROR;
unsigned char *buffer;
buffer = rand_pool_add_begin(pool, bytes_needed);
while ((result != OK) && (retryCount < 10)) {
RANDOM_NUM_GEN_STATUS status = randStatus();
if ((status == RANDOM_NUM_GEN_ENOUGH_ENTROPY)
|| (status == RANDOM_NUM_GEN_MAX_ENTROPY) ) {
result = randBytes(buffer, bytes_needed);
if (result == OK)
rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
/*
* no else here: randStatus said ok, if randBytes failed
* it will result in another loop or no entropy
*/
} else {
/*
* give a minimum delay here to allow OS to collect more
* entropy. taskDelay duration will depend on the system tick,
* this is by design as the sw-random lib uses interrupts
* which will at least happen during ticks
*/
taskDelay(5);
}
retryCount++;
}
}
return rand_pool_entropy_available(pool);
# else
/*
* SEED_NONE means none, without randlib we dont have entropy and
* rely on it being added externally
*/
return rand_pool_entropy_available(pool);
# endif /* defined(RAND_SEED_VXRANDLIB) */
}
#endif /* OPENSSL_SYS_VXWORKS */
+3 -5
View File
@@ -25,11 +25,9 @@ int RSA_check_key(const RSA *key)
int RSA_check_key_ex(const RSA *key, BN_GENCB *cb)
{
#ifdef FIPS_MODE
if (!(rsa_sp800_56b_check_public(key)
&& rsa_sp800_56b_check_private(key)
&& rsa_sp800_56b_check_keypair(key, NULL, -1, RSA_bits(key))
return 0;
return rsa_sp800_56b_check_public(key)
&& rsa_sp800_56b_check_private(key)
&& rsa_sp800_56b_check_keypair(key, NULL, -1, RSA_bits(key));
#else
BIGNUM *i, *j, *k, *l, *m;
BN_CTX *ctx;
+2 -1
View File
@@ -56,7 +56,7 @@ static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
if (rctx == NULL)
return 0;
rctx->nbits = 1024;
rctx->nbits = 2048;
rctx->primes = RSA_DEFAULT_PRIME_NUM;
if (pkey_ctx_is_pss(ctx))
rctx->pad_mode = RSA_PKCS1_PSS_PADDING;
@@ -89,6 +89,7 @@ static int pkey_rsa_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
dctx->pad_mode = sctx->pad_mode;
dctx->md = sctx->md;
dctx->mgf1md = sctx->mgf1md;
dctx->saltlen = sctx->saltlen;
if (sctx->oaep_label) {
OPENSSL_free(dctx->oaep_label);
dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen);
+4 -5
View File
@@ -11,7 +11,6 @@
#include "internal/cryptlib.h"
#include "internal/numbers.h"
#include <openssl/stack.h>
#include <openssl/objects.h>
#include <errno.h>
#include <openssl/e_os2.h> /* For ossl_inline */
@@ -307,20 +306,20 @@ static int internal_find(OPENSSL_STACK *st, const void *data,
}
if (data == NULL)
return -1;
r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp,
ret_val_options);
r = ossl_bsearch(&data, st->data, st->num, sizeof(void *), st->comp,
ret_val_options);
return r == NULL ? -1 : (int)((const void **)r - st->data);
}
int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data)
{
return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH);
return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH);
}
int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data)
{
return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH);
return internal_find(st, data, OSSL_BSEARCH_VALUE_ON_NOMATCH);
}
int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data)