mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-21 05:59:29 +00:00
feat(real-world-vfc-slice): add labeled OpenSSL/Firefox/Chromium/curl pair corpus
Harvest 176 isolated vuln-vs-fix functions (109 CVEs, 352 training rows) into benchmarks/pairs/vfc with provenance and a JSONL training manifest. Score the slice as an honesty dashboard (ousast pairs --slice vfc); keep the pair gate on the local fixtures only.
This commit is contained in:
@@ -0,0 +1,362 @@
|
||||
/* Provenance: openssl/openssl evp_cipher_init_internal (fixed).
|
||||
* repo: openssl/openssl
|
||||
* commit: 0df40630850fb2740e6be6890bb905d3fc623b2d
|
||||
* parent: 23d21359e35536a4ee8f7be0b245ddbfac909bff
|
||||
* commit_url: https://github.com/openssl/openssl/commit/0df40630850fb2740e6be6890bb905d3fc623b2d
|
||||
* cve: CVE-2023-5363
|
||||
* license: Apache-2.0
|
||||
* function: evp_cipher_init_internal
|
||||
* relpath: crypto/evp/evp_enc.c
|
||||
*/
|
||||
|
||||
static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
|
||||
const EVP_CIPHER *cipher,
|
||||
ENGINE *impl, const unsigned char *key,
|
||||
const unsigned char *iv, int enc,
|
||||
const OSSL_PARAM params[])
|
||||
{
|
||||
int n;
|
||||
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
|
||||
ENGINE *tmpimpl = NULL;
|
||||
#endif
|
||||
|
||||
ctx->iv_len = -1;
|
||||
|
||||
/*
|
||||
* enc == 1 means we are encrypting.
|
||||
* enc == 0 means we are decrypting.
|
||||
* enc == -1 means, use the previously initialised value for encrypt/decrypt
|
||||
*/
|
||||
if (enc == -1) {
|
||||
enc = ctx->encrypt;
|
||||
} else {
|
||||
if (enc)
|
||||
enc = 1;
|
||||
ctx->encrypt = enc;
|
||||
}
|
||||
|
||||
if (cipher == NULL && ctx->cipher == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Code below to be removed when legacy support is dropped. */
|
||||
|
||||
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
|
||||
/*
|
||||
* Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
|
||||
* this context may already have an ENGINE! Try to avoid releasing the
|
||||
* previous handle, re-querying for an ENGINE, and having a
|
||||
* reinitialisation, when it may all be unnecessary.
|
||||
*/
|
||||
if (ctx->engine && ctx->cipher
|
||||
&& (cipher == NULL || cipher->nid == ctx->cipher->nid))
|
||||
goto skip_to_init;
|
||||
|
||||
if (cipher != NULL && impl == NULL) {
|
||||
/* Ask if an ENGINE is reserved for this job */
|
||||
tmpimpl = ENGINE_get_cipher_engine(cipher->nid);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If there are engines involved then we should use legacy handling for now.
|
||||
*/
|
||||
if (ctx->engine != NULL
|
||||
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
|
||||
|| tmpimpl != NULL
|
||||
#endif
|
||||
|| impl != NULL
|
||||
|| (cipher != NULL && cipher->origin == EVP_ORIG_METH)
|
||||
|| (cipher == NULL && ctx->cipher != NULL
|
||||
&& ctx->cipher->origin == EVP_ORIG_METH)) {
|
||||
if (ctx->cipher == ctx->fetched_cipher)
|
||||
ctx->cipher = NULL;
|
||||
EVP_CIPHER_free(ctx->fetched_cipher);
|
||||
ctx->fetched_cipher = NULL;
|
||||
goto legacy;
|
||||
}
|
||||
/*
|
||||
* Ensure a context left lying around from last time is cleared
|
||||
* (legacy code)
|
||||
*/
|
||||
if (cipher != NULL && ctx->cipher != NULL) {
|
||||
if (ctx->cipher->cleanup != NULL && !ctx->cipher->cleanup(ctx))
|
||||
return 0;
|
||||
OPENSSL_clear_free(ctx->cipher_data, ctx->cipher->ctx_size);
|
||||
ctx->cipher_data = NULL;
|
||||
}
|
||||
|
||||
/* Start of non-legacy code below */
|
||||
|
||||
/* Ensure a context left lying around from last time is cleared */
|
||||
if (cipher != NULL && ctx->cipher != NULL) {
|
||||
unsigned long flags = ctx->flags;
|
||||
|
||||
EVP_CIPHER_CTX_reset(ctx);
|
||||
/* Restore encrypt and flags */
|
||||
ctx->encrypt = enc;
|
||||
ctx->flags = flags;
|
||||
}
|
||||
|
||||
if (cipher == NULL)
|
||||
cipher = ctx->cipher;
|
||||
|
||||
if (cipher->prov == NULL) {
|
||||
#ifdef FIPS_MODULE
|
||||
/* We only do explicit fetches inside the FIPS module */
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
#else
|
||||
EVP_CIPHER *provciph =
|
||||
EVP_CIPHER_fetch(NULL,
|
||||
cipher->nid == NID_undef ? "NULL"
|
||||
: OBJ_nid2sn(cipher->nid),
|
||||
"");
|
||||
|
||||
if (provciph == NULL)
|
||||
return 0;
|
||||
cipher = provciph;
|
||||
EVP_CIPHER_free(ctx->fetched_cipher);
|
||||
ctx->fetched_cipher = provciph;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!ossl_assert(cipher->prov != NULL)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cipher != ctx->fetched_cipher) {
|
||||
if (!EVP_CIPHER_up_ref((EVP_CIPHER *)cipher)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
EVP_CIPHER_free(ctx->fetched_cipher);
|
||||
ctx->fetched_cipher = (EVP_CIPHER *)cipher;
|
||||
}
|
||||
ctx->cipher = cipher;
|
||||
if (ctx->algctx == NULL) {
|
||||
ctx->algctx = ctx->cipher->newctx(ossl_provider_ctx(cipher->prov));
|
||||
if (ctx->algctx == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ctx->flags & EVP_CIPH_NO_PADDING) != 0) {
|
||||
/*
|
||||
* If this ctx was already set up for no padding then we need to tell
|
||||
* the new cipher about it.
|
||||
*/
|
||||
if (!EVP_CIPHER_CTX_set_padding(ctx, 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODULE
|
||||
/*
|
||||
* Fix for CVE-2023-5363
|
||||
* Passing in a size as part of the init call takes effect late
|
||||
* so, force such to occur before the initialisation.
|
||||
*
|
||||
* The FIPS provider's internal library context is used in a manner
|
||||
* such that this is not an issue.
|
||||
*/
|
||||
if (params != NULL) {
|
||||
OSSL_PARAM param_lens[3] = { OSSL_PARAM_END, OSSL_PARAM_END,
|
||||
OSSL_PARAM_END };
|
||||
OSSL_PARAM *q = param_lens;
|
||||
const OSSL_PARAM *p;
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
|
||||
if (p != NULL)
|
||||
memcpy(q++, p, sizeof(*q));
|
||||
|
||||
/*
|
||||
* Note that OSSL_CIPHER_PARAM_AEAD_IVLEN is a synomym for
|
||||
* OSSL_CIPHER_PARAM_IVLEN so both are covered here.
|
||||
*/
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_IVLEN);
|
||||
if (p != NULL)
|
||||
memcpy(q++, p, sizeof(*q));
|
||||
|
||||
if (q != param_lens) {
|
||||
if (!EVP_CIPHER_CTX_set_params(ctx, param_lens)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (enc) {
|
||||
if (ctx->cipher->einit == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ctx->cipher->einit(ctx->algctx,
|
||||
key,
|
||||
key == NULL ? 0
|
||||
: EVP_CIPHER_CTX_get_key_length(ctx),
|
||||
iv,
|
||||
iv == NULL ? 0
|
||||
: EVP_CIPHER_CTX_get_iv_length(ctx),
|
||||
params);
|
||||
}
|
||||
|
||||
if (ctx->cipher->dinit == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ctx->cipher->dinit(ctx->algctx,
|
||||
key,
|
||||
key == NULL ? 0
|
||||
: EVP_CIPHER_CTX_get_key_length(ctx),
|
||||
iv,
|
||||
iv == NULL ? 0
|
||||
: EVP_CIPHER_CTX_get_iv_length(ctx),
|
||||
params);
|
||||
|
||||
/* Code below to be removed when legacy support is dropped. */
|
||||
legacy:
|
||||
|
||||
if (cipher != NULL) {
|
||||
/*
|
||||
* Ensure a context left lying around from last time is cleared (we
|
||||
* previously attempted to avoid this if the same ENGINE and
|
||||
* EVP_CIPHER could be used).
|
||||
*/
|
||||
if (ctx->cipher) {
|
||||
unsigned long flags = ctx->flags;
|
||||
EVP_CIPHER_CTX_reset(ctx);
|
||||
/* Restore encrypt and flags */
|
||||
ctx->encrypt = enc;
|
||||
ctx->flags = flags;
|
||||
}
|
||||
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
|
||||
if (impl != NULL) {
|
||||
if (!ENGINE_init(impl)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
impl = tmpimpl;
|
||||
}
|
||||
if (impl != NULL) {
|
||||
/* There's an ENGINE for this job ... (apparently) */
|
||||
const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
|
||||
|
||||
if (c == NULL) {
|
||||
/*
|
||||
* One positive side-effect of US's export control history,
|
||||
* is that we should at least be able to avoid using US
|
||||
* misspellings of "initialisation"?
|
||||
*/
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
/* We'll use the ENGINE's private cipher definition */
|
||||
cipher = c;
|
||||
/*
|
||||
* Store the ENGINE functional reference so we know 'cipher' came
|
||||
* from an ENGINE and we need to release it when done.
|
||||
*/
|
||||
ctx->engine = impl;
|
||||
} else {
|
||||
ctx->engine = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
ctx->cipher = cipher;
|
||||
if (ctx->cipher->ctx_size) {
|
||||
ctx->cipher_data = OPENSSL_zalloc(ctx->cipher->ctx_size);
|
||||
if (ctx->cipher_data == NULL) {
|
||||
ctx->cipher = NULL;
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
ctx->cipher_data = NULL;
|
||||
}
|
||||
ctx->key_len = cipher->key_len;
|
||||
/* Preserve wrap enable flag, zero everything else */
|
||||
ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW;
|
||||
if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) {
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL) <= 0) {
|
||||
ctx->cipher = NULL;
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
|
||||
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
|
||||
|| ctx->cipher->block_size == 16);
|
||||
|
||||
if (!(ctx->flags & EVP_CIPHER_CTX_FLAG_WRAP_ALLOW)
|
||||
&& EVP_CIPHER_CTX_get_mode(ctx) == EVP_CIPH_WRAP_MODE) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_WRAP_MODE_NOT_ALLOWED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx))
|
||||
& EVP_CIPH_CUSTOM_IV) == 0) {
|
||||
switch (EVP_CIPHER_CTX_get_mode(ctx)) {
|
||||
|
||||
case EVP_CIPH_STREAM_CIPHER:
|
||||
case EVP_CIPH_ECB_MODE:
|
||||
break;
|
||||
|
||||
case EVP_CIPH_CFB_MODE:
|
||||
case EVP_CIPH_OFB_MODE:
|
||||
|
||||
ctx->num = 0;
|
||||
/* fall-through */
|
||||
|
||||
case EVP_CIPH_CBC_MODE:
|
||||
n = EVP_CIPHER_CTX_get_iv_length(ctx);
|
||||
if (n < 0 || n > (int)sizeof(ctx->iv)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
if (iv != NULL)
|
||||
memcpy(ctx->oiv, iv, n);
|
||||
memcpy(ctx->iv, ctx->oiv, n);
|
||||
break;
|
||||
|
||||
case EVP_CIPH_CTR_MODE:
|
||||
ctx->num = 0;
|
||||
/* Don't reuse IV for CTR mode */
|
||||
if (iv != NULL) {
|
||||
n = EVP_CIPHER_CTX_get_iv_length(ctx);
|
||||
if (n <= 0 || n > (int)sizeof(ctx->iv)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
memcpy(ctx->iv, iv, n);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (key != NULL || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
|
||||
if (!ctx->cipher->init(ctx, key, iv, enc))
|
||||
return 0;
|
||||
}
|
||||
ctx->buf_len = 0;
|
||||
ctx->final_used = 0;
|
||||
ctx->block_mask = ctx->cipher->block_size - 1;
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user