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