Skip to content

Commit

Permalink
Enable OpenSSL's SP800-108 5.1 implementation
Browse files Browse the repository at this point in the history
Starting in 3.0, OpenSSL implements part of SP800-108, which we use as
part of KDF for the aes2 enctypes.
  • Loading branch information
frozencemetery committed Oct 4, 2019
1 parent edac33b commit b351fdc
Showing 1 changed file with 82 additions and 3 deletions.
85 changes: 82 additions & 3 deletions src/lib/crypto/krb/derive.c
Expand Up @@ -27,6 +27,12 @@

#include "crypto_int.h"

#ifdef HAVE_OPENSSL_KDFS
#include <openssl/core_names.h>
#include <openssl/evp.h>
#include <openssl/kdf.h>
#endif

static krb5_key
find_cached_dkey(struct derived_key *list, const krb5_data *constant)
{
Expand Down Expand Up @@ -204,6 +210,64 @@ derive_random_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
return ret;
}

#ifdef HAVE_OPENSSL_KDFS
krb5_error_code
openssl_kbdkf_counter_hmac(const struct krb5_hash_provider *hash,
krb5_key inkey, krb5_data *outrnd,
const krb5_data *label, const krb5_data *context)
{
krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
EVP_KDF *kdf = NULL;
EVP_KDF_CTX *kctx = NULL;
OSSL_PARAM params[6];
size_t i = 0;
char *digest;

if (!strcmp(hash->hash_name, "SHA1"))
digest = "SHA1";
else if (!strcmp(hash->hash_name, "SHA-256"))
digest = "SHA256";
else if (!strcmp(hash->hash_name, "SHA-384"))
digest = "SHA384";
else
goto done;

kdf = EVP_KDF_fetch(NULL, "KBKDF", NULL);
if (!kdf)
goto done;

kctx = EVP_KDF_CTX_new(kdf);
if (!kctx)
goto done;

params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
digest, 0);
params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC,
"HMAC", 0);
params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
inkey->keyblock.contents,
inkey->keyblock.length);
params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
context->data,
context->length);
params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
label->data,
label->length);
params[i] = OSSL_PARAM_construct_end();
if (EVP_KDF_CTX_set_params(kctx, params) <= 0) {
goto done;
} else if (EVP_KDF_derive(kctx, (unsigned char *)outrnd->data,
outrnd->length) <= 0) {
goto done;
}

ret = 0;
done:
EVP_KDF_free(kdf);
EVP_KDF_CTX_free(kctx);
return ret;
}
#else
/*
* NIST SP800-108 KDF in counter mode (section 5.1).
* Parameters:
Expand All @@ -214,9 +278,10 @@ derive_random_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
* There are no uses requiring more than a single PRF invocation.
*/
krb5_error_code
k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
krb5_key inkey, krb5_data *outrnd,
const krb5_data *label, const krb5_data *context)
builtin_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
krb5_key inkey, krb5_data *outrnd,
const krb5_data *label,
const krb5_data *context)
{
krb5_crypto_iov iov[5];
krb5_error_code ret;
Expand Down Expand Up @@ -255,6 +320,20 @@ k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
zapfree(prf.data, prf.length);
return ret;
}
#endif
krb5_error_code
k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
krb5_key inkey, krb5_data *outrnd,
const krb5_data *label, const krb5_data *context)
{
#ifdef HAVE_OPENSSL_KDFS
return openssl_kbdkf_counter_hmac(hash, inkey, outrnd, label, context);
#else
return builtin_sp800_108_counter_hmac(hash, inkey, outrnd, label,
context);
#endif
}


krb5_error_code
krb5int_derive_random(const struct krb5_enc_provider *enc,
Expand Down

0 comments on commit b351fdc

Please sign in to comment.