]> git.ipfire.org Git - thirdparty/openssl.git/blob - providers/common/kdfs/x942kdf.c
Teach TLSProxy how to parse CertificateRequest messages
[thirdparty/openssl.git] / providers / common / kdfs / x942kdf.c
1 /*
2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
4 *
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
9 */
10
11 #include "e_os.h"
12
13 #ifndef OPENSSL_NO_CMS
14
15 # include <stdlib.h>
16 # include <stdarg.h>
17 # include <string.h>
18 # include <openssl/hmac.h>
19 # include <openssl/cms.h>
20 # include <openssl/evp.h>
21 # include <openssl/kdf.h>
22 # include <openssl/x509.h>
23 # include <openssl/obj_mac.h>
24 # include "internal/cryptlib.h"
25 # include "internal/evp_int.h"
26 # include "kdf_local.h"
27
28 # define X942KDF_MAX_INLEN (1 << 30)
29
30 struct evp_kdf_impl_st {
31 const EVP_MD *md;
32 unsigned char *secret;
33 size_t secret_len;
34 int cek_nid;
35 unsigned char *ukm;
36 size_t ukm_len;
37 size_t dkm_len;
38 };
39
40 /* A table of allowed wrapping algorithms and the associated output lengths */
41 static const struct {
42 int nid;
43 size_t keklen; /* size in bytes */
44 } kek_algs[] = {
45 { NID_id_smime_alg_CMS3DESwrap, 24 },
46 { NID_id_smime_alg_CMSRC2wrap, 16 },
47 { NID_id_aes128_wrap, 16 },
48 { NID_id_aes192_wrap, 24 },
49 { NID_id_aes256_wrap, 32 },
50 { NID_id_camellia128_wrap, 16 },
51 { NID_id_camellia192_wrap, 24 },
52 { NID_id_camellia256_wrap, 32 }
53 };
54
55 /* Skip past an ASN1 structure: for OBJECT skip content octets too */
56 static int skip_asn1(unsigned char **pp, long *plen, int exptag)
57 {
58 int i, tag, xclass;
59 long tmplen;
60 const unsigned char *q = *pp;
61
62 i = ASN1_get_object(&q, &tmplen, &tag, &xclass, *plen);
63 if ((i & 0x80) != 0 || tag != exptag || xclass != V_ASN1_UNIVERSAL)
64 return 0;
65 if (tag == V_ASN1_OBJECT)
66 q += tmplen;
67 *pp = (unsigned char *)q;
68 *plen -= q - *pp;
69 return 1;
70 }
71
72 /*
73 * Encode the other info structure.
74 *
75 * RFC2631 Section 2.1.2 Contains the following definition for otherinfo
76 *
77 * OtherInfo ::= SEQUENCE {
78 * keyInfo KeySpecificInfo,
79 * partyAInfo [0] OCTET STRING OPTIONAL,
80 * suppPubInfo [2] OCTET STRING
81 * }
82 *
83 * KeySpecificInfo ::= SEQUENCE {
84 * algorithm OBJECT IDENTIFIER,
85 * counter OCTET STRING SIZE (4..4)
86 * }
87 *
88 * |nid| is the algorithm object identifier.
89 * |keylen| is the length (in bytes) of the generated KEK. It is stored into
90 * suppPubInfo (in bits).
91 * |ukm| is the optional user keying material that is stored into partyAInfo. It
92 * can be NULL.
93 * |ukmlen| is the user keying material length (in bytes).
94 * |der| is the returned encoded data. It must be freed by the caller.
95 * |der_len| is the returned size of the encoded data.
96 * |out_ctr| returns a pointer to the counter data which is embedded inside the
97 * encoded data. This allows the counter bytes to be updated without re-encoding.
98 *
99 * Returns: 1 if successfully encoded, or 0 otherwise.
100 * Assumptions: |der|, |der_len| & |out_ctr| are not NULL.
101 */
102 static int x942_encode_otherinfo(int nid, size_t keylen,
103 const unsigned char *ukm, size_t ukmlen,
104 unsigned char **der, size_t *der_len,
105 unsigned char **out_ctr)
106 {
107 unsigned char *p, *encoded = NULL;
108 int ret = 0, encoded_len;
109 long tlen;
110 /* "magic" value to check offset is sane */
111 static unsigned char ctr[4] = { 0x00, 0x00, 0x00, 0x01 };
112 X509_ALGOR *ksi = NULL;
113 ASN1_OBJECT *alg_oid = NULL;
114 ASN1_OCTET_STRING *ctr_oct = NULL, *ukm_oct = NULL;
115
116 /* set the KeySpecificInfo - which contains an algorithm oid and counter */
117 ksi = X509_ALGOR_new();
118 alg_oid = OBJ_dup(OBJ_nid2obj(nid));
119 ctr_oct = ASN1_OCTET_STRING_new();
120 if (ksi == NULL
121 || alg_oid == NULL
122 || ctr_oct == NULL
123 || !ASN1_OCTET_STRING_set(ctr_oct, ctr, sizeof(ctr))
124 || !X509_ALGOR_set0(ksi, alg_oid, V_ASN1_OCTET_STRING, ctr_oct))
125 goto err;
126 /* NULL these as they now belong to ksi */
127 alg_oid = NULL;
128 ctr_oct = NULL;
129
130 /* Set the optional partyAInfo */
131 if (ukm != NULL) {
132 ukm_oct = ASN1_OCTET_STRING_new();
133 if (ukm_oct == NULL)
134 goto err;
135 ASN1_OCTET_STRING_set(ukm_oct, (unsigned char *)ukm, ukmlen);
136 }
137 /* Generate the OtherInfo DER data */
138 encoded_len = CMS_SharedInfo_encode(&encoded, ksi, ukm_oct, keylen);
139 if (encoded_len <= 0)
140 goto err;
141
142 /* Parse the encoded data to find the offset of the counter data */
143 p = encoded;
144 tlen = (long)encoded_len;
145 if (skip_asn1(&p, &tlen, V_ASN1_SEQUENCE)
146 && skip_asn1(&p, &tlen, V_ASN1_SEQUENCE)
147 && skip_asn1(&p, &tlen, V_ASN1_OBJECT)
148 && skip_asn1(&p, &tlen, V_ASN1_OCTET_STRING)
149 && CRYPTO_memcmp(p, ctr, 4) == 0) {
150 *out_ctr = p;
151 *der = encoded;
152 *der_len = (size_t)encoded_len;
153 ret = 1;
154 }
155 err:
156 if (ret != 1)
157 OPENSSL_free(encoded);
158 ASN1_OCTET_STRING_free(ctr_oct);
159 ASN1_OCTET_STRING_free(ukm_oct);
160 ASN1_OBJECT_free(alg_oid);
161 X509_ALGOR_free(ksi);
162 return ret;
163 }
164
165 static int x942kdf_hash_kdm(const EVP_MD *kdf_md,
166 const unsigned char *z, size_t z_len,
167 const unsigned char *other, size_t other_len,
168 unsigned char *ctr,
169 unsigned char *derived_key, size_t derived_key_len)
170 {
171 int ret = 0, hlen;
172 size_t counter, out_len, len = derived_key_len;
173 unsigned char mac[EVP_MAX_MD_SIZE];
174 unsigned char *out = derived_key;
175 EVP_MD_CTX *ctx = NULL, *ctx_init = NULL;
176
177 if (z_len > X942KDF_MAX_INLEN || other_len > X942KDF_MAX_INLEN
178 || derived_key_len > X942KDF_MAX_INLEN
179 || derived_key_len == 0) {
180 KDFerr(KDF_F_X942KDF_HASH_KDM, KDF_R_BAD_LENGTH);
181 return 0;
182 }
183
184 hlen = EVP_MD_size(kdf_md);
185 if (hlen <= 0)
186 return 0;
187 out_len = (size_t)hlen;
188
189 ctx = EVP_MD_CTX_create();
190 ctx_init = EVP_MD_CTX_create();
191 if (ctx == NULL || ctx_init == NULL)
192 goto end;
193
194 if (!EVP_DigestInit(ctx_init, kdf_md))
195 goto end;
196
197 for (counter = 1;; counter++) {
198 /* updating the ctr modifies 4 bytes in the 'other' buffer */
199 ctr[0] = (unsigned char)((counter >> 24) & 0xff);
200 ctr[1] = (unsigned char)((counter >> 16) & 0xff);
201 ctr[2] = (unsigned char)((counter >> 8) & 0xff);
202 ctr[3] = (unsigned char)(counter & 0xff);
203
204 if (!EVP_MD_CTX_copy_ex(ctx, ctx_init)
205 || !EVP_DigestUpdate(ctx, z, z_len)
206 || !EVP_DigestUpdate(ctx, other, other_len))
207 goto end;
208 if (len >= out_len) {
209 if (!EVP_DigestFinal_ex(ctx, out, NULL))
210 goto end;
211 out += out_len;
212 len -= out_len;
213 if (len == 0)
214 break;
215 } else {
216 if (!EVP_DigestFinal_ex(ctx, mac, NULL))
217 goto end;
218 memcpy(out, mac, len);
219 break;
220 }
221 }
222 ret = 1;
223 end:
224 EVP_MD_CTX_free(ctx);
225 EVP_MD_CTX_free(ctx_init);
226 OPENSSL_cleanse(mac, sizeof(mac));
227 return ret;
228 }
229
230 static EVP_KDF_IMPL *x942kdf_new(void)
231 {
232 EVP_KDF_IMPL *impl;
233
234 if ((impl = OPENSSL_zalloc(sizeof(*impl))) == NULL)
235 KDFerr(KDF_F_X942KDF_NEW, ERR_R_MALLOC_FAILURE);
236 return impl;
237 }
238
239 static void x942kdf_reset(EVP_KDF_IMPL *impl)
240 {
241 OPENSSL_clear_free(impl->secret, impl->secret_len);
242 OPENSSL_clear_free(impl->ukm, impl->ukm_len);
243 memset(impl, 0, sizeof(*impl));
244 }
245
246 static void x942kdf_free(EVP_KDF_IMPL *impl)
247 {
248 x942kdf_reset(impl);
249 OPENSSL_free(impl);
250 }
251
252 static int x942kdf_set_buffer(va_list args, unsigned char **out, size_t *out_len)
253 {
254 const unsigned char *p;
255 size_t len;
256
257 p = va_arg(args, const unsigned char *);
258 len = va_arg(args, size_t);
259 if (len == 0 || p == NULL)
260 return 1;
261
262 OPENSSL_free(*out);
263 *out = OPENSSL_memdup(p, len);
264 if (*out == NULL)
265 return 0;
266
267 *out_len = len;
268 return 1;
269 }
270
271 static int x942kdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
272 {
273 const EVP_MD *md;
274 char *alg_str = NULL;
275 size_t i;
276
277 switch (cmd) {
278 case EVP_KDF_CTRL_SET_MD:
279 md = va_arg(args, const EVP_MD *);
280 if (md == NULL)
281 return 0;
282
283 impl->md = md;
284 return 1;
285
286 case EVP_KDF_CTRL_SET_KEY:
287 return x942kdf_set_buffer(args, &impl->secret, &impl->secret_len);
288
289 case EVP_KDF_CTRL_SET_UKM:
290 return x942kdf_set_buffer(args, &impl->ukm, &impl->ukm_len);
291
292 case EVP_KDF_CTRL_SET_CEK_ALG:
293 alg_str = va_arg(args, char *);
294 if (alg_str == NULL)
295 return 0;
296 impl->cek_nid = OBJ_sn2nid(alg_str);
297 for (i = 0; i < (size_t)OSSL_NELEM(kek_algs); ++i) {
298 if (kek_algs[i].nid == impl->cek_nid) {
299 impl->dkm_len = kek_algs[i].keklen;
300 return 1;
301 }
302 }
303 KDFerr(KDF_F_X942KDF_CTRL, KDF_R_UNSUPPORTED_CEK_ALG);
304 return 0;
305
306 default:
307 return -2;
308 }
309 }
310
311 static int x942kdf_ctrl_str(EVP_KDF_IMPL *impl, const char *type,
312 const char *value)
313 {
314 if (strcmp(type, "digest") == 0)
315 return kdf_md2ctrl(impl, x942kdf_ctrl, EVP_KDF_CTRL_SET_MD, value);
316
317 if (strcmp(type, "secret") == 0 || strcmp(type, "key") == 0)
318 return kdf_str2ctrl(impl, x942kdf_ctrl, EVP_KDF_CTRL_SET_KEY,
319 value);
320
321 if (strcmp(type, "hexsecret") == 0 || strcmp(type, "hexkey") == 0)
322 return kdf_hex2ctrl(impl, x942kdf_ctrl, EVP_KDF_CTRL_SET_KEY,
323 value);
324
325 if (strcmp(type, "ukm") == 0)
326 return kdf_str2ctrl(impl, x942kdf_ctrl, EVP_KDF_CTRL_SET_UKM,
327 value);
328
329 if (strcmp(type, "hexukm") == 0)
330 return kdf_hex2ctrl(impl, x942kdf_ctrl, EVP_KDF_CTRL_SET_UKM,
331 value);
332
333 if (strcmp(type, "cekalg") == 0)
334 return kdf_str2ctrl(impl, x942kdf_ctrl, EVP_KDF_CTRL_SET_CEK_ALG,
335 value);
336
337 return -2;
338 }
339
340 static size_t x942kdf_size(EVP_KDF_IMPL *impl)
341 {
342 int len;
343
344 if (impl->md == NULL) {
345 KDFerr(KDF_F_X942KDF_SIZE, KDF_R_MISSING_MESSAGE_DIGEST);
346 return 0;
347 }
348 len = EVP_MD_size(impl->md);
349 return (len <= 0) ? 0 : (size_t)len;
350 }
351
352 static int x942kdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen)
353 {
354 int ret = 0;
355 unsigned char *ctr;
356 unsigned char *der = NULL;
357 size_t der_len = 0;
358
359 if (impl->secret == NULL) {
360 KDFerr(KDF_F_X942KDF_DERIVE, KDF_R_MISSING_SECRET);
361 return 0;
362 }
363 if (impl->md == NULL) {
364 KDFerr(KDF_F_X942KDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
365 return 0;
366 }
367 if (impl->cek_nid == NID_undef) {
368 KDFerr(KDF_F_X942KDF_DERIVE, KDF_R_MISSING_CEK_ALG);
369 return 0;
370 }
371 if (impl->ukm != NULL && impl->ukm_len >= X942KDF_MAX_INLEN) {
372 /*
373 * Note the ukm length MUST be 512 bits.
374 * For backwards compatibility the old check is being done.
375 */
376 KDFerr(KDF_F_X942KDF_DERIVE, KDF_R_INAVLID_UKM_LEN);
377 return 0;
378 }
379 if (keylen != impl->dkm_len) {
380 KDFerr(KDF_F_X942KDF_DERIVE, KDF_R_MISSING_CEK_ALG);
381 return 0;
382 }
383 /* generate the otherinfo der */
384 if (!x942_encode_otherinfo(impl->cek_nid, impl->dkm_len,
385 impl->ukm, impl->ukm_len,
386 &der, &der_len, &ctr)) {
387 KDFerr(KDF_F_X942KDF_DERIVE, KDF_R_BAD_ENCODING);
388 return 0;
389 }
390 ret = x942kdf_hash_kdm(impl->md, impl->secret, impl->secret_len,
391 der, der_len, ctr, key, keylen);
392 OPENSSL_free(der);
393 return ret;
394 }
395
396 const EVP_KDF x942_kdf_meth = {
397 EVP_KDF_X942,
398 x942kdf_new,
399 x942kdf_free,
400 x942kdf_reset,
401 x942kdf_ctrl,
402 x942kdf_ctrl_str,
403 x942kdf_size,
404 x942kdf_derive
405 };
406
407 #endif /* OPENSSL_NO_CMS */