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