1 /*
2  * Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include "internal/cryptlib.h"
11 #include <openssl/asn1t.h>
12 #include <openssl/pem.h>
13 #include <openssl/x509v3.h>
14 #include <openssl/err.h>
15 #include <openssl/cms.h>
16 #include <openssl/aes.h>
17 #include "cms_local.h"
18 #include "crypto/asn1.h"
19 
20 /* Key Agreement Recipient Info (KARI) routines */
21 
CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo * ri,X509_ALGOR ** palg,ASN1_OCTET_STRING ** pukm)22 int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
23                                     X509_ALGOR **palg,
24                                     ASN1_OCTET_STRING **pukm)
25 {
26     if (ri->type != CMS_RECIPINFO_AGREE) {
27         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
28         return 0;
29     }
30     if (palg)
31         *palg = ri->d.kari->keyEncryptionAlgorithm;
32     if (pukm)
33         *pukm = ri->d.kari->ukm;
34     return 1;
35 }
36 
37 /* Retrieve recipient encrypted keys from a kari */
38 
STACK_OF(CMS_RecipientEncryptedKey)39 STACK_OF(CMS_RecipientEncryptedKey)
40 *CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri)
41 {
42     if (ri->type != CMS_RECIPINFO_AGREE) {
43         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
44         return NULL;
45     }
46     return ri->d.kari->recipientEncryptedKeys;
47 }
48 
CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo * ri,X509_ALGOR ** pubalg,ASN1_BIT_STRING ** pubkey,ASN1_OCTET_STRING ** keyid,X509_NAME ** issuer,ASN1_INTEGER ** sno)49 int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
50                                         X509_ALGOR **pubalg,
51                                         ASN1_BIT_STRING **pubkey,
52                                         ASN1_OCTET_STRING **keyid,
53                                         X509_NAME **issuer,
54                                         ASN1_INTEGER **sno)
55 {
56     CMS_OriginatorIdentifierOrKey *oik;
57 
58     if (ri->type != CMS_RECIPINFO_AGREE) {
59         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
60         return 0;
61     }
62     oik = ri->d.kari->originator;
63     if (issuer)
64         *issuer = NULL;
65     if (sno)
66         *sno = NULL;
67     if (keyid)
68         *keyid = NULL;
69     if (pubalg)
70         *pubalg = NULL;
71     if (pubkey)
72         *pubkey = NULL;
73     if (oik->type == CMS_OIK_ISSUER_SERIAL) {
74         if (issuer)
75             *issuer = oik->d.issuerAndSerialNumber->issuer;
76         if (sno)
77             *sno = oik->d.issuerAndSerialNumber->serialNumber;
78     } else if (oik->type == CMS_OIK_KEYIDENTIFIER) {
79         if (keyid)
80             *keyid = oik->d.subjectKeyIdentifier;
81     } else if (oik->type == CMS_OIK_PUBKEY) {
82         if (pubalg)
83             *pubalg = oik->d.originatorKey->algorithm;
84         if (pubkey)
85             *pubkey = oik->d.originatorKey->publicKey;
86     } else
87         return 0;
88     return 1;
89 }
90 
CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo * ri,X509 * cert)91 int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert)
92 {
93     CMS_OriginatorIdentifierOrKey *oik;
94 
95     if (ri->type != CMS_RECIPINFO_AGREE) {
96         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
97         return -2;
98     }
99     oik = ri->d.kari->originator;
100     if (oik->type == CMS_OIK_ISSUER_SERIAL)
101         return ossl_cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert);
102     else if (oik->type == CMS_OIK_KEYIDENTIFIER)
103         return ossl_cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert);
104     return -1;
105 }
106 
CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey * rek,ASN1_OCTET_STRING ** keyid,ASN1_GENERALIZEDTIME ** tm,CMS_OtherKeyAttribute ** other,X509_NAME ** issuer,ASN1_INTEGER ** sno)107 int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
108                                       ASN1_OCTET_STRING **keyid,
109                                       ASN1_GENERALIZEDTIME **tm,
110                                       CMS_OtherKeyAttribute **other,
111                                       X509_NAME **issuer, ASN1_INTEGER **sno)
112 {
113     CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
114 
115     if (rid->type == CMS_REK_ISSUER_SERIAL) {
116         if (issuer)
117             *issuer = rid->d.issuerAndSerialNumber->issuer;
118         if (sno)
119             *sno = rid->d.issuerAndSerialNumber->serialNumber;
120         if (keyid)
121             *keyid = NULL;
122         if (tm)
123             *tm = NULL;
124         if (other)
125             *other = NULL;
126     } else if (rid->type == CMS_REK_KEYIDENTIFIER) {
127         if (keyid)
128             *keyid = rid->d.rKeyId->subjectKeyIdentifier;
129         if (tm)
130             *tm = rid->d.rKeyId->date;
131         if (other)
132             *other = rid->d.rKeyId->other;
133         if (issuer)
134             *issuer = NULL;
135         if (sno)
136             *sno = NULL;
137     } else
138         return 0;
139     return 1;
140 }
141 
CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey * rek,X509 * cert)142 int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
143                                        X509 *cert)
144 {
145     CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
146 
147     if (rid->type == CMS_REK_ISSUER_SERIAL)
148         return ossl_cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert);
149     else if (rid->type == CMS_REK_KEYIDENTIFIER)
150         return ossl_cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier,
151                                        cert);
152     else
153         return -1;
154 }
155 
CMS_RecipientInfo_kari_set0_pkey_and_peer(CMS_RecipientInfo * ri,EVP_PKEY * pk,X509 * peer)156 int CMS_RecipientInfo_kari_set0_pkey_and_peer(CMS_RecipientInfo *ri,
157                                               EVP_PKEY *pk, X509 *peer)
158 {
159     EVP_PKEY_CTX *pctx;
160     CMS_KeyAgreeRecipientInfo *kari = ri->d.kari;
161 
162     EVP_PKEY_CTX_free(kari->pctx);
163     kari->pctx = NULL;
164     if (pk == NULL)
165         return 1;
166 
167     pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(kari->cms_ctx),
168                                       pk,
169                                       ossl_cms_ctx_get0_propq(kari->cms_ctx));
170     if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0)
171         goto err;
172 
173     if (peer != NULL) {
174         EVP_PKEY *pub_pkey = X509_get0_pubkey(peer);
175 
176         if (EVP_PKEY_derive_set_peer(pctx, pub_pkey) <= 0)
177             goto err;
178     }
179 
180     kari->pctx = pctx;
181     return 1;
182  err:
183     EVP_PKEY_CTX_free(pctx);
184     return 0;
185 }
186 
CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo * ri,EVP_PKEY * pk)187 int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk)
188 {
189     return CMS_RecipientInfo_kari_set0_pkey_and_peer(ri, pk, NULL);
190 }
191 
CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo * ri)192 EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri)
193 {
194     if (ri->type == CMS_RECIPINFO_AGREE)
195         return ri->d.kari->ctx;
196     return NULL;
197 }
198 
199 /*
200  * Derive KEK and decrypt/encrypt with it to produce either the original CEK
201  * or the encrypted CEK.
202  */
203 
cms_kek_cipher(unsigned char ** pout,size_t * poutlen,const unsigned char * in,size_t inlen,CMS_KeyAgreeRecipientInfo * kari,int enc)204 static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
205                           const unsigned char *in, size_t inlen,
206                           CMS_KeyAgreeRecipientInfo *kari, int enc)
207 {
208     /* Key encryption key */
209     unsigned char kek[EVP_MAX_KEY_LENGTH];
210     size_t keklen;
211     int rv = 0;
212     unsigned char *out = NULL;
213     int outlen;
214 
215     keklen = EVP_CIPHER_CTX_get_key_length(kari->ctx);
216     if (keklen > EVP_MAX_KEY_LENGTH || inlen > INT_MAX)
217         return 0;
218     /* Derive KEK */
219     if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0)
220         goto err;
221     /* Set KEK in context */
222     if (!EVP_CipherInit_ex(kari->ctx, NULL, NULL, kek, NULL, enc))
223         goto err;
224     /* obtain output length of ciphered key */
225     if (!EVP_CipherUpdate(kari->ctx, NULL, &outlen, in, (int)inlen))
226         goto err;
227     out = OPENSSL_malloc(outlen);
228     if (out == NULL)
229         goto err;
230     if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, (int)inlen))
231         goto err;
232     *pout = out;
233     *poutlen = (size_t)outlen;
234     rv = 1;
235 
236  err:
237     OPENSSL_cleanse(kek, keklen);
238     if (!rv)
239         OPENSSL_free(out);
240     EVP_CIPHER_CTX_reset(kari->ctx);
241     /* FIXME: WHY IS kari->pctx freed here?  /RL */
242     EVP_PKEY_CTX_free(kari->pctx);
243     kari->pctx = NULL;
244     return rv;
245 }
246 
CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo * cms,CMS_RecipientInfo * ri,CMS_RecipientEncryptedKey * rek)247 int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
248                                    CMS_RecipientInfo *ri,
249                                    CMS_RecipientEncryptedKey *rek)
250 {
251     int rv = 0;
252     unsigned char *enckey = NULL, *cek = NULL;
253     size_t enckeylen;
254     size_t ceklen;
255     CMS_EncryptedContentInfo *ec;
256 
257     enckeylen = rek->encryptedKey->length;
258     enckey = rek->encryptedKey->data;
259     /* Setup all parameters to derive KEK */
260     if (!ossl_cms_env_asn1_ctrl(ri, 1))
261         goto err;
262     /* Attempt to decrypt CEK */
263     if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0))
264         goto err;
265     ec = ossl_cms_get0_env_enc_content(cms);
266     OPENSSL_clear_free(ec->key, ec->keylen);
267     ec->key = cek;
268     ec->keylen = ceklen;
269     cek = NULL;
270     rv = 1;
271  err:
272     OPENSSL_free(cek);
273     return rv;
274 }
275 
276 /* Create ephemeral key and initialise context based on it */
cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo * kari,EVP_PKEY * pk)277 static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
278                                          EVP_PKEY *pk)
279 {
280     EVP_PKEY_CTX *pctx = NULL;
281     EVP_PKEY *ekey = NULL;
282     int rv = 0;
283     const CMS_CTX *ctx = kari->cms_ctx;
284     OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(ctx);
285     const char *propq = ossl_cms_ctx_get0_propq(ctx);
286 
287     pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, propq);
288     if (pctx == NULL)
289         goto err;
290     if (EVP_PKEY_keygen_init(pctx) <= 0)
291         goto err;
292     if (EVP_PKEY_keygen(pctx, &ekey) <= 0)
293         goto err;
294     EVP_PKEY_CTX_free(pctx);
295     pctx = EVP_PKEY_CTX_new_from_pkey(libctx, ekey, propq);
296     if (pctx == NULL)
297         goto err;
298     if (EVP_PKEY_derive_init(pctx) <= 0)
299         goto err;
300     kari->pctx = pctx;
301     rv = 1;
302  err:
303     if (!rv)
304         EVP_PKEY_CTX_free(pctx);
305     EVP_PKEY_free(ekey);
306     return rv;
307 }
308 
309 /* Set originator private key and initialise context based on it */
cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo * kari,EVP_PKEY * originatorPrivKey)310 static int cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo *kari,
311                                                EVP_PKEY *originatorPrivKey )
312 {
313     EVP_PKEY_CTX *pctx = NULL;
314     int rv = 0;
315     const CMS_CTX *ctx = kari->cms_ctx;
316 
317     pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx),
318                                       originatorPrivKey,
319                                       ossl_cms_ctx_get0_propq(ctx));
320     if (pctx == NULL)
321         goto err;
322     if (EVP_PKEY_derive_init(pctx) <= 0)
323          goto err;
324 
325     kari->pctx = pctx;
326     rv = 1;
327  err:
328     if (rv == 0)
329         EVP_PKEY_CTX_free(pctx);
330     return rv;
331 }
332 
333 /* Initialise a kari based on passed certificate and key */
334 
ossl_cms_RecipientInfo_kari_init(CMS_RecipientInfo * ri,X509 * recip,EVP_PKEY * recipPubKey,X509 * originator,EVP_PKEY * originatorPrivKey,unsigned int flags,const CMS_CTX * ctx)335 int ossl_cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri,  X509 *recip,
336                                      EVP_PKEY *recipPubKey, X509 *originator,
337                                      EVP_PKEY *originatorPrivKey,
338                                      unsigned int flags, const CMS_CTX *ctx)
339 {
340     CMS_KeyAgreeRecipientInfo *kari;
341     CMS_RecipientEncryptedKey *rek = NULL;
342 
343     ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo);
344     if (ri->d.kari == NULL)
345         return 0;
346     ri->encoded_type = ri->type = CMS_RECIPINFO_AGREE;
347 
348     kari = ri->d.kari;
349     kari->version = 3;
350     kari->cms_ctx = ctx;
351 
352     rek = M_ASN1_new_of(CMS_RecipientEncryptedKey);
353     if (rek == NULL)
354         return 0;
355 
356     if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) {
357         M_ASN1_free_of(rek, CMS_RecipientEncryptedKey);
358         return 0;
359     }
360 
361     if (flags & CMS_USE_KEYID) {
362         rek->rid->type = CMS_REK_KEYIDENTIFIER;
363         rek->rid->d.rKeyId = M_ASN1_new_of(CMS_RecipientKeyIdentifier);
364         if (rek->rid->d.rKeyId == NULL)
365             return 0;
366         if (!ossl_cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip))
367             return 0;
368     } else {
369         rek->rid->type = CMS_REK_ISSUER_SERIAL;
370         if (!ossl_cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip))
371             return 0;
372     }
373 
374     if (originatorPrivKey == NULL && originator == NULL) {
375         /* Create ephemeral key */
376         if (!cms_kari_create_ephemeral_key(kari, recipPubKey))
377             return 0;
378     } else {
379         /* Use originator key */
380         CMS_OriginatorIdentifierOrKey *oik = ri->d.kari->originator;
381 
382         if (originatorPrivKey == NULL || originator == NULL)
383             return 0;
384 
385         if (flags & CMS_USE_ORIGINATOR_KEYID) {
386              oik->type = CMS_OIK_KEYIDENTIFIER;
387              oik->d.subjectKeyIdentifier = ASN1_OCTET_STRING_new();
388              if (oik->d.subjectKeyIdentifier == NULL)
389                   return 0;
390              if (!ossl_cms_set1_keyid(&oik->d.subjectKeyIdentifier, originator))
391                   return 0;
392         } else {
393              oik->type = CMS_REK_ISSUER_SERIAL;
394              if (!ossl_cms_set1_ias(&oik->d.issuerAndSerialNumber, originator))
395                   return 0;
396         }
397 
398         if (!cms_kari_set_originator_private_key(kari, originatorPrivKey))
399             return 0;
400     }
401 
402     if (!EVP_PKEY_up_ref(recipPubKey))
403         return 0;
404 
405     rek->pkey = recipPubKey;
406     return 1;
407 }
408 
409 /* Encrypt content key in key agreement recipient info */
410 
ossl_cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo * cms,CMS_RecipientInfo * ri)411 int ossl_cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
412                                         CMS_RecipientInfo *ri)
413 {
414     CMS_KeyAgreeRecipientInfo *kari;
415     CMS_EncryptedContentInfo *ec;
416     CMS_RecipientEncryptedKey *rek;
417     STACK_OF(CMS_RecipientEncryptedKey) *reks;
418     int i;
419 
420     if (ri->type != CMS_RECIPINFO_AGREE) {
421         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
422         return 0;
423     }
424     kari = ri->d.kari;
425     reks = kari->recipientEncryptedKeys;
426     ec = ossl_cms_get0_env_enc_content(cms);
427     /* Initialise wrap algorithm parameters */
428     if (!ossl_cms_RecipientInfo_wrap_init(ri, ec->cipher))
429         return 0;
430     /*
431      * If no originator key set up initialise for ephemeral key the public key
432      * ASN1 structure will set the actual public key value.
433      */
434     if (kari->originator->type == -1) {
435         CMS_OriginatorIdentifierOrKey *oik = kari->originator;
436         oik->type = CMS_OIK_PUBKEY;
437         oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey);
438         if (!oik->d.originatorKey)
439             return 0;
440     } else {
441         /*
442          * Currently it is not possible to get public key as it is not stored
443          * during kari initialization.
444          */
445         ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_UNSUPPORTED_STATIC_KEY_AGREEMENT);
446         return 0;
447     }
448     /* Initialise KDF algorithm */
449     if (!ossl_cms_env_asn1_ctrl(ri, 0))
450         return 0;
451     /* For each rek, derive KEK, encrypt CEK */
452     for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
453         unsigned char *enckey;
454         size_t enckeylen;
455         rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
456         if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0)
457             return 0;
458         if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen,
459                             kari, 1))
460             return 0;
461         ASN1_STRING_set0(rek->encryptedKey, enckey, (int)enckeylen);
462     }
463 
464     return 1;
465 }
466