Latest update

This commit is contained in:
2019-07-13 19:13:22 +09:00
parent 9a23f88dc2
commit 2e57f602ae
542 changed files with 17287 additions and 6184 deletions
+2 -2
View File
@@ -38,9 +38,9 @@
of memory.
BIO_f_reliable splits data stream into blocks. Each block is prefixed
with it's length and suffixed with it's digest. So you need only
with its length and suffixed with its digest. So you need only
several Kbytes of memory to buffer single block before verifying
it's digest.
its digest.
BIO_f_reliable goes further and adds several important capabilities:
+6 -12
View File
@@ -1,6 +1,7 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=\
encode.c digest.c evp_enc.c evp_key.c evp_cnf.c \
$COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c evp_utils.c
SOURCE[../../libcrypto]=$COMMON\
encode.c evp_key.c evp_cnf.c \
e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
e_rc4.c e_aes.c names.c e_seed.c e_aria.c e_sm4.c \
e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \
@@ -8,21 +9,14 @@ SOURCE[../../libcrypto]=\
m_md5_sha1.c m_mdc2.c m_ripemd.c m_sha3.c \
p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \
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 \
c_allc.c c_alld.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 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 \
e_chacha20_poly1305.c \
mac_lib.c c_allm.c pkey_mac.c
# New design
SOURCE[../../libcrypto]=\
evp_fetch.c
# FIPS Module
SOURCE[../../providers/fips]=\
digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c
SOURCE[../../providers/fips]=$COMMON
INCLUDE[e_aes.o]=.. ../modes
INCLUDE[e_aes_cbc_hmac_sha1.o]=../modes
+3
View File
@@ -21,4 +21,7 @@ void openssl_add_all_kdfs_int(void)
EVP_add_kdf(&sshkdf_kdf_meth);
EVP_add_kdf(&ss_kdf_meth);
EVP_add_kdf(&x963_kdf_meth);
#ifndef OPENSSL_NO_CMS
EVP_add_kdf(&x942_kdf_meth);
#endif
}
+1 -1
View File
@@ -60,7 +60,7 @@ void EVP_CIPHER_meth_free(EVP_CIPHER *cipher)
}
}
int EVP_CIPHER_upref(EVP_CIPHER *cipher)
int EVP_CIPHER_up_ref(EVP_CIPHER *cipher)
{
int ref = 0;
+125 -61
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
@@ -8,10 +8,12 @@
*/
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/engine.h>
#include <openssl/params.h>
#include <openssl/core_names.h>
#include "internal/cryptlib.h"
#include "internal/evp_int.h"
#include "internal/provider.h"
#include "evp_locl.h"
@@ -127,6 +129,16 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
(type == NULL || (type->type == ctx->digest->type)))
goto skip_to_init;
if (type != NULL) {
/*
* Ensure an ENGINE left lying around from last time is cleared (the
* previous check attempted to avoid this if the same ENGINE and
* EVP_MD could be used).
*/
ENGINE_finish(ctx->engine);
ctx->engine = NULL;
}
if (type != NULL && impl == NULL)
tmpimpl = ENGINE_get_digest_engine(type->type);
#endif
@@ -149,16 +161,6 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
goto legacy;
}
if (type->prov == NULL) {
switch(type->type) {
case NID_sha256:
case NID_md2:
break;
default:
goto legacy;
}
}
if (ctx->digest != NULL && ctx->digest->ctx_size > 0) {
OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
ctx->md_data = NULL;
@@ -184,6 +186,11 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
#endif
}
if (ctx->provctx != NULL && ctx->digest != NULL && ctx->digest != type) {
if (ctx->digest->freectx != NULL)
ctx->digest->freectx(ctx->provctx);
ctx->provctx = NULL;
}
ctx->digest = type;
if (ctx->provctx == NULL) {
ctx->provctx = ctx->digest->newctx(ossl_provider_ctx(type->prov));
@@ -205,12 +212,6 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
if (type) {
/*
* Ensure an ENGINE left lying around from last time is cleared (the
* previous check attempted to avoid this if the same ENGINE and
* EVP_MD could be used).
*/
ENGINE_finish(ctx->engine);
if (impl != NULL) {
if (!ENGINE_init(impl)) {
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
@@ -334,7 +335,6 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize)
}
EVP_MD_CTX_reset(ctx);
return ret;
/* TODO(3.0): Remove legacy code below */
@@ -354,12 +354,30 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize)
int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size)
{
int ret = 0;
OSSL_PARAM params[2];
size_t i = 0;
if (ctx->digest == NULL || ctx->digest->prov == NULL)
goto legacy;
if (ctx->digest->dfinal == NULL) {
EVPerr(EVP_F_EVP_DIGESTFINALXOF, EVP_R_FINAL_ERROR);
return 0;
}
params[i++] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &size);
params[i++] = OSSL_PARAM_construct_end();
if (EVP_MD_CTX_set_params(ctx, params) > 0)
ret = ctx->digest->dfinal(ctx->provctx, md, &size, size);
EVP_MD_CTX_reset(ctx);
return ret;
legacy:
if (ctx->digest->flags & EVP_MD_FLAG_XOF
&& size <= INT_MAX
&& ctx->digest->md_ctrl(ctx, EVP_MD_CTRL_XOF_LEN, (int)size, NULL)) {
ret = ctx->digest->final(ctx, md);
if (ctx->digest->cleanup != NULL) {
ctx->digest->cleanup(ctx);
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
@@ -404,7 +422,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
out->provctx = NULL;
if (in->fetched_digest != NULL)
EVP_MD_upref(in->fetched_digest);
EVP_MD_up_ref(in->fetched_digest);
out->provctx = in->digest->dupctx(in->provctx);
if (out->provctx == NULL) {
@@ -506,13 +524,55 @@ int EVP_Digest(const void *data, size_t count,
return ret;
}
int EVP_MD_CTX_set_params(EVP_MD_CTX *ctx, const OSSL_PARAM params[])
{
if (ctx->digest != NULL && ctx->digest->set_params != NULL)
return ctx->digest->set_params(ctx->provctx, params);
return 0;
}
int EVP_MD_CTX_get_params(EVP_MD_CTX *ctx, OSSL_PARAM params[])
{
if (ctx->digest != NULL && ctx->digest->get_params != NULL)
return ctx->digest->get_params(ctx->provctx, params);
return 0;
}
/* TODO(3.0): Remove legacy code below - only used by engines & DigestSign */
int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
{
if (ctx->digest && ctx->digest->md_ctrl) {
int ret = ctx->digest->md_ctrl(ctx, cmd, p1, p2);
if (ret <= 0)
if (ctx->digest != NULL) {
if (ctx->digest->prov != NULL) {
OSSL_PARAM params[2];
size_t i, n = 0;
switch (cmd) {
case EVP_MD_CTRL_XOF_LEN:
if (ctx->digest->set_params == NULL)
break;
i = (size_t)p1;
params[n++] =
OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &i);
params[n++] = OSSL_PARAM_construct_end();
return ctx->digest->set_params(ctx->provctx, params);
case EVP_MD_CTRL_MICALG:
if (ctx->digest->get_params == NULL)
break;
params[n++] =
OSSL_PARAM_construct_utf8_string(OSSL_DIGEST_PARAM_MICALG,
p2, p1 ? p1 : 9999);
params[n++] = OSSL_PARAM_construct_end();
return ctx->digest->get_params(ctx->provctx, params);
}
return 0;
return 1;
}
/* legacy code */
if (ctx->digest->md_ctrl != NULL) {
int ret = ctx->digest->md_ctrl(ctx, cmd, p1, p2);
if (ret <= 0)
return 0;
return 1;
}
}
return 0;
}
@@ -530,55 +590,59 @@ static void *evp_md_from_dispatch(const OSSL_DISPATCH *fns,
for (; fns->function_id != 0; fns++) {
switch (fns->function_id) {
case OSSL_FUNC_DIGEST_NEWCTX:
if (md->newctx != NULL)
break;
md->newctx = OSSL_get_OP_digest_newctx(fns);
fncnt++;
if (md->newctx == NULL) {
md->newctx = OSSL_get_OP_digest_newctx(fns);
fncnt++;
}
break;
case OSSL_FUNC_DIGEST_INIT:
if (md->dinit != NULL)
break;
md->dinit = OSSL_get_OP_digest_init(fns);
fncnt++;
if (md->dinit == NULL) {
md->dinit = OSSL_get_OP_digest_init(fns);
fncnt++;
}
break;
case OSSL_FUNC_DIGEST_UPDATE:
if (md->dupdate != NULL)
break;
md->dupdate = OSSL_get_OP_digest_update(fns);
fncnt++;
if (md->dupdate == NULL) {
md->dupdate = OSSL_get_OP_digest_update(fns);
fncnt++;
}
break;
case OSSL_FUNC_DIGEST_FINAL:
if (md->dfinal != NULL)
break;
md->dfinal = OSSL_get_OP_digest_final(fns);
fncnt++;
if (md->dfinal == NULL) {
md->dfinal = OSSL_get_OP_digest_final(fns);
fncnt++;
}
break;
case OSSL_FUNC_DIGEST_DIGEST:
if (md->digest != NULL)
break;
md->digest = OSSL_get_OP_digest_digest(fns);
if (md->digest == NULL)
md->digest = OSSL_get_OP_digest_digest(fns);
/* We don't increment fnct for this as it is stand alone */
break;
case OSSL_FUNC_DIGEST_FREECTX:
if (md->freectx != NULL)
break;
md->freectx = OSSL_get_OP_digest_freectx(fns);
fncnt++;
if (md->freectx == NULL) {
md->freectx = OSSL_get_OP_digest_freectx(fns);
fncnt++;
}
break;
case OSSL_FUNC_DIGEST_DUPCTX:
if (md->dupctx != NULL)
break;
md->dupctx = OSSL_get_OP_digest_dupctx(fns);
if (md->dupctx == NULL)
md->dupctx = OSSL_get_OP_digest_dupctx(fns);
break;
case OSSL_FUNC_DIGEST_SIZE:
if (md->size != NULL)
break;
md->size = OSSL_get_OP_digest_size(fns);
if (md->size == NULL)
md->size = OSSL_get_OP_digest_size(fns);
break;
case OSSL_FUNC_DIGEST_BLOCK_SIZE:
if (md->dblock_size != NULL)
break;
md->dblock_size = OSSL_get_OP_digest_block_size(fns);
if (md->dblock_size == NULL)
md->dblock_size = OSSL_get_OP_digest_block_size(fns);
break;
case OSSL_FUNC_DIGEST_SET_PARAMS:
if (md->set_params == NULL)
md->set_params = OSSL_get_OP_digest_set_params(fns);
break;
case OSSL_FUNC_DIGEST_GET_PARAMS:
if (md->get_params == NULL)
md->get_params = OSSL_get_OP_digest_get_params(fns);
break;
}
}
@@ -596,14 +660,14 @@ static void *evp_md_from_dispatch(const OSSL_DISPATCH *fns,
}
md->prov = prov;
if (prov != NULL)
ossl_provider_upref(prov);
ossl_provider_up_ref(prov);
return md;
}
static int evp_md_upref(void *md)
static int evp_md_up_ref(void *md)
{
return EVP_MD_upref(md);
return EVP_MD_up_ref(md);
}
static void evp_md_free(void *md)
@@ -616,7 +680,7 @@ EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm,
{
EVP_MD *md =
evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties,
evp_md_from_dispatch, evp_md_upref,
evp_md_from_dispatch, evp_md_up_ref,
evp_md_free);
#ifndef FIPS_MODE
+24 -9
View File
@@ -7,18 +7,19 @@
* https://www.openssl.org/source/license.html
*/
#include <string.h>
#include <assert.h>
#include <openssl/opensslconf.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>
#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>
#include "internal/evp_int.h"
#include "internal/cryptlib.h"
#include "internal/modes_int.h"
#include "modes_lcl.h"
#include "evp_locl.h"
typedef struct {
@@ -63,6 +64,12 @@ typedef struct {
const unsigned char iv[16]);
} EVP_AES_XTS_CTX;
#ifdef FIPS_MODE
static const int allow_insecure_decrypt = 0;
#else
static const int allow_insecure_decrypt = 1;
#endif
typedef struct {
union {
OSSL_UNION_ALIGN;
@@ -387,6 +394,7 @@ static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx);
if (!iv && !key)
return 1;
@@ -401,7 +409,8 @@ static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
* This addresses Rogaway's vulnerability.
* See comment in aes_xts_init_key() below.
*/
if (memcmp(key, key + bytes, bytes) == 0) {
if ((!allow_insecure_decrypt || enc)
&& CRYPTO_memcmp(key, key + bytes, bytes) == 0) {
EVPerr(EVP_F_AESNI_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS);
return 0;
}
@@ -804,6 +813,7 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx);
if (!iv && !key)
return 1;
@@ -818,7 +828,8 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
* This addresses Rogaway's vulnerability.
* See comment in aes_xts_init_key() below.
*/
if (memcmp(key, key + bytes, bytes) == 0) {
if ((!allow_insecure_decrypt || enc)
&& CRYPTO_memcmp(key, key + bytes, bytes) == 0) {
EVPerr(EVP_F_AES_T4_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS);
return 0;
}
@@ -3408,10 +3419,12 @@ BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM,
static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
{
EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,c);
EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX, c);
if (type == EVP_CTRL_COPY) {
EVP_CIPHER_CTX *out = ptr;
EVP_AES_XTS_CTX *xctx_out = EVP_C_DATA(EVP_AES_XTS_CTX,out);
if (xctx->xts.key1) {
if (xctx->xts.key1 != &xctx->ks1)
return 0;
@@ -3435,6 +3448,7 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx);
if (!iv && !key)
return 1;
@@ -3460,7 +3474,8 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
* BEFORE using the keys in the XTS-AES algorithm to process
* data with them."
*/
if (memcmp(key, key + bytes, bytes) == 0) {
if ((!allow_insecure_decrypt || enc)
&& CRYPTO_memcmp(key, key + bytes, bytes) == 0) {
EVPerr(EVP_F_AES_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS);
return 0;
}
+6 -3
View File
@@ -66,9 +66,12 @@ static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
RC5_32_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
key, data(ctx)->rounds);
return 1;
if (EVP_CIPHER_CTX_key_length(ctx) > 255) {
EVPerr(EVP_F_R_32_12_16_INIT_KEY, EVP_R_BAD_KEY_LENGTH);
return 0;
}
return RC5_32_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
key, data(ctx)->rounds);
}
#endif
+44 -43
View File
@@ -920,6 +920,14 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
{
int ok = evp_do_param(c->cipher, &keylen, sizeof(keylen),
OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER,
evp_do_ciph_ctx_setparams, c->provctx);
if (ok != -2)
return ok;
/* TODO(3.0) legacy code follows */
if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
if (EVP_CIPHER_CTX_key_length(c) == keylen)
@@ -934,40 +942,51 @@ int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
{
int ok;
if (pad)
ctx->flags &= ~EVP_CIPH_NO_PADDING;
else
ctx->flags |= EVP_CIPH_NO_PADDING;
if (ctx->cipher != NULL && ctx->cipher->prov != NULL) {
OSSL_PARAM params[] = {
OSSL_PARAM_int(OSSL_CIPHER_PARAM_PADDING, NULL),
OSSL_PARAM_END
};
params[0].data = &pad;
if (ctx->cipher->ctx_set_params == NULL) {
EVPerr(EVP_F_EVP_CIPHER_CTX_SET_PADDING, EVP_R_CTRL_NOT_IMPLEMENTED);
return 0;
}
if (!ctx->cipher->ctx_set_params(ctx->provctx, params))
return 0;
}
return 1;
ok = evp_do_param(ctx->cipher, &pad, sizeof(pad),
OSSL_CIPHER_PARAM_PADDING, OSSL_PARAM_INTEGER,
evp_do_ciph_ctx_setparams, ctx->provctx);
return ok != 0;
}
int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
{
int ret;
int ret = -2; /* Unsupported */
if (!ctx->cipher) {
EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
return 0;
}
if (ctx->cipher->prov == NULL)
goto legacy;
switch (type) {
case EVP_CTRL_SET_KEY_LENGTH:
ret = evp_do_param(ctx->cipher, &arg, sizeof(arg),
OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER,
evp_do_ciph_ctx_setparams, ctx->provctx);
break;
case EVP_CTRL_GET_IV:
ret = evp_do_param(ctx->cipher, ptr, arg,
OSSL_CIPHER_PARAM_IV, OSSL_PARAM_OCTET_STRING,
evp_do_ciph_ctx_getparams, ctx->provctx);
break;
case EVP_CTRL_RAND_KEY: /* Used by DES */
case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS: /* Used by DASYNC */
case EVP_CTRL_INIT: /* TODO(3.0) Purely legacy, no provider counterpart */
ret = -2; /* Unsupported */
break;
}
return ret;
legacy:
if (!ctx->cipher->ctrl) {
EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
return 0;
@@ -1016,7 +1035,7 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
*out = *in;
out->provctx = NULL;
if (in->fetched_cipher != NULL && !EVP_CIPHER_upref(in->fetched_cipher)) {
if (in->fetched_cipher != NULL && !EVP_CIPHER_up_ref(in->fetched_cipher)) {
out->fetched_cipher = NULL;
return 0;
}
@@ -1123,21 +1142,6 @@ static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns,
break;
cipher->dupctx = OSSL_get_OP_cipher_dupctx(fns);
break;
case OSSL_FUNC_CIPHER_KEY_LENGTH:
if (cipher->key_length != NULL)
break;
cipher->key_length = OSSL_get_OP_cipher_key_length(fns);
break;
case OSSL_FUNC_CIPHER_IV_LENGTH:
if (cipher->iv_length != NULL)
break;
cipher->iv_length = OSSL_get_OP_cipher_iv_length(fns);
break;
case OSSL_FUNC_CIPHER_BLOCK_SIZE:
if (cipher->blocksize != NULL)
break;
cipher->blocksize = OSSL_get_OP_cipher_block_size(fns);
break;
case OSSL_FUNC_CIPHER_GET_PARAMS:
if (cipher->get_params != NULL)
break;
@@ -1157,10 +1161,7 @@ static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns,
}
if ((fnciphcnt != 0 && fnciphcnt != 3 && fnciphcnt != 4)
|| (fnciphcnt == 0 && cipher->ccipher == NULL)
|| fnctxcnt != 2
|| cipher->blocksize == NULL
|| cipher->iv_length == NULL
|| cipher->key_length == NULL) {
|| fnctxcnt != 2) {
/*
* In order to be a consistent set of functions we must have at least
* a complete set of "encrypt" functions, or a complete set of "decrypt"
@@ -1174,14 +1175,14 @@ static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns,
}
cipher->prov = prov;
if (prov != NULL)
ossl_provider_upref(prov);
ossl_provider_up_ref(prov);
return cipher;
}
static int evp_cipher_upref(void *cipher)
static int evp_cipher_up_ref(void *cipher)
{
return EVP_CIPHER_upref(cipher);
return EVP_CIPHER_up_ref(cipher);
}
static void evp_cipher_free(void *cipher)
@@ -1194,7 +1195,7 @@ EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
{
EVP_CIPHER *cipher =
evp_generic_fetch(ctx, OSSL_OP_CIPHER, algorithm, properties,
evp_cipher_from_dispatch, evp_cipher_upref,
evp_cipher_from_dispatch, evp_cipher_up_ref,
evp_cipher_free);
#ifndef FIPS_MODE
+6 -2
View File
@@ -78,7 +78,7 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
{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"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTX_COPY, 0), "EVP_MAC_CTX_copy"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTX_DUP, 0), "EVP_MAC_CTX_dup"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTX_NEW, 0), "EVP_MAC_CTX_new"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_INIT, 0), "EVP_MAC_init"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_BLOCK_SIZE, 0), "EVP_MD_block_size"},
@@ -179,11 +179,14 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, 0),
"PKCS5_v2_scrypt_keyivgen"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_KDF_CTRL, 0), "pkey_kdf_ctrl"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_MAC_COPY, 0), "pkey_mac_copy"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_MAC_INIT, 0), "pkey_mac_init"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_SET_TYPE, 0), "pkey_set_type"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_POLY1305_CTRL, 0), "poly1305_ctrl"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_RC2_MAGIC_TO_METH, 0), "rc2_magic_to_meth"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_RC5_CTRL, 0), "rc5_ctrl"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_R_32_12_16_INIT_KEY, 0),
"r_32_12_16_init_key"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_CTRL, 0), "s390x_aes_gcm_ctrl"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_TLS_CIPHER, 0),
"s390x_aes_gcm_tls_cipher"},
@@ -198,6 +201,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ARIA_KEY_SETUP_FAILED),
"aria key setup failed"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_DECRYPT), "bad decrypt"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_KEY_LENGTH), "bad key length"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BUFFER_TOO_SMALL), "buffer too small"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CAMELLIA_KEY_SETUP_FAILED),
"camellia key setup failed"},
@@ -280,7 +284,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),
"operation not supported for this keytype"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATON_NOT_INITIALIZED),
"operaton not initialized"},
"operation not initialized"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARAMETER_TOO_LARGE),
"parameter too large"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARTIALLY_OVERLAPPING),
+72 -21
View File
@@ -39,7 +39,6 @@ static const OPENSSL_CTX_METHOD default_method_store_method = {
struct method_data_st {
OPENSSL_CTX *libctx;
const char *name;
int id;
OSSL_METHOD_CONSTRUCT_METHOD *mcm;
void *(*method_from_dispatch)(const OSSL_DISPATCH *, OSSL_PROVIDER *);
int (*refcnt_up_method)(void *method);
@@ -66,24 +65,45 @@ static OSSL_METHOD_STORE *get_default_method_store(OPENSSL_CTX *libctx)
&default_method_store_method);
}
/*
* To identity the method in the method store, we mix the name identity
* with the operation identity, with the assumption that we don't have
* more than 2^24 names or more than 2^8 operation types.
*
* The resulting identity is a 32-bit integer, composed like this:
*
* +---------24 bits--------+-8 bits-+
* | name identity | op id |
* +------------------------+--------+
*/
static uint32_t method_id(unsigned int operation_id, unsigned int name_id)
{
if (!ossl_assert(name_id < (1 << 24) || operation_id < (1 << 8))
|| !ossl_assert(name_id > 0 && operation_id > 0))
return 0;
return ((name_id << 8) & 0xFFFFFF00) | (operation_id & 0x000000FF);
}
static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
const char *name, const char *propquery,
void *data)
int operation_id, const char *name,
const char *propquery, void *data)
{
struct method_data_st *methdata = data;
void *method = NULL;
OSSL_NAMEMAP *namemap;
int id;
int nameid;
uint32_t methid;
if (store == NULL
&& (store = get_default_method_store(libctx)) == NULL)
return NULL;
if ((namemap = ossl_namemap_stored(libctx)) == NULL
|| (id = ossl_namemap_add(namemap, name)) == 0)
|| (nameid = ossl_namemap_name2num(namemap, name)) == 0
|| (methid = method_id(operation_id, nameid)) == 0)
return NULL;
(void)ossl_method_store_fetch(store, id, propquery, &method);
(void)ossl_method_store_fetch(store, methid, propquery, &method);
if (method != NULL
&& !methdata->refcnt_up_method(method)) {
@@ -93,15 +113,18 @@ static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
}
static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
void *method, const char *name,
const char *propdef, void *data)
void *method, int operation_id,
const char *name, const char *propdef,
void *data)
{
struct method_data_st *methdata = data;
OSSL_NAMEMAP *namemap;
int id;
int nameid;
uint32_t methid;
if ((namemap = ossl_namemap_stored(methdata->libctx)) == NULL
|| (id = ossl_namemap_add(namemap, name)) == 0)
|| (nameid = ossl_namemap_add(namemap, 0, name)) == 0
|| (methid = method_id(operation_id, nameid)) == 0)
return 0;
if (store == NULL
@@ -109,7 +132,7 @@ static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
return 0;
if (methdata->refcnt_up_method(method)
&& ossl_method_store_add(store, id, propdef, method,
&& ossl_method_store_add(store, methid, propdef, method,
methdata->destruct_method))
return 1;
return 0;
@@ -134,19 +157,37 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
const char *name, const char *properties,
void *(*new_method)(const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov),
int (*upref_method)(void *),
int (*up_ref_method)(void *),
void (*free_method)(void *))
{
OSSL_METHOD_STORE *store = get_default_method_store(libctx);
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
int id;
int nameid = 0;
uint32_t methid = 0;
void *method = NULL;
if (store == NULL || namemap == NULL)
return NULL;
if ((id = ossl_namemap_number(namemap, name)) == 0
|| !ossl_method_store_cache_get(store, id, properties, &method)) {
/*
* If there's ever an operation_id == 0 passed, we have an internal
* programming error.
*/
if (!ossl_assert(operation_id > 0))
return NULL;
/*
* method_id returns 0 if we have too many operations (more than
* about 2^8) or too many names (more than about 2^24). In that
* case, we can't create any new method.
*/
if ((nameid = ossl_namemap_name2num(namemap, name)) != 0
&& (methid = method_id(operation_id, nameid)) == 0)
return NULL;
if (nameid == 0
|| !ossl_method_store_cache_get(store, methid, properties,
&method)) {
OSSL_METHOD_CONSTRUCT_METHOD mcm = {
alloc_tmp_method_store,
dealloc_tmp_method_store,
@@ -159,16 +200,26 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
mcmdata.mcm = &mcm;
mcmdata.libctx = libctx;
mcmdata.name = name;
mcmdata.method_from_dispatch = new_method;
mcmdata.destruct_method = free_method;
mcmdata.refcnt_up_method = upref_method;
mcmdata.refcnt_up_method = up_ref_method;
mcmdata.destruct_method = free_method;
method = ossl_method_construct(libctx, operation_id, name,
properties, 0 /* !force_cache */,
&mcm, &mcmdata);
ossl_method_store_cache_set(store, id, properties, method);
if ((method = ossl_method_construct(libctx, operation_id, name,
properties, 0 /* !force_cache */,
&mcm, &mcmdata)) != NULL) {
/*
* If construction did create a method for us, we know that
* there is a correct nameid and methodid, since those have
* already been calculated in get_method_from_store() and
* put_method_in_store() above.
*/
nameid = ossl_namemap_name2num(namemap, name);
methid = method_id(operation_id, nameid);
ossl_method_store_cache_set(store, methid, properties, method);
}
} else {
upref_method(method);
up_ref_method(method);
}
return method;
+61 -53
View File
@@ -217,13 +217,12 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx)
int EVP_CIPHER_block_size(const EVP_CIPHER *cipher)
{
if (cipher->prov != NULL) {
if (cipher->blocksize != NULL)
return cipher->blocksize();
/* We default to a block size of 1 */
return 1;
}
return cipher->block_size;
int v = cipher->block_size;
int ok = evp_do_param(cipher, &v, sizeof(v),
OSSL_CIPHER_PARAM_BLOCK_SIZE, OSSL_PARAM_INTEGER,
evp_do_ciph_getparams, NULL);
return ok != 0 ? v : -1;
}
int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
@@ -266,7 +265,12 @@ int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx)
unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
{
return cipher->flags;
unsigned long v = cipher->flags;
int ok = evp_do_param(cipher, &v, sizeof(v),
OSSL_CIPHER_PARAM_FLAGS, OSSL_PARAM_UNSIGNED_INTEGER,
evp_do_ciph_getparams, NULL);
return ok != 0 ? v : 0;
}
void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
@@ -296,13 +300,12 @@ void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data)
int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
{
if (cipher->prov != NULL) {
if (cipher->iv_length != NULL)
return (int)cipher->iv_length();
return 0;
}
int v = cipher->iv_len;
int ok = evp_do_param(cipher, &v, sizeof(v),
OSSL_CIPHER_PARAM_IVLEN, OSSL_PARAM_UNSIGNED_INTEGER,
evp_do_ciph_getparams, NULL);
return cipher->iv_len;
return ok != 0 ? v: -1;
}
int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
@@ -315,14 +318,27 @@ const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx)
return ctx->oiv;
}
/*
* OSSL_PARAM_OCTET_PTR gets us the pointer to the running IV in the provider
*/
const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx)
{
return ctx->iv;
const unsigned char *v = ctx->iv;
int ok = evp_do_param(ctx->cipher, &v, sizeof(ctx->iv),
OSSL_CIPHER_PARAM_IV, OSSL_PARAM_OCTET_PTR,
evp_do_ciph_ctx_getparams, ctx->provctx);
return ok != 0 ? v: NULL;
}
unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx)
{
return ctx->iv;
unsigned char *v = ctx->iv;
int ok = evp_do_param(ctx->cipher, &v, sizeof(ctx->iv),
OSSL_CIPHER_PARAM_IV, OSSL_PARAM_OCTET_PTR,
evp_do_ciph_ctx_getparams, ctx->provctx);
return ok != 0 ? v: NULL;
}
unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx)
@@ -332,34 +348,42 @@ unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx)
int EVP_CIPHER_CTX_num(const EVP_CIPHER_CTX *ctx)
{
return ctx->num;
int v = ctx->num;
int ok = evp_do_param(ctx->cipher, &v, sizeof(v),
OSSL_CIPHER_PARAM_NUM, OSSL_PARAM_INTEGER,
evp_do_ciph_ctx_getparams, ctx->provctx);
return ok != 0 ? v: -1;
}
void EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num)
int EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num)
{
int ok = evp_do_param(ctx->cipher, &num, sizeof(num),
OSSL_CIPHER_PARAM_NUM, OSSL_PARAM_INTEGER,
evp_do_ciph_ctx_setparams, ctx->provctx);
ctx->num = num;
return ok != 0;
}
int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
{
if (cipher->prov != NULL) {
if (cipher->key_length != NULL)
return (int)cipher->key_length();
return -1;
}
int v = cipher->key_len;
int ok = evp_do_param(cipher, &v, sizeof(v),
OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER,
evp_do_ciph_getparams, NULL);
return cipher->key_len;
return ok != 0 ? v: -1;
}
int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
{
/*
* TODO(3.0): This may need to change if/when we introduce variable length
* key ciphers into the providers.
*/
if (ctx->cipher != NULL && ctx->cipher->prov != NULL)
return EVP_CIPHER_key_length(ctx->cipher);
return ctx->key_len;
int v = ctx->key_len;
int ok = evp_do_param(ctx->cipher, &v, sizeof(v),
OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER,
evp_do_ciph_ctx_getparams, ctx->provctx);
return ok != 0 ? v: -1;
}
int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
@@ -374,28 +398,12 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
int EVP_CIPHER_mode(const EVP_CIPHER *cipher)
{
if (cipher->prov != NULL) {
int mode;
int v = EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE;
int ok = evp_do_param(cipher, &v, sizeof(v),
OSSL_CIPHER_PARAM_MODE, OSSL_PARAM_INTEGER,
evp_do_ciph_getparams, NULL);
/* Cipher comes from a provider - so ask the provider for the mode */
OSSL_PARAM params[] = {
OSSL_PARAM_int(OSSL_CIPHER_PARAM_MODE, NULL),
OSSL_PARAM_END
};
params[0].data = &mode;
if (cipher->get_params == NULL) {
EVPerr(EVP_F_EVP_CIPHER_MODE, EVP_R_CTRL_NOT_IMPLEMENTED);
return 0;
}
if (!cipher->get_params(params))
return 0;
return mode;
}
return EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE;
return ok != 0 ? v: 0;
}
@@ -469,7 +477,7 @@ EVP_MD *EVP_MD_meth_dup(const EVP_MD *md)
return to;
}
int EVP_MD_upref(EVP_MD *md)
int EVP_MD_up_ref(EVP_MD *md)
{
int ref = 0;
+38 -1
View File
@@ -93,5 +93,42 @@ void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id,
const char *algorithm, const char *properties,
void *(*new_method)(const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov),
int (*upref_method)(void *),
int (*up_ref_method)(void *),
void (*free_method)(void *));
/* Helper functions to avoid duplicating code */
/*
* The callbacks implement different ways to pass a params array to the
* provider. They will return one of these values:
*
* -2 if the method doesn't come from a provider
* (evp_do_param will return this to the called)
* -1 if the provider doesn't offer the desired function
* (evp_do_param will raise an error and return 0)
* or the return value from the desired function
* (evp_do_param will return it to the caller)
*/
int evp_do_ciph_getparams(const void *vciph, void *ignored,
OSSL_PARAM params[]);
int evp_do_ciph_ctx_getparams(const void *vciph, void *provctx,
OSSL_PARAM params[]);
int evp_do_ciph_ctx_setparams(const void *vciph, void *provctx,
OSSL_PARAM params[]);
/*-
* prepares a singular parameter, then calls the callback to execute.
*
* |method| points to the method used by the callback.
* EVP_CIPHER, EVP_MD, ...
* |ptr| points at the data to transfer.
* |sz| is the size of the data to transfer.
* |key| is the name of the parameter to pass.
* |datatype| is the data type of the parameter to pass.
* |cb| is the callback that actually performs the parameter passing
* |cb_ctx| is the cipher context
*/
int evp_do_param(const void *method, void *ptr, size_t sz, const char *key,
int datatype,
int (*cb)(const void *method, void *ctx, OSSL_PARAM params[]),
void *cb_ctx);
+78
View File
@@ -0,0 +1,78 @@
/*
* 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
*/
/* Internal EVP utility functions */
#include <openssl/core.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/asn1.h> /* evp_locl.h needs it */
#include <openssl/safestack.h> /* evp_locl.h needs it */
#include "internal/evp_int.h" /* evp_locl.h needs it */
#include "evp_locl.h"
int evp_do_ciph_getparams(const void *vciph, void *ignored,
OSSL_PARAM params[])
{
const EVP_CIPHER *ciph = vciph;
if (ciph->prov == NULL)
return -2;
if (ciph->get_params == NULL)
return -1;
return ciph->get_params(params);
}
int evp_do_ciph_ctx_getparams(const void *vciph, void *provctx,
OSSL_PARAM params[])
{
const EVP_CIPHER *ciph = vciph;
if (ciph->prov == NULL)
return -2;
if (ciph->ctx_get_params == NULL)
return -1;
return ciph->ctx_get_params(provctx, params);
}
int evp_do_ciph_ctx_setparams(const void *vciph, void *provctx,
OSSL_PARAM params[])
{
const EVP_CIPHER *ciph = vciph;
if (ciph->prov == NULL)
return -2;
if (ciph->ctx_set_params == NULL)
return -1;
return ciph->ctx_set_params(provctx, params);
}
int evp_do_param(const void *method, void *ptr, size_t sz, const char *key,
int datatype,
int (*cb)(const void *method, void *ctx, OSSL_PARAM params[]),
void *cb_ctx)
{
OSSL_PARAM params[2] = {
OSSL_PARAM_END,
OSSL_PARAM_END
};
int ret;
params[0].key = key;
params[0].data_type = datatype;
params[0].data = ptr;
params[0].data_size = sz;
ret = cb(method, cb_ctx, params);
if (ret == -1) {
EVPerr(0, EVP_R_CTRL_NOT_IMPLEMENTED);
ret = 0;
}
return ret;
}
+14 -98
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2016 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
@@ -7,131 +7,46 @@
* https://www.openssl.org/source/license.html
*/
#if !defined(OPENSSL_NO_MD5)
#ifndef OPENSSL_NO_MD5
# include <string.h>
# include <openssl/evp.h>
# include <openssl/objects.h>
# include <openssl/x509.h>
# include <openssl/md5.h>
# include <openssl/sha.h>
# include "internal/cryptlib.h"
# include <openssl/obj_mac.h>
# include "internal/evp_int.h"
# include <openssl/rsa.h>
struct md5_sha1_ctx {
MD5_CTX md5;
SHA_CTX sha1;
};
# include "internal/md5_sha1.h"
static int init(EVP_MD_CTX *ctx)
{
struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
if (!MD5_Init(&mctx->md5))
return 0;
return SHA1_Init(&mctx->sha1);
return md5_sha1_init(EVP_MD_CTX_md_data(ctx));
}
static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
if (!MD5_Update(&mctx->md5, data, count))
return 0;
return SHA1_Update(&mctx->sha1, data, count);
return md5_sha1_update(EVP_MD_CTX_md_data(ctx), data, count);
}
static int final(EVP_MD_CTX *ctx, unsigned char *md)
{
struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
if (!MD5_Final(md, &mctx->md5))
return 0;
return SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1);
return md5_sha1_final(md, EVP_MD_CTX_md_data(ctx));
}
static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms)
{
unsigned char padtmp[48];
unsigned char md5tmp[MD5_DIGEST_LENGTH];
unsigned char sha1tmp[SHA_DIGEST_LENGTH];
struct md5_sha1_ctx *mctx;
if (cmd != EVP_CTRL_SSL3_MASTER_SECRET)
return -2;
if (ctx == NULL)
return 0;
mctx = EVP_MD_CTX_md_data(ctx);
/* SSLv3 client auth handling: see RFC-6101 5.6.8 */
if (mslen != 48)
return 0;
/* At this point hash contains all handshake messages, update
* with master secret and pad_1.
*/
if (update(ctx, ms, mslen) <= 0)
return 0;
/* Set padtmp to pad_1 value */
memset(padtmp, 0x36, sizeof(padtmp));
if (!MD5_Update(&mctx->md5, padtmp, sizeof(padtmp)))
return 0;
if (!MD5_Final(md5tmp, &mctx->md5))
return 0;
if (!SHA1_Update(&mctx->sha1, padtmp, 40))
return 0;
if (!SHA1_Final(sha1tmp, &mctx->sha1))
return 0;
/* Reinitialise context */
if (!init(ctx))
return 0;
if (update(ctx, ms, mslen) <= 0)
return 0;
/* Set padtmp to pad_2 value */
memset(padtmp, 0x5c, sizeof(padtmp));
if (!MD5_Update(&mctx->md5, padtmp, sizeof(padtmp)))
return 0;
if (!MD5_Update(&mctx->md5, md5tmp, sizeof(md5tmp)))
return 0;
if (!SHA1_Update(&mctx->sha1, padtmp, 40))
return 0;
if (!SHA1_Update(&mctx->sha1, sha1tmp, sizeof(sha1tmp)))
return 0;
/* Now when ctx is finalised it will return the SSL v3 hash value */
OPENSSL_cleanse(md5tmp, sizeof(md5tmp));
OPENSSL_cleanse(sha1tmp, sizeof(sha1tmp));
return 1;
return md5_sha1_ctrl(EVP_MD_CTX_md_data(ctx), cmd, mslen, ms);
}
static const EVP_MD md5_sha1_md = {
NID_md5_sha1,
NID_md5_sha1,
MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
MD5_SHA1_DIGEST_LENGTH,
0,
init,
update,
final,
NULL,
NULL,
MD5_CBLOCK,
sizeof(EVP_MD *) + sizeof(struct md5_sha1_ctx),
MD5_SHA1_CBLOCK,
sizeof(EVP_MD *) + sizeof(MD5_SHA1_CTX),
ctrl
};
@@ -139,4 +54,5 @@ const EVP_MD *EVP_md5_sha1(void)
{
return &md5_sha1_md;
}
#endif
#endif /* OPENSSL_NO_MD5 */
+2 -56
View File
@@ -32,63 +32,9 @@ static int final(EVP_MD_CTX *ctx, unsigned char *md)
return SHA1_Final(md, EVP_MD_CTX_md_data(ctx));
}
static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms)
static int ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
{
unsigned char padtmp[40];
unsigned char sha1tmp[SHA_DIGEST_LENGTH];
SHA_CTX *sha1;
if (cmd != EVP_CTRL_SSL3_MASTER_SECRET)
return -2;
if (ctx == NULL)
return 0;
sha1 = EVP_MD_CTX_md_data(ctx);
/* SSLv3 client auth handling: see RFC-6101 5.6.8 */
if (mslen != 48)
return 0;
/* At this point hash contains all handshake messages, update
* with master secret and pad_1.
*/
if (SHA1_Update(sha1, ms, mslen) <= 0)
return 0;
/* Set padtmp to pad_1 value */
memset(padtmp, 0x36, sizeof(padtmp));
if (!SHA1_Update(sha1, padtmp, sizeof(padtmp)))
return 0;
if (!SHA1_Final(sha1tmp, sha1))
return 0;
/* Reinitialise context */
if (!SHA1_Init(sha1))
return 0;
if (SHA1_Update(sha1, ms, mslen) <= 0)
return 0;
/* Set padtmp to pad_2 value */
memset(padtmp, 0x5c, sizeof(padtmp));
if (!SHA1_Update(sha1, padtmp, sizeof(padtmp)))
return 0;
if (!SHA1_Update(sha1, sha1tmp, sizeof(sha1tmp)))
return 0;
/* Now when ctx is finalised it will return the SSL v3 hash value */
OPENSSL_cleanse(sha1tmp, sizeof(sha1tmp));
return 1;
return sha1_ctrl(ctx != NULL ? EVP_MD_CTX_md_data(ctx) : NULL, cmd, p1, p2);
}
static const EVP_MD sha1_md = {
+33 -120
View File
@@ -13,120 +13,33 @@
#include <openssl/evp.h>
#include <openssl/objects.h>
#include "internal/evp_int.h"
#include "internal/sha3.h"
#include "evp_locl.h"
size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t len,
size_t r);
void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r);
#define KECCAK1600_WIDTH 1600
typedef struct {
uint64_t A[5][5];
size_t block_size; /* cached ctx->digest->block_size */
size_t md_size; /* output length, variable in XOF */
size_t num; /* used bytes in below buffer */
unsigned char buf[KECCAK1600_WIDTH / 8 - 32];
unsigned char pad;
} KECCAK1600_CTX;
static int init(EVP_MD_CTX *evp_ctx, unsigned char pad)
static int init(EVP_MD_CTX *ctx)
{
KECCAK1600_CTX *ctx = evp_ctx->md_data;
size_t bsz = evp_ctx->digest->block_size;
if (bsz <= sizeof(ctx->buf)) {
memset(ctx->A, 0, sizeof(ctx->A));
ctx->num = 0;
ctx->block_size = bsz;
ctx->md_size = evp_ctx->digest->md_size;
ctx->pad = pad;
return 1;
}
return 0;
return sha3_init(EVP_MD_CTX_md_data(ctx), '\x06', ctx->digest->md_size * 8);
}
static int sha3_init(EVP_MD_CTX *evp_ctx)
static int update(EVP_MD_CTX *ctx, const void *_inp, size_t len)
{
return init(evp_ctx, '\x06');
return sha3_update(EVP_MD_CTX_md_data(ctx), _inp, len);
}
static int shake_init(EVP_MD_CTX *evp_ctx)
static int final(EVP_MD_CTX *ctx, unsigned char *md)
{
return init(evp_ctx, '\x1f');
return sha3_final(md, EVP_MD_CTX_md_data(ctx));
}
static int kmac_init(EVP_MD_CTX *evp_ctx)
static int shake_init(EVP_MD_CTX *ctx)
{
return init(evp_ctx, '\x04');
return sha3_init(EVP_MD_CTX_md_data(ctx), '\x1f', ctx->digest->md_size * 8);
}
static int sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len)
static int kmac_init(EVP_MD_CTX *ctx)
{
KECCAK1600_CTX *ctx = evp_ctx->md_data;
const unsigned char *inp = _inp;
size_t bsz = ctx->block_size;
size_t num, rem;
if (len == 0)
return 1;
if ((num = ctx->num) != 0) { /* process intermediate buffer? */
rem = bsz - num;
if (len < rem) {
memcpy(ctx->buf + num, inp, len);
ctx->num += len;
return 1;
}
/*
* We have enough data to fill or overflow the intermediate
* buffer. So we append |rem| bytes and process the block,
* leaving the rest for later processing...
*/
memcpy(ctx->buf + num, inp, rem);
inp += rem, len -= rem;
(void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
ctx->num = 0;
/* ctx->buf is processed, ctx->num is guaranteed to be zero */
}
if (len >= bsz)
rem = SHA3_absorb(ctx->A, inp, len, bsz);
else
rem = len;
if (rem) {
memcpy(ctx->buf, inp + len - rem, rem);
ctx->num = rem;
}
return 1;
}
static int sha3_final(EVP_MD_CTX *evp_ctx, unsigned char *md)
{
KECCAK1600_CTX *ctx = evp_ctx->md_data;
size_t bsz = ctx->block_size;
size_t num = ctx->num;
/*
* Pad the data with 10*1. Note that |num| can be |bsz - 1|
* in which case both byte operations below are performed on
* same byte...
*/
memset(ctx->buf + num, 0, bsz - num);
ctx->buf[num] = ctx->pad;
ctx->buf[bsz - 1] |= 0x80;
(void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
SHA3_squeeze(ctx->A, md, ctx->md_size, bsz);
return 1;
return keccak_kmac_init(EVP_MD_CTX_md_data(ctx), '\x04',
ctx->digest->md_size * 8 / 2);
}
static int shake_ctrl(EVP_MD_CTX *evp_ctx, int cmd, int p1, void *p2)
@@ -205,7 +118,7 @@ static int s390x_sha3_init(EVP_MD_CTX *evp_ctx)
}
memset(ctx->A, 0, sizeof(ctx->A));
ctx->num = 0;
ctx->bufsz = 0;
ctx->block_size = bsz;
ctx->md_size = evp_ctx->digest->md_size;
return 1;
@@ -232,7 +145,7 @@ static int s390x_shake_init(EVP_MD_CTX *evp_ctx)
}
memset(ctx->A, 0, sizeof(ctx->A));
ctx->num = 0;
ctx->bufsz = 0;
ctx->block_size = bsz;
ctx->md_size = evp_ctx->digest->md_size;
return 1;
@@ -248,19 +161,19 @@ static int s390x_sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len)
if (len == 0)
return 1;
if ((num = ctx->num) != 0) {
if ((num = ctx->bufsz) != 0) {
rem = bsz - num;
if (len < rem) {
memcpy(ctx->buf + num, inp, len);
ctx->num += len;
ctx->bufsz += len;
return 1;
}
memcpy(ctx->buf + num, inp, rem);
inp += rem;
len -= rem;
s390x_kimd(ctx->buf, bsz, ctx->pad, ctx->A);
ctx->num = 0;
ctx->bufsz = 0;
}
rem = len % bsz;
@@ -268,7 +181,7 @@ static int s390x_sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len)
if (rem) {
memcpy(ctx->buf, inp + len - rem, rem);
ctx->num = rem;
ctx->bufsz = rem;
}
return 1;
}
@@ -277,7 +190,7 @@ static int s390x_sha3_final(EVP_MD_CTX *evp_ctx, unsigned char *md)
{
KECCAK1600_CTX *ctx = evp_ctx->md_data;
s390x_klmd(ctx->buf, ctx->num, NULL, 0, ctx->pad, ctx->A);
s390x_klmd(ctx->buf, ctx->bufsz, NULL, 0, ctx->pad, ctx->A);
memcpy(md, ctx->A, ctx->md_size);
return 1;
}
@@ -286,7 +199,7 @@ static int s390x_shake_final(EVP_MD_CTX *evp_ctx, unsigned char *md)
{
KECCAK1600_CTX *ctx = evp_ctx->md_data;
s390x_klmd(ctx->buf, ctx->num, md, ctx->md_size, ctx->pad, ctx->A);
s390x_klmd(ctx->buf, ctx->bufsz, md, ctx->md_size, ctx->pad, ctx->A);
return 1;
}
@@ -311,9 +224,9 @@ const EVP_MD *EVP_sha3_##bitlen(void) \
NID_RSA_SHA3_##bitlen, \
bitlen / 8, \
EVP_MD_FLAG_DIGALGID_ABSENT, \
sha3_init, \
sha3_update, \
sha3_final, \
init, \
update, \
final, \
NULL, \
NULL, \
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
@@ -347,8 +260,8 @@ const EVP_MD *EVP_shake##bitlen(void) \
bitlen / 8, \
EVP_MD_FLAG_XOF, \
shake_init, \
sha3_update, \
sha3_final, \
update, \
final, \
NULL, \
NULL, \
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
@@ -370,9 +283,9 @@ const EVP_MD *EVP_sha3_##bitlen(void) \
NID_RSA_SHA3_##bitlen, \
bitlen / 8, \
EVP_MD_FLAG_DIGALGID_ABSENT, \
sha3_init, \
sha3_update, \
sha3_final, \
init, \
update, \
final, \
NULL, \
NULL, \
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
@@ -390,8 +303,8 @@ const EVP_MD *EVP_shake##bitlen(void) \
bitlen / 8, \
EVP_MD_FLAG_XOF, \
shake_init, \
sha3_update, \
sha3_final, \
update, \
final, \
NULL, \
NULL, \
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
@@ -416,13 +329,13 @@ EVP_MD_SHAKE(256)
const EVP_MD *evp_keccak_kmac##bitlen(void) \
{ \
static const EVP_MD kmac_##bitlen##_md = { \
-1, \
NID_kmac##bitlen, \
0, \
2 * bitlen / 8, \
EVP_MD_FLAG_XOF, \
kmac_init, \
sha3_update, \
sha3_final, \
update, \
final, \
NULL, \
NULL, \
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
+17 -7
View File
@@ -48,18 +48,28 @@ void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx)
OPENSSL_free(ctx);
}
int EVP_MAC_CTX_copy(EVP_MAC_CTX *dst, const EVP_MAC_CTX *src)
EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src)
{
EVP_MAC_IMPL *macdata;
EVP_MAC_CTX *dst;
if (src->data != NULL && !dst->meth->copy(dst->data, src->data))
return 0;
if (src->data == NULL)
return NULL;
dst = OPENSSL_malloc(sizeof(*dst));
if (dst == NULL) {
EVPerr(EVP_F_EVP_MAC_CTX_DUP, ERR_R_MALLOC_FAILURE);
return NULL;
}
macdata = dst->data;
*dst = *src;
dst->data = macdata;
return 1;
dst->data = src->meth->dup(src->data);
if (dst->data == NULL) {
EVP_MAC_CTX_free(dst);
return NULL;
}
return dst;
}
const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx)
+2 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1999-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
@@ -40,6 +40,7 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
if (kctx == NULL)
return 0;
if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, pass, (size_t)passlen) != 1
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE, 1) != 1
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT,
salt, (size_t)saltlen) != 1
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, iter) != 1
+29 -17
View File
@@ -10,6 +10,7 @@
#include <openssl/err.h>
#include <openssl/evp.h>
#include "internal/evp_int.h"
#include "evp_locl.h"
/* MAC PKEY context structure */
@@ -75,15 +76,25 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
{
MAC_PKEY_CTX *sctx, *dctx;
if (!pkey_mac_init(dst))
sctx = EVP_PKEY_CTX_get_data(src);
if (sctx->ctx->data == NULL)
return 0;
sctx = EVP_PKEY_CTX_get_data(src);
dctx = EVP_PKEY_CTX_get_data(dst);
dctx = OPENSSL_zalloc(sizeof(*dctx));
if (dctx == NULL) {
EVPerr(EVP_F_PKEY_MAC_COPY, ERR_R_MALLOC_FAILURE);
return 0;
}
if (!EVP_MAC_CTX_copy(dctx->ctx, sctx->ctx))
EVP_PKEY_CTX_set_data(dst, dctx);
dst->keygen_info_count = 0;
dctx->ctx = EVP_MAC_CTX_dup(sctx->ctx);
if (dctx->ctx == NULL)
goto err;
dctx->type = sctx->type;
switch (dctx->type) {
case MAC_TYPE_RAW:
dctx->raw_data.md = sctx->raw_data.md;
@@ -100,7 +111,7 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
}
return 1;
err:
pkey_mac_cleanup (dst);
pkey_mac_cleanup(dst);
return 0;
}
@@ -141,14 +152,10 @@ static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
break;
case MAC_TYPE_MAC:
{
EVP_MAC_CTX *cmkey = EVP_MAC_CTX_new_id(nid);
EVP_MAC_CTX *cmkey = EVP_MAC_CTX_dup(hctx->ctx);
if (cmkey == NULL)
return 0;
if (!EVP_MAC_CTX_copy(cmkey, hctx->ctx)) {
EVP_MAC_CTX_free(cmkey);
return 0;
}
EVP_PKEY_assign(pkey, nid, cmkey);
}
break;
@@ -249,13 +256,18 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
case MAC_TYPE_RAW:
hctx->raw_data.md = p2;
break;
case MAC_TYPE_MAC:
if (ctx->pkey != NULL
&& !EVP_MAC_CTX_copy(hctx->ctx,
(EVP_MAC_CTX *)ctx->pkey->pkey.ptr))
return 0;
if (!EVP_MAC_init(hctx->ctx))
return 0;
case MAC_TYPE_MAC: {
EVP_MAC_CTX *new_mac_ctx;
if (ctx->pkey == NULL)
return 0;
new_mac_ctx = EVP_MAC_CTX_dup((EVP_MAC_CTX *)ctx->pkey
->pkey.ptr);
if (new_mac_ctx == NULL)
return 0;
EVP_MAC_CTX_free(hctx->ctx);
hctx->ctx = new_mac_ctx;
}
break;
default:
/* This should be dead code */