• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2009-2022 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/rand.h>
17 #include <openssl/aes.h>
18 #include "internal/sizes.h"
19 #include "crypto/asn1.h"
20 #include "cms_local.h"
21 
CMS_RecipientInfo_set0_password(CMS_RecipientInfo * ri,unsigned char * pass,ossl_ssize_t passlen)22 int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
23                                     unsigned char *pass, ossl_ssize_t passlen)
24 {
25     CMS_PasswordRecipientInfo *pwri;
26     if (ri->type != CMS_RECIPINFO_PASS) {
27         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_PWRI);
28         return 0;
29     }
30 
31     pwri = ri->d.pwri;
32     pwri->pass = pass;
33     if (pass && passlen < 0)
34         passlen = strlen((char *)pass);
35     pwri->passlen = passlen;
36     return 1;
37 }
38 
CMS_add0_recipient_password(CMS_ContentInfo * cms,int iter,int wrap_nid,int pbe_nid,unsigned char * pass,ossl_ssize_t passlen,const EVP_CIPHER * kekciph)39 CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
40                                                int iter, int wrap_nid,
41                                                int pbe_nid,
42                                                unsigned char *pass,
43                                                ossl_ssize_t passlen,
44                                                const EVP_CIPHER *kekciph)
45 {
46     STACK_OF(CMS_RecipientInfo) *ris;
47     CMS_RecipientInfo *ri = NULL;
48     CMS_EncryptedContentInfo *ec;
49     CMS_PasswordRecipientInfo *pwri;
50     EVP_CIPHER_CTX *ctx = NULL;
51     X509_ALGOR *encalg = NULL;
52     unsigned char iv[EVP_MAX_IV_LENGTH];
53     int ivlen;
54     const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms);
55 
56     ec = ossl_cms_get0_env_enc_content(cms);
57     if (ec == NULL)
58         return NULL;
59     ris = CMS_get0_RecipientInfos(cms);
60     if (ris == NULL)
61         return NULL;
62 
63     if (wrap_nid <= 0)
64         wrap_nid = NID_id_alg_PWRI_KEK;
65 
66     if (pbe_nid <= 0)
67         pbe_nid = NID_id_pbkdf2;
68 
69     /* Get from enveloped data */
70     if (kekciph == NULL)
71         kekciph = ec->cipher;
72 
73     if (kekciph == NULL) {
74         ERR_raise(ERR_LIB_CMS, CMS_R_NO_CIPHER);
75         return NULL;
76     }
77     if (wrap_nid != NID_id_alg_PWRI_KEK) {
78         ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
79         return NULL;
80     }
81 
82     /* Setup algorithm identifier for cipher */
83     encalg = X509_ALGOR_new();
84     if (encalg == NULL) {
85         goto merr;
86     }
87     ctx = EVP_CIPHER_CTX_new();
88     if (ctx == NULL) {
89         ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
90         goto err;
91     }
92 
93     if (EVP_EncryptInit_ex(ctx, kekciph, NULL, NULL, NULL) <= 0) {
94         ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
95         goto err;
96     }
97 
98     ivlen = EVP_CIPHER_CTX_get_iv_length(ctx);
99     if (ivlen < 0) {
100         ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
101         goto err;
102     }
103 
104     if (ivlen > 0) {
105         if (RAND_bytes_ex(ossl_cms_ctx_get0_libctx(cms_ctx), iv, ivlen, 0) <= 0)
106             goto err;
107         if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) {
108             ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
109             goto err;
110         }
111         encalg->parameter = ASN1_TYPE_new();
112         if (!encalg->parameter) {
113             ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
114             goto err;
115         }
116         if (EVP_CIPHER_param_to_asn1(ctx, encalg->parameter) <= 0) {
117             ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
118             goto err;
119         }
120     }
121 
122     encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_get_type(ctx));
123 
124     EVP_CIPHER_CTX_free(ctx);
125     ctx = NULL;
126 
127     /* Initialize recipient info */
128     ri = M_ASN1_new_of(CMS_RecipientInfo);
129     if (ri == NULL)
130         goto merr;
131 
132     ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo);
133     if (ri->d.pwri == NULL)
134         goto merr;
135     ri->type = CMS_RECIPINFO_PASS;
136 
137     pwri = ri->d.pwri;
138     pwri->cms_ctx = cms_ctx;
139     /* Since this is overwritten, free up empty structure already there */
140     X509_ALGOR_free(pwri->keyEncryptionAlgorithm);
141     pwri->keyEncryptionAlgorithm = X509_ALGOR_new();
142     if (pwri->keyEncryptionAlgorithm == NULL)
143         goto merr;
144     pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid);
145     pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new();
146     if (pwri->keyEncryptionAlgorithm->parameter == NULL)
147         goto merr;
148 
149     if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR),
150                         &pwri->keyEncryptionAlgorithm->parameter->
151                         value.sequence))
152          goto merr;
153     pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE;
154 
155     X509_ALGOR_free(encalg);
156     encalg = NULL;
157 
158     /* Setup PBE algorithm */
159 
160     pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1);
161 
162     if (pwri->keyDerivationAlgorithm == NULL)
163         goto err;
164 
165     CMS_RecipientInfo_set0_password(ri, pass, passlen);
166     pwri->version = 0;
167 
168     if (!sk_CMS_RecipientInfo_push(ris, ri))
169         goto merr;
170 
171     return ri;
172 
173  merr:
174     ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
175  err:
176     EVP_CIPHER_CTX_free(ctx);
177     if (ri)
178         M_ASN1_free_of(ri, CMS_RecipientInfo);
179     X509_ALGOR_free(encalg);
180     return NULL;
181 
182 }
183 
184 /*
185  * This is an implementation of the key wrapping mechanism in RFC3211, at
186  * some point this should go into EVP.
187  */
188 
kek_unwrap_key(unsigned char * out,size_t * outlen,const unsigned char * in,size_t inlen,EVP_CIPHER_CTX * ctx)189 static int kek_unwrap_key(unsigned char *out, size_t *outlen,
190                           const unsigned char *in, size_t inlen,
191                           EVP_CIPHER_CTX *ctx)
192 {
193     size_t blocklen = EVP_CIPHER_CTX_get_block_size(ctx);
194     unsigned char *tmp;
195     int outl, rv = 0;
196     if (inlen < 2 * blocklen) {
197         /* too small */
198         return 0;
199     }
200     if (inlen % blocklen) {
201         /* Invalid size */
202         return 0;
203     }
204     if ((tmp = OPENSSL_malloc(inlen)) == NULL) {
205         ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
206         return 0;
207     }
208     /* setup IV by decrypting last two blocks */
209     if (!EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl,
210                            in + inlen - 2 * blocklen, blocklen * 2)
211         /*
212          * Do a decrypt of last decrypted block to set IV to correct value
213          * output it to start of buffer so we don't corrupt decrypted block
214          * this works because buffer is at least two block lengths long.
215          */
216         || !EVP_DecryptUpdate(ctx, tmp, &outl,
217                               tmp + inlen - blocklen, blocklen)
218         /* Can now decrypt first n - 1 blocks */
219         || !EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen)
220 
221         /* Reset IV to original value */
222         || !EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL)
223         /* Decrypt again */
224         || !EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen))
225         goto err;
226     /* Check check bytes */
227     if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) {
228         /* Check byte failure */
229         goto err;
230     }
231     if (inlen < (size_t)(tmp[0] - 4)) {
232         /* Invalid length value */
233         goto err;
234     }
235     *outlen = (size_t)tmp[0];
236     memcpy(out, tmp + 4, *outlen);
237     rv = 1;
238  err:
239     OPENSSL_clear_free(tmp, inlen);
240     return rv;
241 
242 }
243 
kek_wrap_key(unsigned char * out,size_t * outlen,const unsigned char * in,size_t inlen,EVP_CIPHER_CTX * ctx,const CMS_CTX * cms_ctx)244 static int kek_wrap_key(unsigned char *out, size_t *outlen,
245                         const unsigned char *in, size_t inlen,
246                         EVP_CIPHER_CTX *ctx, const CMS_CTX *cms_ctx)
247 {
248     size_t blocklen = EVP_CIPHER_CTX_get_block_size(ctx);
249     size_t olen;
250     int dummy;
251     /*
252      * First decide length of output buffer: need header and round up to
253      * multiple of block length.
254      */
255     olen = (inlen + 4 + blocklen - 1) / blocklen;
256     olen *= blocklen;
257     if (olen < 2 * blocklen) {
258         /* Key too small */
259         return 0;
260     }
261     if (inlen > 0xFF) {
262         /* Key too large */
263         return 0;
264     }
265     if (out) {
266         /* Set header */
267         out[0] = (unsigned char)inlen;
268         out[1] = in[0] ^ 0xFF;
269         out[2] = in[1] ^ 0xFF;
270         out[3] = in[2] ^ 0xFF;
271         memcpy(out + 4, in, inlen);
272         /* Add random padding to end */
273         if (olen > inlen + 4
274             && RAND_bytes_ex(ossl_cms_ctx_get0_libctx(cms_ctx), out + 4 + inlen,
275                              olen - 4 - inlen, 0) <= 0)
276             return 0;
277         /* Encrypt twice */
278         if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen)
279             || !EVP_EncryptUpdate(ctx, out, &dummy, out, olen))
280             return 0;
281     }
282 
283     *outlen = olen;
284 
285     return 1;
286 }
287 
288 /* Encrypt/Decrypt content key in PWRI recipient info */
289 
ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo * cms,CMS_RecipientInfo * ri,int en_de)290 int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms,
291                                       CMS_RecipientInfo *ri, int en_de)
292 {
293     CMS_EncryptedContentInfo *ec;
294     CMS_PasswordRecipientInfo *pwri;
295     int r = 0;
296     X509_ALGOR *algtmp, *kekalg = NULL;
297     EVP_CIPHER_CTX *kekctx = NULL;
298     char name[OSSL_MAX_NAME_SIZE];
299     EVP_CIPHER *kekcipher;
300     unsigned char *key = NULL;
301     size_t keylen;
302     const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms);
303 
304     ec = ossl_cms_get0_env_enc_content(cms);
305 
306     pwri = ri->d.pwri;
307 
308     if (pwri->pass == NULL) {
309         ERR_raise(ERR_LIB_CMS, CMS_R_NO_PASSWORD);
310         return 0;
311     }
312     algtmp = pwri->keyEncryptionAlgorithm;
313 
314     if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) {
315         ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
316         return 0;
317     }
318 
319     kekalg = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR),
320                                        algtmp->parameter);
321 
322     if (kekalg == NULL) {
323         ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER);
324         return 0;
325     }
326 
327     OBJ_obj2txt(name, sizeof(name), kekalg->algorithm, 0);
328     kekcipher = EVP_CIPHER_fetch(ossl_cms_ctx_get0_libctx(cms_ctx), name,
329                                  ossl_cms_ctx_get0_propq(cms_ctx));
330 
331     if (kekcipher == NULL) {
332         ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_CIPHER);
333         goto err;
334     }
335 
336     kekctx = EVP_CIPHER_CTX_new();
337     if (kekctx == NULL) {
338         ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
339         goto err;
340     }
341     /* Fixup cipher based on AlgorithmIdentifier to set IV etc */
342     if (!EVP_CipherInit_ex(kekctx, kekcipher, NULL, NULL, NULL, en_de))
343         goto err;
344     EVP_CIPHER_CTX_set_padding(kekctx, 0);
345     if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) {
346         ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
347         goto err;
348     }
349 
350     algtmp = pwri->keyDerivationAlgorithm;
351 
352     /* Finish password based key derivation to setup key in "ctx" */
353 
354     if (EVP_PBE_CipherInit(algtmp->algorithm,
355                            (char *)pwri->pass, pwri->passlen,
356                            algtmp->parameter, kekctx, en_de) < 0) {
357         ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
358         goto err;
359     }
360 
361     /* Finally wrap/unwrap the key */
362 
363     if (en_de) {
364 
365         if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx, cms_ctx))
366             goto err;
367 
368         key = OPENSSL_malloc(keylen);
369 
370         if (key == NULL)
371             goto err;
372 
373         if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx, cms_ctx))
374             goto err;
375         pwri->encryptedKey->data = key;
376         pwri->encryptedKey->length = keylen;
377     } else {
378         key = OPENSSL_malloc(pwri->encryptedKey->length);
379 
380         if (key == NULL) {
381             ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
382             goto err;
383         }
384         if (!kek_unwrap_key(key, &keylen,
385                             pwri->encryptedKey->data,
386                             pwri->encryptedKey->length, kekctx)) {
387             ERR_raise(ERR_LIB_CMS, CMS_R_UNWRAP_FAILURE);
388             goto err;
389         }
390 
391         OPENSSL_clear_free(ec->key, ec->keylen);
392         ec->key = key;
393         ec->keylen = keylen;
394 
395     }
396 
397     r = 1;
398 
399  err:
400     EVP_CIPHER_free(kekcipher);
401     EVP_CIPHER_CTX_free(kekctx);
402 
403     if (!r)
404         OPENSSL_free(key);
405     X509_ALGOR_free(kekalg);
406 
407     return r;
408 
409 }
410