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