diff options
Diffstat (limited to 'src/lib/libcrypto/cms/cms_kari.c')
| -rw-r--r-- | src/lib/libcrypto/cms/cms_kari.c | 490 |
1 files changed, 0 insertions, 490 deletions
diff --git a/src/lib/libcrypto/cms/cms_kari.c b/src/lib/libcrypto/cms/cms_kari.c deleted file mode 100644 index 86b1ad9e83..0000000000 --- a/src/lib/libcrypto/cms/cms_kari.c +++ /dev/null | |||
| @@ -1,490 +0,0 @@ | |||
| 1 | /* $OpenBSD: cms_kari.c,v 1.17 2024/11/01 18:34:06 tb 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 <stdlib.h> | ||
| 56 | #include <string.h> | ||
| 57 | |||
| 58 | #include <openssl/asn1.h> | ||
| 59 | #include <openssl/cms.h> | ||
| 60 | #include <openssl/err.h> | ||
| 61 | #include <openssl/evp.h> | ||
| 62 | |||
| 63 | #include "cms_local.h" | ||
| 64 | |||
| 65 | /* Key Agreement Recipient Info (KARI) routines */ | ||
| 66 | |||
| 67 | int | ||
| 68 | CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, X509_ALGOR **palg, | ||
| 69 | ASN1_OCTET_STRING **pukm) | ||
| 70 | { | ||
| 71 | if (ri->type != CMS_RECIPINFO_AGREE) { | ||
| 72 | CMSerror(CMS_R_NOT_KEY_AGREEMENT); | ||
| 73 | return 0; | ||
| 74 | } | ||
| 75 | if (palg) | ||
| 76 | *palg = ri->d.kari->keyEncryptionAlgorithm; | ||
| 77 | if (pukm) | ||
| 78 | *pukm = ri->d.kari->ukm; | ||
| 79 | |||
| 80 | return 1; | ||
| 81 | } | ||
| 82 | LCRYPTO_ALIAS(CMS_RecipientInfo_kari_get0_alg); | ||
| 83 | |||
| 84 | /* Retrieve recipient encrypted keys from a kari */ | ||
| 85 | |||
| 86 | STACK_OF(CMS_RecipientEncryptedKey) * | ||
| 87 | CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri) | ||
| 88 | { | ||
| 89 | if (ri->type != CMS_RECIPINFO_AGREE) { | ||
| 90 | CMSerror(CMS_R_NOT_KEY_AGREEMENT); | ||
| 91 | return NULL; | ||
| 92 | } | ||
| 93 | return ri->d.kari->recipientEncryptedKeys; | ||
| 94 | } | ||
| 95 | LCRYPTO_ALIAS(CMS_RecipientInfo_kari_get0_reks); | ||
| 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 | LCRYPTO_ALIAS(CMS_RecipientInfo_kari_get0_orig_id); | ||
| 138 | |||
| 139 | int | ||
| 140 | CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert) | ||
| 141 | { | ||
| 142 | CMS_OriginatorIdentifierOrKey *oik; | ||
| 143 | |||
| 144 | if (ri->type != CMS_RECIPINFO_AGREE) { | ||
| 145 | CMSerror(CMS_R_NOT_KEY_AGREEMENT); | ||
| 146 | return -2; | ||
| 147 | } | ||
| 148 | oik = ri->d.kari->originator; | ||
| 149 | if (oik->type == CMS_OIK_ISSUER_SERIAL) | ||
| 150 | return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert); | ||
| 151 | else if (oik->type == CMS_OIK_KEYIDENTIFIER) | ||
| 152 | return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert); | ||
| 153 | |||
| 154 | return -1; | ||
| 155 | } | ||
| 156 | LCRYPTO_ALIAS(CMS_RecipientInfo_kari_orig_id_cmp); | ||
| 157 | |||
| 158 | int | ||
| 159 | CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, | ||
| 160 | ASN1_OCTET_STRING **keyid, ASN1_GENERALIZEDTIME **tm, | ||
| 161 | CMS_OtherKeyAttribute **other, X509_NAME **issuer, ASN1_INTEGER **sno) | ||
| 162 | { | ||
| 163 | CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; | ||
| 164 | |||
| 165 | if (rid->type == CMS_REK_ISSUER_SERIAL) { | ||
| 166 | if (issuer) | ||
| 167 | *issuer = rid->d.issuerAndSerialNumber->issuer; | ||
| 168 | if (sno) | ||
| 169 | *sno = rid->d.issuerAndSerialNumber->serialNumber; | ||
| 170 | if (keyid) | ||
| 171 | *keyid = NULL; | ||
| 172 | if (tm) | ||
| 173 | *tm = NULL; | ||
| 174 | if (other) | ||
| 175 | *other = NULL; | ||
| 176 | } else if (rid->type == CMS_REK_KEYIDENTIFIER) { | ||
| 177 | if (keyid) | ||
| 178 | *keyid = rid->d.rKeyId->subjectKeyIdentifier; | ||
| 179 | if (tm) | ||
| 180 | *tm = rid->d.rKeyId->date; | ||
| 181 | if (other) | ||
| 182 | *other = rid->d.rKeyId->other; | ||
| 183 | if (issuer) | ||
| 184 | *issuer = NULL; | ||
| 185 | if (sno) | ||
| 186 | *sno = NULL; | ||
| 187 | } else | ||
| 188 | return 0; | ||
| 189 | |||
| 190 | return 1; | ||
| 191 | } | ||
| 192 | LCRYPTO_ALIAS(CMS_RecipientEncryptedKey_get0_id); | ||
| 193 | |||
| 194 | int | ||
| 195 | CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, X509 *cert) | ||
| 196 | { | ||
| 197 | CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; | ||
| 198 | |||
| 199 | if (rid->type == CMS_REK_ISSUER_SERIAL) | ||
| 200 | return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert); | ||
| 201 | else if (rid->type == CMS_REK_KEYIDENTIFIER) | ||
| 202 | return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert); | ||
| 203 | else | ||
| 204 | return -1; | ||
| 205 | } | ||
| 206 | LCRYPTO_ALIAS(CMS_RecipientEncryptedKey_cert_cmp); | ||
| 207 | |||
| 208 | int | ||
| 209 | CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk) | ||
| 210 | { | ||
| 211 | EVP_PKEY_CTX *pctx; | ||
| 212 | CMS_KeyAgreeRecipientInfo *kari = ri->d.kari; | ||
| 213 | |||
| 214 | EVP_PKEY_CTX_free(kari->pctx); | ||
| 215 | kari->pctx = NULL; | ||
| 216 | if (!pk) | ||
| 217 | return 1; | ||
| 218 | pctx = EVP_PKEY_CTX_new(pk, NULL); | ||
| 219 | if (!pctx || !EVP_PKEY_derive_init(pctx)) | ||
| 220 | goto err; | ||
| 221 | kari->pctx = pctx; | ||
| 222 | return 1; | ||
| 223 | |||
| 224 | err: | ||
| 225 | EVP_PKEY_CTX_free(pctx); | ||
| 226 | return 0; | ||
| 227 | } | ||
| 228 | LCRYPTO_ALIAS(CMS_RecipientInfo_kari_set0_pkey); | ||
| 229 | |||
| 230 | EVP_CIPHER_CTX * | ||
| 231 | CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri) | ||
| 232 | { | ||
| 233 | if (ri->type == CMS_RECIPINFO_AGREE) | ||
| 234 | return ri->d.kari->ctx; | ||
| 235 | return NULL; | ||
| 236 | } | ||
| 237 | LCRYPTO_ALIAS(CMS_RecipientInfo_kari_get0_ctx); | ||
| 238 | |||
| 239 | /* | ||
| 240 | * Derive KEK and decrypt/encrypt with it to produce either the original CEK | ||
| 241 | * or the encrypted CEK. | ||
| 242 | */ | ||
| 243 | |||
| 244 | static int | ||
| 245 | cms_kek_cipher(unsigned char **pout, size_t *poutlen, const unsigned char *in, | ||
| 246 | size_t inlen, CMS_KeyAgreeRecipientInfo *kari, int enc) | ||
| 247 | { | ||
| 248 | /* Key encryption key */ | ||
| 249 | unsigned char kek[EVP_MAX_KEY_LENGTH]; | ||
| 250 | size_t keklen; | ||
| 251 | int rv = 0; | ||
| 252 | unsigned char *out = NULL; | ||
| 253 | int outlen; | ||
| 254 | |||
| 255 | keklen = EVP_CIPHER_CTX_key_length(kari->ctx); | ||
| 256 | if (keklen > EVP_MAX_KEY_LENGTH) | ||
| 257 | return 0; | ||
| 258 | /* Derive KEK */ | ||
| 259 | if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0) | ||
| 260 | goto err; | ||
| 261 | /* Set KEK in context */ | ||
| 262 | if (!EVP_CipherInit_ex(kari->ctx, NULL, NULL, kek, NULL, enc)) | ||
| 263 | goto err; | ||
| 264 | /* obtain output length of ciphered key */ | ||
| 265 | if (!EVP_CipherUpdate(kari->ctx, NULL, &outlen, in, inlen)) | ||
| 266 | goto err; | ||
| 267 | out = malloc(outlen); | ||
| 268 | if (out == NULL) | ||
| 269 | goto err; | ||
| 270 | if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, inlen)) | ||
| 271 | goto err; | ||
| 272 | *pout = out; | ||
| 273 | *poutlen = (size_t)outlen; | ||
| 274 | rv = 1; | ||
| 275 | |||
| 276 | err: | ||
| 277 | explicit_bzero(kek, keklen); | ||
| 278 | if (!rv) | ||
| 279 | free(out); | ||
| 280 | (void)EVP_CIPHER_CTX_reset(kari->ctx); | ||
| 281 | /* FIXME: WHY IS kari->pctx freed here? /RL */ | ||
| 282 | EVP_PKEY_CTX_free(kari->pctx); | ||
| 283 | kari->pctx = NULL; | ||
| 284 | |||
| 285 | return rv; | ||
| 286 | } | ||
| 287 | |||
| 288 | int | ||
| 289 | CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, | ||
| 290 | CMS_RecipientEncryptedKey *rek) | ||
| 291 | { | ||
| 292 | int rv = 0; | ||
| 293 | unsigned char *enckey = NULL, *cek = NULL; | ||
| 294 | size_t enckeylen; | ||
| 295 | size_t ceklen; | ||
| 296 | CMS_EncryptedContentInfo *ec; | ||
| 297 | |||
| 298 | enckeylen = rek->encryptedKey->length; | ||
| 299 | enckey = rek->encryptedKey->data; | ||
| 300 | /* Setup all parameters to derive KEK */ | ||
| 301 | if (!cms_env_asn1_ctrl(ri, 1)) | ||
| 302 | goto err; | ||
| 303 | /* Attempt to decrypt CEK */ | ||
| 304 | if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0)) | ||
| 305 | goto err; | ||
| 306 | ec = cms->d.envelopedData->encryptedContentInfo; | ||
| 307 | freezero(ec->key, ec->keylen); | ||
| 308 | ec->key = cek; | ||
| 309 | ec->keylen = ceklen; | ||
| 310 | cek = NULL; | ||
| 311 | rv = 1; | ||
| 312 | |||
| 313 | err: | ||
| 314 | free(cek); | ||
| 315 | |||
| 316 | return rv; | ||
| 317 | } | ||
| 318 | LCRYPTO_ALIAS(CMS_RecipientInfo_kari_decrypt); | ||
| 319 | |||
| 320 | /* Create ephemeral key and initialise context based on it */ | ||
| 321 | static int | ||
| 322 | cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, EVP_PKEY *pk) | ||
| 323 | { | ||
| 324 | EVP_PKEY_CTX *pctx = NULL; | ||
| 325 | EVP_PKEY *ekey = NULL; | ||
| 326 | int rv = 0; | ||
| 327 | |||
| 328 | pctx = EVP_PKEY_CTX_new(pk, NULL); | ||
| 329 | if (!pctx) | ||
| 330 | goto err; | ||
| 331 | if (EVP_PKEY_keygen_init(pctx) <= 0) | ||
| 332 | goto err; | ||
| 333 | if (EVP_PKEY_keygen(pctx, &ekey) <= 0) | ||
| 334 | goto err; | ||
| 335 | EVP_PKEY_CTX_free(pctx); | ||
| 336 | pctx = EVP_PKEY_CTX_new(ekey, NULL); | ||
| 337 | if (!pctx) | ||
| 338 | goto err; | ||
| 339 | if (EVP_PKEY_derive_init(pctx) <= 0) | ||
| 340 | goto err; | ||
| 341 | kari->pctx = pctx; | ||
| 342 | rv = 1; | ||
| 343 | |||
| 344 | err: | ||
| 345 | if (!rv) | ||
| 346 | EVP_PKEY_CTX_free(pctx); | ||
| 347 | EVP_PKEY_free(ekey); | ||
| 348 | |||
| 349 | return rv; | ||
| 350 | } | ||
| 351 | |||
| 352 | /* Initialise a kari based on passed certificate and key */ | ||
| 353 | |||
| 354 | int | ||
| 355 | cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *pk, | ||
| 356 | unsigned int flags) | ||
| 357 | { | ||
| 358 | CMS_KeyAgreeRecipientInfo *kari; | ||
| 359 | CMS_RecipientEncryptedKey *rek = NULL; | ||
| 360 | |||
| 361 | ri->d.kari = (CMS_KeyAgreeRecipientInfo *)ASN1_item_new(&CMS_KeyAgreeRecipientInfo_it); | ||
| 362 | if (!ri->d.kari) | ||
| 363 | return 0; | ||
| 364 | ri->type = CMS_RECIPINFO_AGREE; | ||
| 365 | |||
| 366 | kari = ri->d.kari; | ||
| 367 | kari->version = 3; | ||
| 368 | |||
| 369 | rek = (CMS_RecipientEncryptedKey *)ASN1_item_new(&CMS_RecipientEncryptedKey_it); | ||
| 370 | if (rek == NULL) | ||
| 371 | return 0; | ||
| 372 | |||
| 373 | if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) { | ||
| 374 | ASN1_item_free((ASN1_VALUE *)rek, &CMS_RecipientEncryptedKey_it); | ||
| 375 | return 0; | ||
| 376 | } | ||
| 377 | |||
| 378 | if (flags & CMS_USE_KEYID) { | ||
| 379 | rek->rid->type = CMS_REK_KEYIDENTIFIER; | ||
| 380 | rek->rid->d.rKeyId = (CMS_RecipientKeyIdentifier *)ASN1_item_new(&CMS_RecipientKeyIdentifier_it); | ||
| 381 | if (rek->rid->d.rKeyId == NULL) | ||
| 382 | return 0; | ||
| 383 | if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip)) | ||
| 384 | return 0; | ||
| 385 | } else { | ||
| 386 | rek->rid->type = CMS_REK_ISSUER_SERIAL; | ||
| 387 | if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip)) | ||
| 388 | return 0; | ||
| 389 | } | ||
| 390 | |||
| 391 | /* Create ephemeral key */ | ||
| 392 | if (!cms_kari_create_ephemeral_key(kari, pk)) | ||
| 393 | return 0; | ||
| 394 | |||
| 395 | EVP_PKEY_up_ref(pk); | ||
| 396 | rek->pkey = pk; | ||
| 397 | |||
| 398 | return 1; | ||
| 399 | } | ||
| 400 | |||
| 401 | static int | ||
| 402 | cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari, const EVP_CIPHER *cipher) | ||
| 403 | { | ||
| 404 | EVP_CIPHER_CTX *ctx = kari->ctx; | ||
| 405 | const EVP_CIPHER *kekcipher; | ||
| 406 | int keylen = EVP_CIPHER_key_length(cipher); | ||
| 407 | |||
| 408 | /* If a suitable wrap algorithm is already set nothing to do */ | ||
| 409 | kekcipher = EVP_CIPHER_CTX_cipher(ctx); | ||
| 410 | |||
| 411 | if (kekcipher) { | ||
| 412 | if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE) | ||
| 413 | return 0; | ||
| 414 | return 1; | ||
| 415 | } | ||
| 416 | /* | ||
| 417 | * Pick a cipher based on content encryption cipher. If it is DES3 use | ||
| 418 | * DES3 wrap otherwise use AES wrap similar to key size. | ||
| 419 | */ | ||
| 420 | #ifndef OPENSSL_NO_DES | ||
| 421 | #if 0 | ||
| 422 | /* | ||
| 423 | * XXX - we do not currently support DES3 wrap and probably should just | ||
| 424 | * drop this code. | ||
| 425 | */ | ||
| 426 | if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc) | ||
| 427 | kekcipher = EVP_des_ede3_wrap(); | ||
| 428 | else | ||
| 429 | #endif | ||
| 430 | #endif | ||
| 431 | if (keylen <= 16) | ||
| 432 | kekcipher = EVP_aes_128_wrap(); | ||
| 433 | else if (keylen <= 24) | ||
| 434 | kekcipher = EVP_aes_192_wrap(); | ||
| 435 | else | ||
| 436 | kekcipher = EVP_aes_256_wrap(); | ||
| 437 | |||
| 438 | return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL); | ||
| 439 | } | ||
| 440 | |||
| 441 | /* Encrypt content key in key agreement recipient info */ | ||
| 442 | |||
| 443 | int | ||
| 444 | cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) | ||
| 445 | { | ||
| 446 | CMS_KeyAgreeRecipientInfo *kari; | ||
| 447 | CMS_EncryptedContentInfo *ec; | ||
| 448 | CMS_RecipientEncryptedKey *rek; | ||
| 449 | STACK_OF(CMS_RecipientEncryptedKey) *reks; | ||
| 450 | int i; | ||
| 451 | |||
| 452 | if (ri->type != CMS_RECIPINFO_AGREE) { | ||
| 453 | CMSerror(CMS_R_NOT_KEY_AGREEMENT); | ||
| 454 | return 0; | ||
| 455 | } | ||
| 456 | kari = ri->d.kari; | ||
| 457 | reks = kari->recipientEncryptedKeys; | ||
| 458 | ec = cms->d.envelopedData->encryptedContentInfo; | ||
| 459 | /* Initialise wrap algorithm parameters */ | ||
| 460 | if (!cms_wrap_init(kari, ec->cipher)) | ||
| 461 | return 0; | ||
| 462 | /* | ||
| 463 | * If no originator key set up initialise for ephemeral key the public key | ||
| 464 | * ASN1 structure will set the actual public key value. | ||
| 465 | */ | ||
| 466 | if (kari->originator->type == -1) { | ||
| 467 | CMS_OriginatorIdentifierOrKey *oik = kari->originator; | ||
| 468 | oik->type = CMS_OIK_PUBKEY; | ||
| 469 | oik->d.originatorKey = (CMS_OriginatorPublicKey *)ASN1_item_new(&CMS_OriginatorPublicKey_it); | ||
| 470 | if (!oik->d.originatorKey) | ||
| 471 | return 0; | ||
| 472 | } | ||
| 473 | /* Initialise KDF algorithm */ | ||
| 474 | if (!cms_env_asn1_ctrl(ri, 0)) | ||
| 475 | return 0; | ||
| 476 | /* For each rek, derive KEK, encrypt CEK */ | ||
| 477 | for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { | ||
| 478 | unsigned char *enckey; | ||
| 479 | size_t enckeylen; | ||
| 480 | rek = sk_CMS_RecipientEncryptedKey_value(reks, i); | ||
| 481 | if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0) | ||
| 482 | return 0; | ||
| 483 | if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen, | ||
| 484 | kari, 1)) | ||
| 485 | return 0; | ||
| 486 | ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen); | ||
| 487 | } | ||
| 488 | |||
| 489 | return 1; | ||
| 490 | } | ||
