Commit d2ba8123 authored by Shane Lontis's avatar Shane Lontis Committed by Richard Levitte
Browse files

Added EVP_KDF (similiar to the EVP_MAC)

parent e616c11e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ SOURCE[../../libcrypto]=\
        bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
        c_allc.c c_alld.c evp_lib.c bio_ok.c \
        evp_pkey.c kdf_lib.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \
        pkey_kdf.c \
        pkey_kdf.c c_allkdf.c \
        e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \
        e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
        e_chacha20_poly1305.c cmeth_lib.c \

crypto/evp/c_allkdf.c

0 → 100644
+23 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <openssl/evp.h>
#include "internal/evp_int.h"

void openssl_add_all_kdfs_int(void)
{
    EVP_add_kdf(&pbkdf2_kdf_meth);
#ifndef OPENSSL_NO_SCRYPT
    EVP_add_kdf(&scrypt_kdf_meth);
#endif
    EVP_add_kdf(&tls1_prf_kdf_meth);
    EVP_add_kdf(&hkdf_kdf_meth);
    EVP_add_kdf(&sshkdf_kdf_meth);
    EVP_add_kdf(&ss_kdf_meth);
}
+1 −1
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ struct evp_mac_ctx_st {
} /* EVP_MAC_CTX */;

struct evp_kdf_ctx_st {
    const EVP_KDF_METHOD *kmeth;
    const EVP_KDF *meth;         /* Method structure */
    EVP_KDF_IMPL *impl;          /* Algorithm-specific data */
} /* EVP_KDF_CTX */ ;

+32 −66
Original line number Diff line number Diff line
/*
 * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright (c) 2018, Oracle and/or its affiliates.  All rights reserved.
 * Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright (c) 2018-2019, Oracle and/or its affiliates.  All rights reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
@@ -20,70 +20,37 @@
#include "internal/numbers.h"
#include "evp_locl.h"

typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);

/* This array needs to be in order of NIDs */
static const EVP_KDF_METHOD *standard_methods[] = {
    &pbkdf2_kdf_meth,
#ifndef OPENSSL_NO_SCRYPT
    &scrypt_kdf_meth,
#endif
    &tls1_prf_kdf_meth,
    &hkdf_kdf_meth,
    &sshkdf_kdf_meth,
    &ss_kdf_meth
};

DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_KDF_METHOD *, const EVP_KDF_METHOD *,
                           kmeth);

static int kmeth_cmp(const EVP_KDF_METHOD *const *a,
                     const EVP_KDF_METHOD *const *b)
EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf)
{
    return ((*a)->type - (*b)->type);
}

IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_KDF_METHOD *, const EVP_KDF_METHOD *,
                             kmeth);

static const EVP_KDF_METHOD *kdf_meth_find(int type)
{
    EVP_KDF_METHOD tmp;
    const EVP_KDF_METHOD *t = &tmp, **ret;
    EVP_KDF_CTX *ctx = OPENSSL_zalloc(sizeof(EVP_KDF_CTX));

    tmp.type = type;
    ret = OBJ_bsearch_kmeth(&t, standard_methods,
                            OSSL_NELEM(standard_methods));
    if (ret == NULL || *ret == NULL)
        return NULL;

    return *ret;
    if (ctx == NULL || (ctx->impl = kdf->new()) == NULL) {
        EVPerr(EVP_F_EVP_KDF_CTX_NEW, ERR_R_MALLOC_FAILURE);
        OPENSSL_free(ctx);
        ctx = NULL;
    } else {
        ctx->meth = kdf;
    }
    return ctx;
}

EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id)
{
    EVP_KDF_CTX *ret;
    const EVP_KDF_METHOD *kmeth;
    const EVP_KDF *kdf = EVP_get_kdfbynid(id);

    kmeth = kdf_meth_find(id);
    if (kmeth == NULL) {
        EVPerr(EVP_F_EVP_KDF_CTX_NEW_ID, EVP_R_UNSUPPORTED_ALGORITHM);
    if (kdf == NULL)
        return NULL;
    return EVP_KDF_CTX_new(kdf);
}

    ret = OPENSSL_zalloc(sizeof(*ret));
    if (ret == NULL) {
        EVPerr(EVP_F_EVP_KDF_CTX_NEW_ID, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    if (kmeth->new != NULL && (ret->impl = kmeth->new()) == NULL) {
        EVP_KDF_CTX_free(ret);
        return NULL;
int EVP_KDF_nid(const EVP_KDF *kdf)
{
    return kdf->type;
}

    ret->kmeth = kmeth;
    return ret;
const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx)
{
    return ctx->meth;
}

void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx)
@@ -91,7 +58,7 @@ void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx)
    if (ctx == NULL)
        return;

    ctx->kmeth->free(ctx->impl);
    ctx->meth->free(ctx->impl);
    OPENSSL_free(ctx);
}

