xref: /third_party/openssl/crypto/cms/cms_pwri.c (revision e1051a39)
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
22int 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
39CMS_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
189static 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
244static 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
290int 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