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
+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 */