Skip to content

Commit

Permalink
fixup! Implement HKDF expand function based on RFC 8446
Browse files Browse the repository at this point in the history
Change-Id: If7fc7984b2262a8ee8558435296ac8512d4cc33a
  • Loading branch information
schwabe committed Nov 21, 2024
1 parent 0908ec4 commit 03b4575
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 3 deletions.
12 changes: 9 additions & 3 deletions src/openvpn/crypto_epoch.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,20 @@ ovpn_expand_label(const uint8_t *secret, size_t secret_len,
}

struct gc_arena gc = gc_new();
/* 2 byte for the outlen encoded as uint16, 5 bytes for "ovpn " */
int hkdf_label_len = 2 + 5 + label_len + context_len;
/* 2 byte for the outlen encoded as uint16, 5 bytes for "ovpn ",
* 1 byte for context len byte and 1 byte for label len byte */
int hkdf_label_len = 2 + 5 + label_len + 1 + context_len;
struct buffer hkdf_label = alloc_buf_gc(hkdf_label_len, &gc);

const uint8_t *label_prefix = (const uint8_t *) ("ovpn ");
int prefix_len = 5;

buf_write_u16(&hkdf_label, out_len);
buf_write(&hkdf_label, "ovpn ", 5);
buf_write_u8(&hkdf_label, prefix_len + label_len);
buf_write(&hkdf_label, label_prefix, prefix_len);
buf_write(&hkdf_label, label, label_len);

buf_write_u8(&hkdf_label, context_len);
if (context_len > 0)
{
buf_write(&hkdf_label, context, context_len);
Expand Down
76 changes: 76 additions & 0 deletions tests/unit_tests/openvpn/test_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@
#include "mss.h"
#include "test_common.h"


#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/core_names.h>
#include <openssl/kdf.h>
#endif

static const char testtext[] = "Dummy text to test PEM encoding";

static void
Expand Down Expand Up @@ -586,6 +592,75 @@ crypto_test_ovpn_label_expand(void **state)
assert_memory_equal(out, out_expected, 16);
}

void
crypto_test_ovpn_expand_openssl3(void **state)
{
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
OSSL_LIB_CTX *libctx = NULL;
const char *properties = NULL;

uint8_t secret[32] =
{0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf,
0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63,
0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5};

const uint8_t *label_prefix = (const uint8_t *) ("ovpn ");
const size_t label_prefix_len = 5;
const uint8_t *label = (const uint8_t *) ("unit test");
const size_t labellen = 9;
uint8_t out[27];
size_t outlen = sizeof(out);

EVP_KDF *kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_TLS1_3_KDF, properties);
assert_non_null(kdf);

const char *mdname = "SHA-256";

size_t hashlen = SHA256_DIGEST_LENGTH;

EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf);
assert_non_null(kctx);

OSSL_PARAM params[7];
OSSL_PARAM *p = params;

int mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY;

*p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
(char *) mdname, 0);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
(unsigned char *) secret, hashlen);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX,
(unsigned char *) label_prefix,
label_prefix_len);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL,
(unsigned char *) label, labellen);

/*
* *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_DATA,
* (unsigned char *)data,
* datalen);
*/
*p++ = OSSL_PARAM_construct_end();

int ret = EVP_KDF_derive(kctx, out, outlen, params);
EVP_KDF_CTX_free(kctx);

assert_int_equal(ret, 1);

/* Do the same derivation with our own function */
uint8_t out_ovpn[27];

ovpn_expand_label(secret, sizeof(secret), label, 9, NULL, 0, out_ovpn, sizeof(out_ovpn));
assert_memory_equal(out_ovpn, out, sizeof(out_ovpn));

#else /* if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L */
skip();
#endif /* if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L */
}

struct epoch_test_state
{
struct key_type kt;
Expand Down Expand Up @@ -831,6 +906,7 @@ main(void)
cmocka_unit_test(crypto_test_hkdf_expand_testa2),
cmocka_unit_test(crypto_test_hkdf_expand_testa3),
cmocka_unit_test(crypto_test_ovpn_label_expand),
cmocka_unit_test(crypto_test_ovpn_expand_openssl3),
cmocka_unit_test_prestate_setup_teardown(crypto_test_epoch_key_generation,
crypto_test_epoch_setup,
crypto_test_epoch_teardown,
Expand Down

0 comments on commit 03b4575

Please sign in to comment.