Handle find-doc-nits script rename
[openssl.git] / crypto / cms / cms_pwri.c
1 /*
2  * Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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_lcl.h"
19 #include "internal/asn1_int.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     tmp = OPENSSL_malloc(inlen);
192     if (tmp == NULL)
193         return 0;
194     /* setup IV by decrypting last two blocks */
195     if (!EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl,
196                            in + inlen - 2 * blocklen, blocklen * 2)
197         /*
198          * Do a decrypt of last decrypted block to set IV to correct value
199          * output it to start of buffer so we don't corrupt decrypted block
200          * this works because buffer is at least two block lengths long.
201          */
202         || !EVP_DecryptUpdate(ctx, tmp, &outl,
203                               tmp + inlen - blocklen, blocklen)
204         /* Can now decrypt first n - 1 blocks */
205         || !EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen)
206
207         /* Reset IV to original value */
208         || !EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL)
209         /* Decrypt again */
210         || !EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen))
211         goto err;
212     /* Check check bytes */
213     if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) {
214         /* Check byte failure */
215         goto err;
216     }
217     if (inlen < (size_t)(tmp[0] - 4)) {
218         /* Invalid length value */
219         goto err;
220     }
221     *outlen = (size_t)tmp[0];
222     memcpy(out, tmp + 4, *outlen);
223     rv = 1;
224  err:
225     OPENSSL_clear_free(tmp, inlen);
226     return rv;
227
228 }
229
230 static int kek_wrap_key(unsigned char *out, size_t *outlen,
231                         const unsigned char *in, size_t inlen,
232                         EVP_CIPHER_CTX *ctx)
233 {
234     size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
235     size_t olen;
236     int dummy;
237     /*
238      * First decide length of output buffer: need header and round up to
239      * multiple of block length.
240      */
241     olen = (inlen + 4 + blocklen - 1) / blocklen;
242     olen *= blocklen;
243     if (olen < 2 * blocklen) {
244         /* Key too small */
245         return 0;
246     }
247     if (inlen > 0xFF) {
248         /* Key too large */
249         return 0;
250     }
251     if (out) {
252         /* Set header */
253         out[0] = (unsigned char)inlen;
254         out[1] = in[0] ^ 0xFF;
255         out[2] = in[1] ^ 0xFF;
256         out[3] = in[2] ^ 0xFF;
257         memcpy(out + 4, in, inlen);
258         /* Add random padding to end */
259         if (olen > inlen + 4
260             && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0)
261             return 0;
262         /* Encrypt twice */
263         if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen)
264             || !EVP_EncryptUpdate(ctx, out, &dummy, out, olen))
265             return 0;
266     }
267
268     *outlen = olen;
269
270     return 1;
271 }
272
273 /* Encrypt/Decrypt content key in PWRI recipient info */
274
275 int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
276                                  int en_de)
277 {
278     CMS_EncryptedContentInfo *ec;
279     CMS_PasswordRecipientInfo *pwri;
280     int r = 0;
281     X509_ALGOR *algtmp, *kekalg = NULL;
282     EVP_CIPHER_CTX *kekctx = NULL;
283     const EVP_CIPHER *kekcipher;
284     unsigned char *key = NULL;
285     size_t keylen;
286
287     ec = cms->d.envelopedData->encryptedContentInfo;
288
289     pwri = ri->d.pwri;
290
291     if (!pwri->pass) {
292         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD);
293         return 0;
294     }
295     algtmp = pwri->keyEncryptionAlgorithm;
296
297     if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) {
298         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
299                CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
300         return 0;
301     }
302
303     kekalg = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR),
304                                        algtmp->parameter);
305
306     if (kekalg == NULL) {
307         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
308                CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER);
309         return 0;
310     }
311
312     kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
313
314     if (!kekcipher) {
315         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER);
316         return 0;
317     }
318
319     kekctx = EVP_CIPHER_CTX_new();
320     if (kekctx == NULL) {
321         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE);
322         return 0;
323     }
324     /* Fixup cipher based on AlgorithmIdentifier to set IV etc */
325     if (!EVP_CipherInit_ex(kekctx, kekcipher, NULL, NULL, NULL, en_de))
326         goto err;
327     EVP_CIPHER_CTX_set_padding(kekctx, 0);
328     if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) < 0) {
329         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
330                CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
331         goto err;
332     }
333
334     algtmp = pwri->keyDerivationAlgorithm;
335
336     /* Finish password based key derivation to setup key in "ctx" */
337
338     if (EVP_PBE_CipherInit(algtmp->algorithm,
339                            (char *)pwri->pass, pwri->passlen,
340                            algtmp->parameter, kekctx, en_de) < 0) {
341         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB);
342         goto err;
343     }
344
345     /* Finally wrap/unwrap the key */
346
347     if (en_de) {
348
349         if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx))
350             goto err;
351
352         key = OPENSSL_malloc(keylen);
353
354         if (key == NULL)
355             goto err;
356
357         if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx))
358             goto err;
359         pwri->encryptedKey->data = key;
360         pwri->encryptedKey->length = keylen;
361     } else {
362         key = OPENSSL_malloc(pwri->encryptedKey->length);
363
364         if (key == NULL) {
365             CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE);
366             goto err;
367         }
368         if (!kek_unwrap_key(key, &keylen,
369                             pwri->encryptedKey->data,
370                             pwri->encryptedKey->length, kekctx)) {
371             CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE);
372             goto err;
373         }
374
375         ec->key = key;
376         ec->keylen = keylen;
377
378     }
379
380     r = 1;
381
382  err:
383
384     EVP_CIPHER_CTX_free(kekctx);
385
386     if (!r)
387         OPENSSL_free(key);
388     X509_ALGOR_free(kekalg);
389
390     return r;
391
392 }