2 * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
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
12 #include <openssl/core_names.h>
13 #include <openssl/core_dispatch.h>
14 #include <openssl/err.h>
15 #include <openssl/evp.h>
16 #include <openssl/params.h>
17 #include "internal/packet.h"
18 #include "internal/der.h"
19 #include "prov/provider_ctx.h"
20 #include "prov/providercommon.h"
21 #include "prov/providercommonerr.h"
22 #include "prov/implementations.h"
23 #include "prov/provider_util.h"
24 #include "prov/der_wrap.h"
26 #define X942KDF_MAX_INLEN (1 << 30)
28 static OSSL_FUNC_kdf_newctx_fn x942kdf_new;
29 static OSSL_FUNC_kdf_freectx_fn x942kdf_free;
30 static OSSL_FUNC_kdf_reset_fn x942kdf_reset;
31 static OSSL_FUNC_kdf_derive_fn x942kdf_derive;
32 static OSSL_FUNC_kdf_settable_ctx_params_fn x942kdf_settable_ctx_params;
33 static OSSL_FUNC_kdf_set_ctx_params_fn x942kdf_set_ctx_params;
34 static OSSL_FUNC_kdf_gettable_ctx_params_fn x942kdf_gettable_ctx_params;
35 static OSSL_FUNC_kdf_get_ctx_params_fn x942kdf_get_ctx_params;
40 unsigned char *secret;
45 const unsigned char *cek_oid;
50 * A table of allowed wrapping algorithms, oids and the associated output
52 * NOTE: RC2wrap and camellia128_wrap have been removed as there are no
53 * corresponding ciphers for these operations.
57 const unsigned char *oid;
59 size_t keklen; /* size in bytes */
61 { "AES-128-WRAP", ossl_der_oid_id_aes128_wrap, DER_OID_SZ_id_aes128_wrap,
63 { "AES-192-WRAP", ossl_der_oid_id_aes192_wrap, DER_OID_SZ_id_aes192_wrap,
65 { "AES-256-WRAP", ossl_der_oid_id_aes256_wrap, DER_OID_SZ_id_aes256_wrap,
68 { "DES3-WRAP", ossl_der_oid_id_alg_CMS3DESwrap,
69 DER_OID_SZ_id_alg_CMS3DESwrap, 24 },
73 static int find_alg_id(OSSL_LIB_CTX *libctx, const char *algname,
74 const char *propq, size_t *id)
80 cipher = EVP_CIPHER_fetch(libctx, algname, propq);
82 for (i = 0; i < OSSL_NELEM(kek_algs); i++) {
83 if (EVP_CIPHER_is_a(cipher, kek_algs[i].name)) {
90 ERR_raise(ERR_LIB_PROV, PROV_R_UNSUPPORTED_CEK_ALG);
92 EVP_CIPHER_free(cipher);
96 static int DER_w_keyinfo(WPACKET *pkt,
97 const unsigned char *der_oid, size_t der_oidlen,
98 unsigned char **pcounter)
100 return ossl_DER_w_begin_sequence(pkt, -1)
101 /* Store the initial value of 1 into the counter */
102 && ossl_DER_w_octet_string_uint32(pkt, -1, 1)
103 /* Remember where we stored the counter in the buffer */
105 || (*pcounter = WPACKET_get_curr(pkt)) != NULL)
106 && ossl_DER_w_precompiled(pkt, -1, der_oid, der_oidlen)
107 && ossl_DER_w_end_sequence(pkt, -1);
110 static int der_encode_sharedinfo(WPACKET *pkt, unsigned char *buf, size_t buflen,
111 const unsigned char *der_oid, size_t der_oidlen,
112 const unsigned char *ukm, size_t ukmlen,
113 uint32_t keylen_bits, unsigned char **pcounter)
115 return (buf != NULL ? WPACKET_init_der(pkt, buf, buflen) :
116 WPACKET_init_null_der(pkt))
117 && ossl_DER_w_begin_sequence(pkt, -1)
118 && ossl_DER_w_octet_string_uint32(pkt, 2, keylen_bits)
119 && (ukm == NULL || ossl_DER_w_octet_string(pkt, 0, ukm, ukmlen))
120 && DER_w_keyinfo(pkt, der_oid, der_oidlen, pcounter)
121 && ossl_DER_w_end_sequence(pkt, -1)
122 && WPACKET_finish(pkt);
126 * Encode the other info structure.
128 * RFC2631 Section 2.1.2 Contains the following definition for otherinfo
130 * OtherInfo ::= SEQUENCE {
131 * keyInfo KeySpecificInfo,
132 * partyAInfo [0] OCTET STRING OPTIONAL,
133 * suppPubInfo [2] OCTET STRING
135 * Note suppPubInfo is the key length (in bits) (stored into 4 bytes)
138 * KeySpecificInfo ::= SEQUENCE {
139 * algorithm OBJECT IDENTIFIER,
140 * counter OCTET STRING SIZE (4..4)
143 * |keylen| is the length (in bytes) of the generated KEK. It is stored into
144 * suppPubInfo (in bits).
145 * |cek_oid| The oid of the key wrapping algorithm.
146 * |cek_oidlen| The length (in bytes) of the key wrapping algorithm oid,
147 * |ukm| is the optional user keying material that is stored into partyAInfo. It
149 * |ukmlen| is the user keying material length (in bytes).
150 * |der| is the returned encoded data. It must be freed by the caller.
151 * |der_len| is the returned size of the encoded data.
152 * |out_ctr| returns a pointer to the counter data which is embedded inside the
153 * encoded data. This allows the counter bytes to be updated without re-encoding.
155 * Returns: 1 if successfully encoded, or 0 otherwise.
156 * Assumptions: |der|, |der_len| & |out_ctr| are not NULL.
158 static int x942_encode_otherinfo(size_t keylen,
159 const unsigned char *cek_oid, size_t cek_oidlen,
160 const unsigned char *ukm, size_t ukmlen,
161 unsigned char **der, size_t *der_len,
162 unsigned char **out_ctr)
165 unsigned char *pcounter = NULL, *der_buf = NULL;
166 size_t der_buflen = 0;
168 uint32_t keylen_bits;
170 /* keylenbits must fit into 4 bytes */
171 if (keylen > 0xFFFFFF)
173 keylen_bits = 8 * keylen;
175 /* Calculate the size of the buffer */
176 if (!der_encode_sharedinfo(&pkt, NULL, 0, cek_oid, cek_oidlen, ukm, ukmlen,
178 || !WPACKET_get_total_written(&pkt, &der_buflen))
180 WPACKET_cleanup(&pkt);
181 /* Alloc the buffer */
182 der_buf = OPENSSL_zalloc(der_buflen);
185 /* Encode into the buffer */
186 if (!der_encode_sharedinfo(&pkt, der_buf, der_buflen, cek_oid, cek_oidlen,
187 ukm, ukmlen, keylen_bits, &pcounter))
190 * Since we allocated the exact size required, the buffer should point to the
191 * start of the alllocated buffer at this point.
193 if (WPACKET_get_curr(&pkt) != der_buf)
197 * The data for the DER encoded octet string of a 32 bit counter = 1
198 * should be 04 04 00 00 00 01
199 * So just check the header is correct and skip over it.
200 * This counter will be incremented in the kdf update loop.
203 || pcounter[0] != 0x04
204 || pcounter[1] != 0x04)
206 *out_ctr = (pcounter + 2);
208 *der_len = der_buflen;
211 WPACKET_cleanup(&pkt);
215 static int x942kdf_hash_kdm(const EVP_MD *kdf_md,
216 const unsigned char *z, size_t z_len,
217 const unsigned char *other, size_t other_len,
219 unsigned char *derived_key, size_t derived_key_len)
222 size_t counter, out_len, len = derived_key_len;
223 unsigned char mac[EVP_MAX_MD_SIZE];
224 unsigned char *out = derived_key;
225 EVP_MD_CTX *ctx = NULL, *ctx_init = NULL;
227 if (z_len > X942KDF_MAX_INLEN || other_len > X942KDF_MAX_INLEN
228 || derived_key_len > X942KDF_MAX_INLEN
229 || derived_key_len == 0) {
230 ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH);
234 hlen = EVP_MD_size(kdf_md);
237 out_len = (size_t)hlen;
239 ctx = EVP_MD_CTX_create();
240 ctx_init = EVP_MD_CTX_create();
241 if (ctx == NULL || ctx_init == NULL)
244 if (!EVP_DigestInit(ctx_init, kdf_md))
247 for (counter = 1;; counter++) {
248 /* updating the ctr modifies 4 bytes in the 'other' buffer */
249 ctr[0] = (unsigned char)((counter >> 24) & 0xff);
250 ctr[1] = (unsigned char)((counter >> 16) & 0xff);
251 ctr[2] = (unsigned char)((counter >> 8) & 0xff);
252 ctr[3] = (unsigned char)(counter & 0xff);
254 if (!EVP_MD_CTX_copy_ex(ctx, ctx_init)
255 || !EVP_DigestUpdate(ctx, z, z_len)
256 || !EVP_DigestUpdate(ctx, other, other_len))
258 if (len >= out_len) {
259 if (!EVP_DigestFinal_ex(ctx, out, NULL))
266 if (!EVP_DigestFinal_ex(ctx, mac, NULL))
268 memcpy(out, mac, len);
274 EVP_MD_CTX_free(ctx);
275 EVP_MD_CTX_free(ctx_init);
276 OPENSSL_cleanse(mac, sizeof(mac));
280 static void *x942kdf_new(void *provctx)
284 if (!ossl_prov_is_running())
287 if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)
288 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
289 ctx->provctx = provctx;
293 static void x942kdf_reset(void *vctx)
295 KDF_X942 *ctx = (KDF_X942 *)vctx;
296 void *provctx = ctx->provctx;
298 ossl_prov_digest_reset(&ctx->digest);
299 OPENSSL_clear_free(ctx->secret, ctx->secret_len);
300 OPENSSL_clear_free(ctx->ukm, ctx->ukm_len);
301 memset(ctx, 0, sizeof(*ctx));
302 ctx->provctx = provctx;
305 static void x942kdf_free(void *vctx)
307 KDF_X942 *ctx = (KDF_X942 *)vctx;
315 static int x942kdf_set_buffer(unsigned char **out, size_t *out_len,
318 if (p->data_size == 0 || p->data == NULL)
323 return OSSL_PARAM_get_octet_string(p, (void **)out, 0, out_len);
326 static size_t x942kdf_size(KDF_X942 *ctx)
329 const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
332 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
335 len = EVP_MD_size(md);
336 return (len <= 0) ? 0 : (size_t)len;
339 static int x942kdf_derive(void *vctx, unsigned char *key, size_t keylen)
341 KDF_X942 *ctx = (KDF_X942 *)vctx;
345 unsigned char *der = NULL;
348 if (!ossl_prov_is_running())
351 if (ctx->secret == NULL) {
352 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);
355 md = ossl_prov_digest_md(&ctx->digest);
357 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
360 if (ctx->cek_oid == NULL || ctx->cek_oid_len == 0) {
361 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CEK_ALG);
364 if (ctx->ukm != NULL && ctx->ukm_len >= X942KDF_MAX_INLEN) {
366 * Note the ukm length MUST be 512 bits.
367 * For backwards compatibility the old check is being done.
369 ERR_raise(ERR_LIB_PROV, PROV_R_INAVLID_UKM_LENGTH);
372 /* generate the otherinfo der */
373 if (!x942_encode_otherinfo(ctx->dkm_len,
374 ctx->cek_oid, ctx->cek_oid_len,
375 ctx->ukm, ctx->ukm_len,
376 &der, &der_len, &ctr)) {
377 ERR_raise(ERR_LIB_PROV, PROV_R_BAD_ENCODING);
380 ret = x942kdf_hash_kdm(md, ctx->secret, ctx->secret_len,
381 der, der_len, ctr, key, keylen);
386 static int x942kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
388 const OSSL_PARAM *p, *pq;
389 KDF_X942 *ctx = vctx;
390 OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx);
391 const char *propq = NULL;
394 if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
397 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL
398 || (p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL)
399 if (!x942kdf_set_buffer(&ctx->secret, &ctx->secret_len, p))
402 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_UKM)) != NULL)
403 if (!x942kdf_set_buffer(&ctx->ukm, &ctx->ukm_len, p))
406 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_CEK_ALG)) != NULL) {
407 if (p->data_type != OSSL_PARAM_UTF8_STRING)
409 pq = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_PROPERTIES);
411 * We already grab the properties during ossl_prov_digest_load_from_params()
412 * so there is no need to check the validity again..
416 if (find_alg_id(provctx, p->data, propq, &id) == 0)
418 ctx->cek_oid = kek_algs[id].oid;
419 ctx->cek_oid_len = kek_algs[id].oid_len;
420 ctx->dkm_len = kek_algs[id].keklen;
425 static const OSSL_PARAM *x942kdf_settable_ctx_params(ossl_unused void *provctx)
427 static const OSSL_PARAM known_settable_ctx_params[] = {
428 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
429 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
430 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0),
431 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),
432 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_UKM, NULL, 0),
433 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0),
436 return known_settable_ctx_params;
439 static int x942kdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
441 KDF_X942 *ctx = (KDF_X942 *)vctx;
444 if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
445 return OSSL_PARAM_set_size_t(p, x942kdf_size(ctx));
449 static const OSSL_PARAM *x942kdf_gettable_ctx_params(ossl_unused void *provctx)
451 static const OSSL_PARAM known_gettable_ctx_params[] = {
452 OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
455 return known_gettable_ctx_params;
458 const OSSL_DISPATCH ossl_kdf_x942_kdf_functions[] = {
459 { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))x942kdf_new },
460 { OSSL_FUNC_KDF_FREECTX, (void(*)(void))x942kdf_free },
461 { OSSL_FUNC_KDF_RESET, (void(*)(void))x942kdf_reset },
462 { OSSL_FUNC_KDF_DERIVE, (void(*)(void))x942kdf_derive },
463 { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
464 (void(*)(void))x942kdf_settable_ctx_params },
465 { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))x942kdf_set_ctx_params },
466 { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
467 (void(*)(void))x942kdf_gettable_ctx_params },
468 { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))x942kdf_get_ctx_params },