summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/cms/cms_pwri.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/cms/cms_pwri.c')
-rw-r--r--src/lib/libcrypto/cms/cms_pwri.c90
1 files changed, 42 insertions, 48 deletions
diff --git a/src/lib/libcrypto/cms/cms_pwri.c b/src/lib/libcrypto/cms/cms_pwri.c
index d7f5697ff0..af237be98f 100644
--- a/src/lib/libcrypto/cms/cms_pwri.c
+++ b/src/lib/libcrypto/cms/cms_pwri.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cms_pwri.c,v 1.16 2019/08/10 16:42:20 jsing Exp $ */ 1/* $OpenBSD: cms_pwri.c,v 1.17 2019/08/10 18:15:52 jsing Exp $ */
2/* 2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4 * project. 4 * project.
@@ -63,10 +63,12 @@
63#include "cms_lcl.h" 63#include "cms_lcl.h"
64#include "asn1/asn1_locl.h" 64#include "asn1/asn1_locl.h"
65 65
66int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, 66int
67 unsigned char *pass, ossl_ssize_t passlen) 67CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, unsigned char *pass,
68 ossl_ssize_t passlen)
68{ 69{
69 CMS_PasswordRecipientInfo *pwri; 70 CMS_PasswordRecipientInfo *pwri;
71
70 if (ri->type != CMS_RECIPINFO_PASS) { 72 if (ri->type != CMS_RECIPINFO_PASS) {
71 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI); 73 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI);
72 return 0; 74 return 0;
@@ -77,15 +79,14 @@ int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
77 if (pass && passlen < 0) 79 if (pass && passlen < 0)
78 passlen = strlen((char *)pass); 80 passlen = strlen((char *)pass);
79 pwri->passlen = passlen; 81 pwri->passlen = passlen;
82
80 return 1; 83 return 1;
81} 84}
82 85
83CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, 86CMS_RecipientInfo *
84 int iter, int wrap_nid, 87CMS_add0_recipient_password(CMS_ContentInfo *cms, int iter, int wrap_nid,
85 int pbe_nid, 88 int pbe_nid, unsigned char *pass, ossl_ssize_t passlen,
86 unsigned char *pass, 89 const EVP_CIPHER *kekciph)
87 ossl_ssize_t passlen,
88 const EVP_CIPHER *kekciph)
89{ 90{
90 CMS_RecipientInfo *ri = NULL; 91 CMS_RecipientInfo *ri = NULL;
91 CMS_EnvelopedData *env; 92 CMS_EnvelopedData *env;
@@ -115,7 +116,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
115 } 116 }
116 if (wrap_nid != NID_id_alg_PWRI_KEK) { 117 if (wrap_nid != NID_id_alg_PWRI_KEK) {
117 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, 118 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
118 CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); 119 CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
119 return NULL; 120 return NULL;
120 } 121 }
121 122
@@ -147,7 +148,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
147 } 148 }
148 if (EVP_CIPHER_param_to_asn1(ctx, encalg->parameter) <= 0) { 149 if (EVP_CIPHER_param_to_asn1(ctx, encalg->parameter) <= 0) {
149 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, 150 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
150 CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); 151 CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
151 goto err; 152 goto err;
152 } 153 }
153 } 154 }
@@ -179,8 +180,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
179 goto merr; 180 goto merr;
180 181
181 if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR), 182 if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR),
182 &pwri->keyEncryptionAlgorithm->parameter-> 183 &pwri->keyEncryptionAlgorithm->parameter->value.sequence))
183 value.sequence))
184 goto merr; 184 goto merr;
185 pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE; 185 pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE;
186 186
@@ -209,8 +209,8 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
209 if (ri) 209 if (ri)
210 M_ASN1_free_of(ri, CMS_RecipientInfo); 210 M_ASN1_free_of(ri, CMS_RecipientInfo);
211 X509_ALGOR_free(encalg); 211 X509_ALGOR_free(encalg);
212 return NULL;
213 212
213 return NULL;
214} 214}
215 215
216/* 216/*
@@ -218,13 +218,14 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
218 * some point this should go into EVP. 218 * some point this should go into EVP.
219 */ 219 */
220 220
221static int kek_unwrap_key(unsigned char *out, size_t *outlen, 221static int
222 const unsigned char *in, size_t inlen, 222kek_unwrap_key(unsigned char *out, size_t *outlen, const unsigned char *in,
223 EVP_CIPHER_CTX *ctx) 223 size_t inlen, EVP_CIPHER_CTX *ctx)
224{ 224{
225 size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); 225 size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
226 unsigned char *tmp; 226 unsigned char *tmp;
227 int outl, rv = 0; 227 int outl, rv = 0;
228
228 if (inlen < 2 * blocklen) { 229 if (inlen < 2 * blocklen) {
229 /* too small */ 230 /* too small */
230 return 0; 231 return 0;
@@ -237,16 +238,16 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen,
237 CMSerr(CMS_F_KEK_UNWRAP_KEY, ERR_R_MALLOC_FAILURE); 238 CMSerr(CMS_F_KEK_UNWRAP_KEY, ERR_R_MALLOC_FAILURE);
238 return 0; 239 return 0;
239 } 240 }
241
240 /* setup IV by decrypting last two blocks */ 242 /* setup IV by decrypting last two blocks */
241 if (!EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl, 243 if (!EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl,
242 in + inlen - 2 * blocklen, blocklen * 2) 244 in + inlen - 2 * blocklen, blocklen * 2)
243 /* 245 /*
244 * Do a decrypt of last decrypted block to set IV to correct value 246 * Do a decrypt of last decrypted block to set IV to correct value
245 * output it to start of buffer so we don't corrupt decrypted block 247 * output it to start of buffer so we don't corrupt decrypted block
246 * this works because buffer is at least two block lengths long. 248 * this works because buffer is at least two block lengths long.
247 */ 249 */
248 || !EVP_DecryptUpdate(ctx, tmp, &outl, 250 || !EVP_DecryptUpdate(ctx, tmp, &outl, tmp + inlen - blocklen, blocklen)
249 tmp + inlen - blocklen, blocklen)
250 /* Can now decrypt first n - 1 blocks */ 251 /* Can now decrypt first n - 1 blocks */
251 || !EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen) 252 || !EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen)
252 253
@@ -267,19 +268,21 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen,
267 *outlen = (size_t)tmp[0]; 268 *outlen = (size_t)tmp[0];
268 memcpy(out, tmp + 4, *outlen); 269 memcpy(out, tmp + 4, *outlen);
269 rv = 1; 270 rv = 1;
271
270 err: 272 err:
271 OPENSSL_clear_free(tmp, inlen); 273 OPENSSL_clear_free(tmp, inlen);
272 return rv;
273 274
275 return rv;
274} 276}
275 277
276static int kek_wrap_key(unsigned char *out, size_t *outlen, 278static int
277 const unsigned char *in, size_t inlen, 279kek_wrap_key(unsigned char *out, size_t *outlen, const unsigned char *in,
278 EVP_CIPHER_CTX *ctx) 280 size_t inlen, EVP_CIPHER_CTX *ctx)
279{ 281{
280 size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); 282 size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
281 size_t olen; 283 size_t olen;
282 int dummy; 284 int dummy;
285
283 /* 286 /*
284 * First decide length of output buffer: need header and round up to 287 * First decide length of output buffer: need header and round up to
285 * multiple of block length. 288 * multiple of block length.
@@ -302,12 +305,12 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen,
302 out[3] = in[2] ^ 0xFF; 305 out[3] = in[2] ^ 0xFF;
303 memcpy(out + 4, in, inlen); 306 memcpy(out + 4, in, inlen);
304 /* Add random padding to end */ 307 /* Add random padding to end */
305 if (olen > inlen + 4 308 if (olen > inlen + 4 &&
306 && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0) 309 RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0)
307 return 0; 310 return 0;
308 /* Encrypt twice */ 311 /* Encrypt twice */
309 if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen) 312 if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen) ||
310 || !EVP_EncryptUpdate(ctx, out, &dummy, out, olen)) 313 !EVP_EncryptUpdate(ctx, out, &dummy, out, olen))
311 return 0; 314 return 0;
312 } 315 }
313 316
@@ -318,8 +321,9 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen,
318 321
319/* Encrypt/Decrypt content key in PWRI recipient info */ 322/* Encrypt/Decrypt content key in PWRI recipient info */
320 323
321int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, 324int
322 int en_de) 325cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
326 int en_de)
323{ 327{
324 CMS_EncryptedContentInfo *ec; 328 CMS_EncryptedContentInfo *ec;
325 CMS_PasswordRecipientInfo *pwri; 329 CMS_PasswordRecipientInfo *pwri;
@@ -342,21 +346,20 @@ int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
342 346
343 if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) { 347 if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) {
344 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, 348 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
345 CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); 349 CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
346 return 0; 350 return 0;
347 } 351 }
348 352
349 kekalg = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR), 353 kekalg = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR),
350 algtmp->parameter); 354 algtmp->parameter);
351 355
352 if (kekalg == NULL) { 356 if (kekalg == NULL) {
353 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, 357 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
354 CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER); 358 CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER);
355 return 0; 359 return 0;
356 } 360 }
357 361
358 kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); 362 kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
359
360 if (!kekcipher) { 363 if (!kekcipher) {
361 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER); 364 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER);
362 return 0; 365 return 0;
@@ -373,7 +376,7 @@ int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
373 EVP_CIPHER_CTX_set_padding(kekctx, 0); 376 EVP_CIPHER_CTX_set_padding(kekctx, 0);
374 if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) { 377 if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) {
375 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, 378 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
376 CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); 379 CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
377 goto err; 380 goto err;
378 } 381 }
379 382
@@ -381,9 +384,8 @@ int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
381 384
382 /* Finish password based key derivation to setup key in "ctx" */ 385 /* Finish password based key derivation to setup key in "ctx" */
383 386
384 if (EVP_PBE_CipherInit(algtmp->algorithm, 387 if (EVP_PBE_CipherInit(algtmp->algorithm, (char *)pwri->pass,
385 (char *)pwri->pass, pwri->passlen, 388 pwri->passlen, algtmp->parameter, kekctx, en_de) < 0) {
386 algtmp->parameter, kekctx, en_de) < 0) {
387 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB); 389 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB);
388 goto err; 390 goto err;
389 } 391 }
@@ -391,12 +393,10 @@ int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
391 /* Finally wrap/unwrap the key */ 393 /* Finally wrap/unwrap the key */
392 394
393 if (en_de) { 395 if (en_de) {
394
395 if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx)) 396 if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx))
396 goto err; 397 goto err;
397 398
398 key = OPENSSL_malloc(keylen); 399 key = OPENSSL_malloc(keylen);
399
400 if (key == NULL) 400 if (key == NULL)
401 goto err; 401 goto err;
402 402
@@ -406,14 +406,12 @@ int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
406 pwri->encryptedKey->length = keylen; 406 pwri->encryptedKey->length = keylen;
407 } else { 407 } else {
408 key = OPENSSL_malloc(pwri->encryptedKey->length); 408 key = OPENSSL_malloc(pwri->encryptedKey->length);
409
410 if (key == NULL) { 409 if (key == NULL) {
411 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE); 410 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE);
412 goto err; 411 goto err;
413 } 412 }
414 if (!kek_unwrap_key(key, &keylen, 413 if (!kek_unwrap_key(key, &keylen, pwri->encryptedKey->data,
415 pwri->encryptedKey->data, 414 pwri->encryptedKey->length, kekctx)) {
416 pwri->encryptedKey->length, kekctx)) {
417 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE); 415 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE);
418 goto err; 416 goto err;
419 } 417 }
@@ -421,19 +419,15 @@ int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
421 OPENSSL_clear_free(ec->key, ec->keylen); 419 OPENSSL_clear_free(ec->key, ec->keylen);
422 ec->key = key; 420 ec->key = key;
423 ec->keylen = keylen; 421 ec->keylen = keylen;
424
425 } 422 }
426 423
427 r = 1; 424 r = 1;
428 425
429 err: 426 err:
430
431 EVP_CIPHER_CTX_free(kekctx); 427 EVP_CIPHER_CTX_free(kekctx);
432
433 if (!r) 428 if (!r)
434 OPENSSL_free(key); 429 OPENSSL_free(key);
435 X509_ALGOR_free(kekalg); 430 X509_ALGOR_free(kekalg);
436 431
437 return r; 432 return r;
438
439} 433}