@@ -100,8 +67,8 @@ void EVP_KDF_reset(EVP_KDF_CTX *ctx)
    if (ctx == NULL)
        return;

    if (ctx->kmeth->reset != NULL)
        ctx->kmeth->reset(ctx->impl);
    if (ctx->meth->reset != NULL)
        ctx->meth->reset(ctx->impl);
}

int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...)
@@ -124,7 +91,7 @@ int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args)
    if (ctx == NULL)
        return 0;

    return ctx->kmeth->ctrl(ctx->impl, cmd, args);
    return ctx->meth->ctrl(ctx->impl, cmd, args);
}

int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value)
@@ -134,12 +101,12 @@ int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value)
    if (ctx == NULL)
        return 0;

    if (ctx->kmeth->ctrl_str == NULL) {
    if (ctx->meth->ctrl_str == NULL) {
        EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
        return -2;
    }

    ret = ctx->kmeth->ctrl_str(ctx->impl, type, value);
    ret = ctx->meth->ctrl_str(ctx->impl, type, value);
    if (ret == -2)
        EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);

@@ -151,10 +118,10 @@ size_t EVP_KDF_size(EVP_KDF_CTX *ctx)
    if (ctx == NULL)
        return 0;

    if (ctx->kmeth->size == NULL)
    if (ctx->meth->size == NULL)
        return SIZE_MAX;

    return ctx->kmeth->size(ctx->impl);
    return ctx->meth->size(ctx->impl);
}

int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen)
@@ -162,6 +129,5 @@ int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen)
    if (ctx == NULL)
        return 0;

    return ctx->kmeth->derive(ctx->impl, key, keylen);
    return ctx->meth->derive(ctx->impl, key, keylen);
}
+32 −1
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/evp.h>
#include <openssl/kdf.h>
#include "internal/objects.h"
#include <openssl/x509.h>
#include "internal/evp_int.h"
@@ -71,6 +72,23 @@ int EVP_add_mac(const EVP_MAC *m)
    return r;
}

/* TODO(3.0) Is this needed after changing to providers? */
int EVP_add_kdf(const EVP_KDF *k)
{
    int r;

    if (k == NULL)
        return 0;

    r = OBJ_NAME_add(OBJ_nid2sn(k->type), OBJ_NAME_TYPE_KDF_METH,
                     (const char *)k);
    if (r == 0)
        return 0;
    r = OBJ_NAME_add(OBJ_nid2ln(k->type), OBJ_NAME_TYPE_KDF_METH,
                     (const char *)k);
    return r;
}

const EVP_CIPHER *EVP_get_cipherbyname(const char *name)
{
    const EVP_CIPHER *cp;
@@ -104,9 +122,22 @@ const EVP_MAC *EVP_get_macbyname(const char *name)
    return mp;
}

/* TODO(3.0) Is this API needed after implementing providers? */
const EVP_KDF *EVP_get_kdfbyname(const char *name)
{
    const EVP_KDF *kdf;

    if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_KDFS, NULL))
        return NULL;

    kdf = (const EVP_KDF *)OBJ_NAME_get(name, OBJ_NAME_TYPE_KDF_METH);
    return kdf;
}

void evp_cleanup_int(void)
{
    OBJ_NAME_cleanup(OBJ_NAME_TYPE_MAC_METH);
    OBJ_NAME_cleanup(OBJ_NAME_TYPE_KDF_METH);
    OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
    OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
    /*
@@ -207,6 +238,7 @@ void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *md,
    OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
}

/* TODO(3.0) Are these do_all API's needed for MAC? */
struct doall_mac {
    void *arg;
    void (*fn) (const EVP_MAC *ciph,
@@ -250,4 +282,3 @@ void EVP_MAC_do_all_sorted(void (*fn)
    dc.arg = arg;
    OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MAC_METH, do_all_mac_fn, &dc);
}
Loading