xref: /third_party/openssl/crypto/cms/cms_dh.c (revision e1051a39)
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