/*
* Copyright 1995-2021 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
*/
/*
* EVP _meth_ APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/params.h>
#include <openssl/core_names.h>
#include <openssl/dh.h>
#include <openssl/ec.h>
#include "crypto/evp.h"
#include "crypto/asn1.h"
#include "internal/provider.h"
#include "evp_local.h"
#if !defined(FIPS_MODULE)
int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
{
return evp_cipher_param_to_asn1_ex(c, type, NULL);
}
int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
{
return evp_cipher_asn1_to_param_ex(c, type, NULL);
}
int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *ctx, ASN1_TYPE *type)
{
int i = 0;
unsigned int l;
if (type != NULL) {
unsigned char iv[EVP_MAX_IV_LENGTH];
l = EVP_CIPHER_CTX_iv_length(ctx);
if (!ossl_assert(l <= sizeof(iv)))
return -1;
i = ASN1_TYPE_get_octetstring(type, iv, l);
if (i != (int)l)
return -1;
if (!EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1))
return -1;
}
return i;
}
int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
{
int i = 0;
unsigned int j;
unsigned char *oiv = NULL;
if (type != NULL) {
oiv = (unsigned char *)EVP_CIPHER_CTX_original_iv(c);
j = EVP_CIPHER_CTX_iv_length(c);
OPENSSL_assert(j <= sizeof(c->iv));
i = ASN1_TYPE_set_octetstring(type, oiv, j);
}
return i;
}
int evp_cipher_param_to_asn1_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,
evp_cipher_aead_asn1_params *asn1_params)
{
int ret = -1; /* Assume the worst */
const EVP_CIPHER *cipher = c->cipher;
/*
* For legacy implementations, we detect custom AlgorithmIdentifier
* parameter handling by checking if the function pointer
* cipher->set_asn1_parameters is set. We know that this pointer
* is NULL for provided implementations.
*
* Otherwise, for any implementation, we check the flag
* EVP_CIPH_FLAG_CUSTOM_ASN1. If it isn't set, we apply
* default AI parameter extraction.
*
* Otherwise, for provided implementations, we convert |type| to
* a DER encoded blob and pass to the implementation in OSSL_PARAM
* form.
*
* If none of the above applies, this operation is unsupported.
*/
if (cipher->set_asn1_parameters != NULL) {
ret = cipher->set_asn1_parameters(c, type);
} else if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_CUSTOM_ASN1) == 0) {
switch (EVP_CIPHER_mode(cipher)) {
case EVP_CIPH_WRAP_MODE:
if (EVP_CIPHER_is_a(cipher, SN_id_smime_alg_CMS3DESwrap))
ASN1_TYPE_set(type, V_ASN1_NULL, NULL);
ret = 1;
break;
case EVP_CIPH_GCM_MODE:
ret = evp_cipher_set_asn1_aead_params(c, type, asn1_params);
break;
case EVP_CIPH_CCM_MODE:
case EVP_CIPH_XTS_MODE:
case EVP_CIPH_OCB_MODE:
ret = -2;
break;
default:
ret = EVP_CIPHER_set_asn1_iv(c, type);
}
} else if (cipher->prov != NULL) {
OSSL_PARAM params[3], *p = params;
unsigned char *der = NULL, *derp;
/*
* We make two passes, the first to get the appropriate buffer size,
* and the second to get the actual value.
*/
*p++ = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_ALG_ID,
NULL, 0);
*p = OSSL_PARAM_construct_end();
if (!EVP_CIPHER_CTX_get_params(c,