1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <assert.h> 11e1051a39Sopenharmony_ci#include <openssl/cms.h> 12e1051a39Sopenharmony_ci#include <openssl/dh.h> 13e1051a39Sopenharmony_ci#include <openssl/err.h> 14e1051a39Sopenharmony_ci#include <openssl/core_names.h> 15e1051a39Sopenharmony_ci#include "internal/sizes.h" 16e1051a39Sopenharmony_ci#include "crypto/evp.h" 17e1051a39Sopenharmony_ci#include "cms_local.h" 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_cistatic int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx, 20e1051a39Sopenharmony_ci X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) 21e1051a39Sopenharmony_ci{ 22e1051a39Sopenharmony_ci const ASN1_OBJECT *aoid; 23e1051a39Sopenharmony_ci int atype; 24e1051a39Sopenharmony_ci const void *aval; 25e1051a39Sopenharmony_ci ASN1_INTEGER *public_key = NULL; 26e1051a39Sopenharmony_ci int rv = 0; 27e1051a39Sopenharmony_ci EVP_PKEY *pkpeer = NULL, *pk = NULL; 28e1051a39Sopenharmony_ci BIGNUM *bnpub = NULL; 29e1051a39Sopenharmony_ci const unsigned char *p; 30e1051a39Sopenharmony_ci unsigned char *buf = NULL; 31e1051a39Sopenharmony_ci int plen; 32e1051a39Sopenharmony_ci 33e1051a39Sopenharmony_ci X509_ALGOR_get0(&aoid, &atype, &aval, alg); 34e1051a39Sopenharmony_ci if (OBJ_obj2nid(aoid) != NID_dhpublicnumber) 35e1051a39Sopenharmony_ci goto err; 36e1051a39Sopenharmony_ci /* Only absent parameters allowed in RFC XXXX */ 37e1051a39Sopenharmony_ci if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL) 38e1051a39Sopenharmony_ci goto err; 39e1051a39Sopenharmony_ci 40e1051a39Sopenharmony_ci pk = EVP_PKEY_CTX_get0_pkey(pctx); 41e1051a39Sopenharmony_ci if (pk == NULL || !EVP_PKEY_is_a(pk, "DHX")) 42e1051a39Sopenharmony_ci goto err; 43e1051a39Sopenharmony_ci 44e1051a39Sopenharmony_ci /* Get public key */ 45e1051a39Sopenharmony_ci plen = ASN1_STRING_length(pubkey); 46e1051a39Sopenharmony_ci p = ASN1_STRING_get0_data(pubkey); 47e1051a39Sopenharmony_ci if (p == NULL || plen == 0) 48e1051a39Sopenharmony_ci goto err; 49e1051a39Sopenharmony_ci 50e1051a39Sopenharmony_ci if ((public_key = d2i_ASN1_INTEGER(NULL, &p, plen)) == NULL) 51e1051a39Sopenharmony_ci goto err; 52e1051a39Sopenharmony_ci /* 53e1051a39Sopenharmony_ci * Pad to full p parameter size as that is checked by 54e1051a39Sopenharmony_ci * EVP_PKEY_set1_encoded_public_key() 55e1051a39Sopenharmony_ci */ 56e1051a39Sopenharmony_ci plen = EVP_PKEY_get_size(pk); 57e1051a39Sopenharmony_ci if ((bnpub = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) 58e1051a39Sopenharmony_ci goto err; 59e1051a39Sopenharmony_ci if ((buf = OPENSSL_malloc(plen)) == NULL) 60e1051a39Sopenharmony_ci goto err; 61e1051a39Sopenharmony_ci if (BN_bn2binpad(bnpub, buf, plen) < 0) 62e1051a39Sopenharmony_ci goto err; 63e1051a39Sopenharmony_ci 64e1051a39Sopenharmony_ci pkpeer = EVP_PKEY_new(); 65e1051a39Sopenharmony_ci if (pkpeer == NULL 66e1051a39Sopenharmony_ci || !EVP_PKEY_copy_parameters(pkpeer, pk) 67e1051a39Sopenharmony_ci || !EVP_PKEY_set1_encoded_public_key(pkpeer, buf, plen)) 68e1051a39Sopenharmony_ci goto err; 69e1051a39Sopenharmony_ci 70e1051a39Sopenharmony_ci if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) 71e1051a39Sopenharmony_ci rv = 1; 72e1051a39Sopenharmony_ci err: 73e1051a39Sopenharmony_ci ASN1_INTEGER_free(public_key); 74e1051a39Sopenharmony_ci BN_free(bnpub); 75e1051a39Sopenharmony_ci OPENSSL_free(buf); 76e1051a39Sopenharmony_ci EVP_PKEY_free(pkpeer); 77e1051a39Sopenharmony_ci return rv; 78e1051a39Sopenharmony_ci} 79e1051a39Sopenharmony_ci 80e1051a39Sopenharmony_cistatic int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) 81e1051a39Sopenharmony_ci{ 82e1051a39Sopenharmony_ci int rv = 0; 83e1051a39Sopenharmony_ci X509_ALGOR *alg, *kekalg = NULL; 84e1051a39Sopenharmony_ci ASN1_OCTET_STRING *ukm; 85e1051a39Sopenharmony_ci const unsigned char *p; 86e1051a39Sopenharmony_ci unsigned char *dukm = NULL; 87e1051a39Sopenharmony_ci size_t dukmlen = 0; 88e1051a39Sopenharmony_ci int keylen, plen; 89e1051a39Sopenharmony_ci EVP_CIPHER *kekcipher = NULL; 90e1051a39Sopenharmony_ci EVP_CIPHER_CTX *kekctx; 91e1051a39Sopenharmony_ci char name[OSSL_MAX_NAME_SIZE]; 92e1051a39Sopenharmony_ci 93e1051a39Sopenharmony_ci if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) 94e1051a39Sopenharmony_ci goto err; 95e1051a39Sopenharmony_ci 96e1051a39Sopenharmony_ci /* 97e1051a39Sopenharmony_ci * For DH we only have one OID permissible. If ever any more get defined 98e1051a39Sopenharmony_ci * we will need something cleverer. 99e1051a39Sopenharmony_ci */ 100e1051a39Sopenharmony_ci if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) { 101e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMS, CMS_R_KDF_PARAMETER_ERROR); 102e1051a39Sopenharmony_ci goto err; 103e1051a39Sopenharmony_ci } 104e1051a39Sopenharmony_ci 105e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0 106e1051a39Sopenharmony_ci || EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0) 107e1051a39Sopenharmony_ci goto err; 108e1051a39Sopenharmony_ci 109e1051a39Sopenharmony_ci if (alg->parameter->type != V_ASN1_SEQUENCE) 110e1051a39Sopenharmony_ci goto err; 111e1051a39Sopenharmony_ci 112e1051a39Sopenharmony_ci p = alg->parameter->value.sequence->data; 113e1051a39Sopenharmony_ci plen = alg->parameter->value.sequence->length; 114e1051a39Sopenharmony_ci kekalg = d2i_X509_ALGOR(NULL, &p, plen); 115e1051a39Sopenharmony_ci if (kekalg == NULL) 116e1051a39Sopenharmony_ci goto err; 117e1051a39Sopenharmony_ci kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); 118e1051a39Sopenharmony_ci if (kekctx == NULL) 119e1051a39Sopenharmony_ci goto err; 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ci if (OBJ_obj2txt(name, sizeof(name), kekalg->algorithm, 0) <= 0) 122e1051a39Sopenharmony_ci goto err; 123e1051a39Sopenharmony_ci 124e1051a39Sopenharmony_ci kekcipher = EVP_CIPHER_fetch(pctx->libctx, name, pctx->propquery); 125e1051a39Sopenharmony_ci if (kekcipher == NULL 126e1051a39Sopenharmony_ci || EVP_CIPHER_get_mode(kekcipher) != EVP_CIPH_WRAP_MODE) 127e1051a39Sopenharmony_ci goto err; 128e1051a39Sopenharmony_ci if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) 129e1051a39Sopenharmony_ci goto err; 130e1051a39Sopenharmony_ci if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) 131e1051a39Sopenharmony_ci goto err; 132e1051a39Sopenharmony_ci 133e1051a39Sopenharmony_ci keylen = EVP_CIPHER_CTX_get_key_length(kekctx); 134e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) 135e1051a39Sopenharmony_ci goto err; 136e1051a39Sopenharmony_ci /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */ 137e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, 138e1051a39Sopenharmony_ci OBJ_nid2obj(EVP_CIPHER_get_type(kekcipher))) 139e1051a39Sopenharmony_ci <= 0) 140e1051a39Sopenharmony_ci goto err; 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_ci if (ukm != NULL) { 143e1051a39Sopenharmony_ci dukmlen = ASN1_STRING_length(ukm); 144e1051a39Sopenharmony_ci dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen); 145e1051a39Sopenharmony_ci if (dukm == NULL) 146e1051a39Sopenharmony_ci goto err; 147e1051a39Sopenharmony_ci } 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) 150e1051a39Sopenharmony_ci goto err; 151e1051a39Sopenharmony_ci dukm = NULL; 152e1051a39Sopenharmony_ci 153e1051a39Sopenharmony_ci rv = 1; 154e1051a39Sopenharmony_ci err: 155e1051a39Sopenharmony_ci X509_ALGOR_free(kekalg); 156e1051a39Sopenharmony_ci EVP_CIPHER_free(kekcipher); 157e1051a39Sopenharmony_ci OPENSSL_free(dukm); 158e1051a39Sopenharmony_ci return rv; 159e1051a39Sopenharmony_ci} 160e1051a39Sopenharmony_ci 161e1051a39Sopenharmony_cistatic int dh_cms_decrypt(CMS_RecipientInfo *ri) 162e1051a39Sopenharmony_ci{ 163e1051a39Sopenharmony_ci EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); 164e1051a39Sopenharmony_ci 165e1051a39Sopenharmony_ci if (pctx == NULL) 166e1051a39Sopenharmony_ci return 0; 167e1051a39Sopenharmony_ci /* See if we need to set peer key */ 168e1051a39Sopenharmony_ci if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { 169e1051a39Sopenharmony_ci X509_ALGOR *alg; 170e1051a39Sopenharmony_ci ASN1_BIT_STRING *pubkey; 171e1051a39Sopenharmony_ci 172e1051a39Sopenharmony_ci if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, 173e1051a39Sopenharmony_ci NULL, NULL, NULL)) 174e1051a39Sopenharmony_ci return 0; 175e1051a39Sopenharmony_ci if (alg == NULL || pubkey == NULL) 176e1051a39Sopenharmony_ci return 0; 177e1051a39Sopenharmony_ci if (!dh_cms_set_peerkey(pctx, alg, pubkey)) { 178e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMS, CMS_R_PEER_KEY_ERROR); 179e1051a39Sopenharmony_ci return 0; 180e1051a39Sopenharmony_ci } 181e1051a39Sopenharmony_ci } 182e1051a39Sopenharmony_ci /* Set DH derivation parameters and initialise unwrap context */ 183e1051a39Sopenharmony_ci if (!dh_cms_set_shared_info(pctx, ri)) { 184e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMS, CMS_R_SHARED_INFO_ERROR); 185e1051a39Sopenharmony_ci return 0; 186e1051a39Sopenharmony_ci } 187e1051a39Sopenharmony_ci return 1; 188e1051a39Sopenharmony_ci} 189e1051a39Sopenharmony_ci 190e1051a39Sopenharmony_cistatic int dh_cms_encrypt(CMS_RecipientInfo *ri) 191e1051a39Sopenharmony_ci{ 192e1051a39Sopenharmony_ci EVP_PKEY_CTX *pctx; 193e1051a39Sopenharmony_ci EVP_PKEY *pkey; 194e1051a39Sopenharmony_ci EVP_CIPHER_CTX *ctx; 195e1051a39Sopenharmony_ci int keylen; 196e1051a39Sopenharmony_ci X509_ALGOR *talg, *wrap_alg = NULL; 197e1051a39Sopenharmony_ci const ASN1_OBJECT *aoid; 198e1051a39Sopenharmony_ci ASN1_BIT_STRING *pubkey; 199e1051a39Sopenharmony_ci ASN1_STRING *wrap_str; 200e1051a39Sopenharmony_ci ASN1_OCTET_STRING *ukm; 201e1051a39Sopenharmony_ci unsigned char *penc = NULL, *dukm = NULL; 202e1051a39Sopenharmony_ci int penclen; 203e1051a39Sopenharmony_ci size_t dukmlen = 0; 204e1051a39Sopenharmony_ci int rv = 0; 205e1051a39Sopenharmony_ci int kdf_type, wrap_nid; 206e1051a39Sopenharmony_ci const EVP_MD *kdf_md; 207e1051a39Sopenharmony_ci 208e1051a39Sopenharmony_ci pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); 209e1051a39Sopenharmony_ci if (pctx == NULL) 210e1051a39Sopenharmony_ci return 0; 211e1051a39Sopenharmony_ci /* Get ephemeral key */ 212e1051a39Sopenharmony_ci pkey = EVP_PKEY_CTX_get0_pkey(pctx); 213e1051a39Sopenharmony_ci if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, 214e1051a39Sopenharmony_ci NULL, NULL, NULL)) 215e1051a39Sopenharmony_ci goto err; 216e1051a39Sopenharmony_ci 217e1051a39Sopenharmony_ci /* Is everything uninitialised? */ 218e1051a39Sopenharmony_ci X509_ALGOR_get0(&aoid, NULL, NULL, talg); 219e1051a39Sopenharmony_ci if (aoid == OBJ_nid2obj(NID_undef)) { 220e1051a39Sopenharmony_ci BIGNUM *bn_pub_key = NULL; 221e1051a39Sopenharmony_ci ASN1_INTEGER *pubk; 222e1051a39Sopenharmony_ci 223e1051a39Sopenharmony_ci if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &bn_pub_key)) 224e1051a39Sopenharmony_ci goto err; 225e1051a39Sopenharmony_ci 226e1051a39Sopenharmony_ci pubk = BN_to_ASN1_INTEGER(bn_pub_key, NULL); 227e1051a39Sopenharmony_ci BN_free(bn_pub_key); 228e1051a39Sopenharmony_ci if (pubk == NULL) 229e1051a39Sopenharmony_ci goto err; 230e1051a39Sopenharmony_ci 231e1051a39Sopenharmony_ci /* Set the key */ 232e1051a39Sopenharmony_ci penclen = i2d_ASN1_INTEGER(pubk, &penc); 233e1051a39Sopenharmony_ci ASN1_INTEGER_free(pubk); 234e1051a39Sopenharmony_ci if (penclen <= 0) 235e1051a39Sopenharmony_ci goto err; 236e1051a39Sopenharmony_ci ASN1_STRING_set0(pubkey, penc, penclen); 237e1051a39Sopenharmony_ci pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 238e1051a39Sopenharmony_ci pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; 239e1051a39Sopenharmony_ci 240e1051a39Sopenharmony_ci penc = NULL; 241e1051a39Sopenharmony_ci X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber), 242e1051a39Sopenharmony_ci V_ASN1_UNDEF, NULL); 243e1051a39Sopenharmony_ci } 244e1051a39Sopenharmony_ci 245e1051a39Sopenharmony_ci /* See if custom parameters set */ 246e1051a39Sopenharmony_ci kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx); 247e1051a39Sopenharmony_ci if (kdf_type <= 0 || EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md) <= 0) 248e1051a39Sopenharmony_ci goto err; 249e1051a39Sopenharmony_ci 250e1051a39Sopenharmony_ci if (kdf_type == EVP_PKEY_DH_KDF_NONE) { 251e1051a39Sopenharmony_ci kdf_type = EVP_PKEY_DH_KDF_X9_42; 252e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0) 253e1051a39Sopenharmony_ci goto err; 254e1051a39Sopenharmony_ci } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42) 255e1051a39Sopenharmony_ci /* Unknown KDF */ 256e1051a39Sopenharmony_ci goto err; 257e1051a39Sopenharmony_ci if (kdf_md == NULL) { 258e1051a39Sopenharmony_ci /* Only SHA1 supported */ 259e1051a39Sopenharmony_ci kdf_md = EVP_sha1(); 260e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0) 261e1051a39Sopenharmony_ci goto err; 262e1051a39Sopenharmony_ci } else if (EVP_MD_get_type(kdf_md) != NID_sha1) 263e1051a39Sopenharmony_ci /* Unsupported digest */ 264e1051a39Sopenharmony_ci goto err; 265e1051a39Sopenharmony_ci 266e1051a39Sopenharmony_ci if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) 267e1051a39Sopenharmony_ci goto err; 268e1051a39Sopenharmony_ci 269e1051a39Sopenharmony_ci /* Get wrap NID */ 270e1051a39Sopenharmony_ci ctx = CMS_RecipientInfo_kari_get0_ctx(ri); 271e1051a39Sopenharmony_ci wrap_nid = EVP_CIPHER_CTX_get_type(ctx); 272e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0) 273e1051a39Sopenharmony_ci goto err; 274e1051a39Sopenharmony_ci keylen = EVP_CIPHER_CTX_get_key_length(ctx); 275e1051a39Sopenharmony_ci 276e1051a39Sopenharmony_ci /* Package wrap algorithm in an AlgorithmIdentifier */ 277e1051a39Sopenharmony_ci 278e1051a39Sopenharmony_ci wrap_alg = X509_ALGOR_new(); 279e1051a39Sopenharmony_ci if (wrap_alg == NULL) 280e1051a39Sopenharmony_ci goto err; 281e1051a39Sopenharmony_ci wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); 282e1051a39Sopenharmony_ci wrap_alg->parameter = ASN1_TYPE_new(); 283e1051a39Sopenharmony_ci if (wrap_alg->parameter == NULL) 284e1051a39Sopenharmony_ci goto err; 285e1051a39Sopenharmony_ci if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) 286e1051a39Sopenharmony_ci goto err; 287e1051a39Sopenharmony_ci if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { 288e1051a39Sopenharmony_ci ASN1_TYPE_free(wrap_alg->parameter); 289e1051a39Sopenharmony_ci wrap_alg->parameter = NULL; 290e1051a39Sopenharmony_ci } 291e1051a39Sopenharmony_ci 292e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) 293e1051a39Sopenharmony_ci goto err; 294e1051a39Sopenharmony_ci 295e1051a39Sopenharmony_ci if (ukm != NULL) { 296e1051a39Sopenharmony_ci dukmlen = ASN1_STRING_length(ukm); 297e1051a39Sopenharmony_ci dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen); 298e1051a39Sopenharmony_ci if (dukm == NULL) 299e1051a39Sopenharmony_ci goto err; 300e1051a39Sopenharmony_ci } 301e1051a39Sopenharmony_ci 302e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) 303e1051a39Sopenharmony_ci goto err; 304e1051a39Sopenharmony_ci dukm = NULL; 305e1051a39Sopenharmony_ci 306e1051a39Sopenharmony_ci /* 307e1051a39Sopenharmony_ci * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter 308e1051a39Sopenharmony_ci * of another AlgorithmIdentifier. 309e1051a39Sopenharmony_ci */ 310e1051a39Sopenharmony_ci penc = NULL; 311e1051a39Sopenharmony_ci penclen = i2d_X509_ALGOR(wrap_alg, &penc); 312e1051a39Sopenharmony_ci if (penclen <= 0) 313e1051a39Sopenharmony_ci goto err; 314e1051a39Sopenharmony_ci wrap_str = ASN1_STRING_new(); 315e1051a39Sopenharmony_ci if (wrap_str == NULL) 316e1051a39Sopenharmony_ci goto err; 317e1051a39Sopenharmony_ci ASN1_STRING_set0(wrap_str, penc, penclen); 318e1051a39Sopenharmony_ci penc = NULL; 319e1051a39Sopenharmony_ci X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH), 320e1051a39Sopenharmony_ci V_ASN1_SEQUENCE, wrap_str); 321e1051a39Sopenharmony_ci 322e1051a39Sopenharmony_ci rv = 1; 323e1051a39Sopenharmony_ci 324e1051a39Sopenharmony_ci err: 325e1051a39Sopenharmony_ci OPENSSL_free(penc); 326e1051a39Sopenharmony_ci X509_ALGOR_free(wrap_alg); 327e1051a39Sopenharmony_ci OPENSSL_free(dukm); 328e1051a39Sopenharmony_ci return rv; 329e1051a39Sopenharmony_ci} 330e1051a39Sopenharmony_ci 331e1051a39Sopenharmony_ciint ossl_cms_dh_envelope(CMS_RecipientInfo *ri, int decrypt) 332e1051a39Sopenharmony_ci{ 333e1051a39Sopenharmony_ci assert(decrypt == 0 || decrypt == 1); 334e1051a39Sopenharmony_ci 335e1051a39Sopenharmony_ci if (decrypt == 1) 336e1051a39Sopenharmony_ci return dh_cms_decrypt(ri); 337e1051a39Sopenharmony_ci 338e1051a39Sopenharmony_ci if (decrypt == 0) 339e1051a39Sopenharmony_ci return dh_cms_encrypt(ri); 340e1051a39Sopenharmony_ci 341e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 342e1051a39Sopenharmony_ci return 0; 343e1051a39Sopenharmony_ci} 344