1 /* $OpenBSD: cms_kari.c,v 1.13 2019/08/11 14:27:01 jsing Exp $ */ 2 /* 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4 * project. 5 */ 6 /* ==================================================================== 7 * Copyright (c) 2013 The OpenSSL Project. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. All advertising materials mentioning features or use of this 22 * software must display the following acknowledgment: 23 * "This product includes software developed by the OpenSSL Project 24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25 * 26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27 * endorse or promote products derived from this software without 28 * prior written permission. For written permission, please contact 29 * licensing@OpenSSL.org. 30 * 31 * 5. Products derived from this software may not be called "OpenSSL" 32 * nor may "OpenSSL" appear in their names without prior written 33 * permission of the OpenSSL Project. 34 * 35 * 6. Redistributions of any form whatsoever must retain the following 36 * acknowledgment: 37 * "This product includes software developed by the OpenSSL Project 38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51 * OF THE POSSIBILITY OF SUCH DAMAGE. 52 * ==================================================================== 53 */ 54 55 #include <string.h> 56 57 #include "cryptlib.h" 58 #include <openssl/asn1t.h> 59 #include <openssl/pem.h> 60 #include <openssl/x509v3.h> 61 #include <openssl/err.h> 62 #include <openssl/cms.h> 63 #include <openssl/aes.h> 64 #include "cms_lcl.h" 65 #include "asn1/asn1_locl.h" 66 67 /* Key Agreement Recipient Info (KARI) routines */ 68 69 int 70 CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, X509_ALGOR **palg, 71 ASN1_OCTET_STRING **pukm) 72 { 73 if (ri->type != CMS_RECIPINFO_AGREE) { 74 CMSerror(CMS_R_NOT_KEY_AGREEMENT); 75 return 0; 76 } 77 if (palg) 78 *palg = ri->d.kari->keyEncryptionAlgorithm; 79 if (pukm) 80 *pukm = ri->d.kari->ukm; 81 82 return 1; 83 } 84 85 /* Retrieve recipient encrypted keys from a kari */ 86 87 STACK_OF(CMS_RecipientEncryptedKey) * 88 CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri) 89 { 90 if (ri->type != CMS_RECIPINFO_AGREE) { 91 CMSerror(CMS_R_NOT_KEY_AGREEMENT); 92 return NULL; 93 } 94 return ri->d.kari->recipientEncryptedKeys; 95 } 96 97 int 98 CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, X509_ALGOR **pubalg, 99 ASN1_BIT_STRING **pubkey, ASN1_OCTET_STRING **keyid, X509_NAME **issuer, 100 ASN1_INTEGER **sno) 101 { 102 CMS_OriginatorIdentifierOrKey *oik; 103 104 if (ri->type != CMS_RECIPINFO_AGREE) { 105 CMSerror(CMS_R_NOT_KEY_AGREEMENT); 106 return 0; 107 } 108 oik = ri->d.kari->originator; 109 if (issuer) 110 *issuer = NULL; 111 if (sno) 112 *sno = NULL; 113 if (keyid) 114 *keyid = NULL; 115 if (pubalg) 116 *pubalg = NULL; 117 if (pubkey) 118 *pubkey = NULL; 119 if (oik->type == CMS_OIK_ISSUER_SERIAL) { 120 if (issuer) 121 *issuer = oik->d.issuerAndSerialNumber->issuer; 122 if (sno) 123 *sno = oik->d.issuerAndSerialNumber->serialNumber; 124 } else if (oik->type == CMS_OIK_KEYIDENTIFIER) { 125 if (keyid) 126 *keyid = oik->d.subjectKeyIdentifier; 127 } else if (oik->type == CMS_OIK_PUBKEY) { 128 if (pubalg) 129 *pubalg = oik->d.originatorKey->algorithm; 130 if (pubkey) 131 *pubkey = oik->d.originatorKey->publicKey; 132 } else 133 return 0; 134 135 return 1; 136 } 137 138 int 139 CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert) 140 { 141 CMS_OriginatorIdentifierOrKey *oik; 142 143 if (ri->type != CMS_RECIPINFO_AGREE) { 144 CMSerror(CMS_R_NOT_KEY_AGREEMENT); 145 return -2; 146 } 147 oik = ri->d.kari->originator; 148 if (oik->type == CMS_OIK_ISSUER_SERIAL) 149 return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert); 150 else if (oik->type == CMS_OIK_KEYIDENTIFIER) 151 return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert); 152 153 return -1; 154 } 155 156 int 157 CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, 158 ASN1_OCTET_STRING **keyid, ASN1_GENERALIZEDTIME **tm, 159 CMS_OtherKeyAttribute **other, X509_NAME **issuer, ASN1_INTEGER **sno) 160 { 161 CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; 162 163 if (rid->type == CMS_REK_ISSUER_SERIAL) { 164 if (issuer) 165 *issuer = rid->d.issuerAndSerialNumber->issuer; 166 if (sno) 167 *sno = rid->d.issuerAndSerialNumber->serialNumber; 168 if (keyid) 169 *keyid = NULL; 170 if (tm) 171 *tm = NULL; 172 if (other) 173 *other = NULL; 174 } else if (rid->type == CMS_REK_KEYIDENTIFIER) { 175 if (keyid) 176 *keyid = rid->d.rKeyId->subjectKeyIdentifier; 177 if (tm) 178 *tm = rid->d.rKeyId->date; 179 if (other) 180 *other = rid->d.rKeyId->other; 181 if (issuer) 182 *issuer = NULL; 183 if (sno) 184 *sno = NULL; 185 } else 186 return 0; 187 188 return 1; 189 } 190 191 int 192 CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, X509 *cert) 193 { 194 CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; 195 196 if (rid->type == CMS_REK_ISSUER_SERIAL) 197 return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert); 198 else if (rid->type == CMS_REK_KEYIDENTIFIER) 199 return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert); 200 else 201 return -1; 202 } 203 204 int 205 CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk) 206 { 207 EVP_PKEY_CTX *pctx; 208 CMS_KeyAgreeRecipientInfo *kari = ri->d.kari; 209 210 EVP_PKEY_CTX_free(kari->pctx); 211 kari->pctx = NULL; 212 if (!pk) 213 return 1; 214 pctx = EVP_PKEY_CTX_new(pk, NULL); 215 if (!pctx || !EVP_PKEY_derive_init(pctx)) 216 goto err; 217 kari->pctx = pctx; 218 return 1; 219 220 err: 221 EVP_PKEY_CTX_free(pctx); 222 return 0; 223 } 224 225 EVP_CIPHER_CTX * 226 CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri) 227 { 228 if (ri->type == CMS_RECIPINFO_AGREE) 229 return ri->d.kari->ctx; 230 return NULL; 231 } 232 233 /* 234 * Derive KEK and decrypt/encrypt with it to produce either the original CEK 235 * or the encrypted CEK. 236 */ 237 238 static int 239 cms_kek_cipher(unsigned char **pout, size_t *poutlen, const unsigned char *in, 240 size_t inlen, CMS_KeyAgreeRecipientInfo *kari, int enc) 241 { 242 /* Key encryption key */ 243 unsigned char kek[EVP_MAX_KEY_LENGTH]; 244 size_t keklen; 245 int rv = 0; 246 unsigned char *out = NULL; 247 int outlen; 248 249 keklen = EVP_CIPHER_CTX_key_length(kari->ctx); 250 if (keklen > EVP_MAX_KEY_LENGTH) 251 return 0; 252 /* Derive KEK */ 253 if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0) 254 goto err; 255 /* Set KEK in context */ 256 if (!EVP_CipherInit_ex(kari->ctx, NULL, NULL, kek, NULL, enc)) 257 goto err; 258 /* obtain output length of ciphered key */ 259 if (!EVP_CipherUpdate(kari->ctx, NULL, &outlen, in, inlen)) 260 goto err; 261 out = malloc(outlen); 262 if (out == NULL) 263 goto err; 264 if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, inlen)) 265 goto err; 266 *pout = out; 267 *poutlen = (size_t)outlen; 268 rv = 1; 269 270 err: 271 explicit_bzero(kek, keklen); 272 if (!rv) 273 free(out); 274 EVP_CIPHER_CTX_reset(kari->ctx); 275 /* FIXME: WHY IS kari->pctx freed here? /RL */ 276 EVP_PKEY_CTX_free(kari->pctx); 277 kari->pctx = NULL; 278 279 return rv; 280 } 281 282 int 283 CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, 284 CMS_RecipientEncryptedKey *rek) 285 { 286 int rv = 0; 287 unsigned char *enckey = NULL, *cek = NULL; 288 size_t enckeylen; 289 size_t ceklen; 290 CMS_EncryptedContentInfo *ec; 291 292 enckeylen = rek->encryptedKey->length; 293 enckey = rek->encryptedKey->data; 294 /* Setup all parameters to derive KEK */ 295 if (!cms_env_asn1_ctrl(ri, 1)) 296 goto err; 297 /* Attempt to decrypt CEK */ 298 if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0)) 299 goto err; 300 ec = cms->d.envelopedData->encryptedContentInfo; 301 freezero(ec->key, ec->keylen); 302 ec->key = cek; 303 ec->keylen = ceklen; 304 cek = NULL; 305 rv = 1; 306 307 err: 308 free(cek); 309 310 return rv; 311 } 312 313 /* Create ephemeral key and initialise context based on it */ 314 static int 315 cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, EVP_PKEY *pk) 316 { 317 EVP_PKEY_CTX *pctx = NULL; 318 EVP_PKEY *ekey = NULL; 319 int rv = 0; 320 321 pctx = EVP_PKEY_CTX_new(pk, NULL); 322 if (!pctx) 323 goto err; 324 if (EVP_PKEY_keygen_init(pctx) <= 0) 325 goto err; 326 if (EVP_PKEY_keygen(pctx, &ekey) <= 0) 327 goto err; 328 EVP_PKEY_CTX_free(pctx); 329 pctx = EVP_PKEY_CTX_new(ekey, NULL); 330 if (!pctx) 331 goto err; 332 if (EVP_PKEY_derive_init(pctx) <= 0) 333 goto err; 334 kari->pctx = pctx; 335 rv = 1; 336 337 err: 338 if (!rv) 339 EVP_PKEY_CTX_free(pctx); 340 EVP_PKEY_free(ekey); 341 342 return rv; 343 } 344 345 /* Initialise a kari based on passed certificate and key */ 346 347 int 348 cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *pk, 349 unsigned int flags) 350 { 351 CMS_KeyAgreeRecipientInfo *kari; 352 CMS_RecipientEncryptedKey *rek = NULL; 353 354 ri->d.kari = (CMS_KeyAgreeRecipientInfo *)ASN1_item_new(&CMS_KeyAgreeRecipientInfo_it); 355 if (!ri->d.kari) 356 return 0; 357 ri->type = CMS_RECIPINFO_AGREE; 358 359 kari = ri->d.kari; 360 kari->version = 3; 361 362 rek = (CMS_RecipientEncryptedKey *)ASN1_item_new(&CMS_RecipientEncryptedKey_it); 363 if (rek == NULL) 364 return 0; 365 366 if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) { 367 ASN1_item_free((ASN1_VALUE *)rek, &CMS_RecipientEncryptedKey_it); 368 return 0; 369 } 370 371 if (flags & CMS_USE_KEYID) { 372 rek->rid->type = CMS_REK_KEYIDENTIFIER; 373 rek->rid->d.rKeyId = (CMS_RecipientKeyIdentifier *)ASN1_item_new(&CMS_RecipientKeyIdentifier_it); 374 if (rek->rid->d.rKeyId == NULL) 375 return 0; 376 if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip)) 377 return 0; 378 } else { 379 rek->rid->type = CMS_REK_ISSUER_SERIAL; 380 if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip)) 381 return 0; 382 } 383 384 /* Create ephemeral key */ 385 if (!cms_kari_create_ephemeral_key(kari, pk)) 386 return 0; 387 388 EVP_PKEY_up_ref(pk); 389 rek->pkey = pk; 390 391 return 1; 392 } 393 394 static int 395 cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari, const EVP_CIPHER *cipher) 396 { 397 EVP_CIPHER_CTX *ctx = kari->ctx; 398 const EVP_CIPHER *kekcipher; 399 int keylen = EVP_CIPHER_key_length(cipher); 400 401 /* If a suitable wrap algorithm is already set nothing to do */ 402 kekcipher = EVP_CIPHER_CTX_cipher(ctx); 403 404 if (kekcipher) { 405 if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE) 406 return 0; 407 return 1; 408 } 409 /* 410 * Pick a cipher based on content encryption cipher. If it is DES3 use 411 * DES3 wrap otherwise use AES wrap similar to key size. 412 */ 413 #ifndef OPENSSL_NO_DES 414 #if 0 415 /* 416 * XXX - we do not currently support DES3 wrap and probably should just 417 * drop this code. 418 */ 419 if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc) 420 kekcipher = EVP_des_ede3_wrap(); 421 else 422 #endif 423 #endif 424 if (keylen <= 16) 425 kekcipher = EVP_aes_128_wrap(); 426 else if (keylen <= 24) 427 kekcipher = EVP_aes_192_wrap(); 428 else 429 kekcipher = EVP_aes_256_wrap(); 430 431 return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL); 432 } 433 434 /* Encrypt content key in key agreement recipient info */ 435 436 int 437 cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) 438 { 439 CMS_KeyAgreeRecipientInfo *kari; 440 CMS_EncryptedContentInfo *ec; 441 CMS_RecipientEncryptedKey *rek; 442 STACK_OF(CMS_RecipientEncryptedKey) *reks; 443 int i; 444 445 if (ri->type != CMS_RECIPINFO_AGREE) { 446 CMSerror(CMS_R_NOT_KEY_AGREEMENT); 447 return 0; 448 } 449 kari = ri->d.kari; 450 reks = kari->recipientEncryptedKeys; 451 ec = cms->d.envelopedData->encryptedContentInfo; 452 /* Initialise wrap algorithm parameters */ 453 if (!cms_wrap_init(kari, ec->cipher)) 454 return 0; 455 /* 456 * If no originator key set up initialise for ephemeral key the public key 457 * ASN1 structure will set the actual public key value. 458 */ 459 if (kari->originator->type == -1) { 460 CMS_OriginatorIdentifierOrKey *oik = kari->originator; 461 oik->type = CMS_OIK_PUBKEY; 462 oik->d.originatorKey = (CMS_OriginatorPublicKey *)ASN1_item_new(&CMS_OriginatorPublicKey_it); 463 if (!oik->d.originatorKey) 464 return 0; 465 } 466 /* Initialise KDF algorithm */ 467 if (!cms_env_asn1_ctrl(ri, 0)) 468 return 0; 469 /* For each rek, derive KEK, encrypt CEK */ 470 for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { 471 unsigned char *enckey; 472 size_t enckeylen; 473 rek = sk_CMS_RecipientEncryptedKey_value(reks, i); 474 if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0) 475 return 0; 476 if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen, 477 kari, 1)) 478 return 0; 479 ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen); 480 } 481 482 return 1; 483 } 484