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
CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo * ri,X509_ALGOR ** palg,ASN1_OCTET_STRING ** pukm)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 
STACK_OF(CMS_RecipientEncryptedKey)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
CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo * ri,X509_ALGOR ** pubalg,ASN1_BIT_STRING ** pubkey,ASN1_OCTET_STRING ** keyid,X509_NAME ** issuer,ASN1_INTEGER ** sno)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
CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo * ri,X509 * cert)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
CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey * rek,ASN1_OCTET_STRING ** keyid,ASN1_GENERALIZEDTIME ** tm,CMS_OtherKeyAttribute ** other,X509_NAME ** issuer,ASN1_INTEGER ** sno)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
CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey * rek,X509 * cert)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
CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo * ri,EVP_PKEY * pk)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 *
CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo * ri)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
cms_kek_cipher(unsigned char ** pout,size_t * poutlen,const unsigned char * in,size_t inlen,CMS_KeyAgreeRecipientInfo * kari,int enc)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
CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo * cms,CMS_RecipientInfo * ri,CMS_RecipientEncryptedKey * rek)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
cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo * kari,EVP_PKEY * pk)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
cms_RecipientInfo_kari_init(CMS_RecipientInfo * ri,X509 * recip,EVP_PKEY * pk,unsigned int flags)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
cms_wrap_init(CMS_KeyAgreeRecipientInfo * kari,const EVP_CIPHER * cipher)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
cms_RecipientInfo_kari_encrypt(CMS_ContentInfo * cms,CMS_RecipientInfo * ri)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