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