2 * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
12 #ifndef OPENSSL_NO_CMS
14 #include <openssl/dh.h>
15 #include <openssl/evp.h>
16 #include <openssl/asn1.h>
17 #include <openssl/cms.h>
20 /* Key derivation from X9.42/RFC2631 */
21 /* Uses CMS functions, hence the #ifdef wrapper. */
23 #define DH_KDF_MAX (1L << 30)
25 /* Skip past an ASN1 structure: for OBJECT skip content octets too */
27 static int skip_asn1(unsigned char **pp
, long *plen
, int exptag
)
29 const unsigned char *q
= *pp
;
32 i
= ASN1_get_object(&q
, &tmplen
, &tag
, &xclass
, *plen
);
35 if (tag
!= exptag
|| xclass
!= V_ASN1_UNIVERSAL
)
37 if (tag
== V_ASN1_OBJECT
)
40 *pp
= (unsigned char *)q
;
45 * Encode the DH shared info structure, return an offset to the counter value
46 * so we can update the structure without reencoding it.
49 static int dh_sharedinfo_encode(unsigned char **pder
, unsigned char **pctr
,
50 ASN1_OBJECT
*key_oid
, size_t outlen
,
51 const unsigned char *ukm
, size_t ukmlen
)
56 /* "magic" value to check offset is sane */
57 static unsigned char ctr
[4] = { 0xF3, 0x17, 0x22, 0x53 };
59 ASN1_OCTET_STRING ctr_oct
, ukm_oct
, *pukm_oct
;
61 if (ukmlen
> DH_KDF_MAX
|| outlen
> DH_KDF_MAX
)
66 ctr_oct
.type
= V_ASN1_OCTET_STRING
;
67 ctr_atype
.type
= V_ASN1_OCTET_STRING
;
68 ctr_atype
.value
.octet_string
= &ctr_oct
;
69 atmp
.algorithm
= key_oid
;
70 atmp
.parameter
= &ctr_atype
;
72 ukm_oct
.type
= V_ASN1_OCTET_STRING
;
74 ukm_oct
.data
= (unsigned char *)ukm
;
75 ukm_oct
.length
= ukmlen
;
79 derlen
= CMS_SharedInfo_encode(pder
, &atmp
, pukm_oct
, outlen
);
84 if (!skip_asn1(&p
, &tlen
, V_ASN1_SEQUENCE
))
86 if (!skip_asn1(&p
, &tlen
, V_ASN1_SEQUENCE
))
88 if (!skip_asn1(&p
, &tlen
, V_ASN1_OBJECT
))
90 if (!skip_asn1(&p
, &tlen
, V_ASN1_OCTET_STRING
))
92 if (CRYPTO_memcmp(p
, ctr
, 4))
98 int DH_KDF_X9_42(unsigned char *out
, size_t outlen
,
99 const unsigned char *Z
, size_t Zlen
,
100 ASN1_OBJECT
*key_oid
,
101 const unsigned char *ukm
, size_t ukmlen
, const EVP_MD
*md
)
103 EVP_MD_CTX
*mctx
= NULL
;
107 unsigned char *der
= NULL
, *ctr
;
109 if (Zlen
> DH_KDF_MAX
)
111 mctx
= EVP_MD_CTX_new();
114 mdlen
= EVP_MD_size(md
);
115 derlen
= dh_sharedinfo_encode(&der
, &ctr
, key_oid
, outlen
, ukm
, ukmlen
);
119 unsigned char mtmp
[EVP_MAX_MD_SIZE
];
120 EVP_DigestInit_ex(mctx
, md
, NULL
);
121 if (!EVP_DigestUpdate(mctx
, Z
, Zlen
))
124 ctr
[2] = (i
>> 8) & 0xFF;
125 ctr
[1] = (i
>> 16) & 0xFF;
126 ctr
[0] = (i
>> 24) & 0xFF;
127 if (!EVP_DigestUpdate(mctx
, der
, derlen
))
129 if (outlen
>= mdlen
) {
130 if (!EVP_DigestFinal(mctx
, out
, NULL
))
137 if (!EVP_DigestFinal(mctx
, mtmp
, NULL
))
139 memcpy(out
, mtmp
, outlen
);
140 OPENSSL_cleanse(mtmp
, mdlen
);
147 EVP_MD_CTX_free(mctx
);