Providers: move common exchange,kdfs,keymgmt,macs,signature
authorRichard Levitte <levitte@openssl.org>
Fri, 4 Oct 2019 08:24:09 +0000 (10:24 +0200)
committerRichard Levitte <levitte@openssl.org>
Thu, 10 Oct 2019 12:12:15 +0000 (14:12 +0200)
From providers/common/ to providers/implementations/

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10088)

43 files changed:
providers/build.info
providers/common/build.info
providers/common/exchange/build.info [deleted file]
providers/common/exchange/dh_exch.c [deleted file]
providers/common/kdfs/build.info [deleted file]
providers/common/kdfs/hkdf.c [deleted file]
providers/common/kdfs/kbkdf.c [deleted file]
providers/common/kdfs/pbkdf2.c [deleted file]
providers/common/kdfs/pbkdf2.h [deleted file]
providers/common/kdfs/pbkdf2_fips.c [deleted file]
providers/common/kdfs/sskdf.c [deleted file]
providers/common/kdfs/tls1_prf.c [deleted file]
providers/common/keymgmt/build.info [deleted file]
providers/common/keymgmt/dh_kmgmt.c [deleted file]
providers/common/keymgmt/dsa_kmgmt.c [deleted file]
providers/common/macs/build.info [deleted file]
providers/common/macs/cmac_prov.c [deleted file]
providers/common/macs/gmac_prov.c [deleted file]
providers/common/macs/hmac_prov.c [deleted file]
providers/common/macs/kmac_prov.c [deleted file]
providers/common/signature/build.info [deleted file]
providers/common/signature/dsa.c [deleted file]
providers/implementations/build.info [new file with mode: 0644]
providers/implementations/exchange/build.info [new file with mode: 0644]
providers/implementations/exchange/dh_exch.c [new file with mode: 0644]
providers/implementations/kdfs/build.info [new file with mode: 0644]
providers/implementations/kdfs/hkdf.c [new file with mode: 0644]
providers/implementations/kdfs/kbkdf.c [new file with mode: 0644]
providers/implementations/kdfs/pbkdf2.c [new file with mode: 0644]
providers/implementations/kdfs/pbkdf2.h [new file with mode: 0644]
providers/implementations/kdfs/pbkdf2_fips.c [new file with mode: 0644]
providers/implementations/kdfs/sskdf.c [new file with mode: 0644]
providers/implementations/kdfs/tls1_prf.c [new file with mode: 0644]
providers/implementations/keymgmt/build.info [new file with mode: 0644]
providers/implementations/keymgmt/dh_kmgmt.c [new file with mode: 0644]
providers/implementations/keymgmt/dsa_kmgmt.c [new file with mode: 0644]
providers/implementations/macs/build.info [new file with mode: 0644]
providers/implementations/macs/cmac_prov.c [new file with mode: 0644]
providers/implementations/macs/gmac_prov.c [new file with mode: 0644]
providers/implementations/macs/hmac_prov.c [new file with mode: 0644]
providers/implementations/macs/kmac_prov.c [new file with mode: 0644]
providers/implementations/signature/build.info [new file with mode: 0644]
providers/implementations/signature/dsa.c [new file with mode: 0644]

index e951c6229db65fe2f23d0a99fda3d7fef75b3545..973adac5c74992479f9abd124d9793175c14e107 100644 (file)
@@ -28,7 +28,7 @@
 #                       FIPS_MODE undefined.  The default and legacy
 #                       providers use this.
 
-SUBDIRS=common default
+SUBDIRS=common default implementations
 
 INCLUDE[../libcrypto]=common/include
 
index 95c2fd107e22e301c65d0dc5912f3daef55486f5..4e662eb97a6a7c565739cbf344262856c53afde3 100644 (file)
@@ -1,4 +1,4 @@
-SUBDIRS=digests ciphers macs kdfs exchange keymgmt signature
+SUBDIRS=digests ciphers
 
 SOURCE[../libcommon.a]=provider_err.c provlib.c
 $FIPSCOMMON=provider_util.c
diff --git a/providers/common/exchange/build.info b/providers/common/exchange/build.info
deleted file mode 100644 (file)
index 90ea0c9..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-$GOAL=../../libimplementations.a
-
-IF[{- !$disabled{dh} -}]
-  SOURCE[$GOAL]=dh_exch.c
-ENDIF
diff --git a/providers/common/exchange/dh_exch.c b/providers/common/exchange/dh_exch.c
deleted file mode 100644 (file)
index cfbda43..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * 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/crypto.h>
-#include <openssl/core_numbers.h>
-#include <openssl/core_names.h>
-#include <openssl/dh.h>
-#include <openssl/params.h>
-#include "internal/provider_algs.h"
-
-static OSSL_OP_keyexch_newctx_fn dh_newctx;
-static OSSL_OP_keyexch_init_fn dh_init;
-static OSSL_OP_keyexch_set_peer_fn dh_set_peer;
-static OSSL_OP_keyexch_derive_fn dh_derive;
-static OSSL_OP_keyexch_freectx_fn dh_freectx;
-static OSSL_OP_keyexch_dupctx_fn dh_dupctx;
-static OSSL_OP_keyexch_set_ctx_params_fn dh_set_ctx_params;
-static OSSL_OP_keyexch_settable_ctx_params_fn dh_settable_ctx_params;
-
-/*
- * What's passed as an actual key is defined by the KEYMGMT interface.
- * We happen to know that our KEYMGMT simply passes DH structures, so
- * we use that here too.
- */
-
-typedef struct {
-    DH *dh;
-    DH *dhpeer;
-    unsigned int pad : 1;
-} PROV_DH_CTX;
-
-static void *dh_newctx(void *provctx)
-{
-    return OPENSSL_zalloc(sizeof(PROV_DH_CTX));
-}
-
-static int dh_init(void *vpdhctx, void *vdh)
-{
-    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
-
-    if (pdhctx == NULL || vdh == NULL || !DH_up_ref(vdh))
-        return 0;
-    DH_free(pdhctx->dh);
-    pdhctx->dh = vdh;
-    return 1;
-}
-
-static int dh_set_peer(void *vpdhctx, void *vdh)
-{
-    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
-
-    if (pdhctx == NULL || vdh == NULL || !DH_up_ref(vdh))
-        return 0;
-    DH_free(pdhctx->dhpeer);
-    pdhctx->dhpeer = vdh;
-    return 1;
-}
-
-static int dh_derive(void *vpdhctx, unsigned char *secret, size_t *secretlen,
-                     size_t outlen)
-{
-    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
-    int ret;
-    size_t dhsize;
-    const BIGNUM *pub_key = NULL;
-
-    /* TODO(3.0): Add errors to stack */
-    if (pdhctx->dh == NULL || pdhctx->dhpeer == NULL)
-        return 0;
-
-    dhsize = (size_t)DH_size(pdhctx->dh);
-    if (secret == NULL) {
-        *secretlen = dhsize;
-        return 1;
-    }
-    if (outlen < dhsize)
-        return 0;
-
-    DH_get0_key(pdhctx->dhpeer, &pub_key, NULL);
-    ret = (pdhctx->pad) ? DH_compute_key_padded(secret, pub_key, pdhctx->dh)
-                        : DH_compute_key(secret, pub_key, pdhctx->dh);
-    if (ret <= 0)
-        return 0;
-
-    *secretlen = ret;
-    return 1;
-}
-
-static void dh_freectx(void *vpdhctx)
-{
-    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
-
-    DH_free(pdhctx->dh);
-    DH_free(pdhctx->dhpeer);
-
-    OPENSSL_free(pdhctx);
-}
-
-static void *dh_dupctx(void *vpdhctx)
-{
-    PROV_DH_CTX *srcctx = (PROV_DH_CTX *)vpdhctx;
-    PROV_DH_CTX *dstctx;
-
-    dstctx = OPENSSL_zalloc(sizeof(*srcctx));
-    if (dstctx == NULL)
-        return NULL;
-
-    *dstctx = *srcctx;
-    if (dstctx->dh != NULL && !DH_up_ref(dstctx->dh)) {
-        OPENSSL_free(dstctx);
-        return NULL;
-    }
-
-    if (dstctx->dhpeer != NULL && !DH_up_ref(dstctx->dhpeer)) {
-        DH_free(dstctx->dh);
-        OPENSSL_free(dstctx);
-        return NULL;
-    }
-
-    return dstctx;
-}
-
-static int dh_set_ctx_params(void *vpdhctx, const OSSL_PARAM params[])
-{
-    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
-    const OSSL_PARAM *p;
-    unsigned int pad;
-
-    if (pdhctx == NULL || params == NULL)
-        return 0;
-
-    p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_PAD);
-    if (p == NULL || !OSSL_PARAM_get_uint(p, &pad))
-        return 0;
-    pdhctx->pad = pad ? 1 : 0;
-    return 1;
-}
-
-static const OSSL_PARAM known_settable_ctx_params[] = {
-    OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD, NULL),
-    OSSL_PARAM_END
-};
-
-static const OSSL_PARAM *dh_settable_ctx_params(void)
-{
-    return known_settable_ctx_params;
-}
-
-const OSSL_DISPATCH dh_keyexch_functions[] = {
-    { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))dh_newctx },
-    { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))dh_init },
-    { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))dh_derive },
-    { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))dh_set_peer },
-    { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))dh_freectx },
-    { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))dh_dupctx },
-    { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))dh_set_ctx_params },
-    { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS,
-      (void (*)(void))dh_settable_ctx_params },
-    { 0, NULL }
-};
diff --git a/providers/common/kdfs/build.info b/providers/common/kdfs/build.info
deleted file mode 100644 (file)
index b2b354d..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-$GOAL=../../libimplementations.a
-
-SOURCE[$GOAL]=tls1_prf.c hkdf.c kbkdf.c pbkdf2.c sskdf.c
-SOURCE[../../libfips.a]=pbkdf2_fips.c
-SOURCE[../../libnonfips.a]=pbkdf2_fips.c
diff --git a/providers/common/kdfs/hkdf.c b/providers/common/kdfs/hkdf.c
deleted file mode 100644 (file)
index 041811f..0000000
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * Copyright 2016-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 <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <openssl/hmac.h>
-#include <openssl/evp.h>
-#include <openssl/kdf.h>
-#include <openssl/core_names.h>
-#include "internal/cryptlib.h"
-#include "internal/numbers.h"
-#include "crypto/evp.h"
-#include "internal/provider_ctx.h"
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_util.h"
-#include "e_os.h"
-
-#define HKDF_MAXBUF 1024
-
-static OSSL_OP_kdf_newctx_fn kdf_hkdf_new;
-static OSSL_OP_kdf_freectx_fn kdf_hkdf_free;
-static OSSL_OP_kdf_reset_fn kdf_hkdf_reset;
-static OSSL_OP_kdf_derive_fn kdf_hkdf_derive;
-static OSSL_OP_kdf_settable_ctx_params_fn kdf_hkdf_settable_ctx_params;
-static OSSL_OP_kdf_set_ctx_params_fn kdf_hkdf_set_ctx_params;
-static OSSL_OP_kdf_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params;
-static OSSL_OP_kdf_get_ctx_params_fn kdf_hkdf_get_ctx_params;
-
-static int HKDF(const EVP_MD *evp_md,
-                const unsigned char *salt, size_t salt_len,
-                const unsigned char *key, size_t key_len,
-                const unsigned char *info, size_t info_len,
-                unsigned char *okm, size_t okm_len);
-static int HKDF_Extract(const EVP_MD *evp_md,
-                        const unsigned char *salt, size_t salt_len,
-                        const unsigned char *ikm, size_t ikm_len,
-                        unsigned char *prk, size_t prk_len);
-static int HKDF_Expand(const EVP_MD *evp_md,
-                       const unsigned char *prk, size_t prk_len,
-                       const unsigned char *info, size_t info_len,
-                       unsigned char *okm, size_t okm_len);
-
-typedef struct {
-    void *provctx;
-    int mode;
-    PROV_DIGEST digest;
-    unsigned char *salt;
-    size_t salt_len;
-    unsigned char *key;
-    size_t key_len;
-    unsigned char info[HKDF_MAXBUF];
-    size_t info_len;
-} KDF_HKDF;
-
-static void *kdf_hkdf_new(void *provctx)
-{
-    KDF_HKDF *ctx;
-
-    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-    else
-        ctx->provctx = provctx;
-    return ctx;
-}
-
-static void kdf_hkdf_free(void *vctx)
-{
-    KDF_HKDF *ctx = (KDF_HKDF *)vctx;
-
-    kdf_hkdf_reset(ctx);
-    OPENSSL_free(ctx);
-}
-
-static void kdf_hkdf_reset(void *vctx)
-{
-    KDF_HKDF *ctx = (KDF_HKDF *)vctx;
-
-    ossl_prov_digest_reset(&ctx->digest);
-    OPENSSL_free(ctx->salt);
-    OPENSSL_clear_free(ctx->key, ctx->key_len);
-    OPENSSL_cleanse(ctx->info, ctx->info_len);
-    memset(ctx, 0, sizeof(*ctx));
-}
-
-static size_t kdf_hkdf_size(KDF_HKDF *ctx)
-{
-    int sz;
-    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
-
-    if (ctx->mode != EVP_KDF_HKDF_MODE_EXTRACT_ONLY)
-        return SIZE_MAX;
-
-    if (md == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
-        return 0;
-    }
-    sz = EVP_MD_size(md);
-    if (sz < 0)
-        return 0;
-
-    return sz;
-}
-
-static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen)
-{
-    KDF_HKDF *ctx = (KDF_HKDF *)vctx;
-    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
-
-    if (md == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
-        return 0;
-    }
-    if (ctx->key == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY);
-        return 0;
-    }
-
-    switch (ctx->mode) {
-    case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
-        return HKDF(md, ctx->salt, ctx->salt_len, ctx->key,
-                    ctx->key_len, ctx->info, ctx->info_len, key,
-                    keylen);
-
-    case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:
-        return HKDF_Extract(md, ctx->salt, ctx->salt_len, ctx->key,
-                            ctx->key_len, key, keylen);
-
-    case EVP_KDF_HKDF_MODE_EXPAND_ONLY:
-        return HKDF_Expand(md, ctx->key, ctx->key_len, ctx->info,
-                           ctx->info_len, key, keylen);
-
-    default:
-        return 0;
-    }
-}
-
-static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    const OSSL_PARAM *p;
-    KDF_HKDF *ctx = vctx;
-    OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
-    int n;
-
-    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
-        return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MODE)) != NULL) {
-        if (p->data_type == OSSL_PARAM_UTF8_STRING) {
-            if (strcasecmp(p->data, "EXTRACT_AND_EXPAND") == 0) {
-                ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND;
-            } else if (strcasecmp(p->data, "EXTRACT_ONLY") == 0) {
-                ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY;
-            } else if (strcasecmp(p->data, "EXPAND_ONLY") == 0) {
-                ctx->mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY;
-            } else {
-                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
-                return 0;
-            }
-        } else if (OSSL_PARAM_get_int(p, &n)) {
-            if (n != EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND
-                && n != EVP_KDF_HKDF_MODE_EXTRACT_ONLY
-                && n != EVP_KDF_HKDF_MODE_EXPAND_ONLY) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
-                return 0;
-            }
-            ctx->mode = n;
-        } else {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
-            return 0;
-        }
-    }
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL) {
-        OPENSSL_clear_free(ctx->key, ctx->key_len);
-        ctx->key = NULL;
-        if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->key, 0,
-                                         &ctx->key_len))
-            return 0;
-    }
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) {
-        if (p->data_size != 0 && p->data != NULL) {
-            OPENSSL_free(ctx->salt);
-            ctx->salt = NULL;
-            if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0,
-                                             &ctx->salt_len))
-                return 0;
-        }
-    }
-    /* The info fields concatenate, so process them all */
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO)) != NULL) {
-        ctx->info_len = 0;
-        for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1,
-                                                      OSSL_KDF_PARAM_INFO)) {
-            const void *q = ctx->info + ctx->info_len;
-            size_t sz = 0;
-
-            if (p->data_size != 0
-                && p->data != NULL
-                && !OSSL_PARAM_get_octet_string(p, (void **)&q,
-                                                HKDF_MAXBUF - ctx->info_len,
-                                                &sz))
-                return 0;
-            ctx->info_len += sz;
-        }
-    }
-    return 1;
-}
-
-static const OSSL_PARAM *kdf_hkdf_settable_ctx_params(void)
-{
-    static const OSSL_PARAM known_settable_ctx_params[] = {
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0),
-        OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL),
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
-        OSSL_PARAM_END
-    };
-    return known_settable_ctx_params;
-}
-
-static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
-{
-    KDF_HKDF *ctx = (KDF_HKDF *)vctx;
-    OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
-        return OSSL_PARAM_set_size_t(p, kdf_hkdf_size(ctx));
-    return -2;
-}
-
-static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(void)
-{
-    static const OSSL_PARAM known_gettable_ctx_params[] = {
-        OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
-        OSSL_PARAM_END
-    };
-    return known_gettable_ctx_params;
-}
-
-const OSSL_DISPATCH kdf_hkdf_functions[] = {
-    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_hkdf_new },
-    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_hkdf_free },
-    { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_hkdf_reset },
-    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_hkdf_derive },
-    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
-      (void(*)(void))kdf_hkdf_settable_ctx_params },
-    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_hkdf_set_ctx_params },
-    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
-      (void(*)(void))kdf_hkdf_gettable_ctx_params },
-    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_hkdf_get_ctx_params },
-    { 0, NULL }
-};
-
-/*
- * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"
- * Section 2 (https://tools.ietf.org/html/rfc5869#section-2) and
- * "Cryptographic Extraction and Key Derivation: The HKDF Scheme"
- * Section 4.2 (https://eprint.iacr.org/2010/264.pdf).
- *
- * From the paper:
- *   The scheme HKDF is specified as:
- *     HKDF(XTS, SKM, CTXinfo, L) = K(1) | K(2) | ... | K(t)
- *
- *     where:
- *       SKM is source key material
- *       XTS is extractor salt (which may be null or constant)
- *       CTXinfo is context information (may be null)
- *       L is the number of key bits to be produced by KDF
- *       k is the output length in bits of the hash function used with HMAC
- *       t = ceil(L/k)
- *       the value K(t) is truncated to its first d = L mod k bits.
- *
- * From RFC 5869:
- *   2.2.  Step 1: Extract
- *     HKDF-Extract(salt, IKM) -> PRK
- *   2.3.  Step 2: Expand
- *     HKDF-Expand(PRK, info, L) -> OKM
- */
-static int HKDF(const EVP_MD *evp_md,
-                const unsigned char *salt, size_t salt_len,
-                const unsigned char *ikm, size_t ikm_len,
-                const unsigned char *info, size_t info_len,
-                unsigned char *okm, size_t okm_len)
-{
-    unsigned char prk[EVP_MAX_MD_SIZE];
-    int ret, sz;
-    size_t prk_len;
-
-    sz = EVP_MD_size(evp_md);
-    if (sz < 0)
-        return 0;
-    prk_len = (size_t)sz;
-
-    /* Step 1: HKDF-Extract(salt, IKM) -> PRK */
-    if (!HKDF_Extract(evp_md, salt, salt_len, ikm, ikm_len, prk, prk_len))
-        return 0;
-
-    /* Step 2: HKDF-Expand(PRK, info, L) -> OKM */
-    ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);
-    OPENSSL_cleanse(prk, sizeof(prk));
-
-    return ret;
-}
-
-/*
- * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"
- * Section 2.2 (https://tools.ietf.org/html/rfc5869#section-2.2).
- *
- * 2.2.  Step 1: Extract
- *
- *   HKDF-Extract(salt, IKM) -> PRK
- *
- *   Options:
- *      Hash     a hash function; HashLen denotes the length of the
- *               hash function output in octets
- *
- *   Inputs:
- *      salt     optional salt value (a non-secret random value);
- *               if not provided, it is set to a string of HashLen zeros.
- *      IKM      input keying material
- *
- *   Output:
- *      PRK      a pseudorandom key (of HashLen octets)
- *
- *   The output PRK is calculated as follows:
- *
- *   PRK = HMAC-Hash(salt, IKM)
- */
-static int HKDF_Extract(const EVP_MD *evp_md,
-                        const unsigned char *salt, size_t salt_len,
-                        const unsigned char *ikm, size_t ikm_len,
-                        unsigned char *prk, size_t prk_len)
-{
-    int sz = EVP_MD_size(evp_md);
-
-    if (sz < 0)
-        return 0;
-    if (prk_len != (size_t)sz) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_OUTPUT_BUFFER_SIZE);
-        return 0;
-    }
-    /* calc: PRK = HMAC-Hash(salt, IKM) */
-    return HMAC(evp_md, salt, salt_len, ikm, ikm_len, prk, NULL) != NULL;
-}
-
-/*
- * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"
- * Section 2.3 (https://tools.ietf.org/html/rfc5869#section-2.3).
- *
- * 2.3.  Step 2: Expand
- *
- *   HKDF-Expand(PRK, info, L) -> OKM
- *
- *   Options:
- *      Hash     a hash function; HashLen denotes the length of the
- *               hash function output in octets
- *
- *   Inputs:
- *      PRK      a pseudorandom key of at least HashLen octets
- *               (usually, the output from the extract step)
- *      info     optional context and application specific information
- *               (can be a zero-length string)
- *      L        length of output keying material in octets
- *               (<= 255*HashLen)
- *
- *   Output:
- *      OKM      output keying material (of L octets)
- *
- *   The output OKM is calculated as follows:
- *
- *   N = ceil(L/HashLen)
- *   T = T(1) | T(2) | T(3) | ... | T(N)
- *   OKM = first L octets of T
- *
- *   where:
- *   T(0) = empty string (zero length)
- *   T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
- *   T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
- *   T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
- *   ...
- *
- *   (where the constant concatenated to the end of each T(n) is a
- *   single octet.)
- */
-static int HKDF_Expand(const EVP_MD *evp_md,
-                       const unsigned char *prk, size_t prk_len,
-                       const unsigned char *info, size_t info_len,
-                       unsigned char *okm, size_t okm_len)
-{
-    HMAC_CTX *hmac;
-    int ret = 0, sz;
-    unsigned int i;
-    unsigned char prev[EVP_MAX_MD_SIZE];
-    size_t done_len = 0, dig_len, n;
-
-    sz = EVP_MD_size(evp_md);
-    if (sz <= 0)
-        return 0;
-    dig_len = (size_t)sz;
-
-    /* calc: N = ceil(L/HashLen) */
-    n = okm_len / dig_len;
-    if (okm_len % dig_len)
-        n++;
-
-    if (n > 255 || okm == NULL)
-        return 0;
-
-    if ((hmac = HMAC_CTX_new()) == NULL)
-        return 0;
-
-    if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL))
-        goto err;
-
-    for (i = 1; i <= n; i++) {
-        size_t copy_len;
-        const unsigned char ctr = i;
-
-        /* calc: T(i) = HMAC-Hash(PRK, T(i - 1) | info | i) */
-        if (i > 1) {
-            if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL))
-                goto err;
-
-            if (!HMAC_Update(hmac, prev, dig_len))
-                goto err;
-        }
-
-        if (!HMAC_Update(hmac, info, info_len))
-            goto err;
-
-        if (!HMAC_Update(hmac, &ctr, 1))
-            goto err;
-
-        if (!HMAC_Final(hmac, prev, NULL))
-            goto err;
-
-        copy_len = (done_len + dig_len > okm_len) ?
-                       okm_len - done_len :
-                       dig_len;
-
-        memcpy(okm + done_len, prev, copy_len);
-
-        done_len += copy_len;
-    }
-    ret = 1;
-
- err:
-    OPENSSL_cleanse(prev, sizeof(prev));
-    HMAC_CTX_free(hmac);
-    return ret;
-}
diff --git a/providers/common/kdfs/kbkdf.c b/providers/common/kdfs/kbkdf.c
deleted file mode 100644 (file)
index ffffef0..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
- * Copyright 2019 Red Hat, Inc.
- *
- * 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
- */
-
-/*
- * This implements https://csrc.nist.gov/publications/detail/sp/800-108/final
- * section 5.1 ("counter mode") in HMAC only.  That document does not name the
- * KDFs it defines; the name is derived from
- * https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/Key-Derivation
- *
- * Note that sections 5.2 ("feedback mode") and 5.3 ("double-pipeline mode")
- * are not implemented, though it would be possible to do so in the future.
- * CMAC mode is also not implemented; some plumbing would be required.
- *
- * These versions all assume the counter is used.  It would be relatively
- * straightforward to expose a configuration handle should the need arise.
- *
- * Variable names attempt to match those of SP800-108.
- */
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <openssl/core_names.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/kdf.h>
-#include <openssl/params.h>
-
-#include "internal/cryptlib.h"
-#include "crypto/evp.h"
-#include "internal/numbers.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
-#include "internal/provider_util.h"
-#include "internal/providercommonerr.h"
-
-#include "e_os.h"
-
-#define MIN(a, b) ((a) < (b)) ? (a) : (b)
-
-/* Our context structure. */
-typedef struct {
-    void *provctx;
-    EVP_MAC_CTX *ctx_init;
-
-    /* Names are lowercased versions of those found in SP800-108. */
-    unsigned char *ki;
-    size_t ki_len;
-    unsigned char *label;
-    size_t label_len;
-    unsigned char *context;
-    size_t context_len;
-} KBKDF;
-
-/* Definitions needed for typechecking. */
-static OSSL_OP_kdf_newctx_fn kbkdf_new;
-static OSSL_OP_kdf_freectx_fn kbkdf_free;
-static OSSL_OP_kdf_reset_fn kbkdf_reset;
-static OSSL_OP_kdf_derive_fn kbkdf_derive;
-static OSSL_OP_kdf_settable_ctx_params_fn kbkdf_settable_ctx_params;
-static OSSL_OP_kdf_set_ctx_params_fn kbkdf_set_ctx_params;
-
-/* Not all platforms have htobe32(). */
-static uint32_t be32(uint32_t host)
-{
-    uint32_t big = 0;
-    const union {
-        long one;
-        char little;
-    } is_endian = { 1 };
-
-    if (!is_endian.little)
-        return host;
-
-    big |= (host & 0xff000000) >> 24;
-    big |= (host & 0x00ff0000) >> 8;
-    big |= (host & 0x0000ff00) << 8;
-    big |= (host & 0x000000ff) << 24;
-    return big;
-}
-
-static void *kbkdf_new(void *provctx)
-{
-    KBKDF *ctx;
-
-    ctx = OPENSSL_zalloc(sizeof(*ctx));
-    if (ctx == NULL) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-        return NULL;
-    }
-
-    ctx->provctx = provctx;
-    return ctx;
-}
-
-static void kbkdf_free(void *vctx)
-{
-    KBKDF *ctx = (KBKDF *)vctx;
-
-    kbkdf_reset(ctx);
-    OPENSSL_free(ctx);
-}
-
-static void kbkdf_reset(void *vctx)
-{
-    KBKDF *ctx = (KBKDF *)vctx;
-
-    EVP_MAC_CTX_free(ctx->ctx_init);
-    OPENSSL_clear_free(ctx->context, ctx->context_len);
-    OPENSSL_clear_free(ctx->label, ctx->label_len);
-    OPENSSL_clear_free(ctx->ki, ctx->ki_len);
-    memset(ctx, 0, sizeof(*ctx));
-}
-
-/* SP800-108 section 5.1. */
-static int kbkdf_derive_counter(EVP_MAC_CTX *ctx_init,
-                                unsigned char *label, size_t label_len,
-                                unsigned char *context, size_t context_len,
-                                unsigned char *k_i, size_t h, uint32_t l,
-                                unsigned char *ko, size_t ko_len)
-{
-    int ret = 0;
-    EVP_MAC_CTX *ctx = NULL;
-    size_t written = 0, to_write;
-    const unsigned char zero = 0;
-    uint32_t counter, i;
-
-    for (counter = 1; written < ko_len; counter++) {
-        i = be32(counter);
-
-        ctx = EVP_MAC_CTX_dup(ctx_init);
-        if (ctx == NULL)
-            goto done;
-
-        if (!EVP_MAC_update(ctx, (unsigned char *)&i, 4)
-            || !EVP_MAC_update(ctx, label, label_len)
-            || !EVP_MAC_update(ctx, &zero, 1)
-            || !EVP_MAC_update(ctx, context, context_len)
-            || !EVP_MAC_update(ctx, (unsigned char *)&l, 4)
-            || !EVP_MAC_final(ctx, k_i, NULL, h))
-            goto done;
-
-        to_write = ko_len - written;
-        memcpy(ko + written, k_i, MIN(to_write, h));
-        written += h;
-
-        EVP_MAC_CTX_free(ctx);
-        ctx = NULL;
-    }
-
-    ret = 1;
-done:
-    EVP_MAC_CTX_free(ctx);
-    return ret;
-}
-
-static int kbkdf_derive(void *vctx, unsigned char *key, size_t keylen)
-{
-    KBKDF *ctx = (KBKDF *)vctx;
-    int ret = 0;
-    unsigned char *k_i = NULL;
-    uint32_t l = be32(keylen * 8);
-    size_t h = 0;
-
-    /* Label and Context are permitted to be empty. Check everything else. */
-    if (ctx->ctx_init == NULL) {
-        if (ctx->ki_len == 0 || ctx->ki == NULL) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
-            return 0;
-        }
-        /* Could either be missing MAC or missing message digest -
-         * arbitrarily, I pick this one. */
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MAC);
-        return 0;
-    }
-
-    h = EVP_MAC_size(ctx->ctx_init);
-    if (h == 0)
-        goto done;
-
-    k_i = OPENSSL_zalloc(h);
-    if (k_i == NULL)
-        goto done;
-
-    ret = kbkdf_derive_counter(
-        ctx->ctx_init, ctx->label, ctx->label_len, ctx->context,
-        ctx->context_len, k_i, h, l, key, keylen);
-done:
-    if (ret != 1)
-        OPENSSL_cleanse(key, keylen);
-    OPENSSL_clear_free(k_i, h);
-    return ret;
-}
-
-static int kbkdf_set_buffer(unsigned char **out, size_t *out_len,
-                            const OSSL_PARAM *p)
-{
-    if (p->data == NULL || p->data_size == 0)
-        return 1;
-
-    OPENSSL_clear_free(*out, *out_len);
-    *out = NULL;
-    return OSSL_PARAM_get_octet_string(p, (void **)out, 0, out_len);
-}
-
-static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    KBKDF *ctx = (KBKDF *)vctx;
-    OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
-    const OSSL_PARAM *p;
-    OSSL_PARAM mparams[2];
-
-    if (!ossl_prov_macctx_load_from_params(&ctx->ctx_init, params, NULL,
-                                           NULL, NULL, libctx))
-        return 0;
-    else if (ctx->ctx_init != NULL
-        && !EVP_MAC_is_a(EVP_MAC_CTX_mac(ctx->ctx_init),
-                         OSSL_MAC_NAME_HMAC)) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MAC);
-        return 0;
-    }
-
-    p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY);
-    if (p != NULL && !kbkdf_set_buffer(&ctx->ki, &ctx->ki_len, p))
-        return 0;
-
-    p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT);
-    if (p != NULL && !kbkdf_set_buffer(&ctx->label, &ctx->label_len, p))
-        return 0;
-
-    p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO);
-    if (p != NULL && !kbkdf_set_buffer(&ctx->context, &ctx->context_len, p))
-        return 0;
-
-    /* Set up digest context, if we can. */
-    if (ctx->ctx_init != NULL && ctx->ki_len != 0) {
-        mparams[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
-                                                       ctx->ki, ctx->ki_len);
-        mparams[1] = OSSL_PARAM_construct_end();
-
-        if (!EVP_MAC_CTX_set_params(ctx->ctx_init, mparams)
-            || !EVP_MAC_init(ctx->ctx_init))
-            return 0;
-    }
-
-    return 1;
-}
-
-static const OSSL_PARAM *kbkdf_settable_ctx_params(void)
-{
-    static const OSSL_PARAM known_settable_ctx_params[] = {
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MAC, NULL, 0),
-
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
-        OSSL_PARAM_END,
-    };
-    return known_settable_ctx_params;
-}
-
-static int kbkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
-{
-    OSSL_PARAM *p;
-
-    p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE);
-    if (p == NULL)
-        return -2;
-
-    /* KBKDF can produce results as large as you like. */
-    return OSSL_PARAM_set_size_t(p, SIZE_MAX);
-}
-
-static const OSSL_PARAM *kbkdf_gettable_ctx_params(void)
-{
-    static const OSSL_PARAM known_gettable_ctx_params[] =
-        { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), OSSL_PARAM_END };
-    return known_gettable_ctx_params;
-}
-
-const OSSL_DISPATCH kdf_kbkdf_functions[] = {
-    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kbkdf_new },
-    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kbkdf_free },
-    { OSSL_FUNC_KDF_RESET, (void(*)(void))kbkdf_reset },
-    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kbkdf_derive },
-    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
-      (void(*)(void))kbkdf_settable_ctx_params },
-    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kbkdf_set_ctx_params },
-    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
-      (void(*)(void))kbkdf_gettable_ctx_params },
-    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kbkdf_get_ctx_params },
-    { 0, NULL },
-};
diff --git a/providers/common/kdfs/pbkdf2.c b/providers/common/kdfs/pbkdf2.c
deleted file mode 100644 (file)
index 68aa0aa..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright 2018-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 <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <openssl/hmac.h>
-#include <openssl/evp.h>
-#include <openssl/kdf.h>
-#include <openssl/core_names.h>
-#include "internal/cryptlib.h"
-#include "internal/numbers.h"
-#include "crypto/evp.h"
-#include "internal/provider_ctx.h"
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_util.h"
-#include "pbkdf2.h"
-
-/* Constants specified in SP800-132 */
-#define KDF_PBKDF2_MIN_KEY_LEN_BITS  112
-#define KDF_PBKDF2_MAX_KEY_LEN_DIGEST_RATIO 0xFFFFFFFF
-#define KDF_PBKDF2_MIN_ITERATIONS 1000
-#define KDF_PBKDF2_MIN_SALT_LEN   (128 / 8)
-
-static OSSL_OP_kdf_newctx_fn kdf_pbkdf2_new;
-static OSSL_OP_kdf_freectx_fn kdf_pbkdf2_free;
-static OSSL_OP_kdf_reset_fn kdf_pbkdf2_reset;
-static OSSL_OP_kdf_derive_fn kdf_pbkdf2_derive;
-static OSSL_OP_kdf_settable_ctx_params_fn kdf_pbkdf2_settable_ctx_params;
-static OSSL_OP_kdf_set_ctx_params_fn kdf_pbkdf2_set_ctx_params;
-
-static int  pbkdf2_derive(const char *pass, size_t passlen,
-                          const unsigned char *salt, int saltlen, uint64_t iter,
-                          const EVP_MD *digest, unsigned char *key,
-                          size_t keylen, int extra_checks);
-
-typedef struct {
-    void *provctx;
-    unsigned char *pass;
-    size_t pass_len;
-    unsigned char *salt;
-    size_t salt_len;
-    uint64_t iter;
-    PROV_DIGEST digest;
-    int lower_bound_checks;
-} KDF_PBKDF2;
-
-static void kdf_pbkdf2_init(KDF_PBKDF2 *ctx);
-
-static void *kdf_pbkdf2_new(void *provctx)
-{
-    KDF_PBKDF2 *ctx;
-
-    ctx = OPENSSL_zalloc(sizeof(*ctx));
-    if (ctx == NULL) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-        return NULL;
-    }
-    ctx->provctx = provctx;
-    kdf_pbkdf2_init(ctx);
-    return ctx;
-}
-
-static void kdf_pbkdf2_cleanup(KDF_PBKDF2 *ctx)
-{
-    ossl_prov_digest_reset(&ctx->digest);
-    OPENSSL_free(ctx->salt);
-    OPENSSL_clear_free(ctx->pass, ctx->pass_len);
-    memset(ctx, 0, sizeof(*ctx));
-}
-
-static void kdf_pbkdf2_free(void *vctx)
-{
-    KDF_PBKDF2 *ctx = (KDF_PBKDF2 *)vctx;
-
-    kdf_pbkdf2_cleanup(ctx);
-    OPENSSL_free(ctx);
-}
-
-static void kdf_pbkdf2_reset(void *vctx)
-{
-    KDF_PBKDF2 *ctx = (KDF_PBKDF2 *)vctx;
-
-    kdf_pbkdf2_cleanup(ctx);
-    kdf_pbkdf2_init(ctx);
-}
-
-static void kdf_pbkdf2_init(KDF_PBKDF2 *ctx)
-{
-    OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
-    OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
-
-    params[0] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
-                                                 SN_sha1, 0);
-    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
-        /* This is an error, but there is no way to indicate such directly */
-        ossl_prov_digest_reset(&ctx->digest);
-    ctx->iter = PKCS5_DEFAULT_ITER;
-    ctx->lower_bound_checks = kdf_pbkdf2_default_checks;
-}
-
-static int pbkdf2_set_membuf(unsigned char **buffer, size_t *buflen,
-                             const OSSL_PARAM *p)
-{
-    OPENSSL_clear_free(*buffer, *buflen);
-    if (p->data_size == 0) {
-        if ((*buffer = OPENSSL_malloc(1)) == NULL) {
-            ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-            return 0;
-        }
-    } else if (p->data != NULL) {
-        *buffer = NULL;
-        if (!OSSL_PARAM_get_octet_string(p, (void **)buffer, 0, buflen))
-            return 0;
-    }
-    return 1;
-}
-
-static int kdf_pbkdf2_derive(void *vctx, unsigned char *key,
-                             size_t keylen)
-{
-    KDF_PBKDF2 *ctx = (KDF_PBKDF2 *)vctx;
-    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
-
-    if (ctx->pass == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_PASS);
-        return 0;
-    }
-
-    if (ctx->salt == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SALT);
-        return 0;
-    }
-
-    return pbkdf2_derive((char *)ctx->pass, ctx->pass_len,
-                         ctx->salt, ctx->salt_len, ctx->iter,
-                         md, key, keylen, ctx->lower_bound_checks);
-}
-
-static int kdf_pbkdf2_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    const OSSL_PARAM *p;
-    KDF_PBKDF2 *ctx = vctx;
-    OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
-    int pkcs5;
-    uint64_t iter, min_iter;
-
-    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
-        return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PKCS5)) != NULL) {
-        if (!OSSL_PARAM_get_int(p, &pkcs5))
-            return 0;
-        ctx->lower_bound_checks = pkcs5 == 0;
-    }
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL)
-        if (!pbkdf2_set_membuf(&ctx->pass, &ctx->pass_len, p))
-            return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) {
-        if (ctx->lower_bound_checks != 0
-            && p->data_size < KDF_PBKDF2_MIN_SALT_LEN) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
-            return 0;
-        }
-        if (!pbkdf2_set_membuf(&ctx->salt, &ctx->salt_len,p))
-            return 0;
-    }
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ITER)) != NULL) {
-        if (!OSSL_PARAM_get_uint64(p, &iter))
-            return 0;
-        min_iter = ctx->lower_bound_checks != 0 ? KDF_PBKDF2_MIN_ITERATIONS : 1;
-        if (iter < min_iter) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_ITERATION_COUNT);
-            return 0;
-        }
-        ctx->iter = iter;
-    }
-    return 1;
-}
-
-static const OSSL_PARAM *kdf_pbkdf2_settable_ctx_params(void)
-{
-    static const OSSL_PARAM known_settable_ctx_params[] = {
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
-        OSSL_PARAM_uint64(OSSL_KDF_PARAM_ITER, NULL),
-        OSSL_PARAM_int(OSSL_KDF_PARAM_PKCS5, NULL),
-        OSSL_PARAM_END
-    };
-    return known_settable_ctx_params;
-}
-
-static int kdf_pbkdf2_get_ctx_params(void *vctx, OSSL_PARAM params[])
-{
-    OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
-        return OSSL_PARAM_set_size_t(p, SIZE_MAX);
-    return -2;
-}
-
-static const OSSL_PARAM *kdf_pbkdf2_gettable_ctx_params(void)
-{
-    static const OSSL_PARAM known_gettable_ctx_params[] = {
-        OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
-        OSSL_PARAM_END
-    };
-    return known_gettable_ctx_params;
-}
-
-const OSSL_DISPATCH kdf_pbkdf2_functions[] = {
-    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_pbkdf2_new },
-    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_pbkdf2_free },
-    { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_pbkdf2_reset },
-    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_pbkdf2_derive },
-    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
-      (void(*)(void))kdf_pbkdf2_settable_ctx_params },
-    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_pbkdf2_set_ctx_params },
-    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
-      (void(*)(void))kdf_pbkdf2_gettable_ctx_params },
-    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_pbkdf2_get_ctx_params },
-    { 0, NULL }
-};
-
-/*
- * This is an implementation of PKCS#5 v2.0 password based encryption key
- * derivation function PBKDF2. SHA1 version verified against test vectors
- * posted by Peter Gutmann to the PKCS-TNG mailing list.
- *
- * The constraints specified by SP800-132 have been added i.e.
- *  - Check the range of the key length.
- *  - Minimum iteration count of 1000.
- *  - Randomly-generated portion of the salt shall be at least 128 bits.
- */
-static int pbkdf2_derive(const char *pass, size_t passlen,
-                         const unsigned char *salt, int saltlen, uint64_t iter,
-                         const EVP_MD *digest, unsigned char *key,
-                         size_t keylen, int lower_bound_checks)
-{
-    int ret = 0;
-    unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
-    int cplen, k, tkeylen, mdlen;
-    uint64_t j;
-    unsigned long i = 1;
-    HMAC_CTX *hctx_tpl = NULL, *hctx = NULL;
-
-    mdlen = EVP_MD_size(digest);
-    if (mdlen <= 0)
-        return 0;
-
-    /*
-     * This check should always be done because keylen / mdlen >= (2^32 - 1)
-     * results in an overflow of the loop counter 'i'.
-     */
-    if ((keylen / mdlen) >= KDF_PBKDF2_MAX_KEY_LEN_DIGEST_RATIO) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LEN);
-        return 0;
-    }
-
-    if (lower_bound_checks) {
-        if ((keylen * 8) < KDF_PBKDF2_MIN_KEY_LEN_BITS) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LEN);
-            return 0;
-        }
-        if (saltlen < KDF_PBKDF2_MIN_SALT_LEN) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
-            return 0;
-        }
-        if (iter < KDF_PBKDF2_MIN_ITERATIONS) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_ITERATION_COUNT);
-            return 0;
-        }
-    }
-
-    hctx_tpl = HMAC_CTX_new();
-    if (hctx_tpl == NULL)
-        return 0;
-    p = key;
-    tkeylen = keylen;
-    if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL))
-        goto err;
-    hctx = HMAC_CTX_new();
-    if (hctx == NULL)
-        goto err;
-    while (tkeylen) {
-        if (tkeylen > mdlen)
-            cplen = mdlen;
-        else
-            cplen = tkeylen;
-        /*
-         * We are unlikely to ever use more than 256 blocks (5120 bits!) but
-         * just in case...
-         */
-        itmp[0] = (unsigned char)((i >> 24) & 0xff);
-        itmp[1] = (unsigned char)((i >> 16) & 0xff);
-        itmp[2] = (unsigned char)((i >> 8) & 0xff);
-        itmp[3] = (unsigned char)(i & 0xff);
-        if (!HMAC_CTX_copy(hctx, hctx_tpl))
-            goto err;
-        if (!HMAC_Update(hctx, salt, saltlen)
-                || !HMAC_Update(hctx, itmp, 4)
-                || !HMAC_Final(hctx, digtmp, NULL))
-            goto err;
-        memcpy(p, digtmp, cplen);
-        for (j = 1; j < iter; j++) {
-            if (!HMAC_CTX_copy(hctx, hctx_tpl))
-                goto err;
-            if (!HMAC_Update(hctx, digtmp, mdlen)
-                    || !HMAC_Final(hctx, digtmp, NULL))
-                goto err;
-            for (k = 0; k < cplen; k++)
-                p[k] ^= digtmp[k];
-        }
-        tkeylen -= cplen;
-        i++;
-        p += cplen;
-    }
-    ret = 1;
-
-err:
-    HMAC_CTX_free(hctx);
-    HMAC_CTX_free(hctx_tpl);
-    return ret;
-}
diff --git a/providers/common/kdfs/pbkdf2.h b/providers/common/kdfs/pbkdf2.h
deleted file mode 100644 (file)
index c8c2e5b..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * 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
- */
-
-/*
- * Available in pbkdfe_fips.c, and compiled with different values depending
- * on we're in the FIPS module or not.
- */
-extern const int kdf_pbkdf2_default_checks;
diff --git a/providers/common/kdfs/pbkdf2_fips.c b/providers/common/kdfs/pbkdf2_fips.c
deleted file mode 100644 (file)
index d33782b..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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 "pbkdf2.h"
-
-/*
- * For backwards compatibility reasons,
- * Extra checks are done by default in fips mode only.
- */
-#ifdef FIPS_MODE
-const int kdf_pbkdf2_default_checks = 1;
-#else
-const int kdf_pbkdf2_default_checks = 0;
-#endif /* FIPS_MODE */
diff --git a/providers/common/kdfs/sskdf.c b/providers/common/kdfs/sskdf.c
deleted file mode 100644 (file)
index 1e538a9..0000000
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
- * Copyright (c) 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * Refer to https://csrc.nist.gov/publications/detail/sp/800-56c/rev-1/final
- * Section 4.1.
- *
- * The Single Step KDF algorithm is given by:
- *
- * Result(0) = empty bit string (i.e., the null string).
- * For i = 1 to reps, do the following:
- *   Increment counter by 1.
- *   Result(i) = Result(i - 1) || H(counter || Z || FixedInfo).
- * DKM = LeftmostBits(Result(reps), L))
- *
- * NOTES:
- *   Z is a shared secret required to produce the derived key material.
- *   counter is a 4 byte buffer.
- *   FixedInfo is a bit string containing context specific data.
- *   DKM is the output derived key material.
- *   L is the required size of the DKM.
- *   reps = [L / H_outputBits]
- *   H(x) is the auxiliary function that can be either a hash, HMAC or KMAC.
- *   H_outputBits is the length of the output of the auxiliary function H(x).
- *
- * Currently there is not a comprehensive list of test vectors for this
- * algorithm, especially for H(x) = HMAC and H(x) = KMAC.
- * Test vectors for H(x) = Hash are indirectly used by CAVS KAS tests.
- */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <openssl/hmac.h>
-#include <openssl/evp.h>
-#include <openssl/kdf.h>
-#include <openssl/core_names.h>
-#include <openssl/params.h>
-#include "internal/cryptlib.h"
-#include "internal/numbers.h"
-#include "crypto/evp.h"
-#include "internal/provider_ctx.h"
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_util.h"
-
-typedef struct {
-    void *provctx;
-    EVP_MAC_CTX *macctx;         /* H(x) = HMAC_hash OR H(x) = KMAC */
-    PROV_DIGEST digest;          /* H(x) = hash(x) */
-    unsigned char *secret;
-    size_t secret_len;
-    unsigned char *info;
-    size_t info_len;
-    unsigned char *salt;
-    size_t salt_len;
-    size_t out_len; /* optional KMAC parameter */
-} KDF_SSKDF;
-
-#define SSKDF_MAX_INLEN (1<<30)
-#define SSKDF_KMAC128_DEFAULT_SALT_SIZE (168 - 4)
-#define SSKDF_KMAC256_DEFAULT_SALT_SIZE (136 - 4)
-
-/* KMAC uses a Customisation string of 'KDF' */
-static const unsigned char kmac_custom_str[] = { 0x4B, 0x44, 0x46 };
-
-static OSSL_OP_kdf_newctx_fn sskdf_new;
-static OSSL_OP_kdf_freectx_fn sskdf_free;
-static OSSL_OP_kdf_reset_fn sskdf_reset;
-static OSSL_OP_kdf_derive_fn sskdf_derive;
-static OSSL_OP_kdf_derive_fn x963kdf_derive;
-static OSSL_OP_kdf_settable_ctx_params_fn sskdf_settable_ctx_params;
-static OSSL_OP_kdf_set_ctx_params_fn sskdf_set_ctx_params;
-static OSSL_OP_kdf_gettable_ctx_params_fn sskdf_gettable_ctx_params;
-static OSSL_OP_kdf_get_ctx_params_fn sskdf_get_ctx_params;
-
-/*
- * Refer to https://csrc.nist.gov/publications/detail/sp/800-56c/rev-1/final
- * Section 4. One-Step Key Derivation using H(x) = hash(x)
- * Note: X9.63 also uses this code with the only difference being that the
- * counter is appended to the secret 'z'.
- * i.e.
- *   result[i] = Hash(counter || z || info) for One Step OR
- *   result[i] = Hash(z || counter || info) for X9.63.
- */
-static int SSKDF_hash_kdm(const EVP_MD *kdf_md,
-                          const unsigned char *z, size_t z_len,
-                          const unsigned char *info, size_t info_len,
-                          unsigned int append_ctr,
-                          unsigned char *derived_key, size_t derived_key_len)
-{
-    int ret = 0, hlen;
-    size_t counter, out_len, len = derived_key_len;
-    unsigned char c[4];
-    unsigned char mac[EVP_MAX_MD_SIZE];
-    unsigned char *out = derived_key;
-    EVP_MD_CTX *ctx = NULL, *ctx_init = NULL;
-
-    if (z_len > SSKDF_MAX_INLEN || info_len > SSKDF_MAX_INLEN
-            || derived_key_len > SSKDF_MAX_INLEN
-            || derived_key_len == 0)
-        return 0;
-
-    hlen = EVP_MD_size(kdf_md);
-    if (hlen <= 0)
-        return 0;
-    out_len = (size_t)hlen;
-
-    ctx = EVP_MD_CTX_create();
-    ctx_init = EVP_MD_CTX_create();
-    if (ctx == NULL || ctx_init == NULL)
-        goto end;
-
-    if (!EVP_DigestInit(ctx_init, kdf_md))
-        goto end;
-
-    for (counter = 1;; counter++) {
-        c[0] = (unsigned char)((counter >> 24) & 0xff);
-        c[1] = (unsigned char)((counter >> 16) & 0xff);
-        c[2] = (unsigned char)((counter >> 8) & 0xff);
-        c[3] = (unsigned char)(counter & 0xff);
-
-        if (!(EVP_MD_CTX_copy_ex(ctx, ctx_init)
-                && (append_ctr || EVP_DigestUpdate(ctx, c, sizeof(c)))
-                && EVP_DigestUpdate(ctx, z, z_len)
-                && (!append_ctr || EVP_DigestUpdate(ctx, c, sizeof(c)))
-                && EVP_DigestUpdate(ctx, info, info_len)))
-            goto end;
-        if (len >= out_len) {
-            if (!EVP_DigestFinal_ex(ctx, out, NULL))
-                goto end;
-            out += out_len;
-            len -= out_len;
-            if (len == 0)
-                break;
-        } else {
-            if (!EVP_DigestFinal_ex(ctx, mac, NULL))
-                goto end;
-            memcpy(out, mac, len);
-            break;
-        }
-    }
-    ret = 1;
-end:
-    EVP_MD_CTX_destroy(ctx);
-    EVP_MD_CTX_destroy(ctx_init);
-    OPENSSL_cleanse(mac, sizeof(mac));
-    return ret;
-}
-
-static int kmac_init(EVP_MAC_CTX *ctx, const unsigned char *custom,
-                     size_t custom_len, size_t kmac_out_len,
-                     size_t derived_key_len, unsigned char **out)
-{
-    OSSL_PARAM params[2];
-
-    /* Only KMAC has custom data - so return if not KMAC */
-    if (custom == NULL)
-        return 1;
-
-    params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_CUSTOM,
-                                                  (void *)custom, custom_len);
-    params[1] = OSSL_PARAM_construct_end();
-
-    if (!EVP_MAC_CTX_set_params(ctx, params))
-        return 0;
-
-    /* By default only do one iteration if kmac_out_len is not specified */
-    if (kmac_out_len == 0)
-        kmac_out_len = derived_key_len;
-    /* otherwise check the size is valid */
-    else if (!(kmac_out_len == derived_key_len
-            || kmac_out_len == 20
-            || kmac_out_len == 28
-            || kmac_out_len == 32
-            || kmac_out_len == 48
-            || kmac_out_len == 64))
-        return 0;
-
-    params[0] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE,
-                                            &kmac_out_len);
-
-    if (EVP_MAC_CTX_set_params(ctx, params) <= 0)
-        return 0;
-
-    /*
-     * For kmac the output buffer can be larger than EVP_MAX_MD_SIZE: so
-     * alloc a buffer for this case.
-     */
-    if (kmac_out_len > EVP_MAX_MD_SIZE) {
-        *out = OPENSSL_zalloc(kmac_out_len);
-        if (*out == NULL)
-            return 0;
-    }
-    return 1;
-}
-
-/*
- * Refer to https://csrc.nist.gov/publications/detail/sp/800-56c/rev-1/final
- * Section 4. One-Step Key Derivation using MAC: i.e either
- *     H(x) = HMAC-hash(salt, x) OR
- *     H(x) = KMAC#(salt, x, outbits, CustomString='KDF')
- */
-static int SSKDF_mac_kdm(EVP_MAC_CTX *ctx_init,
-                         const unsigned char *kmac_custom,
-                         size_t kmac_custom_len, size_t kmac_out_len,
-                         const unsigned char *salt, size_t salt_len,
-                         const unsigned char *z, size_t z_len,
-                         const unsigned char *info, size_t info_len,
-                         unsigned char *derived_key, size_t derived_key_len)
-{
-    int ret = 0;
-    size_t counter, out_len, len;
-    unsigned char c[4];
-    unsigned char mac_buf[EVP_MAX_MD_SIZE];
-    unsigned char *out = derived_key;
-    EVP_MAC_CTX *ctx = NULL;
-    unsigned char *mac = mac_buf, *kmac_buffer = NULL;
-    OSSL_PARAM params[2], *p = params;
-
-    if (z_len > SSKDF_MAX_INLEN || info_len > SSKDF_MAX_INLEN
-            || derived_key_len > SSKDF_MAX_INLEN
-            || derived_key_len == 0)
-        return 0;
-
-    *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
-                                             (void *)salt, salt_len);
-    *p = OSSL_PARAM_construct_end();
-
-    if (!EVP_MAC_CTX_set_params(ctx_init, params))
-        goto end;
-
-    if (!kmac_init(ctx_init, kmac_custom, kmac_custom_len, kmac_out_len,
-                   derived_key_len, &kmac_buffer))
-        goto end;
-    if (kmac_buffer != NULL)
-        mac = kmac_buffer;
-
-    if (!EVP_MAC_init(ctx_init))
-        goto end;
-
-    out_len = EVP_MAC_size(ctx_init); /* output size */
-    if (out_len <= 0)
-        goto end;
-    len = derived_key_len;
-
-    for (counter = 1;; counter++) {
-        c[0] = (unsigned char)((counter >> 24) & 0xff);
-        c[1] = (unsigned char)((counter >> 16) & 0xff);
-        c[2] = (unsigned char)((counter >> 8) & 0xff);
-        c[3] = (unsigned char)(counter & 0xff);
-
-        ctx = EVP_MAC_CTX_dup(ctx_init);
-        if (!(ctx != NULL
-                && EVP_MAC_update(ctx, c, sizeof(c))
-                && EVP_MAC_update(ctx, z, z_len)
-                && EVP_MAC_update(ctx, info, info_len)))
-            goto end;
-        if (len >= out_len) {
-            if (!EVP_MAC_final(ctx, out, NULL, len))
-                goto end;
-            out += out_len;
-            len -= out_len;
-            if (len == 0)
-                break;
-        } else {
-            if (!EVP_MAC_final(ctx, mac, NULL, len))
-                goto end;
-            memcpy(out, mac, len);
-            break;
-        }
-        EVP_MAC_CTX_free(ctx);
-        ctx = NULL;
-    }
-    ret = 1;
-end:
-    if (kmac_buffer != NULL)
-        OPENSSL_clear_free(kmac_buffer, kmac_out_len);
-    else
-        OPENSSL_cleanse(mac_buf, sizeof(mac_buf));
-
-    EVP_MAC_CTX_free(ctx);
-    return ret;
-}
-
-static void *sskdf_new(void *provctx)
-{
-    KDF_SSKDF *ctx;
-
-    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-    ctx->provctx = provctx;
-    return ctx;
-}
-
-static void sskdf_reset(void *vctx)
-{
-    KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
-
-    EVP_MAC_CTX_free(ctx->macctx);
-    ossl_prov_digest_reset(&ctx->digest);
-    OPENSSL_clear_free(ctx->secret, ctx->secret_len);
-    OPENSSL_clear_free(ctx->info, ctx->info_len);
-    OPENSSL_clear_free(ctx->salt, ctx->salt_len);
-    memset(ctx, 0, sizeof(*ctx));
-}
-
-static void sskdf_free(void *vctx)
-{
-    KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
-
-    sskdf_reset(ctx);
-    OPENSSL_free(ctx);
-}
-
-static int sskdf_set_buffer(unsigned char **out, size_t *out_len,
-                            const OSSL_PARAM *p)
-{
-    if (p->data == NULL || p->data_size == 0)
-        return 1;
-    OPENSSL_free(*out);
-    *out = NULL;
-    return OSSL_PARAM_get_octet_string(p, (void **)out, 0, out_len);
-}
-
-static size_t sskdf_size(KDF_SSKDF *ctx)
-{
-    int len;
-    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
-
-    if (md == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
-        return 0;
-    }
-    len = EVP_MD_size(md);
-    return (len <= 0) ? 0 : (size_t)len;
-}
-
-static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen)
-{
-    KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
-    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
-
-    if (ctx->secret == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);
-        return 0;
-    }
-
-    if (ctx->macctx != NULL) {
-        /* H(x) = KMAC or H(x) = HMAC */
-        int ret;
-        const unsigned char *custom = NULL;
-        size_t custom_len = 0;
-        int default_salt_len;
-        EVP_MAC *mac = EVP_MAC_CTX_mac(ctx->macctx);
-
-        /*
-         * TODO(3.0) investigate the necessity to have all these controls.
-         * Why does KMAC require a salt length that's shorter than the MD
-         * block size?
-         */
-        if (EVP_MAC_is_a(mac, OSSL_MAC_NAME_HMAC)) {
-            /* H(x) = HMAC(x, salt, hash) */
-            if (md == NULL) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
-                return 0;
-            }
-            default_salt_len = EVP_MD_size(md);
-            if (default_salt_len <= 0)
-                return 0;
-        } else if (EVP_MAC_is_a(mac, OSSL_MAC_NAME_KMAC128)
-                   || EVP_MAC_is_a(mac, OSSL_MAC_NAME_KMAC256)) {
-            /* H(x) = KMACzzz(x, salt, custom) */
-            custom = kmac_custom_str;
-            custom_len = sizeof(kmac_custom_str);
-            if (EVP_MAC_is_a(mac, OSSL_MAC_NAME_KMAC128))
-                default_salt_len = SSKDF_KMAC128_DEFAULT_SALT_SIZE;
-            else
-                default_salt_len = SSKDF_KMAC256_DEFAULT_SALT_SIZE;
-        } else {
-            ERR_raise(ERR_LIB_PROV, PROV_R_UNSUPPORTED_MAC_TYPE);
-            return 0;
-        }
-        /* If no salt is set then use a default_salt of zeros */
-        if (ctx->salt == NULL || ctx->salt_len <= 0) {
-            ctx->salt = OPENSSL_zalloc(default_salt_len);
-            if (ctx->salt == NULL) {
-                ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-                return 0;
-            }
-            ctx->salt_len = default_salt_len;
-        }
-        ret = SSKDF_mac_kdm(ctx->macctx,
-                            custom, custom_len, ctx->out_len,
-                            ctx->salt, ctx->salt_len,
-                            ctx->secret, ctx->secret_len,
-                            ctx->info, ctx->info_len, key, keylen);
-        return ret;
-    } else {
-        /* H(x) = hash */
-        if (md == NULL) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
-            return 0;
-        }
-        return SSKDF_hash_kdm(md, ctx->secret, ctx->secret_len,
-                              ctx->info, ctx->info_len, 0, key, keylen);
-    }
-}
-
-static int x963kdf_derive(void *vctx, unsigned char *key, size_t keylen)
-{
-    KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
-    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
-
-    if (ctx->secret == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);
-        return 0;
-    }
-
-    if (ctx->macctx != NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED);
-        return 0;
-    }
-
-    /* H(x) = hash */
-    if (md == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
-        return 0;
-    }
-
-    return SSKDF_hash_kdm(md, ctx->secret, ctx->secret_len,
-                          ctx->info, ctx->info_len, 1, key, keylen);
-}
-
-static int sskdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    const OSSL_PARAM *p;
-    KDF_SSKDF *ctx = vctx;
-    OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
-    size_t sz;
-
-    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx))
-        return 0;
-
-    if (!ossl_prov_macctx_load_from_params(&ctx->macctx, params,
-                                           NULL, NULL, NULL, libctx))
-        return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL
-        || (p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL)
-        if (!sskdf_set_buffer(&ctx->secret, &ctx->secret_len, p))
-            return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO)) != NULL)
-        if (!sskdf_set_buffer(&ctx->info, &ctx->info_len, p))
-            return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL)
-        if (!sskdf_set_buffer(&ctx->salt, &ctx->salt_len, p))
-            return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MAC_SIZE))
-        != NULL) {
-        if (!OSSL_PARAM_get_size_t(p, &sz) || sz == 0)
-            return 0;
-        ctx->out_len = sz;
-    }
-    return 1;
-}
-
-static const OSSL_PARAM *sskdf_settable_ctx_params(void)
-{
-    static const OSSL_PARAM known_settable_ctx_params[] = {
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MAC, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
-        OSSL_PARAM_size_t(OSSL_KDF_PARAM_MAC_SIZE, NULL),
-        OSSL_PARAM_END
-    };
-    return known_settable_ctx_params;
-}
-
-static int sskdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
-{
-    KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
-    OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
-        return OSSL_PARAM_set_size_t(p, sskdf_size(ctx));
-    return -2;
-}
-
-static const OSSL_PARAM *sskdf_gettable_ctx_params(void)
-{
-    static const OSSL_PARAM known_gettable_ctx_params[] = {
-        OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
-        OSSL_PARAM_END
-    };
-    return known_gettable_ctx_params;
-}
-
-const OSSL_DISPATCH kdf_sskdf_functions[] = {
-    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))sskdf_new },
-    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))sskdf_free },
-    { OSSL_FUNC_KDF_RESET, (void(*)(void))sskdf_reset },
-    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))sskdf_derive },
-    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
-      (void(*)(void))sskdf_settable_ctx_params },
-    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))sskdf_set_ctx_params },
-    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
-      (void(*)(void))sskdf_gettable_ctx_params },
-    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))sskdf_get_ctx_params },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH kdf_x963_kdf_functions[] = {
-    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))sskdf_new },
-    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))sskdf_free },
-    { OSSL_FUNC_KDF_RESET, (void(*)(void))sskdf_reset },
-    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))x963kdf_derive },
-    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
-      (void(*)(void))sskdf_settable_ctx_params },
-    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))sskdf_set_ctx_params },
-    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
-      (void(*)(void))sskdf_gettable_ctx_params },
-    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))sskdf_get_ctx_params },
-    { 0, NULL }
-};
diff --git a/providers/common/kdfs/tls1_prf.c b/providers/common/kdfs/tls1_prf.c
deleted file mode 100644 (file)
index af49b1b..0000000
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright 2016-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
- */
-
-/*
- * Refer to "The TLS Protocol Version 1.0" Section 5
- * (https://tools.ietf.org/html/rfc2246#section-5) and
- * "The Transport Layer Security (TLS) Protocol Version 1.2" Section 5
- * (https://tools.ietf.org/html/rfc5246#section-5).
- *
- * For TLS v1.0 and TLS v1.1 the TLS PRF algorithm is given by:
- *
- *   PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
- *                              P_SHA-1(S2, label + seed)
- *
- * where P_MD5 and P_SHA-1 are defined by P_<hash>, below, and S1 and S2 are
- * two halves of the secret (with the possibility of one shared byte, in the
- * case where the length of the original secret is odd).  S1 is taken from the
- * first half of the secret, S2 from the second half.
- *
- * For TLS v1.2 the TLS PRF algorithm is given by:
- *
- *   PRF(secret, label, seed) = P_<hash>(secret, label + seed)
- *
- * where hash is SHA-256 for all cipher suites defined in RFC 5246 as well as
- * those published prior to TLS v1.2 while the TLS v1.2 protocol is in effect,
- * unless defined otherwise by the cipher suite.
- *
- * P_<hash> is an expansion function that uses a single hash function to expand
- * a secret and seed into an arbitrary quantity of output:
- *
- *   P_<hash>(secret, seed) = HMAC_<hash>(secret, A(1) + seed) +
- *                            HMAC_<hash>(secret, A(2) + seed) +
- *                            HMAC_<hash>(secret, A(3) + seed) + ...
- *
- * where + indicates concatenation.  P_<hash> can be iterated as many times as
- * is necessary to produce the required quantity of data.
- *
- * A(i) is defined as:
- *     A(0) = seed
- *     A(i) = HMAC_<hash>(secret, A(i-1))
- */
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <openssl/evp.h>
-#include <openssl/kdf.h>
-#include <openssl/core_names.h>
-#include <openssl/params.h>
-#include "internal/cryptlib.h"
-#include "internal/numbers.h"
-#include "crypto/evp.h"
-#include "internal/provider_ctx.h"
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_util.h"
-#include "e_os.h"
-
-static OSSL_OP_kdf_newctx_fn kdf_tls1_prf_new;
-static OSSL_OP_kdf_freectx_fn kdf_tls1_prf_free;
-static OSSL_OP_kdf_reset_fn kdf_tls1_prf_reset;
-static OSSL_OP_kdf_derive_fn kdf_tls1_prf_derive;
-static OSSL_OP_kdf_settable_ctx_params_fn kdf_tls1_prf_settable_ctx_params;
-static OSSL_OP_kdf_set_ctx_params_fn kdf_tls1_prf_set_ctx_params;
-
-static int tls1_prf_alg(EVP_MAC_CTX *mdctx, EVP_MAC_CTX *sha1ctx,
-                        const unsigned char *sec, size_t slen,
-                        const unsigned char *seed, size_t seed_len,
-                        unsigned char *out, size_t olen);
-
-#define TLS1_PRF_MAXBUF 1024
-
-/* TLS KDF kdf context structure */
-typedef struct {
-    void *provctx;
-
-    /* MAC context for the main digest */
-    EVP_MAC_CTX *P_hash;
-    /* MAC context for SHA1 for the MD5/SHA-1 combined PRF */
-    EVP_MAC_CTX *P_sha1;
-
-    /* Secret value to use for PRF */
-    unsigned char *sec;
-    size_t seclen;
-    /* Buffer of concatenated seed data */
-    unsigned char seed[TLS1_PRF_MAXBUF];
-    size_t seedlen;
-} TLS1_PRF;
-
-static void *kdf_tls1_prf_new(void *provctx)
-{
-    TLS1_PRF *ctx;
-
-    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-    ctx->provctx = provctx;
-    return ctx;
-}
-
-static void kdf_tls1_prf_free(void *vctx)
-{
-    TLS1_PRF *ctx = (TLS1_PRF *)vctx;
-
-    kdf_tls1_prf_reset(ctx);
-    OPENSSL_free(ctx);
-}
-
-static void kdf_tls1_prf_reset(void *vctx)
-{
-    TLS1_PRF *ctx = (TLS1_PRF *)vctx;
-
-    EVP_MAC_CTX_free(ctx->P_hash);
-    EVP_MAC_CTX_free(ctx->P_sha1);
-    OPENSSL_clear_free(ctx->sec, ctx->seclen);
-    OPENSSL_cleanse(ctx->seed, ctx->seedlen);
-    memset(ctx, 0, sizeof(*ctx));
-}
-
-static int kdf_tls1_prf_derive(void *vctx, unsigned char *key,
-                               size_t keylen)
-{
-    TLS1_PRF *ctx = (TLS1_PRF *)vctx;
-
-    if (ctx->P_hash == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
-        return 0;
-    }
-    if (ctx->sec == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);
-        return 0;
-    }
-    if (ctx->seedlen == 0) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SEED);
-        return 0;
-    }
-
-    return tls1_prf_alg(ctx->P_hash, ctx->P_sha1,
-                        ctx->sec, ctx->seclen,
-                        ctx->seed, ctx->seedlen,
-                        key, keylen);
-}
-
-static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    const OSSL_PARAM *p;
-    TLS1_PRF *ctx = vctx;
-    OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DIGEST)) != NULL) {
-        if (strcasecmp(p->data, SN_md5_sha1) == 0) {
-            if (!ossl_prov_macctx_load_from_params(&ctx->P_hash, params,
-                                                   OSSL_MAC_NAME_HMAC,
-                                                   NULL, SN_md5, libctx)
-                || !ossl_prov_macctx_load_from_params(&ctx->P_sha1, params,
-                                                      OSSL_MAC_NAME_HMAC,
-                                                      NULL, SN_sha1, libctx))
-                return 0;
-        } else {
-            EVP_MAC_CTX_free(ctx->P_sha1);
-            if (!ossl_prov_macctx_load_from_params(&ctx->P_hash, params,
-                                                   OSSL_MAC_NAME_HMAC,
-                                                   NULL, NULL, libctx))
-                return 0;
-        }
-    }
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL) {
-        OPENSSL_clear_free(ctx->sec, ctx->seclen);
-        ctx->sec = NULL;
-        if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->sec, 0, &ctx->seclen))
-            return 0;
-    }
-    /* The seed fields concatenate, so process them all */
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SEED)) != NULL) {
-        OPENSSL_cleanse(ctx->seed, ctx->seedlen);
-        ctx->seedlen = 0;
-
-        for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1,
-                                                      OSSL_KDF_PARAM_SEED)) {
-            const void *q = ctx->seed + ctx->seedlen;
-            size_t sz = 0;
-
-            if (p->data_size != 0
-                && p->data != NULL
-                && !OSSL_PARAM_get_octet_string(p, (void **)&q,
-                                                TLS1_PRF_MAXBUF - ctx->seedlen,
-                                                &sz))
-                return 0;
-            ctx->seedlen += sz;
-        }
-    }
-    return 1;
-}
-
-static const OSSL_PARAM *kdf_tls1_prf_settable_ctx_params(void)
-{
-    static const OSSL_PARAM known_settable_ctx_params[] = {
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SEED, NULL, 0),
-        OSSL_PARAM_END
-    };
-    return known_settable_ctx_params;
-}
-
-static int kdf_tls1_prf_get_ctx_params(void *vctx, OSSL_PARAM params[])
-{
-    OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
-        return OSSL_PARAM_set_size_t(p, SIZE_MAX);
-    return -2;
-}
-
-static const OSSL_PARAM *kdf_tls1_prf_gettable_ctx_params(void)
-{
-    static const OSSL_PARAM known_gettable_ctx_params[] = {
-        OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
-        OSSL_PARAM_END
-    };
-    return known_gettable_ctx_params;
-}
-
-const OSSL_DISPATCH kdf_tls1_prf_functions[] = {
-    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_tls1_prf_new },
-    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_tls1_prf_free },
-    { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_tls1_prf_reset },
-    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_tls1_prf_derive },
-    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
-      (void(*)(void))kdf_tls1_prf_settable_ctx_params },
-    { OSSL_FUNC_KDF_SET_CTX_PARAMS,
-      (void(*)(void))kdf_tls1_prf_set_ctx_params },
-    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
-      (void(*)(void))kdf_tls1_prf_gettable_ctx_params },
-    { OSSL_FUNC_KDF_GET_CTX_PARAMS,
-      (void(*)(void))kdf_tls1_prf_get_ctx_params },
-    { 0, NULL }
-};
-
-/*
- * Refer to "The TLS Protocol Version 1.0" Section 5
- * (https://tools.ietf.org/html/rfc2246#section-5) and
- * "The Transport Layer Security (TLS) Protocol Version 1.2" Section 5
- * (https://tools.ietf.org/html/rfc5246#section-5).
- *
- * P_<hash> is an expansion function that uses a single hash function to expand
- * a secret and seed into an arbitrary quantity of output:
- *
- *   P_<hash>(secret, seed) = HMAC_<hash>(secret, A(1) + seed) +
- *                            HMAC_<hash>(secret, A(2) + seed) +
- *                            HMAC_<hash>(secret, A(3) + seed) + ...
- *
- * where + indicates concatenation.  P_<hash> can be iterated as many times as
- * is necessary to produce the required quantity of data.
- *
- * A(i) is defined as:
- *     A(0) = seed
- *     A(i) = HMAC_<hash>(secret, A(i-1))
- */
-static int tls1_prf_P_hash(EVP_MAC_CTX *ctx_init,
-                           const unsigned char *sec, size_t sec_len,
-                           const unsigned char *seed, size_t seed_len,
-                           unsigned char *out, size_t olen)
-{
-    size_t chunk;
-    EVP_MAC_CTX *ctx = NULL, *ctx_Ai = NULL;
-    unsigned char Ai[EVP_MAX_MD_SIZE];
-    size_t Ai_len;
-    int ret = 0;
-    OSSL_PARAM params[2], *p = params;
-
-    *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
-                                             (void *)sec, sec_len);
-    *p = OSSL_PARAM_construct_end();
-    if (!EVP_MAC_CTX_set_params(ctx_init, params))
-        goto err;
-    if (!EVP_MAC_init(ctx_init))
-        goto err;
-    chunk = EVP_MAC_size(ctx_init);
-    if (chunk == 0)
-        goto err;
-    /* A(0) = seed */
-    ctx_Ai = EVP_MAC_CTX_dup(ctx_init);
-    if (ctx_Ai == NULL)
-        goto err;
-    if (seed != NULL && !EVP_MAC_update(ctx_Ai, seed, seed_len))
-        goto err;
-
-    for (;;) {
-        /* calc: A(i) = HMAC_<hash>(secret, A(i-1)) */
-        if (!EVP_MAC_final(ctx_Ai, Ai, &Ai_len, sizeof(Ai)))
-            goto err;
-        EVP_MAC_CTX_free(ctx_Ai);
-        ctx_Ai = NULL;
-
-        /* calc next chunk: HMAC_<hash>(secret, A(i) + seed) */
-        ctx = EVP_MAC_CTX_dup(ctx_init);
-        if (ctx == NULL)
-            goto err;
-        if (!EVP_MAC_update(ctx, Ai, Ai_len))
-            goto err;
-        /* save state for calculating next A(i) value */
-        if (olen > chunk) {
-            ctx_Ai = EVP_MAC_CTX_dup(ctx);
-            if (ctx_Ai == NULL)
-                goto err;
-        }
-        if (seed != NULL && !EVP_MAC_update(ctx, seed, seed_len))
-            goto err;
-        if (olen <= chunk) {
-            /* last chunk - use Ai as temp bounce buffer */
-            if (!EVP_MAC_final(ctx, Ai, &Ai_len, sizeof(Ai)))
-                goto err;
-            memcpy(out, Ai, olen);
-            break;
-        }
-        if (!EVP_MAC_final(ctx, out, NULL, olen))
-            goto err;
-        EVP_MAC_CTX_free(ctx);
-        ctx = NULL;
-        out += chunk;
-        olen -= chunk;
-    }
-    ret = 1;
- err:
-    EVP_MAC_CTX_free(ctx);
-    EVP_MAC_CTX_free(ctx_Ai);
-    OPENSSL_cleanse(Ai, sizeof(Ai));
-    return ret;
-}
-
-/*
- * Refer to "The TLS Protocol Version 1.0" Section 5
- * (https://tools.ietf.org/html/rfc2246#section-5) and
- * "The Transport Layer Security (TLS) Protocol Version 1.2" Section 5
- * (https://tools.ietf.org/html/rfc5246#section-5).
- *
- * For TLS v1.0 and TLS v1.1:
- *
- *   PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
- *                              P_SHA-1(S2, label + seed)
- *
- * S1 is taken from the first half of the secret, S2 from the second half.
- *
- *   L_S = length in bytes of secret;
- *   L_S1 = L_S2 = ceil(L_S / 2);
- *
- * For TLS v1.2:
- *
- *   PRF(secret, label, seed) = P_<hash>(secret, label + seed)
- */
-static int tls1_prf_alg(EVP_MAC_CTX *mdctx, EVP_MAC_CTX *sha1ctx,
-                        const unsigned char *sec, size_t slen,
-                        const unsigned char *seed, size_t seed_len,
-                        unsigned char *out, size_t olen)
-{
-    if (sha1ctx != NULL) {
-        /* TLS v1.0 and TLS v1.1 */
-        size_t i;
-        unsigned char *tmp;
-        /* calc: L_S1 = L_S2 = ceil(L_S / 2) */
-        size_t L_S1 = (slen + 1) / 2;
-        size_t L_S2 = L_S1;
-
-        if (!tls1_prf_P_hash(mdctx, sec, L_S1,
-                             seed, seed_len, out, olen))
-            return 0;
-
-        if ((tmp = OPENSSL_malloc(olen)) == NULL) {
-            ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-            return 0;
-        }
-
-        if (!tls1_prf_P_hash(sha1ctx, sec + slen - L_S2, L_S2,
-                             seed, seed_len, tmp, olen)) {
-            OPENSSL_clear_free(tmp, olen);
-            return 0;
-        }
-        for (i = 0; i < olen; i++)
-            out[i] ^= tmp[i];
-        OPENSSL_clear_free(tmp, olen);
-        return 1;
-    }
-
-    /* TLS v1.2 */
-    if (!tls1_prf_P_hash(mdctx, sec, slen, seed, seed_len, out, olen))
-        return 0;
-
-    return 1;
-}
diff --git a/providers/common/keymgmt/build.info b/providers/common/keymgmt/build.info
deleted file mode 100644 (file)
index 533c489..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-$GOAL=../../libimplementations.a
-
-IF[{- !$disabled{dh} -}]
-  SOURCE[$GOAL]=dh_kmgmt.c
-ENDIF
-IF[{- !$disabled{dsa} -}]
-  SOURCE[$GOAL]=dsa_kmgmt.c
-ENDIF
diff --git a/providers/common/keymgmt/dh_kmgmt.c b/providers/common/keymgmt/dh_kmgmt.c
deleted file mode 100644 (file)
index c13f075..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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/core_numbers.h>
-#include <openssl/core_names.h>
-#include <openssl/bn.h>
-#include <openssl/dh.h>
-#include <openssl/params.h>
-#include "internal/provider_algs.h"
-
-static OSSL_OP_keymgmt_importkey_fn dh_importkey;
-
-static int params_to_key(DH *dh, const OSSL_PARAM params[])
-{
-    const OSSL_PARAM *param_p, *param_g, *param_priv_key, *param_pub_key;
-    BIGNUM *p = NULL, *g = NULL, *priv_key = NULL, *pub_key = NULL;
-
-    if (dh == NULL)
-        return 0;
-
-    param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P);
-    param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G);
-    param_priv_key =
-        OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_KEY);
-    param_pub_key =
-        OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PUB_KEY);
-
-    /*
-     * DH documentation says that a public key must be present if a
-     * private key is present.
-     * We want to have at least a public key either way, so we end up
-     * requiring it unconditionally.
-     */
-    if (param_pub_key == NULL)
-        return 0;
-
-    if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p))
-        || (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g))
-        || (param_priv_key != NULL
-            && !OSSL_PARAM_get_BN(param_priv_key, &priv_key))
-        || !OSSL_PARAM_get_BN(param_pub_key, &pub_key))
-        goto err;
-
-    if (!DH_set0_pqg(dh, p, NULL, g))
-        goto err;
-    p = g = NULL;
-
-    if (!DH_set0_key(dh, pub_key, priv_key))
-        goto err;
-    priv_key = pub_key = NULL;
-
-    return 1;
-
- err:
-    BN_free(p);
-    BN_free(g);
-    BN_free(priv_key);
-    BN_free(pub_key);
-    return 0;
-}
-
-static void *dh_importkey(void *provctx, const OSSL_PARAM params[])
-{
-    DH *dh;
-
-    if ((dh = DH_new()) == NULL
-        || !params_to_key(dh, params)) {
-        DH_free(dh);
-        dh = NULL;
-    }
-    return dh;
-}
-
-const OSSL_DISPATCH dh_keymgmt_functions[] = {
-    /*
-     * TODO(3.0) When implementing OSSL_FUNC_KEYMGMT_GENKEY, remember to also
-     * implement OSSL_FUNC_KEYMGMT_EXPORTKEY.
-     */
-    { OSSL_FUNC_KEYMGMT_IMPORTKEY, (void (*)(void))dh_importkey },
-    { OSSL_FUNC_KEYMGMT_FREEKEY, (void (*)(void))DH_free },
-    { 0, NULL }
-};
diff --git a/providers/common/keymgmt/dsa_kmgmt.c b/providers/common/keymgmt/dsa_kmgmt.c
deleted file mode 100644 (file)
index a53c0b2..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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/core_numbers.h>
-#include <openssl/core_names.h>
-#include <openssl/bn.h>
-#include <openssl/dsa.h>
-#include <openssl/params.h>
-#include "internal/provider_algs.h"
-
-static OSSL_OP_keymgmt_importkey_fn dsa_importkey;
-
-static int params_to_key(DSA *dsa, const OSSL_PARAM params[])
-{
-    const OSSL_PARAM *param_p, *param_q, *param_g, *param_priv_key;
-    const OSSL_PARAM *param_pub_key;
-    BIGNUM *p = NULL, *q = NULL, *g = NULL, *priv_key = NULL, *pub_key = NULL;
-
-    if (dsa == NULL)
-        return 0;
-
-    param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P);
-    param_q = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_Q);
-    param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G);
-    param_priv_key =
-        OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DSA_PRIV_KEY);
-    param_pub_key =
-        OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DSA_PUB_KEY);
-
-    /*
-     * DSA documentation says that a public key must be present if a private key
-     * is.
-     */
-    if (param_priv_key != NULL && param_pub_key == NULL)
-        return 0;
-
-    if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p))
-        || (param_q != NULL && !OSSL_PARAM_get_BN(param_q, &q))
-        || (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g))
-        || (param_priv_key != NULL
-            && !OSSL_PARAM_get_BN(param_priv_key, &priv_key))
-        || (param_pub_key != NULL
-            && !OSSL_PARAM_get_BN(param_pub_key, &pub_key)))
-        goto err;
-
-    if (!DSA_set0_pqg(dsa, p, q, g))
-        goto err;
-    p = q = g = NULL;
-
-    if (pub_key != NULL && !DSA_set0_key(dsa, pub_key, priv_key))
-        goto err;
-    priv_key = pub_key = NULL;
-
-    return 1;
-
- err:
-    BN_free(p);
-    BN_free(q);
-    BN_free(g);
-    BN_free(priv_key);
-    BN_free(pub_key);
-    return 0;
-}
-
-static void *dsa_importkey(void *provctx, const OSSL_PARAM params[])
-{
-    DSA *dsa;
-
-    if ((dsa = DSA_new()) == NULL
-        || !params_to_key(dsa, params)) {
-        DSA_free(dsa);
-        dsa = NULL;
-    }
-    return dsa;
-}
-
-const OSSL_DISPATCH dsa_keymgmt_functions[] = {
-    /*
-     * TODO(3.0) When implementing OSSL_FUNC_KEYMGMT_GENKEY, remember to also
-     * implement OSSL_FUNC_KEYMGMT_EXPORTKEY.
-     */
-    { OSSL_FUNC_KEYMGMT_IMPORTKEY, (void (*)(void))dsa_importkey },
-    { OSSL_FUNC_KEYMGMT_FREEKEY, (void (*)(void))DSA_free },
-    { 0, NULL }
-};
diff --git a/providers/common/macs/build.info b/providers/common/macs/build.info
deleted file mode 100644 (file)
index 1eafe70..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-$GOAL=../../libimplementations.a
-
-$COMMON=gmac_prov.c hmac_prov.c kmac_prov.c
-
-IF[{- !$disabled{cmac} -}]
-  $COMMON=$COMMON cmac_prov.c
-ENDIF
-
-SOURCE[$GOAL]=$COMMON
diff --git a/providers/common/macs/cmac_prov.c b/providers/common/macs/cmac_prov.c
deleted file mode 100644 (file)
index c01b2f8..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright 2018 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/core_numbers.h>
-#include <openssl/core_names.h>
-#include <openssl/params.h>
-#include <openssl/engine.h>
-#include <openssl/evp.h>
-#include <openssl/cmac.h>
-
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
-#include "internal/provider_util.h"
-
-/*
- * Forward declaration of everything implemented here.  This is not strictly
- * necessary for the compiler, but provides an assurance that the signatures
- * of the functions in the dispatch table are correct.
- */
-static OSSL_OP_mac_newctx_fn cmac_new;
-static OSSL_OP_mac_dupctx_fn cmac_dup;
-static OSSL_OP_mac_freectx_fn cmac_free;
-static OSSL_OP_mac_gettable_ctx_params_fn cmac_gettable_ctx_params;
-static OSSL_OP_mac_get_ctx_params_fn cmac_get_ctx_params;
-static OSSL_OP_mac_settable_ctx_params_fn cmac_settable_ctx_params;
-static OSSL_OP_mac_set_ctx_params_fn cmac_set_ctx_params;
-static OSSL_OP_mac_init_fn cmac_init;
-static OSSL_OP_mac_update_fn cmac_update;
-static OSSL_OP_mac_final_fn cmac_final;
-
-/* local CMAC data */
-
-struct cmac_data_st {
-    void *provctx;
-    CMAC_CTX *ctx;
-    PROV_CIPHER cipher;
-};
-
-static void *cmac_new(void *provctx)
-{
-    struct cmac_data_st *macctx;
-
-    if ((macctx = OPENSSL_zalloc(sizeof(*macctx))) == NULL
-        || (macctx->ctx = CMAC_CTX_new()) == NULL) {
-        OPENSSL_free(macctx);
-        macctx = NULL;
-    } else {
-        macctx->provctx = provctx;
-    }
-
-    return macctx;
-}
-
-static void cmac_free(void *vmacctx)
-{
-    struct cmac_data_st *macctx = vmacctx;
-
-    if (macctx != NULL) {
-        CMAC_CTX_free(macctx->ctx);
-        ossl_prov_cipher_reset(&macctx->cipher);
-        OPENSSL_free(macctx);
-    }
-}
-
-static void *cmac_dup(void *vsrc)
-{
-    struct cmac_data_st *src = vsrc;
-    struct cmac_data_st *dst = cmac_new(src->provctx);
-
-    if (!CMAC_CTX_copy(dst->ctx, src->ctx)
-        || !ossl_prov_cipher_copy(&dst->cipher, &src->cipher)) {
-        cmac_free(dst);
-        return NULL;
-    }
-    return dst;
-}
-
-static size_t cmac_size(void *vmacctx)
-{
-    struct cmac_data_st *macctx = vmacctx;
-
-    return EVP_CIPHER_CTX_block_size(CMAC_CTX_get0_cipher_ctx(macctx->ctx));
-}
-
-static int cmac_init(void *vmacctx)
-{
-    struct cmac_data_st *macctx = vmacctx;
-    int rv = CMAC_Init(macctx->ctx, NULL, 0,
-                       ossl_prov_cipher_cipher(&macctx->cipher),
-                       ossl_prov_cipher_engine(&macctx->cipher));
-
-    ossl_prov_cipher_reset(&macctx->cipher);
-    return rv;
-}
-
-static int cmac_update(void *vmacctx, const unsigned char *data,
-                       size_t datalen)
-{
-    struct cmac_data_st *macctx = vmacctx;
-
-    return CMAC_Update(macctx->ctx, data, datalen);
-}
-
-static int cmac_final(void *vmacctx, unsigned char *out, size_t *outl,
-                      size_t outsize)
-{
-    struct cmac_data_st *macctx = vmacctx;
-
-    return CMAC_Final(macctx->ctx, out, outl);
-}
-
-static const OSSL_PARAM known_gettable_ctx_params[] = {
-    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
-    OSSL_PARAM_END
-};
-static const OSSL_PARAM *cmac_gettable_ctx_params(void)
-{
-    return known_gettable_ctx_params;
-}
-
-static int cmac_get_ctx_params(void *vmacctx, OSSL_PARAM params[])
-{
-    OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL)
-        return OSSL_PARAM_set_size_t(p, cmac_size(vmacctx));
-
-    return 1;
-}
-
-static const OSSL_PARAM known_settable_ctx_params[] = {
-    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_CIPHER, NULL, 0),
-    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0),
-    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
-    OSSL_PARAM_END
-};
-static const OSSL_PARAM *cmac_settable_ctx_params(void)
-{
-    return known_settable_ctx_params;
-}
-
-/*
- * ALL parameters should be set before init().
- */
-static int cmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[])
-{
-    struct cmac_data_st *macctx = vmacctx;
-    OPENSSL_CTX *ctx = PROV_LIBRARY_CONTEXT_OF(macctx->provctx);
-    const OSSL_PARAM *p;
-
-    if (!ossl_prov_cipher_load_from_params(&macctx->cipher, params, ctx))
-        return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
-        if (p->data_type != OSSL_PARAM_OCTET_STRING)
-            return 0;
-
-        if (!CMAC_Init(macctx->ctx, p->data, p->data_size,
-                       ossl_prov_cipher_cipher(&macctx->cipher),
-                       ossl_prov_cipher_engine(&macctx->cipher)))
-            return 0;
-
-        ossl_prov_cipher_reset(&macctx->cipher);
-    }
-    return 1;
-}
-
-const OSSL_DISPATCH cmac_functions[] = {
-    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))cmac_new },
-    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))cmac_dup },
-    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))cmac_free },
-    { OSSL_FUNC_MAC_INIT, (void (*)(void))cmac_init },
-    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))cmac_update },
-    { OSSL_FUNC_MAC_FINAL, (void (*)(void))cmac_final },
-    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
-      (void (*)(void))cmac_gettable_ctx_params },
-    { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))cmac_get_ctx_params },
-    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
-      (void (*)(void))cmac_settable_ctx_params },
-    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))cmac_set_ctx_params },
-    { 0, NULL }
-};
diff --git a/providers/common/macs/gmac_prov.c b/providers/common/macs/gmac_prov.c
deleted file mode 100644 (file)
index 3d81af8..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright 2018 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 <stdlib.h>
-#include <openssl/core_numbers.h>
-#include <openssl/core_names.h>
-#include <openssl/params.h>
-#include <openssl/engine.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
-
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
-#include "internal/provider_util.h"
-
-/*
- * Forward declaration of everything implemented here.  This is not strictly
- * necessary for the compiler, but provides an assurance that the signatures
- * of the functions in the dispatch table are correct.
- */
-static OSSL_OP_mac_newctx_fn gmac_new;
-static OSSL_OP_mac_dupctx_fn gmac_dup;
-static OSSL_OP_mac_freectx_fn gmac_free;
-static OSSL_OP_mac_gettable_params_fn gmac_gettable_params;
-static OSSL_OP_mac_get_params_fn gmac_get_params;
-static OSSL_OP_mac_settable_ctx_params_fn gmac_settable_ctx_params;
-static OSSL_OP_mac_set_ctx_params_fn gmac_set_ctx_params;
-static OSSL_OP_mac_init_fn gmac_init;
-static OSSL_OP_mac_update_fn gmac_update;
-static OSSL_OP_mac_final_fn gmac_final;
-
-/* local GMAC pkey structure */
-
-struct gmac_data_st {
-    void *provctx;
-    EVP_CIPHER_CTX *ctx;         /* Cipher context */
-    PROV_CIPHER cipher;
-};
-
-static size_t gmac_size(void);
-
-static void gmac_free(void *vmacctx)
-{
-    struct gmac_data_st *macctx = vmacctx;
-
-    if (macctx != NULL) {
-        EVP_CIPHER_CTX_free(macctx->ctx);
-        ossl_prov_cipher_reset(&macctx->cipher);
-        OPENSSL_free(macctx);
-    }
-}
-
-static void *gmac_new(void *provctx)
-{
-    struct gmac_data_st *macctx;
-
-    if ((macctx = OPENSSL_zalloc(sizeof(*macctx))) == NULL
-        || (macctx->ctx = EVP_CIPHER_CTX_new()) == NULL) {
-        gmac_free(macctx);
-        return NULL;
-    }
-    macctx->provctx = provctx;
-
-    return macctx;
-}
-
-static void *gmac_dup(void *vsrc)
-{
-    struct gmac_data_st *src = vsrc;
-    struct gmac_data_st *dst = gmac_new(src->provctx);
-
-    if (dst == NULL)
-        return NULL;
-
-    if (!EVP_CIPHER_CTX_copy(dst->ctx, src->ctx)
-        || !ossl_prov_cipher_copy(&dst->cipher, &src->cipher)) {
-        gmac_free(dst);
-        return NULL;
-    }
-    return dst;
-}
-
-static int gmac_init(void *vmacctx)
-{
-    return 1;
-}
-
-static int gmac_update(void *vmacctx, const unsigned char *data,
-                       size_t datalen)
-{
-    struct gmac_data_st *macctx = vmacctx;
-    EVP_CIPHER_CTX *ctx = macctx->ctx;
-    int outlen;
-
-    while (datalen > INT_MAX) {
-        if (!EVP_EncryptUpdate(ctx, NULL, &outlen, data, INT_MAX))
-            return 0;
-        data += INT_MAX;
-        datalen -= INT_MAX;
-    }
-    return EVP_EncryptUpdate(ctx, NULL, &outlen, data, datalen);
-}
-
-static int gmac_final(void *vmacctx, unsigned char *out, size_t *outl,
-                      size_t outsize)
-{
-    struct gmac_data_st *macctx = vmacctx;
-    int hlen = 0;
-
-    if (!EVP_EncryptFinal_ex(macctx->ctx, out, &hlen))
-        return 0;
-
-    /* TODO(3.0) Use params */
-    hlen = gmac_size();
-    if (!EVP_CIPHER_CTX_ctrl(macctx->ctx, EVP_CTRL_AEAD_GET_TAG,
-                             hlen, out))
-        return 0;
-
-    *outl = hlen;
-    return 1;
-}
-
-static size_t gmac_size(void)
-{
-    return EVP_GCM_TLS_TAG_LEN;
-}
-
-static const OSSL_PARAM known_gettable_params[] = {
-    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
-    OSSL_PARAM_END
-};
-static const OSSL_PARAM *gmac_gettable_params(void)
-{
-    return known_gettable_params;
-}
-
-static int gmac_get_params(OSSL_PARAM params[])
-{
-    OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL)
-        return OSSL_PARAM_set_size_t(p, gmac_size());
-
-    return 1;
-}
-
-static const OSSL_PARAM known_settable_ctx_params[] = {
-    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_CIPHER, NULL, 0),
-    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0),
-    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
-    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_IV, NULL, 0),
-    OSSL_PARAM_END
-};
-static const OSSL_PARAM *gmac_settable_ctx_params(void)
-{
-    return known_settable_ctx_params;
-}
-
-/*
- * ALL parameters should be set before init().
- */
-static int gmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[])
-{
-    struct gmac_data_st *macctx = vmacctx;
-    EVP_CIPHER_CTX *ctx = macctx->ctx;
-    OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(macctx->provctx);
-    const OSSL_PARAM *p;
-
-   if (ctx == NULL
-        || !ossl_prov_cipher_load_from_params(&macctx->cipher, params, provctx))
-        return 0;
-
-    if (EVP_CIPHER_mode(ossl_prov_cipher_cipher(&macctx->cipher))
-        != EVP_CIPH_GCM_MODE) {
-        ERR_raise(ERR_LIB_PROV, EVP_R_CIPHER_NOT_GCM_MODE);
-        return 0;
-    }
-    if (!EVP_EncryptInit_ex(ctx, ossl_prov_cipher_cipher(&macctx->cipher),
-                            ossl_prov_cipher_engine(&macctx->cipher), NULL,
-                            NULL))
-        return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
-        if (p->data_type != OSSL_PARAM_OCTET_STRING)
-            return 0;
-
-        if (p->data_size != (size_t)EVP_CIPHER_CTX_key_length(ctx)) {
-            ERR_raise(ERR_LIB_PROV, EVP_R_INVALID_KEY_LENGTH);
-            return 0;
-        }
-        if (!EVP_EncryptInit_ex(ctx, NULL, NULL, p->data, NULL))
-            return 0;
-    }
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_IV)) != NULL) {
-        if (p->data_type != OSSL_PARAM_OCTET_STRING)
-            return 0;
-
-        if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
-                                 p->data_size, NULL)
-            || !EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, p->data))
-            return 0;
-    }
-    return 1;
-}
-
-const OSSL_DISPATCH gmac_functions[] = {
-    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))gmac_new },
-    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))gmac_dup },
-    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))gmac_free },
-    { OSSL_FUNC_MAC_INIT, (void (*)(void))gmac_init },
-    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))gmac_update },
-    { OSSL_FUNC_MAC_FINAL, (void (*)(void))gmac_final },
-    { OSSL_FUNC_MAC_GETTABLE_PARAMS, (void (*)(void))gmac_gettable_params },
-    { OSSL_FUNC_MAC_GET_PARAMS, (void (*)(void))gmac_get_params },
-    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
-      (void (*)(void))gmac_settable_ctx_params },
-    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))gmac_set_ctx_params },
-    { 0, NULL }
-};
diff --git a/providers/common/macs/hmac_prov.c b/providers/common/macs/hmac_prov.c
deleted file mode 100644 (file)
index e9d7647..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright 2018 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/core_numbers.h>
-#include <openssl/core_names.h>
-#include <openssl/params.h>
-#include <openssl/engine.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
-#include "internal/provider_util.h"
-
-/*
- * Forward declaration of everything implemented here.  This is not strictly
- * necessary for the compiler, but provides an assurance that the signatures
- * of the functions in the dispatch table are correct.
- */
-static OSSL_OP_mac_newctx_fn hmac_new;
-static OSSL_OP_mac_dupctx_fn hmac_dup;
-static OSSL_OP_mac_freectx_fn hmac_free;
-static OSSL_OP_mac_gettable_ctx_params_fn hmac_gettable_ctx_params;
-static OSSL_OP_mac_get_ctx_params_fn hmac_get_ctx_params;
-static OSSL_OP_mac_settable_ctx_params_fn hmac_settable_ctx_params;
-static OSSL_OP_mac_set_ctx_params_fn hmac_set_ctx_params;
-static OSSL_OP_mac_init_fn hmac_init;
-static OSSL_OP_mac_update_fn hmac_update;
-static OSSL_OP_mac_final_fn hmac_final;
-
-/* local HMAC context structure */
-
-/* typedef EVP_MAC_IMPL */
-struct hmac_data_st {
-    void *provctx;
-    HMAC_CTX *ctx;               /* HMAC context */
-    PROV_DIGEST digest;
-};
-
-static size_t hmac_size(void *vmacctx);
-
-static void *hmac_new(void *provctx)
-{
-    struct hmac_data_st *macctx;
-
-    if ((macctx = OPENSSL_zalloc(sizeof(*macctx))) == NULL
-        || (macctx->ctx = HMAC_CTX_new()) == NULL) {
-        OPENSSL_free(macctx);
-        return NULL;
-    }
-    /* TODO(3.0) Should we do something more with that context? */
-    macctx->provctx = provctx;
-
-    return macctx;
-}
-
-static void hmac_free(void *vmacctx)
-{
-    struct hmac_data_st *macctx = vmacctx;
-
-    if (macctx != NULL) {
-        HMAC_CTX_free(macctx->ctx);
-        ossl_prov_digest_reset(&macctx->digest);
-        OPENSSL_free(macctx);
-    }
-}
-
-static void *hmac_dup(void *vsrc)
-{
-    struct hmac_data_st *src = vsrc;
-    struct hmac_data_st *dst = hmac_new(src->provctx);
-
-    if (dst == NULL)
-        return NULL;
-
-    if (!HMAC_CTX_copy(dst->ctx, src->ctx)
-        || !ossl_prov_digest_copy(&dst->digest, &src->digest)) {
-        hmac_free(dst);
-        return NULL;
-    }
-    return dst;
-}
-
-static size_t hmac_size(void *vmacctx)
-{
-    struct hmac_data_st *macctx = vmacctx;
-
-    return HMAC_size(macctx->ctx);
-}
-
-static int hmac_init(void *vmacctx)
-{
-    struct hmac_data_st *macctx = vmacctx;
-    const EVP_MD *digest = ossl_prov_digest_md(&macctx->digest);
-    int rv = 1;
-
-    /* HMAC_Init_ex doesn't tolerate all zero params, so we must be careful */
-    if (digest != NULL)
-        rv = HMAC_Init_ex(macctx->ctx, NULL, 0, digest,
-                          ossl_prov_digest_engine(&macctx->digest));
-    ossl_prov_digest_reset(&macctx->digest);
-    return rv;
-}
-
-static int hmac_update(void *vmacctx, const unsigned char *data,
-                       size_t datalen)
-{
-    struct hmac_data_st *macctx = vmacctx;
-
-    return HMAC_Update(macctx->ctx, data, datalen);
-}
-
-static int hmac_final(void *vmacctx, unsigned char *out, size_t *outl,
-                      size_t outsize)
-{
-    unsigned int hlen;
-    struct hmac_data_st *macctx = vmacctx;
-
-    if (!HMAC_Final(macctx->ctx, out, &hlen))
-        return 0;
-    if (outl != NULL)
-        *outl = hlen;
-    return 1;
-}
-
-static const OSSL_PARAM known_gettable_ctx_params[] = {
-    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
-    OSSL_PARAM_END
-};
-static const OSSL_PARAM *hmac_gettable_ctx_params(void)
-{
-    return known_gettable_ctx_params;
-}
-
-static int hmac_get_ctx_params(void *vmacctx, OSSL_PARAM params[])
-{
-    OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL)
-        return OSSL_PARAM_set_size_t(p, hmac_size(vmacctx));
-
-    return 1;
-}
-
-static const OSSL_PARAM known_settable_ctx_params[] = {
-    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_DIGEST, NULL, 0),
-    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0),
-    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
-    OSSL_PARAM_int(OSSL_MAC_PARAM_FLAGS, NULL),
-    OSSL_PARAM_END
-};
-static const OSSL_PARAM *hmac_settable_ctx_params(void)
-{
-    return known_settable_ctx_params;
-}
-
-/*
- * ALL parameters should be set before init().
- */
-static int hmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[])
-{
-    struct hmac_data_st *macctx = vmacctx;
-    OPENSSL_CTX *ctx = PROV_LIBRARY_CONTEXT_OF(macctx->provctx);
-    const OSSL_PARAM *p;
-
-    if (!ossl_prov_digest_load_from_params(&macctx->digest, params, ctx))
-        return 0;
-
-    /* TODO(3.0) formalize the meaning of "flags", perhaps as other params */
-    if ((p = OSSL_PARAM_locate_const(params,
-                                     OSSL_MAC_PARAM_FLAGS)) != NULL) {
-        int flags = 0;
-
-        if (!OSSL_PARAM_get_int(p, &flags))
-            return 0;
-        HMAC_CTX_set_flags(macctx->ctx, flags);
-    }
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
-        if (p->data_type != OSSL_PARAM_OCTET_STRING)
-            return 0;
-
-        if (!HMAC_Init_ex(macctx->ctx, p->data, p->data_size,
-                          ossl_prov_digest_md(&macctx->digest),
-                          NULL /* ENGINE */))
-            return 0;
-
-        ossl_prov_digest_reset(&macctx->digest);
-    }
-    return 1;
-}
-
-const OSSL_DISPATCH hmac_functions[] = {
-    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))hmac_new },
-    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))hmac_dup },
-    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))hmac_free },
-    { OSSL_FUNC_MAC_INIT, (void (*)(void))hmac_init },
-    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))hmac_update },
-    { OSSL_FUNC_MAC_FINAL, (void (*)(void))hmac_final },
-    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
-      (void (*)(void))hmac_gettable_ctx_params },
-    { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))hmac_get_ctx_params },
-    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
-      (void (*)(void))hmac_settable_ctx_params },
-    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))hmac_set_ctx_params },
-    { 0, NULL }
-};
diff --git a/providers/common/macs/kmac_prov.c b/providers/common/macs/kmac_prov.c
deleted file mode 100644 (file)
index 99bcbf7..0000000
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
- * Copyright 2018 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
- */
-
-/*
- * See SP800-185 "Appendix A - KMAC, .... in Terms of Keccak[c]"
- *
- * Inputs are:
- *    K = Key                  (len(K) < 2^2040 bits)
- *    X = Input
- *    L = Output length        (0 <= L < 2^2040 bits)
- *    S = Customization String Default="" (len(S) < 2^2040 bits)
- *
- * KMAC128(K, X, L, S)
- * {
- *     newX = bytepad(encode_string(K), 168) ||  X || right_encode(L).
- *     T = bytepad(encode_string("KMAC") || encode_string(S), 168).
- *     return KECCAK[256](T || newX || 00, L).
- * }
- *
- * KMAC256(K, X, L, S)
- * {
- *     newX = bytepad(encode_string(K), 136) ||  X || right_encode(L).
- *     T = bytepad(encode_string("KMAC") || encode_string(S), 136).
- *     return KECCAK[512](T || newX || 00, L).
- * }
- *
- * KMAC128XOF(K, X, L, S)
- * {
- *     newX = bytepad(encode_string(K), 168) ||  X || right_encode(0).
- *     T = bytepad(encode_string("KMAC") || encode_string(S), 168).
- *     return KECCAK[256](T || newX || 00, L).
- * }
- *
- * KMAC256XOF(K, X, L, S)
- * {
- *     newX = bytepad(encode_string(K), 136) ||  X || right_encode(0).
- *     T = bytepad(encode_string("KMAC") || encode_string(S), 136).
- *     return KECCAK[512](T || newX || 00, L).
- * }
- *
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <openssl/core_numbers.h>
-#include <openssl/core_names.h>
-#include <openssl/params.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
-
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
-#include "internal/provider_util.h"
-
-/*
- * Forward declaration of everything implemented here.  This is not strictly
- * necessary for the compiler, but provides an assurance that the signatures
- * of the functions in the dispatch table are correct.
- */
-static OSSL_OP_mac_newctx_fn kmac128_new;
-static OSSL_OP_mac_newctx_fn kmac256_new;
-static OSSL_OP_mac_dupctx_fn kmac_dup;
-static OSSL_OP_mac_freectx_fn kmac_free;
-static OSSL_OP_mac_gettable_ctx_params_fn kmac_gettable_ctx_params;
-static OSSL_OP_mac_get_ctx_params_fn kmac_get_ctx_params;
-static OSSL_OP_mac_settable_ctx_params_fn kmac_settable_ctx_params;
-static OSSL_OP_mac_set_ctx_params_fn kmac_set_ctx_params;
-static OSSL_OP_mac_size_fn kmac_size;
-static OSSL_OP_mac_init_fn kmac_init;
-static OSSL_OP_mac_update_fn kmac_update;
-static OSSL_OP_mac_final_fn kmac_final;
-
-#define KMAC_MAX_BLOCKSIZE ((1600 - 128*2) / 8) /* 168 */
-#define KMAC_MIN_BLOCKSIZE ((1600 - 256*2) / 8) /* 136 */
-
-/* Length encoding will be  a 1 byte size + length in bits (2 bytes max) */
-#define KMAC_MAX_ENCODED_HEADER_LEN 3
-
-/*
- * Custom string max size is chosen such that:
- *   len(encoded_string(custom) + len(kmac_encoded_string) <= KMAC_MIN_BLOCKSIZE
- *   i.e: (KMAC_MAX_CUSTOM + KMAC_MAX_ENCODED_LEN) + 6 <= 136
- */
-#define KMAC_MAX_CUSTOM 127
-
-/* Maximum size of encoded custom string */
-#define KMAC_MAX_CUSTOM_ENCODED (KMAC_MAX_CUSTOM + KMAC_MAX_ENCODED_HEADER_LEN)
-
-/* Maximum key size in bytes = 2040 / 8 */
-#define KMAC_MAX_KEY 255
-
-/*
- * Maximum Encoded Key size will be padded to a multiple of the blocksize
- * i.e KMAC_MAX_KEY + KMAC_MAX_ENCODED_LEN = 258
- * Padded to a multiple of KMAC_MAX_BLOCKSIZE
- */
-#define KMAC_MAX_KEY_ENCODED (KMAC_MAX_BLOCKSIZE * 2)
-
-/* Fixed value of encode_string("KMAC") */
-static const unsigned char kmac_string[] = {
-    0x01, 0x20, 0x4B, 0x4D, 0x41, 0x43
-};
-
-
-#define KMAC_FLAG_XOF_MODE          1
-
-struct kmac_data_st {
-    void  *provctx;
-    EVP_MD_CTX *ctx;
-    PROV_DIGEST digest;
-    size_t out_len;
-    int key_len;
-    int custom_len;
-    /* If xof_mode = 1 then we use right_encode(0) */
-    int xof_mode;
-    /* key and custom are stored in encoded form */
-    unsigned char key[KMAC_MAX_KEY_ENCODED];
-    unsigned char custom[KMAC_MAX_CUSTOM_ENCODED];
-};
-
-static int encode_string(unsigned char *out, int *out_len,
-                         const unsigned char *in, int in_len);
-static int right_encode(unsigned char *out, int *out_len, size_t bits);
-static int bytepad(unsigned char *out, int *out_len,
-                   const unsigned char *in1, int in1_len,
-                   const unsigned char *in2, int in2_len,
-                   int w);
-static int kmac_bytepad_encode_key(unsigned char *out, int *out_len,
-                                   const unsigned char *in, int in_len,
-                                   int w);
-
-static void kmac_free(void *vmacctx)
-{
-    struct kmac_data_st *kctx = vmacctx;
-
-    if (kctx != NULL) {
-        EVP_MD_CTX_free(kctx->ctx);
-        ossl_prov_digest_reset(&kctx->digest);
-        OPENSSL_cleanse(kctx->key, kctx->key_len);
-        OPENSSL_cleanse(kctx->custom, kctx->custom_len);
-        OPENSSL_free(kctx);
-    }
-}
-
-/*
- * We have KMAC implemented as a hash, which we can use instead of
- * reimplementing the EVP functionality with direct use of
- * keccak_mac_init() and friends.
- */
-static struct kmac_data_st *kmac_new(void *provctx)
-{
-    struct kmac_data_st *kctx;
-
-    if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL
-            || (kctx->ctx = EVP_MD_CTX_new()) == NULL) {
-        kmac_free(kctx);
-        return NULL;
-    }
-    kctx->provctx = provctx;
-    return kctx;
-}
-
-static void *kmac_fetch_new(void *provctx, const OSSL_PARAM *params)
-{
-    struct kmac_data_st *kctx = kmac_new(provctx);
-
-    if (kctx == NULL)
-        return 0;
-    if (!ossl_prov_digest_load_from_params(&kctx->digest, params,
-                                      PROV_LIBRARY_CONTEXT_OF(provctx))) {
-        kmac_free(kctx);
-        return 0;
-    }
-
-    kctx->out_len = EVP_MD_size(ossl_prov_digest_md(&kctx->digest));
-    return kctx;
-}
-
-static void *kmac128_new(void *provctx)
-{
-    static const OSSL_PARAM kmac128_params[] = {
-        OSSL_PARAM_utf8_string("digest", OSSL_DIGEST_NAME_KECCAK_KMAC128,
-                               sizeof(OSSL_DIGEST_NAME_KECCAK_KMAC128)),
-        OSSL_PARAM_END
-    };
-    return kmac_fetch_new(provctx, kmac128_params);
-}
-
-static void *kmac256_new(void *provctx)
-{
-    static const OSSL_PARAM kmac256_params[] = {
-        OSSL_PARAM_utf8_string("digest", OSSL_DIGEST_NAME_KECCAK_KMAC256,
-                               sizeof(OSSL_DIGEST_NAME_KECCAK_KMAC256)),
-        OSSL_PARAM_END
-    };
-    return kmac_fetch_new(provctx, kmac256_params);
-}
-
-static void *kmac_dup(void *vsrc)
-{
-    struct kmac_data_st *src = vsrc;
-    struct kmac_data_st *dst = kmac_new(src->provctx);
-
-    if (dst == NULL)
-        return NULL;
-
-    if (!EVP_MD_CTX_copy(dst->ctx, src->ctx)
-        || !ossl_prov_digest_copy(&dst->digest, &src->digest)) {
-        kmac_free(dst);
-        return NULL;
-    }
-
-    dst->out_len = src->out_len;
-    dst->key_len = src->key_len;
-    dst->custom_len = src->custom_len;
-    dst->xof_mode = src->xof_mode;
-    memcpy(dst->key, src->key, src->key_len);
-    memcpy(dst->custom, src->custom, dst->custom_len);
-
-    return dst;
-}
-
-/*
- * The init() assumes that any ctrl methods are set beforehand for
- * md, key and custom. Setting the fields afterwards will have no
- * effect on the output mac.
- */
-static int kmac_init(void *vmacctx)
-{
-    struct kmac_data_st *kctx = vmacctx;
-    EVP_MD_CTX *ctx = kctx->ctx;
-    unsigned char out[KMAC_MAX_BLOCKSIZE];
-    int out_len, block_len;
-
-
-    /* Check key has been set */
-    if (kctx->key_len == 0) {
-        EVPerr(EVP_F_KMAC_INIT, EVP_R_NO_KEY_SET);
-        return 0;
-    }
-    if (!EVP_DigestInit_ex(kctx->ctx, ossl_prov_digest_md(&kctx->digest),
-                           NULL))
-        return 0;
-
-    block_len = EVP_MD_block_size(ossl_prov_digest_md(&kctx->digest));
-
-    /* Set default custom string if it is not already set */
-    if (kctx->custom_len == 0) {
-        const OSSL_PARAM params[] = {
-            OSSL_PARAM_octet_string(OSSL_MAC_PARAM_CUSTOM, "", 0),
-            OSSL_PARAM_END
-        };
-        (void)kmac_set_ctx_params(kctx, params);
-    }
-
-    return bytepad(out, &out_len, kmac_string, sizeof(kmac_string),
-                   kctx->custom, kctx->custom_len, block_len)
-           && EVP_DigestUpdate(ctx, out, out_len)
-           && EVP_DigestUpdate(ctx, kctx->key, kctx->key_len);
-}
-
-static size_t kmac_size(void *vmacctx)
-{
-    struct kmac_data_st *kctx = vmacctx;
-
-    return kctx->out_len;
-}
-
-static int kmac_update(void *vmacctx, const unsigned char *data,
-                       size_t datalen)
-{
-    struct kmac_data_st *kctx = vmacctx;
-
-    return EVP_DigestUpdate(kctx->ctx, data, datalen);
-}
-
-static int kmac_final(void *vmacctx, unsigned char *out, size_t *outl,
-                      size_t outsize)
-{
-    struct kmac_data_st *kctx = vmacctx;
-    EVP_MD_CTX *ctx = kctx->ctx;
-    int lbits, len;
-    unsigned char encoded_outlen[KMAC_MAX_ENCODED_HEADER_LEN];
-    int ok;
-
-    /* KMAC XOF mode sets the encoded length to 0 */
-    lbits = (kctx->xof_mode ? 0 : (kctx->out_len * 8));
-
-    ok = right_encode(encoded_outlen, &len, lbits)
-        && EVP_DigestUpdate(ctx, encoded_outlen, len)
-        && EVP_DigestFinalXOF(ctx, out, kctx->out_len);
-    if (ok && outl != NULL)
-        *outl = kctx->out_len;
-    return ok;
-}
-
-static const OSSL_PARAM known_gettable_ctx_params[] = {
-    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
-    OSSL_PARAM_END
-};
-static const OSSL_PARAM *kmac_gettable_ctx_params(void)
-{
-    return known_gettable_ctx_params;
-}
-
-static int kmac_get_ctx_params(void *vmacctx, OSSL_PARAM params[])
-{
-    OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL)
-        return OSSL_PARAM_set_size_t(p, kmac_size(vmacctx));
-
-    return 1;
-}
-
-static const OSSL_PARAM known_settable_ctx_params[] = {
-    OSSL_PARAM_int(OSSL_MAC_PARAM_XOF, NULL),
-    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
-    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
-    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_CUSTOM, NULL, 0),
-    OSSL_PARAM_END
-};
-static const OSSL_PARAM *kmac_settable_ctx_params(void)
-{
-    return known_settable_ctx_params;
-}
-
-/*
- * The following params can be set any time before final():
- *     - "outlen" or "size":    The requested output length.
- *     - "xof":                 If set, this indicates that right_encoded(0)
- *                              is part of the digested data, otherwise it
- *                              uses right_encoded(requested output length).
- *
- * All other params should be set before init().
- */
-static int kmac_set_ctx_params(void *vmacctx, const OSSL_PARAM *params)
-{
-    struct kmac_data_st *kctx = vmacctx;
-    const OSSL_PARAM *p;
-    const EVP_MD *digest = ossl_prov_digest_md(&kctx->digest);
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_XOF)) != NULL
-        && !OSSL_PARAM_get_int(p, &kctx->xof_mode))
-        return 0;
-    if (((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE)) != NULL)
-        && !OSSL_PARAM_get_size_t(p, &kctx->out_len))
-        return 0;
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
-        if (p->data_size < 4 || p->data_size > KMAC_MAX_KEY) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
-            return 0;
-        }
-        if (!kmac_bytepad_encode_key(kctx->key, &kctx->key_len,
-                                     p->data, p->data_size,
-                                     EVP_MD_block_size(digest)))
-            return 0;
-    }
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_CUSTOM))
-        != NULL) {
-        if (p->data_size > KMAC_MAX_CUSTOM) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CUSTOM_LENGTH);
-            return 0;
-        }
-        if (!encode_string(kctx->custom, &kctx->custom_len,
-                           p->data, p->data_size))
-            return 0;
-    }
-    return 1;
-}
-
-/*
- * Encoding/Padding Methods.
- */
-
-/* Returns the number of bytes required to store 'bits' into a byte array */
-static unsigned int get_encode_size(size_t bits)
-{
-    unsigned int cnt = 0, sz = sizeof(size_t);
-
-    while (bits && (cnt < sz)) {
-        ++cnt;
-        bits >>= 8;
-    }
-    /* If bits is zero 1 byte is required */
-    if (cnt == 0)
-        cnt = 1;
-    return cnt;
-}
-
-/*
- * Convert an integer into bytes . The number of bytes is appended
- * to the end of the buffer. Returns an array of bytes 'out' of size
- * *out_len.
- *
- * e.g if bits = 32, out[2] = { 0x20, 0x01 }
- *
- */
-static int right_encode(unsigned char *out, int *out_len, size_t bits)
-{
-    unsigned int len = get_encode_size(bits);
-    int i;
-
-    /* The length is constrained to a single byte: 2040/8 = 255 */
-    if (len > 0xFF)
-        return 0;
-
-    /* MSB's are at the start of the bytes array */
-    for (i = len - 1; i >= 0; --i) {
-        out[i] = (unsigned char)(bits & 0xFF);
-        bits >>= 8;
-    }
-    /* Tack the length onto the end */
-    out[len] = (unsigned char)len;
-
-    /* The Returned length includes the tacked on byte */
-    *out_len = len + 1;
-    return 1;
-}
-
-/*
- * Encodes a string with a left encoded length added. Note that the
- * in_len is converted to bits (*8).
- *
- * e.g- in="KMAC" gives out[6] = { 0x01, 0x20, 0x4B, 0x4D, 0x41, 0x43 }
- *                                 len   bits    K     M     A     C
- */
-static int encode_string(unsigned char *out, int *out_len,
-                         const unsigned char *in, int in_len)
-{
-    if (in == NULL) {
-        *out_len = 0;
-    } else {
-        int i, bits, len;
-
-        bits = 8 * in_len;
-        len = get_encode_size(bits);
-        if (len > 0xFF)
-            return 0;
-
-        out[0] = len;
-        for (i = len; i > 0; --i) {
-            out[i] = (bits & 0xFF);
-            bits >>= 8;
-        }
-        memcpy(out + len + 1, in, in_len);
-        *out_len = (1 + len + in_len);
-    }
-    return 1;
-}
-
-/*
- * Returns a zero padded encoding of the inputs in1 and an optional
- * in2 (can be NULL). The padded output must be a multiple of the blocksize 'w'.
- * The value of w is in bytes (< 256).
- *
- * The returned output is:
- *    zero_padded(multiple of w, (left_encode(w) || in1 [|| in2])
- */
-static int bytepad(unsigned char *out, int *out_len,
-                   const unsigned char *in1, int in1_len,
-                   const unsigned char *in2, int in2_len, int w)
-{
-    int len;
-    unsigned char *p = out;
-    int sz = w;
-
-    /* Left encoded w */
-    *p++ = 1;
-    *p++ = w;
-    /* || in1 */
-    memcpy(p, in1, in1_len);
-    p += in1_len;
-    /* [ || in2 ] */
-    if (in2 != NULL && in2_len > 0) {
-        memcpy(p, in2, in2_len);
-        p += in2_len;
-    }
-    /* Figure out the pad size (divisible by w) */
-    len = p - out;
-    while (len > sz) {
-        sz += w;
-    }
-    /* zero pad the end of the buffer */
-    memset(p, 0, sz - len);
-    *out_len = sz;
-    return 1;
-}
-
-/*
- * Returns out = bytepad(encode_string(in), w)
- */
-static int kmac_bytepad_encode_key(unsigned char *out, int *out_len,
-                                   const unsigned char *in, int in_len,
-                                   int w)
-{
-    unsigned char tmp[KMAC_MAX_KEY + KMAC_MAX_ENCODED_HEADER_LEN];
-    int tmp_len;
-
-    if (!encode_string(tmp, &tmp_len, in, in_len))
-        return 0;
-
-    return bytepad(out, out_len, tmp, tmp_len, NULL, 0, w);
-}
-
-const OSSL_DISPATCH kmac128_functions[] = {
-    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))kmac128_new },
-    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))kmac_dup },
-    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))kmac_free },
-    { OSSL_FUNC_MAC_INIT, (void (*)(void))kmac_init },
-    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))kmac_update },
-    { OSSL_FUNC_MAC_FINAL, (void (*)(void))kmac_final },
-    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
-      (void (*)(void))kmac_gettable_ctx_params },
-    { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))kmac_get_ctx_params },
-    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
-      (void (*)(void))kmac_settable_ctx_params },
-    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))kmac_set_ctx_params },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH kmac256_functions[] = {
-    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))kmac256_new },
-    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))kmac_dup },
-    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))kmac_free },
-    { OSSL_FUNC_MAC_INIT, (void (*)(void))kmac_init },
-    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))kmac_update },
-    { OSSL_FUNC_MAC_FINAL, (void (*)(void))kmac_final },
-    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
-      (void (*)(void))kmac_gettable_ctx_params },
-    { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))kmac_get_ctx_params },
-    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
-      (void (*)(void))kmac_settable_ctx_params },
-    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))kmac_set_ctx_params },
-    { 0, NULL }
-};
diff --git a/providers/common/signature/build.info b/providers/common/signature/build.info
deleted file mode 100644 (file)
index 496fb7d..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-$GOAL=../../libimplementations.a
-
-IF[{- !$disabled{dsa} -}]
-  SOURCE[$GOAL]=dsa.c
-ENDIF
-
-
diff --git a/providers/common/signature/dsa.c b/providers/common/signature/dsa.c
deleted file mode 100644 (file)
index 1d6b565..0000000
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * 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/crypto.h>
-#include <openssl/core_numbers.h>
-#include <openssl/core_names.h>
-#include <openssl/dsa.h>
-#include <openssl/params.h>
-#include <openssl/evp.h>
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
-
-static OSSL_OP_signature_newctx_fn dsa_newctx;
-static OSSL_OP_signature_sign_init_fn dsa_signature_init;
-static OSSL_OP_signature_verify_init_fn dsa_signature_init;
-static OSSL_OP_signature_sign_fn dsa_sign;
-static OSSL_OP_signature_verify_fn dsa_verify;
-static OSSL_OP_signature_digest_sign_init_fn dsa_digest_signverify_init;
-static OSSL_OP_signature_digest_sign_update_fn dsa_digest_signverify_update;
-static OSSL_OP_signature_digest_sign_final_fn dsa_digest_sign_final;
-static OSSL_OP_signature_digest_verify_init_fn dsa_digest_signverify_init;
-static OSSL_OP_signature_digest_verify_update_fn dsa_digest_signverify_update;
-static OSSL_OP_signature_digest_verify_final_fn dsa_digest_verify_final;
-static OSSL_OP_signature_freectx_fn dsa_freectx;
-static OSSL_OP_signature_dupctx_fn dsa_dupctx;
-static OSSL_OP_signature_get_ctx_params_fn dsa_get_ctx_params;
-static OSSL_OP_signature_gettable_ctx_params_fn dsa_gettable_ctx_params;
-static OSSL_OP_signature_set_ctx_params_fn dsa_set_ctx_params;
-static OSSL_OP_signature_settable_ctx_params_fn dsa_settable_ctx_params;
-static OSSL_OP_signature_get_ctx_md_params_fn dsa_get_ctx_md_params;
-static OSSL_OP_signature_gettable_ctx_md_params_fn dsa_gettable_ctx_md_params;
-static OSSL_OP_signature_set_ctx_md_params_fn dsa_set_ctx_md_params;
-static OSSL_OP_signature_settable_ctx_md_params_fn dsa_settable_ctx_md_params;
-
-/*
- * What's passed as an actual key is defined by the KEYMGMT interface.
- * We happen to know that our KEYMGMT simply passes DSA structures, so
- * we use that here too.
- */
-
-typedef struct {
-    OPENSSL_CTX *libctx;
-    DSA *dsa;
-    size_t mdsize;
-    /* Should be big enough */
-    char mdname[80];
-    EVP_MD *md;
-    EVP_MD_CTX *mdctx;
-} PROV_DSA_CTX;
-
-static void *dsa_newctx(void *provctx)
-{
-    PROV_DSA_CTX *pdsactx = OPENSSL_zalloc(sizeof(PROV_DSA_CTX));
-
-    if (pdsactx == NULL)
-        return NULL;
-
-    pdsactx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
-    return pdsactx;
-}
-
-static int dsa_signature_init(void *vpdsactx, void *vdsa)
-{
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-
-    if (pdsactx == NULL || vdsa == NULL || !DSA_up_ref(vdsa))
-        return 0;
-    DSA_free(pdsactx->dsa);
-    pdsactx->dsa = vdsa;
-    return 1;
-}
-
-static int dsa_sign(void *vpdsactx, unsigned char *sig, size_t *siglen,
-                    size_t sigsize, const unsigned char *tbs, size_t tbslen)
-{
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-    int ret;
-    unsigned int sltmp;
-    size_t dsasize = DSA_size(pdsactx->dsa);
-
-    if (sig == NULL) {
-        *siglen = dsasize;
-        return 1;
-    }
-
-    if (sigsize < (size_t)dsasize)
-        return 0;
-
-    if (pdsactx->mdsize != 0 && tbslen != pdsactx->mdsize)
-        return 0;
-
-    ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, pdsactx->dsa);
-
-    if (ret <= 0)
-        return 0;
-
-    *siglen = sltmp;
-    return 1;
-}
-
-static int dsa_verify(void *vpdsactx, const unsigned char *sig, size_t siglen,
-                      const unsigned char *tbs, size_t tbslen)
-{
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-
-    if (pdsactx->mdsize != 0 && tbslen != pdsactx->mdsize)
-        return 0;
-
-    return DSA_verify(0, tbs, tbslen, sig, siglen, pdsactx->dsa);
-}
-
-static int dsa_digest_signverify_init(void *vpdsactx, const char *mdname,
-                                      const char *props, void *vdsa)
-{
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-    EVP_MD *md;
-
-    if (!dsa_signature_init(vpdsactx, vdsa))
-        return 0;
-
-    md = EVP_MD_fetch(pdsactx->libctx, mdname, props);
-    if (md == NULL)
-        return 0;
-    pdsactx->md = md;
-    pdsactx->mdsize = EVP_MD_size(md);
-    pdsactx->mdctx = EVP_MD_CTX_new();
-    if (pdsactx->mdctx == NULL)
-        return 0;
-
-    if (!EVP_DigestInit_ex(pdsactx->mdctx, md, NULL))
-        return 0;
-
-    return 1;
-}
-
-int dsa_digest_signverify_update(void *vpdsactx, const unsigned char *data,
-                                 size_t datalen)
-{
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-
-    if (pdsactx == NULL || pdsactx->mdctx == NULL)
-        return 0;
-
-    return EVP_DigestUpdate(pdsactx->mdctx, data, datalen);
-}
-
-int dsa_digest_sign_final(void *vpdsactx, unsigned char *sig, size_t *siglen,
-                          size_t sigsize)
-{
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-    unsigned char digest[EVP_MAX_MD_SIZE];
-    unsigned int dlen = 0;
-
-    if (pdsactx == NULL || pdsactx->mdctx == NULL)
-        return 0;
-
-    /*
-     * If sig is NULL then we're just finding out the sig size. Other fields
-     * are ignored. Defer to dsa_sign.
-     */
-    if (sig != NULL) {
-        /*
-         * TODO(3.0): There is the possibility that some externally provided
-         * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow -
-         * but that problem is much larger than just in DSA.
-         */
-        if (!EVP_DigestFinal_ex(pdsactx->mdctx, digest, &dlen))
-            return 0;
-    }
-
-    return dsa_sign(vpdsactx, sig, siglen, sigsize, digest, (size_t)dlen);
-}
-
-
-int dsa_digest_verify_final(void *vpdsactx, const unsigned char *sig,
-                            size_t siglen)
-{
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-    unsigned char digest[EVP_MAX_MD_SIZE];
-    unsigned int dlen = 0;
-
-    if (pdsactx == NULL || pdsactx->mdctx == NULL)
-        return 0;
-
-    /*
-     * TODO(3.0): There is the possibility that some externally provided
-     * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow -
-     * but that problem is much larger than just in DSA.
-     */
-    if (!EVP_DigestFinal_ex(pdsactx->mdctx, digest, &dlen))
-        return 0;
-
-    return dsa_verify(vpdsactx, sig, siglen, digest, (size_t)dlen);
-}
-
-static void dsa_freectx(void *vpdsactx)
-{
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-
-    DSA_free(pdsactx->dsa);
-    EVP_MD_CTX_free(pdsactx->mdctx);
-    EVP_MD_free(pdsactx->md);
-
-    OPENSSL_free(pdsactx);
-}
-
-static void *dsa_dupctx(void *vpdsactx)
-{
-    PROV_DSA_CTX *srcctx = (PROV_DSA_CTX *)vpdsactx;
-    PROV_DSA_CTX *dstctx;
-
-    dstctx = OPENSSL_zalloc(sizeof(*srcctx));
-    if (dstctx == NULL)
-        return NULL;
-
-    *dstctx = *srcctx;
-    dstctx->dsa = NULL;
-    dstctx->md = NULL;
-    dstctx->mdctx = NULL;
-
-    if (srcctx->dsa != NULL && !DSA_up_ref(srcctx->dsa))
-        goto err;
-    dstctx->dsa = srcctx->dsa;
-
-    if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md))
-        goto err;
-    dstctx->md = srcctx->md;
-
-    if (srcctx->mdctx != NULL) {
-        dstctx->mdctx = EVP_MD_CTX_new();
-        if (dstctx->mdctx == NULL
-                || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx))
-            goto err;
-    }
-
-    return dstctx;
- err:
-    dsa_freectx(dstctx);
-    return NULL;
-}
-
-static int dsa_get_ctx_params(void *vpdsactx, OSSL_PARAM *params)
-{
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-    OSSL_PARAM *p;
-
-    if (pdsactx == NULL || params == NULL)
-        return 0;
-
-    p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
-    if (p != NULL && !OSSL_PARAM_set_size_t(p, pdsactx->mdsize))
-        return 0;
-
-    p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST);
-    if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdsactx->md == NULL
-                                                    ? pdsactx->mdname
-                                                    : EVP_MD_name(pdsactx->md)))
-        return 0;
-
-    return 1;
-}
-
-static const OSSL_PARAM known_gettable_ctx_params[] = {
-    OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
-    OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
-    OSSL_PARAM_END
-};
-
-static const OSSL_PARAM *dsa_gettable_ctx_params(void)
-{
-    return known_gettable_ctx_params;
-}
-
-static int dsa_set_ctx_params(void *vpdsactx, const OSSL_PARAM params[])
-{
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-    const OSSL_PARAM *p;
-    char *mdname;
-
-    if (pdsactx == NULL || params == NULL)
-        return 0;
-
-    if (pdsactx->md != NULL) {
-        /*
-         * You cannot set the digest name/size when doing a DigestSign or
-         * DigestVerify.
-         */
-        return 1;
-    }
-
-    p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
-    if (p != NULL && !OSSL_PARAM_get_size_t(p, &pdsactx->mdsize))
-        return 0;
-
-    /*
-     * We never actually use the mdname, but we do support getting it later.
-     * This can be useful for applications that want to know the MD that they
-     * previously set.
-     */
-    p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST);
-    mdname = pdsactx->mdname;
-    if (p != NULL
-            && !OSSL_PARAM_get_utf8_string(p, &mdname, sizeof(pdsactx->mdname)))
-        return 0;
-
-    return 1;
-}
-
-static const OSSL_PARAM known_settable_ctx_params[] = {
-    OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
-    OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
-    OSSL_PARAM_END
-};
-
-static const OSSL_PARAM *dsa_settable_ctx_params(void)
-{
-    /*
-     * TODO(3.0): Should this function return a different set of settable ctx
-     * params if the ctx is being used for a DigestSign/DigestVerify? In that
-     * case it is not allowed to set the digest size/digest name because the
-     * digest is explicitly set as part of the init.
-     */
-    return known_settable_ctx_params;
-}
-
-static int dsa_get_ctx_md_params(void *vpdsactx, OSSL_PARAM *params)
-{
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-
-    if (pdsactx->mdctx == NULL)
-        return 0;
-
-    return EVP_MD_CTX_get_params(pdsactx->mdctx, params);
-}
-
-static const OSSL_PARAM *dsa_gettable_ctx_md_params(void *vpdsactx)
-{
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-
-    if (pdsactx->md == NULL)
-        return 0;
-
-    return EVP_MD_gettable_ctx_params(pdsactx->md);
-}
-
-static int dsa_set_ctx_md_params(void *vpdsactx, const OSSL_PARAM params[])
-{
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-
-    if (pdsactx->mdctx == NULL)
-        return 0;
-
-    return EVP_MD_CTX_set_params(pdsactx->mdctx, params);
-}
-
-static const OSSL_PARAM *dsa_settable_ctx_md_params(void *vpdsactx)
-{
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-
-    if (pdsactx->md == NULL)
-        return 0;
-
-    return EVP_MD_settable_ctx_params(pdsactx->md);
-}
-
-const OSSL_DISPATCH dsa_signature_functions[] = {
-    { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))dsa_newctx },
-    { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))dsa_signature_init },
-    { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))dsa_sign },
-    { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))dsa_signature_init },
-    { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))dsa_verify },
-    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
-      (void (*)(void))dsa_digest_signverify_init },
-    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE,
-      (void (*)(void))dsa_digest_signverify_update },
-    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL,
-      (void (*)(void))dsa_digest_sign_final },
-    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
-      (void (*)(void))dsa_digest_signverify_init },
-    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE,
-      (void (*)(void))dsa_digest_signverify_update },
-    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL,
-      (void (*)(void))dsa_digest_verify_final },
-    { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))dsa_freectx },
-    { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))dsa_dupctx },
-    { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))dsa_get_ctx_params },
-    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
-      (void (*)(void))dsa_gettable_ctx_params },
-    { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))dsa_set_ctx_params },
-    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
-      (void (*)(void))dsa_settable_ctx_params },
-    { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS,
-      (void (*)(void))dsa_get_ctx_md_params },
-    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS,
-      (void (*)(void))dsa_gettable_ctx_md_params },
-    { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS,
-      (void (*)(void))dsa_set_ctx_md_params },
-    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS,
-      (void (*)(void))dsa_settable_ctx_md_params },
-    { 0, NULL }
-};
diff --git a/providers/implementations/build.info b/providers/implementations/build.info
new file mode 100644 (file)
index 0000000..1170ef9
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS=macs kdfs exchange keymgmt signature
diff --git a/providers/implementations/exchange/build.info b/providers/implementations/exchange/build.info
new file mode 100644 (file)
index 0000000..fdedb86
--- /dev/null
@@ -0,0 +1,8 @@
+# We make separate GOAL variables for each algorithm, to make it easy to
+# switch each to the Legacy provider when needed.
+
+$DH_GOAL=../../libimplementations.a
+
+IF[{- !$disabled{dh} -}]
+  SOURCE[$DH_GOAL]=dh_exch.c
+ENDIF
diff --git a/providers/implementations/exchange/dh_exch.c b/providers/implementations/exchange/dh_exch.c
new file mode 100644 (file)
index 0000000..cfbda43
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * 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/crypto.h>
+#include <openssl/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/dh.h>
+#include <openssl/params.h>
+#include "internal/provider_algs.h"
+
+static OSSL_OP_keyexch_newctx_fn dh_newctx;
+static OSSL_OP_keyexch_init_fn dh_init;
+static OSSL_OP_keyexch_set_peer_fn dh_set_peer;
+static OSSL_OP_keyexch_derive_fn dh_derive;
+static OSSL_OP_keyexch_freectx_fn dh_freectx;
+static OSSL_OP_keyexch_dupctx_fn dh_dupctx;
+static OSSL_OP_keyexch_set_ctx_params_fn dh_set_ctx_params;
+static OSSL_OP_keyexch_settable_ctx_params_fn dh_settable_ctx_params;
+
+/*
+ * What's passed as an actual key is defined by the KEYMGMT interface.
+ * We happen to know that our KEYMGMT simply passes DH structures, so
+ * we use that here too.
+ */
+
+typedef struct {
+    DH *dh;
+    DH *dhpeer;
+    unsigned int pad : 1;
+} PROV_DH_CTX;
+
+static void *dh_newctx(void *provctx)
+{
+    return OPENSSL_zalloc(sizeof(PROV_DH_CTX));
+}
+
+static int dh_init(void *vpdhctx, void *vdh)
+{
+    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
+
+    if (pdhctx == NULL || vdh == NULL || !DH_up_ref(vdh))
+        return 0;
+    DH_free(pdhctx->dh);
+    pdhctx->dh = vdh;
+    return 1;
+}
+
+static int dh_set_peer(void *vpdhctx, void *vdh)
+{
+    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
+
+    if (pdhctx == NULL || vdh == NULL || !DH_up_ref(vdh))
+        return 0;
+    DH_free(pdhctx->dhpeer);
+    pdhctx->dhpeer = vdh;
+    return 1;
+}
+
+static int dh_derive(void *vpdhctx, unsigned char *secret, size_t *secretlen,
+                     size_t outlen)
+{
+    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
+    int ret;
+    size_t dhsize;
+    const BIGNUM *pub_key = NULL;
+
+    /* TODO(3.0): Add errors to stack */
+    if (pdhctx->dh == NULL || pdhctx->dhpeer == NULL)
+        return 0;
+
+    dhsize = (size_t)DH_size(pdhctx->dh);
+    if (secret == NULL) {
+        *secretlen = dhsize;
+        return 1;
+    }
+    if (outlen < dhsize)
+        return 0;
+
+    DH_get0_key(pdhctx->dhpeer, &pub_key, NULL);
+    ret = (pdhctx->pad) ? DH_compute_key_padded(secret, pub_key, pdhctx->dh)
+                        : DH_compute_key(secret, pub_key, pdhctx->dh);
+    if (ret <= 0)
+        return 0;
+
+    *secretlen = ret;
+    return 1;
+}
+
+static void dh_freectx(void *vpdhctx)
+{
+    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
+
+    DH_free(pdhctx->dh);
+    DH_free(pdhctx->dhpeer);
+
+    OPENSSL_free(pdhctx);
+}
+
+static void *dh_dupctx(void *vpdhctx)
+{
+    PROV_DH_CTX *srcctx = (PROV_DH_CTX *)vpdhctx;
+    PROV_DH_CTX *dstctx;
+
+    dstctx = OPENSSL_zalloc(sizeof(*srcctx));
+    if (dstctx == NULL)
+        return NULL;
+
+    *dstctx = *srcctx;
+    if (dstctx->dh != NULL && !DH_up_ref(dstctx->dh)) {
+        OPENSSL_free(dstctx);
+        return NULL;
+    }
+
+    if (dstctx->dhpeer != NULL && !DH_up_ref(dstctx->dhpeer)) {
+        DH_free(dstctx->dh);
+        OPENSSL_free(dstctx);
+        return NULL;
+    }
+
+    return dstctx;
+}
+
+static int dh_set_ctx_params(void *vpdhctx, const OSSL_PARAM params[])
+{
+    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
+    const OSSL_PARAM *p;
+    unsigned int pad;
+
+    if (pdhctx == NULL || params == NULL)
+        return 0;
+
+    p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_PAD);
+    if (p == NULL || !OSSL_PARAM_get_uint(p, &pad))
+        return 0;
+    pdhctx->pad = pad ? 1 : 0;
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD, NULL),
+    OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *dh_settable_ctx_params(void)
+{
+    return known_settable_ctx_params;
+}
+
+const OSSL_DISPATCH dh_keyexch_functions[] = {
+    { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))dh_newctx },
+    { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))dh_init },
+    { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))dh_derive },
+    { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))dh_set_peer },
+    { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))dh_freectx },
+    { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))dh_dupctx },
+    { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))dh_set_ctx_params },
+    { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS,
+      (void (*)(void))dh_settable_ctx_params },
+    { 0, NULL }
+};
diff --git a/providers/implementations/kdfs/build.info b/providers/implementations/kdfs/build.info
new file mode 100644 (file)
index 0000000..8800b12
--- /dev/null
@@ -0,0 +1,22 @@
+# We make separate GOAL variables for each algorithm, to make it easy to
+# switch each to the Legacy provider when needed.
+
+$TLS1_PRF_GOAL=../../libimplementations.a
+$HKDF_GOAL=../../libimplementations.a
+$KBKDF_GOAL=../../libimplementations.a
+$PBKDF2_GOAL=../../libimplementations.a
+$SSKDF_GOAL=../../libimplementations.a
+
+SOURCE[$TLS1_PRF_GOAL]=tls1_prf.c
+
+SOURCE[$HKDF_GOAL]=hkdf.c
+
+SOURCE[$KBKDF_GOAL]=kbkdf.c
+
+SOURCE[$PBKDF2_GOAL]=pbkdf2.c
+# Extra code to satisfy the FIPS and non-FIPS separation.
+# When the PBKDF2 moves to legacy, this can be removed.
+SOURCE[../../libfips.a]=pbkdf2_fips.c
+SOURCE[../../libnonfips.a]=pbkdf2_fips.c
+
+SOURCE[$SSKDF_GOAL]=sskdf.c
diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c
new file mode 100644 (file)
index 0000000..041811f
--- /dev/null
@@ -0,0 +1,463 @@
+/*
+ * Copyright 2016-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 <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <openssl/hmac.h>
+#include <openssl/evp.h>
+#include <openssl/kdf.h>
+#include <openssl/core_names.h>
+#include "internal/cryptlib.h"
+#include "internal/numbers.h"
+#include "crypto/evp.h"
+#include "internal/provider_ctx.h"
+#include "internal/providercommonerr.h"
+#include "internal/provider_algs.h"
+#include "internal/provider_util.h"
+#include "e_os.h"
+
+#define HKDF_MAXBUF 1024
+
+static OSSL_OP_kdf_newctx_fn kdf_hkdf_new;
+static OSSL_OP_kdf_freectx_fn kdf_hkdf_free;
+static OSSL_OP_kdf_reset_fn kdf_hkdf_reset;
+static OSSL_OP_kdf_derive_fn kdf_hkdf_derive;
+static OSSL_OP_kdf_settable_ctx_params_fn kdf_hkdf_settable_ctx_params;
+static OSSL_OP_kdf_set_ctx_params_fn kdf_hkdf_set_ctx_params;
+static OSSL_OP_kdf_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params;
+static OSSL_OP_kdf_get_ctx_params_fn kdf_hkdf_get_ctx_params;
+
+static int HKDF(const EVP_MD *evp_md,
+                const unsigned char *salt, size_t salt_len,
+                const unsigned char *key, size_t key_len,
+                const unsigned char *info, size_t info_len,
+                unsigned char *okm, size_t okm_len);
+static int HKDF_Extract(const EVP_MD *evp_md,
+                        const unsigned char *salt, size_t salt_len,
+                        const unsigned char *ikm, size_t ikm_len,
+                        unsigned char *prk, size_t prk_len);
+static int HKDF_Expand(const EVP_MD *evp_md,
+                       const unsigned char *prk, size_t prk_len,
+                       const unsigned char *info, size_t info_len,
+                       unsigned char *okm, size_t okm_len);
+
+typedef struct {
+    void *provctx;
+    int mode;
+    PROV_DIGEST digest;
+    unsigned char *salt;
+    size_t salt_len;
+    unsigned char *key;
+    size_t key_len;
+    unsigned char info[HKDF_MAXBUF];
+    size_t info_len;
+} KDF_HKDF;
+
+static void *kdf_hkdf_new(void *provctx)
+{
+    KDF_HKDF *ctx;
+
+    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+    else
+        ctx->provctx = provctx;
+    return ctx;
+}
+
+static void kdf_hkdf_free(void *vctx)
+{
+    KDF_HKDF *ctx = (KDF_HKDF *)vctx;
+
+    kdf_hkdf_reset(ctx);
+    OPENSSL_free(ctx);
+}
+
+static void kdf_hkdf_reset(void *vctx)
+{
+    KDF_HKDF *ctx = (KDF_HKDF *)vctx;
+
+    ossl_prov_digest_reset(&ctx->digest);
+    OPENSSL_free(ctx->salt);
+    OPENSSL_clear_free(ctx->key, ctx->key_len);
+    OPENSSL_cleanse(ctx->info, ctx->info_len);
+    memset(ctx, 0, sizeof(*ctx));
+}
+
+static size_t kdf_hkdf_size(KDF_HKDF *ctx)
+{
+    int sz;
+    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
+
+    if (ctx->mode != EVP_KDF_HKDF_MODE_EXTRACT_ONLY)
+        return SIZE_MAX;
+
+    if (md == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
+        return 0;
+    }
+    sz = EVP_MD_size(md);
+    if (sz < 0)
+        return 0;
+
+    return sz;
+}
+
+static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen)
+{
+    KDF_HKDF *ctx = (KDF_HKDF *)vctx;
+    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
+
+    if (md == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
+        return 0;
+    }
+    if (ctx->key == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY);
+        return 0;
+    }
+
+    switch (ctx->mode) {
+    case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
+        return HKDF(md, ctx->salt, ctx->salt_len, ctx->key,
+                    ctx->key_len, ctx->info, ctx->info_len, key,
+                    keylen);
+
+    case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:
+        return HKDF_Extract(md, ctx->salt, ctx->salt_len, ctx->key,
+                            ctx->key_len, key, keylen);
+
+    case EVP_KDF_HKDF_MODE_EXPAND_ONLY:
+        return HKDF_Expand(md, ctx->key, ctx->key_len, ctx->info,
+                           ctx->info_len, key, keylen);
+
+    default:
+        return 0;
+    }
+}
+
+static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    const OSSL_PARAM *p;
+    KDF_HKDF *ctx = vctx;
+    OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
+    int n;
+
+    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
+        return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MODE)) != NULL) {
+        if (p->data_type == OSSL_PARAM_UTF8_STRING) {
+            if (strcasecmp(p->data, "EXTRACT_AND_EXPAND") == 0) {
+                ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND;
+            } else if (strcasecmp(p->data, "EXTRACT_ONLY") == 0) {
+                ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY;
+            } else if (strcasecmp(p->data, "EXPAND_ONLY") == 0) {
+                ctx->mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY;
+            } else {
+                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
+                return 0;
+            }
+        } else if (OSSL_PARAM_get_int(p, &n)) {
+            if (n != EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND
+                && n != EVP_KDF_HKDF_MODE_EXTRACT_ONLY
+                && n != EVP_KDF_HKDF_MODE_EXPAND_ONLY) {
+                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
+                return 0;
+            }
+            ctx->mode = n;
+        } else {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
+            return 0;
+        }
+    }
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL) {
+        OPENSSL_clear_free(ctx->key, ctx->key_len);
+        ctx->key = NULL;
+        if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->key, 0,
+                                         &ctx->key_len))
+            return 0;
+    }
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) {
+        if (p->data_size != 0 && p->data != NULL) {
+            OPENSSL_free(ctx->salt);
+            ctx->salt = NULL;
+            if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0,
+                                             &ctx->salt_len))
+                return 0;
+        }
+    }
+    /* The info fields concatenate, so process them all */
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO)) != NULL) {
+        ctx->info_len = 0;
+        for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1,
+                                                      OSSL_KDF_PARAM_INFO)) {
+            const void *q = ctx->info + ctx->info_len;
+            size_t sz = 0;
+
+            if (p->data_size != 0
+                && p->data != NULL
+                && !OSSL_PARAM_get_octet_string(p, (void **)&q,
+                                                HKDF_MAXBUF - ctx->info_len,
+                                                &sz))
+                return 0;
+            ctx->info_len += sz;
+        }
+    }
+    return 1;
+}
+
+static const OSSL_PARAM *kdf_hkdf_settable_ctx_params(void)
+{
+    static const OSSL_PARAM known_settable_ctx_params[] = {
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0),
+        OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL),
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
+        OSSL_PARAM_END
+    };
+    return known_settable_ctx_params;
+}
+
+static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+    KDF_HKDF *ctx = (KDF_HKDF *)vctx;
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, kdf_hkdf_size(ctx));
+    return -2;
+}
+
+static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(void)
+{
+    static const OSSL_PARAM known_gettable_ctx_params[] = {
+        OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
+        OSSL_PARAM_END
+    };
+    return known_gettable_ctx_params;
+}
+
+const OSSL_DISPATCH kdf_hkdf_functions[] = {
+    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_hkdf_new },
+    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_hkdf_free },
+    { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_hkdf_reset },
+    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_hkdf_derive },
+    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
+      (void(*)(void))kdf_hkdf_settable_ctx_params },
+    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_hkdf_set_ctx_params },
+    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
+      (void(*)(void))kdf_hkdf_gettable_ctx_params },
+    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_hkdf_get_ctx_params },
+    { 0, NULL }
+};
+
+/*
+ * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"
+ * Section 2 (https://tools.ietf.org/html/rfc5869#section-2) and
+ * "Cryptographic Extraction and Key Derivation: The HKDF Scheme"
+ * Section 4.2 (https://eprint.iacr.org/2010/264.pdf).
+ *
+ * From the paper:
+ *   The scheme HKDF is specified as:
+ *     HKDF(XTS, SKM, CTXinfo, L) = K(1) | K(2) | ... | K(t)
+ *
+ *     where:
+ *       SKM is source key material
+ *       XTS is extractor salt (which may be null or constant)
+ *       CTXinfo is context information (may be null)
+ *       L is the number of key bits to be produced by KDF
+ *       k is the output length in bits of the hash function used with HMAC
+ *       t = ceil(L/k)
+ *       the value K(t) is truncated to its first d = L mod k bits.
+ *
+ * From RFC 5869:
+ *   2.2.  Step 1: Extract
+ *     HKDF-Extract(salt, IKM) -> PRK
+ *   2.3.  Step 2: Expand
+ *     HKDF-Expand(PRK, info, L) -> OKM
+ */
+static int HKDF(const EVP_MD *evp_md,
+                const unsigned char *salt, size_t salt_len,
+                const unsigned char *ikm, size_t ikm_len,
+                const unsigned char *info, size_t info_len,
+                unsigned char *okm, size_t okm_len)
+{
+    unsigned char prk[EVP_MAX_MD_SIZE];
+    int ret, sz;
+    size_t prk_len;
+
+    sz = EVP_MD_size(evp_md);
+    if (sz < 0)
+        return 0;
+    prk_len = (size_t)sz;
+
+    /* Step 1: HKDF-Extract(salt, IKM) -> PRK */
+    if (!HKDF_Extract(evp_md, salt, salt_len, ikm, ikm_len, prk, prk_len))
+        return 0;
+
+    /* Step 2: HKDF-Expand(PRK, info, L) -> OKM */
+    ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);
+    OPENSSL_cleanse(prk, sizeof(prk));
+
+    return ret;
+}
+
+/*
+ * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"
+ * Section 2.2 (https://tools.ietf.org/html/rfc5869#section-2.2).
+ *
+ * 2.2.  Step 1: Extract
+ *
+ *   HKDF-Extract(salt, IKM) -> PRK
+ *
+ *   Options:
+ *      Hash     a hash function; HashLen denotes the length of the
+ *               hash function output in octets
+ *
+ *   Inputs:
+ *      salt     optional salt value (a non-secret random value);
+ *               if not provided, it is set to a string of HashLen zeros.
+ *      IKM      input keying material
+ *
+ *   Output:
+ *      PRK      a pseudorandom key (of HashLen octets)
+ *
+ *   The output PRK is calculated as follows:
+ *
+ *   PRK = HMAC-Hash(salt, IKM)
+ */
+static int HKDF_Extract(const EVP_MD *evp_md,
+                        const unsigned char *salt, size_t salt_len,
+                        const unsigned char *ikm, size_t ikm_len,
+                        unsigned char *prk, size_t prk_len)
+{
+    int sz = EVP_MD_size(evp_md);
+
+    if (sz < 0)
+        return 0;
+    if (prk_len != (size_t)sz) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_OUTPUT_BUFFER_SIZE);
+        return 0;
+    }
+    /* calc: PRK = HMAC-Hash(salt, IKM) */
+    return HMAC(evp_md, salt, salt_len, ikm, ikm_len, prk, NULL) != NULL;
+}
+
+/*
+ * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"
+ * Section 2.3 (https://tools.ietf.org/html/rfc5869#section-2.3).
+ *
+ * 2.3.  Step 2: Expand
+ *
+ *   HKDF-Expand(PRK, info, L) -> OKM
+ *
+ *   Options:
+ *      Hash     a hash function; HashLen denotes the length of the
+ *               hash function output in octets
+ *
+ *   Inputs:
+ *      PRK      a pseudorandom key of at least HashLen octets
+ *               (usually, the output from the extract step)
+ *      info     optional context and application specific information
+ *               (can be a zero-length string)
+ *      L        length of output keying material in octets
+ *               (<= 255*HashLen)
+ *
+ *   Output:
+ *      OKM      output keying material (of L octets)
+ *
+ *   The output OKM is calculated as follows:
+ *
+ *   N = ceil(L/HashLen)
+ *   T = T(1) | T(2) | T(3) | ... | T(N)
+ *   OKM = first L octets of T
+ *
+ *   where:
+ *   T(0) = empty string (zero length)
+ *   T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ *   T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ *   T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ *   ...
+ *
+ *   (where the constant concatenated to the end of each T(n) is a
+ *   single octet.)
+ */
+static int HKDF_Expand(const EVP_MD *evp_md,
+                       const unsigned char *prk, size_t prk_len,
+                       const unsigned char *info, size_t info_len,
+                       unsigned char *okm, size_t okm_len)
+{
+    HMAC_CTX *hmac;
+    int ret = 0, sz;
+    unsigned int i;
+    unsigned char prev[EVP_MAX_MD_SIZE];
+    size_t done_len = 0, dig_len, n;
+
+    sz = EVP_MD_size(evp_md);
+    if (sz <= 0)
+        return 0;
+    dig_len = (size_t)sz;
+
+    /* calc: N = ceil(L/HashLen) */
+    n = okm_len / dig_len;
+    if (okm_len % dig_len)
+        n++;
+
+    if (n > 255 || okm == NULL)
+        return 0;
+
+    if ((hmac = HMAC_CTX_new()) == NULL)
+        return 0;
+
+    if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL))
+        goto err;
+
+    for (i = 1; i <= n; i++) {
+        size_t copy_len;
+        const unsigned char ctr = i;
+
+        /* calc: T(i) = HMAC-Hash(PRK, T(i - 1) | info | i) */
+        if (i > 1) {
+            if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL))
+                goto err;
+
+            if (!HMAC_Update(hmac, prev, dig_len))
+                goto err;
+        }
+
+        if (!HMAC_Update(hmac, info, info_len))
+            goto err;
+
+        if (!HMAC_Update(hmac, &ctr, 1))
+            goto err;
+
+        if (!HMAC_Final(hmac, prev, NULL))
+            goto err;
+
+        copy_len = (done_len + dig_len > okm_len) ?
+                       okm_len - done_len :
+                       dig_len;
+
+        memcpy(okm + done_len, prev, copy_len);
+
+        done_len += copy_len;
+    }
+    ret = 1;
+
+ err:
+    OPENSSL_cleanse(prev, sizeof(prev));
+    HMAC_CTX_free(hmac);
+    return ret;
+}
diff --git a/providers/implementations/kdfs/kbkdf.c b/providers/implementations/kdfs/kbkdf.c
new file mode 100644 (file)
index 0000000..ffffef0
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019 Red Hat, Inc.
+ *
+ * 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
+ */
+
+/*
+ * This implements https://csrc.nist.gov/publications/detail/sp/800-108/final
+ * section 5.1 ("counter mode") in HMAC only.  That document does not name the
+ * KDFs it defines; the name is derived from
+ * https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/Key-Derivation
+ *
+ * Note that sections 5.2 ("feedback mode") and 5.3 ("double-pipeline mode")
+ * are not implemented, though it would be possible to do so in the future.
+ * CMAC mode is also not implemented; some plumbing would be required.
+ *
+ * These versions all assume the counter is used.  It would be relatively
+ * straightforward to expose a configuration handle should the need arise.
+ *
+ * Variable names attempt to match those of SP800-108.
+ */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/core_names.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/kdf.h>
+#include <openssl/params.h>
+
+#include "internal/cryptlib.h"
+#include "crypto/evp.h"
+#include "internal/numbers.h"
+#include "internal/provider_algs.h"
+#include "internal/provider_ctx.h"
+#include "internal/provider_util.h"
+#include "internal/providercommonerr.h"
+
+#include "e_os.h"
+
+#define MIN(a, b) ((a) < (b)) ? (a) : (b)
+
+/* Our context structure. */
+typedef struct {
+    void *provctx;
+    EVP_MAC_CTX *ctx_init;
+
+    /* Names are lowercased versions of those found in SP800-108. */
+    unsigned char *ki;
+    size_t ki_len;
+    unsigned char *label;
+    size_t label_len;
+    unsigned char *context;
+    size_t context_len;
+} KBKDF;
+
+/* Definitions needed for typechecking. */
+static OSSL_OP_kdf_newctx_fn kbkdf_new;
+static OSSL_OP_kdf_freectx_fn kbkdf_free;
+static OSSL_OP_kdf_reset_fn kbkdf_reset;
+static OSSL_OP_kdf_derive_fn kbkdf_derive;
+static OSSL_OP_kdf_settable_ctx_params_fn kbkdf_settable_ctx_params;
+static OSSL_OP_kdf_set_ctx_params_fn kbkdf_set_ctx_params;
+
+/* Not all platforms have htobe32(). */
+static uint32_t be32(uint32_t host)
+{
+    uint32_t big = 0;
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+
+    if (!is_endian.little)
+        return host;
+
+    big |= (host & 0xff000000) >> 24;
+    big |= (host & 0x00ff0000) >> 8;
+    big |= (host & 0x0000ff00) << 8;
+    big |= (host & 0x000000ff) << 24;
+    return big;
+}
+
+static void *kbkdf_new(void *provctx)
+{
+    KBKDF *ctx;
+
+    ctx = OPENSSL_zalloc(sizeof(*ctx));
+    if (ctx == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ctx->provctx = provctx;
+    return ctx;
+}
+
+static void kbkdf_free(void *vctx)
+{
+    KBKDF *ctx = (KBKDF *)vctx;
+
+    kbkdf_reset(ctx);
+    OPENSSL_free(ctx);
+}
+
+static void kbkdf_reset(void *vctx)
+{
+    KBKDF *ctx = (KBKDF *)vctx;
+
+    EVP_MAC_CTX_free(ctx->ctx_init);
+    OPENSSL_clear_free(ctx->context, ctx->context_len);
+    OPENSSL_clear_free(ctx->label, ctx->label_len);
+    OPENSSL_clear_free(ctx->ki, ctx->ki_len);
+    memset(ctx, 0, sizeof(*ctx));
+}
+
+/* SP800-108 section 5.1. */
+static int kbkdf_derive_counter(EVP_MAC_CTX *ctx_init,
+                                unsigned char *label, size_t label_len,
+                                unsigned char *context, size_t context_len,
+                                unsigned char *k_i, size_t h, uint32_t l,
+                                unsigned char *ko, size_t ko_len)
+{
+    int ret = 0;
+    EVP_MAC_CTX *ctx = NULL;
+    size_t written = 0, to_write;
+    const unsigned char zero = 0;
+    uint32_t counter, i;
+
+    for (counter = 1; written < ko_len; counter++) {
+        i = be32(counter);
+
+        ctx = EVP_MAC_CTX_dup(ctx_init);
+        if (ctx == NULL)
+            goto done;
+
+        if (!EVP_MAC_update(ctx, (unsigned char *)&i, 4)
+            || !EVP_MAC_update(ctx, label, label_len)
+            || !EVP_MAC_update(ctx, &zero, 1)
+            || !EVP_MAC_update(ctx, context, context_len)
+            || !EVP_MAC_update(ctx, (unsigned char *)&l, 4)
+            || !EVP_MAC_final(ctx, k_i, NULL, h))
+            goto done;
+
+        to_write = ko_len - written;
+        memcpy(ko + written, k_i, MIN(to_write, h));
+        written += h;
+
+        EVP_MAC_CTX_free(ctx);
+        ctx = NULL;
+    }
+
+    ret = 1;
+done:
+    EVP_MAC_CTX_free(ctx);
+    return ret;
+}
+
+static int kbkdf_derive(void *vctx, unsigned char *key, size_t keylen)
+{
+    KBKDF *ctx = (KBKDF *)vctx;
+    int ret = 0;
+    unsigned char *k_i = NULL;
+    uint32_t l = be32(keylen * 8);
+    size_t h = 0;
+
+    /* Label and Context are permitted to be empty. Check everything else. */
+    if (ctx->ctx_init == NULL) {
+        if (ctx->ki_len == 0 || ctx->ki == NULL) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
+            return 0;
+        }
+        /* Could either be missing MAC or missing message digest -
+         * arbitrarily, I pick this one. */
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MAC);
+        return 0;
+    }
+
+    h = EVP_MAC_size(ctx->ctx_init);
+    if (h == 0)
+        goto done;
+
+    k_i = OPENSSL_zalloc(h);
+    if (k_i == NULL)
+        goto done;
+
+    ret = kbkdf_derive_counter(
+        ctx->ctx_init, ctx->label, ctx->label_len, ctx->context,
+        ctx->context_len, k_i, h, l, key, keylen);
+done:
+    if (ret != 1)
+        OPENSSL_cleanse(key, keylen);
+    OPENSSL_clear_free(k_i, h);
+    return ret;
+}
+
+static int kbkdf_set_buffer(unsigned char **out, size_t *out_len,
+                            const OSSL_PARAM *p)
+{
+    if (p->data == NULL || p->data_size == 0)
+        return 1;
+
+    OPENSSL_clear_free(*out, *out_len);
+    *out = NULL;
+    return OSSL_PARAM_get_octet_string(p, (void **)out, 0, out_len);
+}
+
+static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    KBKDF *ctx = (KBKDF *)vctx;
+    OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
+    const OSSL_PARAM *p;
+    OSSL_PARAM mparams[2];
+
+    if (!ossl_prov_macctx_load_from_params(&ctx->ctx_init, params, NULL,
+                                           NULL, NULL, libctx))
+        return 0;
+    else if (ctx->ctx_init != NULL
+        && !EVP_MAC_is_a(EVP_MAC_CTX_mac(ctx->ctx_init),
+                         OSSL_MAC_NAME_HMAC)) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MAC);
+        return 0;
+    }
+
+    p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY);
+    if (p != NULL && !kbkdf_set_buffer(&ctx->ki, &ctx->ki_len, p))
+        return 0;
+
+    p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT);
+    if (p != NULL && !kbkdf_set_buffer(&ctx->label, &ctx->label_len, p))
+        return 0;
+
+    p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO);
+    if (p != NULL && !kbkdf_set_buffer(&ctx->context, &ctx->context_len, p))
+        return 0;
+
+    /* Set up digest context, if we can. */
+    if (ctx->ctx_init != NULL && ctx->ki_len != 0) {
+        mparams[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+                                                       ctx->ki, ctx->ki_len);
+        mparams[1] = OSSL_PARAM_construct_end();
+
+        if (!EVP_MAC_CTX_set_params(ctx->ctx_init, mparams)
+            || !EVP_MAC_init(ctx->ctx_init))
+            return 0;
+    }
+
+    return 1;
+}
+
+static const OSSL_PARAM *kbkdf_settable_ctx_params(void)
+{
+    static const OSSL_PARAM known_settable_ctx_params[] = {
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MAC, NULL, 0),
+
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
+        OSSL_PARAM_END,
+    };
+    return known_settable_ctx_params;
+}
+
+static int kbkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+    OSSL_PARAM *p;
+
+    p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE);
+    if (p == NULL)
+        return -2;
+
+    /* KBKDF can produce results as large as you like. */
+    return OSSL_PARAM_set_size_t(p, SIZE_MAX);
+}
+
+static const OSSL_PARAM *kbkdf_gettable_ctx_params(void)
+{
+    static const OSSL_PARAM known_gettable_ctx_params[] =
+        { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), OSSL_PARAM_END };
+    return known_gettable_ctx_params;
+}
+
+const OSSL_DISPATCH kdf_kbkdf_functions[] = {
+    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kbkdf_new },
+    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kbkdf_free },
+    { OSSL_FUNC_KDF_RESET, (void(*)(void))kbkdf_reset },
+    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kbkdf_derive },
+    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
+      (void(*)(void))kbkdf_settable_ctx_params },
+    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kbkdf_set_ctx_params },
+    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
+      (void(*)(void))kbkdf_gettable_ctx_params },
+    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kbkdf_get_ctx_params },
+    { 0, NULL },
+};
diff --git a/providers/implementations/kdfs/pbkdf2.c b/providers/implementations/kdfs/pbkdf2.c
new file mode 100644 (file)
index 0000000..68aa0aa
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2018-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 <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <openssl/hmac.h>
+#include <openssl/evp.h>
+#include <openssl/kdf.h>
+#include <openssl/core_names.h>
+#include "internal/cryptlib.h"
+#include "internal/numbers.h"
+#include "crypto/evp.h"
+#include "internal/provider_ctx.h"
+#include "internal/providercommonerr.h"
+#include "internal/provider_algs.h"
+#include "internal/provider_util.h"
+#include "pbkdf2.h"
+
+/* Constants specified in SP800-132 */
+#define KDF_PBKDF2_MIN_KEY_LEN_BITS  112
+#define KDF_PBKDF2_MAX_KEY_LEN_DIGEST_RATIO 0xFFFFFFFF
+#define KDF_PBKDF2_MIN_ITERATIONS 1000
+#define KDF_PBKDF2_MIN_SALT_LEN   (128 / 8)
+
+static OSSL_OP_kdf_newctx_fn kdf_pbkdf2_new;
+static OSSL_OP_kdf_freectx_fn kdf_pbkdf2_free;
+static OSSL_OP_kdf_reset_fn kdf_pbkdf2_reset;
+static OSSL_OP_kdf_derive_fn kdf_pbkdf2_derive;
+static OSSL_OP_kdf_settable_ctx_params_fn kdf_pbkdf2_settable_ctx_params;
+static OSSL_OP_kdf_set_ctx_params_fn kdf_pbkdf2_set_ctx_params;
+
+static int  pbkdf2_derive(const char *pass, size_t passlen,
+                          const unsigned char *salt, int saltlen, uint64_t iter,
+                          const EVP_MD *digest, unsigned char *key,
+                          size_t keylen, int extra_checks);
+
+typedef struct {
+    void *provctx;
+    unsigned char *pass;
+    size_t pass_len;
+    unsigned char *salt;
+    size_t salt_len;
+    uint64_t iter;
+    PROV_DIGEST digest;
+    int lower_bound_checks;
+} KDF_PBKDF2;
+
+static void kdf_pbkdf2_init(KDF_PBKDF2 *ctx);
+
+static void *kdf_pbkdf2_new(void *provctx)
+{
+    KDF_PBKDF2 *ctx;
+
+    ctx = OPENSSL_zalloc(sizeof(*ctx));
+    if (ctx == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    ctx->provctx = provctx;
+    kdf_pbkdf2_init(ctx);
+    return ctx;
+}
+
+static void kdf_pbkdf2_cleanup(KDF_PBKDF2 *ctx)
+{
+    ossl_prov_digest_reset(&ctx->digest);
+    OPENSSL_free(ctx->salt);
+    OPENSSL_clear_free(ctx->pass, ctx->pass_len);
+    memset(ctx, 0, sizeof(*ctx));
+}
+
+static void kdf_pbkdf2_free(void *vctx)
+{
+    KDF_PBKDF2 *ctx = (KDF_PBKDF2 *)vctx;
+
+    kdf_pbkdf2_cleanup(ctx);
+    OPENSSL_free(ctx);
+}
+
+static void kdf_pbkdf2_reset(void *vctx)
+{
+    KDF_PBKDF2 *ctx = (KDF_PBKDF2 *)vctx;
+
+    kdf_pbkdf2_cleanup(ctx);
+    kdf_pbkdf2_init(ctx);
+}
+
+static void kdf_pbkdf2_init(KDF_PBKDF2 *ctx)
+{
+    OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
+    OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
+
+    params[0] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
+                                                 SN_sha1, 0);
+    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
+        /* This is an error, but there is no way to indicate such directly */
+        ossl_prov_digest_reset(&ctx->digest);
+    ctx->iter = PKCS5_DEFAULT_ITER;
+    ctx->lower_bound_checks = kdf_pbkdf2_default_checks;
+}
+
+static int pbkdf2_set_membuf(unsigned char **buffer, size_t *buflen,
+                             const OSSL_PARAM *p)
+{
+    OPENSSL_clear_free(*buffer, *buflen);
+    if (p->data_size == 0) {
+        if ((*buffer = OPENSSL_malloc(1)) == NULL) {
+            ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    } else if (p->data != NULL) {
+        *buffer = NULL;
+        if (!OSSL_PARAM_get_octet_string(p, (void **)buffer, 0, buflen))
+            return 0;
+    }
+    return 1;
+}
+
+static int kdf_pbkdf2_derive(void *vctx, unsigned char *key,
+                             size_t keylen)
+{
+    KDF_PBKDF2 *ctx = (KDF_PBKDF2 *)vctx;
+    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
+
+    if (ctx->pass == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_PASS);
+        return 0;
+    }
+
+    if (ctx->salt == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SALT);
+        return 0;
+    }
+
+    return pbkdf2_derive((char *)ctx->pass, ctx->pass_len,
+                         ctx->salt, ctx->salt_len, ctx->iter,
+                         md, key, keylen, ctx->lower_bound_checks);
+}
+
+static int kdf_pbkdf2_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    const OSSL_PARAM *p;
+    KDF_PBKDF2 *ctx = vctx;
+    OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
+    int pkcs5;
+    uint64_t iter, min_iter;
+
+    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
+        return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PKCS5)) != NULL) {
+        if (!OSSL_PARAM_get_int(p, &pkcs5))
+            return 0;
+        ctx->lower_bound_checks = pkcs5 == 0;
+    }
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL)
+        if (!pbkdf2_set_membuf(&ctx->pass, &ctx->pass_len, p))
+            return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) {
+        if (ctx->lower_bound_checks != 0
+            && p->data_size < KDF_PBKDF2_MIN_SALT_LEN) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
+            return 0;
+        }
+        if (!pbkdf2_set_membuf(&ctx->salt, &ctx->salt_len,p))
+            return 0;
+    }
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ITER)) != NULL) {
+        if (!OSSL_PARAM_get_uint64(p, &iter))
+            return 0;
+        min_iter = ctx->lower_bound_checks != 0 ? KDF_PBKDF2_MIN_ITERATIONS : 1;
+        if (iter < min_iter) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_ITERATION_COUNT);
+            return 0;
+        }
+        ctx->iter = iter;
+    }
+    return 1;
+}
+
+static const OSSL_PARAM *kdf_pbkdf2_settable_ctx_params(void)
+{
+    static const OSSL_PARAM known_settable_ctx_params[] = {
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
+        OSSL_PARAM_uint64(OSSL_KDF_PARAM_ITER, NULL),
+        OSSL_PARAM_int(OSSL_KDF_PARAM_PKCS5, NULL),
+        OSSL_PARAM_END
+    };
+    return known_settable_ctx_params;
+}
+
+static int kdf_pbkdf2_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, SIZE_MAX);
+    return -2;
+}
+
+static const OSSL_PARAM *kdf_pbkdf2_gettable_ctx_params(void)
+{
+    static const OSSL_PARAM known_gettable_ctx_params[] = {
+        OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
+        OSSL_PARAM_END
+    };
+    return known_gettable_ctx_params;
+}
+
+const OSSL_DISPATCH kdf_pbkdf2_functions[] = {
+    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_pbkdf2_new },
+    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_pbkdf2_free },
+    { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_pbkdf2_reset },
+    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_pbkdf2_derive },
+    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
+      (void(*)(void))kdf_pbkdf2_settable_ctx_params },
+    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_pbkdf2_set_ctx_params },
+    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
+      (void(*)(void))kdf_pbkdf2_gettable_ctx_params },
+    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_pbkdf2_get_ctx_params },
+    { 0, NULL }
+};
+
+/*
+ * This is an implementation of PKCS#5 v2.0 password based encryption key
+ * derivation function PBKDF2. SHA1 version verified against test vectors
+ * posted by Peter Gutmann to the PKCS-TNG mailing list.
+ *
+ * The constraints specified by SP800-132 have been added i.e.
+ *  - Check the range of the key length.
+ *  - Minimum iteration count of 1000.
+ *  - Randomly-generated portion of the salt shall be at least 128 bits.
+ */
+static int pbkdf2_derive(const char *pass, size_t passlen,
+                         const unsigned char *salt, int saltlen, uint64_t iter,
+                         const EVP_MD *digest, unsigned char *key,
+                         size_t keylen, int lower_bound_checks)
+{
+    int ret = 0;
+    unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
+    int cplen, k, tkeylen, mdlen;
+    uint64_t j;
+    unsigned long i = 1;
+    HMAC_CTX *hctx_tpl = NULL, *hctx = NULL;
+
+    mdlen = EVP_MD_size(digest);
+    if (mdlen <= 0)
+        return 0;
+
+    /*
+     * This check should always be done because keylen / mdlen >= (2^32 - 1)
+     * results in an overflow of the loop counter 'i'.
+     */
+    if ((keylen / mdlen) >= KDF_PBKDF2_MAX_KEY_LEN_DIGEST_RATIO) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LEN);
+        return 0;
+    }
+
+    if (lower_bound_checks) {
+        if ((keylen * 8) < KDF_PBKDF2_MIN_KEY_LEN_BITS) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LEN);
+            return 0;
+        }
+        if (saltlen < KDF_PBKDF2_MIN_SALT_LEN) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
+            return 0;
+        }
+        if (iter < KDF_PBKDF2_MIN_ITERATIONS) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_ITERATION_COUNT);
+            return 0;
+        }
+    }
+
+    hctx_tpl = HMAC_CTX_new();
+    if (hctx_tpl == NULL)
+        return 0;
+    p = key;
+    tkeylen = keylen;
+    if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL))
+        goto err;
+    hctx = HMAC_CTX_new();
+    if (hctx == NULL)
+        goto err;
+    while (tkeylen) {
+        if (tkeylen > mdlen)
+            cplen = mdlen;
+        else
+            cplen = tkeylen;
+        /*
+         * We are unlikely to ever use more than 256 blocks (5120 bits!) but
+         * just in case...
+         */
+        itmp[0] = (unsigned char)((i >> 24) & 0xff);
+        itmp[1] = (unsigned char)((i >> 16) & 0xff);
+        itmp[2] = (unsigned char)((i >> 8) & 0xff);
+        itmp[3] = (unsigned char)(i & 0xff);
+        if (!HMAC_CTX_copy(hctx, hctx_tpl))
+            goto err;
+        if (!HMAC_Update(hctx, salt, saltlen)
+                || !HMAC_Update(hctx, itmp, 4)
+                || !HMAC_Final(hctx, digtmp, NULL))
+            goto err;
+        memcpy(p, digtmp, cplen);
+        for (j = 1; j < iter; j++) {
+            if (!HMAC_CTX_copy(hctx, hctx_tpl))
+                goto err;
+            if (!HMAC_Update(hctx, digtmp, mdlen)
+                    || !HMAC_Final(hctx, digtmp, NULL))
+                goto err;
+            for (k = 0; k < cplen; k++)
+                p[k] ^= digtmp[k];
+        }
+        tkeylen -= cplen;
+        i++;
+        p += cplen;
+    }
+    ret = 1;
+
+err:
+    HMAC_CTX_free(hctx);
+    HMAC_CTX_free(hctx_tpl);
+    return ret;
+}
diff --git a/providers/implementations/kdfs/pbkdf2.h b/providers/implementations/kdfs/pbkdf2.h
new file mode 100644 (file)
index 0000000..c8c2e5b
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * 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
+ */
+
+/*
+ * Available in pbkdfe_fips.c, and compiled with different values depending
+ * on we're in the FIPS module or not.
+ */
+extern const int kdf_pbkdf2_default_checks;
diff --git a/providers/implementations/kdfs/pbkdf2_fips.c b/providers/implementations/kdfs/pbkdf2_fips.c
new file mode 100644 (file)
index 0000000..d33782b
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * 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 "pbkdf2.h"
+
+/*
+ * For backwards compatibility reasons,
+ * Extra checks are done by default in fips mode only.
+ */
+#ifdef FIPS_MODE
+const int kdf_pbkdf2_default_checks = 1;
+#else
+const int kdf_pbkdf2_default_checks = 0;
+#endif /* FIPS_MODE */
diff --git a/providers/implementations/kdfs/sskdf.c b/providers/implementations/kdfs/sskdf.c
new file mode 100644 (file)
index 0000000..1e538a9
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * Refer to https://csrc.nist.gov/publications/detail/sp/800-56c/rev-1/final
+ * Section 4.1.
+ *
+ * The Single Step KDF algorithm is given by:
+ *
+ * Result(0) = empty bit string (i.e., the null string).
+ * For i = 1 to reps, do the following:
+ *   Increment counter by 1.
+ *   Result(i) = Result(i - 1) || H(counter || Z || FixedInfo).
+ * DKM = LeftmostBits(Result(reps), L))
+ *
+ * NOTES:
+ *   Z is a shared secret required to produce the derived key material.
+ *   counter is a 4 byte buffer.
+ *   FixedInfo is a bit string containing context specific data.
+ *   DKM is the output derived key material.
+ *   L is the required size of the DKM.
+ *   reps = [L / H_outputBits]
+ *   H(x) is the auxiliary function that can be either a hash, HMAC or KMAC.
+ *   H_outputBits is the length of the output of the auxiliary function H(x).
+ *
+ * Currently there is not a comprehensive list of test vectors for this
+ * algorithm, especially for H(x) = HMAC and H(x) = KMAC.
+ * Test vectors for H(x) = Hash are indirectly used by CAVS KAS tests.
+ */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <openssl/hmac.h>
+#include <openssl/evp.h>
+#include <openssl/kdf.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
+#include "internal/cryptlib.h"
+#include "internal/numbers.h"
+#include "crypto/evp.h"
+#include "internal/provider_ctx.h"
+#include "internal/providercommonerr.h"
+#include "internal/provider_algs.h"
+#include "internal/provider_util.h"
+
+typedef struct {
+    void *provctx;
+    EVP_MAC_CTX *macctx;         /* H(x) = HMAC_hash OR H(x) = KMAC */
+    PROV_DIGEST digest;          /* H(x) = hash(x) */
+    unsigned char *secret;
+    size_t secret_len;
+    unsigned char *info;
+    size_t info_len;
+    unsigned char *salt;
+    size_t salt_len;
+    size_t out_len; /* optional KMAC parameter */
+} KDF_SSKDF;
+
+#define SSKDF_MAX_INLEN (1<<30)
+#define SSKDF_KMAC128_DEFAULT_SALT_SIZE (168 - 4)
+#define SSKDF_KMAC256_DEFAULT_SALT_SIZE (136 - 4)
+
+/* KMAC uses a Customisation string of 'KDF' */
+static const unsigned char kmac_custom_str[] = { 0x4B, 0x44, 0x46 };
+
+static OSSL_OP_kdf_newctx_fn sskdf_new;
+static OSSL_OP_kdf_freectx_fn sskdf_free;
+static OSSL_OP_kdf_reset_fn sskdf_reset;
+static OSSL_OP_kdf_derive_fn sskdf_derive;
+static OSSL_OP_kdf_derive_fn x963kdf_derive;
+static OSSL_OP_kdf_settable_ctx_params_fn sskdf_settable_ctx_params;
+static OSSL_OP_kdf_set_ctx_params_fn sskdf_set_ctx_params;
+static OSSL_OP_kdf_gettable_ctx_params_fn sskdf_gettable_ctx_params;
+static OSSL_OP_kdf_get_ctx_params_fn sskdf_get_ctx_params;
+
+/*
+ * Refer to https://csrc.nist.gov/publications/detail/sp/800-56c/rev-1/final
+ * Section 4. One-Step Key Derivation using H(x) = hash(x)
+ * Note: X9.63 also uses this code with the only difference being that the
+ * counter is appended to the secret 'z'.
+ * i.e.
+ *   result[i] = Hash(counter || z || info) for One Step OR
+ *   result[i] = Hash(z || counter || info) for X9.63.
+ */
+static int SSKDF_hash_kdm(const EVP_MD *kdf_md,
+                          const unsigned char *z, size_t z_len,
+                          const unsigned char *info, size_t info_len,
+                          unsigned int append_ctr,
+                          unsigned char *derived_key, size_t derived_key_len)
+{
+    int ret = 0, hlen;
+    size_t counter, out_len, len = derived_key_len;
+    unsigned char c[4];
+    unsigned char mac[EVP_MAX_MD_SIZE];
+    unsigned char *out = derived_key;
+    EVP_MD_CTX *ctx = NULL, *ctx_init = NULL;
+
+    if (z_len > SSKDF_MAX_INLEN || info_len > SSKDF_MAX_INLEN
+            || derived_key_len > SSKDF_MAX_INLEN
+            || derived_key_len == 0)
+        return 0;
+
+    hlen = EVP_MD_size(kdf_md);
+    if (hlen <= 0)
+        return 0;
+    out_len = (size_t)hlen;
+
+    ctx = EVP_MD_CTX_create();
+    ctx_init = EVP_MD_CTX_create();
+    if (ctx == NULL || ctx_init == NULL)
+        goto end;
+
+    if (!EVP_DigestInit(ctx_init, kdf_md))
+        goto end;
+
+    for (counter = 1;; counter++) {
+        c[0] = (unsigned char)((counter >> 24) & 0xff);
+        c[1] = (unsigned char)((counter >> 16) & 0xff);
+        c[2] = (unsigned char)((counter >> 8) & 0xff);
+        c[3] = (unsigned char)(counter & 0xff);
+
+        if (!(EVP_MD_CTX_copy_ex(ctx, ctx_init)
+                && (append_ctr || EVP_DigestUpdate(ctx, c, sizeof(c)))
+                && EVP_DigestUpdate(ctx, z, z_len)
+                && (!append_ctr || EVP_DigestUpdate(ctx, c, sizeof(c)))
+                && EVP_DigestUpdate(ctx, info, info_len)))
+            goto end;
+        if (len >= out_len) {
+            if (!EVP_DigestFinal_ex(ctx, out, NULL))
+                goto end;
+            out += out_len;
+            len -= out_len;
+            if (len == 0)
+                break;
+        } else {
+            if (!EVP_DigestFinal_ex(ctx, mac, NULL))
+                goto end;
+            memcpy(out, mac, len);
+            break;
+        }
+    }
+    ret = 1;
+end:
+    EVP_MD_CTX_destroy(ctx);
+    EVP_MD_CTX_destroy(ctx_init);
+    OPENSSL_cleanse(mac, sizeof(mac));
+    return ret;
+}
+
+static int kmac_init(EVP_MAC_CTX *ctx, const unsigned char *custom,
+                     size_t custom_len, size_t kmac_out_len,
+                     size_t derived_key_len, unsigned char **out)
+{
+    OSSL_PARAM params[2];
+
+    /* Only KMAC has custom data - so return if not KMAC */
+    if (custom == NULL)
+        return 1;
+
+    params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_CUSTOM,
+                                                  (void *)custom, custom_len);
+    params[1] = OSSL_PARAM_construct_end();
+
+    if (!EVP_MAC_CTX_set_params(ctx, params))
+        return 0;
+
+    /* By default only do one iteration if kmac_out_len is not specified */
+    if (kmac_out_len == 0)
+        kmac_out_len = derived_key_len;
+    /* otherwise check the size is valid */
+    else if (!(kmac_out_len == derived_key_len
+            || kmac_out_len == 20
+            || kmac_out_len == 28
+            || kmac_out_len == 32
+            || kmac_out_len == 48
+            || kmac_out_len == 64))
+        return 0;
+
+    params[0] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE,
+                                            &kmac_out_len);
+
+    if (EVP_MAC_CTX_set_params(ctx, params) <= 0)
+        return 0;
+
+    /*
+     * For kmac the output buffer can be larger than EVP_MAX_MD_SIZE: so
+     * alloc a buffer for this case.
+     */
+    if (kmac_out_len > EVP_MAX_MD_SIZE) {
+        *out = OPENSSL_zalloc(kmac_out_len);
+        if (*out == NULL)
+            return 0;
+    }
+    return 1;
+}
+
+/*
+ * Refer to https://csrc.nist.gov/publications/detail/sp/800-56c/rev-1/final
+ * Section 4. One-Step Key Derivation using MAC: i.e either
+ *     H(x) = HMAC-hash(salt, x) OR
+ *     H(x) = KMAC#(salt, x, outbits, CustomString='KDF')
+ */
+static int SSKDF_mac_kdm(EVP_MAC_CTX *ctx_init,
+                         const unsigned char *kmac_custom,
+                         size_t kmac_custom_len, size_t kmac_out_len,
+                         const unsigned char *salt, size_t salt_len,
+                         const unsigned char *z, size_t z_len,
+                         const unsigned char *info, size_t info_len,
+                         unsigned char *derived_key, size_t derived_key_len)
+{
+    int ret = 0;
+    size_t counter, out_len, len;
+    unsigned char c[4];
+    unsigned char mac_buf[EVP_MAX_MD_SIZE];
+    unsigned char *out = derived_key;
+    EVP_MAC_CTX *ctx = NULL;
+    unsigned char *mac = mac_buf, *kmac_buffer = NULL;
+    OSSL_PARAM params[2], *p = params;
+
+    if (z_len > SSKDF_MAX_INLEN || info_len > SSKDF_MAX_INLEN
+            || derived_key_len > SSKDF_MAX_INLEN
+            || derived_key_len == 0)
+        return 0;
+
+    *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+                                             (void *)salt, salt_len);
+    *p = OSSL_PARAM_construct_end();
+
+    if (!EVP_MAC_CTX_set_params(ctx_init, params))
+        goto end;
+
+    if (!kmac_init(ctx_init, kmac_custom, kmac_custom_len, kmac_out_len,
+                   derived_key_len, &kmac_buffer))
+        goto end;
+    if (kmac_buffer != NULL)
+        mac = kmac_buffer;
+
+    if (!EVP_MAC_init(ctx_init))
+        goto end;
+
+    out_len = EVP_MAC_size(ctx_init); /* output size */
+    if (out_len <= 0)
+        goto end;
+    len = derived_key_len;
+
+    for (counter = 1;; counter++) {
+        c[0] = (unsigned char)((counter >> 24) & 0xff);
+        c[1] = (unsigned char)((counter >> 16) & 0xff);
+        c[2] = (unsigned char)((counter >> 8) & 0xff);
+        c[3] = (unsigned char)(counter & 0xff);
+
+        ctx = EVP_MAC_CTX_dup(ctx_init);
+        if (!(ctx != NULL
+                && EVP_MAC_update(ctx, c, sizeof(c))
+                && EVP_MAC_update(ctx, z, z_len)
+                && EVP_MAC_update(ctx, info, info_len)))
+            goto end;
+        if (len >= out_len) {
+            if (!EVP_MAC_final(ctx, out, NULL, len))
+                goto end;
+            out += out_len;
+            len -= out_len;
+            if (len == 0)
+                break;
+        } else {
+            if (!EVP_MAC_final(ctx, mac, NULL, len))
+                goto end;
+            memcpy(out, mac, len);
+            break;
+        }
+        EVP_MAC_CTX_free(ctx);
+        ctx = NULL;
+    }
+    ret = 1;
+end:
+    if (kmac_buffer != NULL)
+        OPENSSL_clear_free(kmac_buffer, kmac_out_len);
+    else
+        OPENSSL_cleanse(mac_buf, sizeof(mac_buf));
+
+    EVP_MAC_CTX_free(ctx);
+    return ret;
+}
+
+static void *sskdf_new(void *provctx)
+{
+    KDF_SSKDF *ctx;
+
+    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+    ctx->provctx = provctx;
+    return ctx;
+}
+
+static void sskdf_reset(void *vctx)
+{
+    KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
+
+    EVP_MAC_CTX_free(ctx->macctx);
+    ossl_prov_digest_reset(&ctx->digest);
+    OPENSSL_clear_free(ctx->secret, ctx->secret_len);
+    OPENSSL_clear_free(ctx->info, ctx->info_len);
+    OPENSSL_clear_free(ctx->salt, ctx->salt_len);
+    memset(ctx, 0, sizeof(*ctx));
+}
+
+static void sskdf_free(void *vctx)
+{
+    KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
+
+    sskdf_reset(ctx);
+    OPENSSL_free(ctx);
+}
+
+static int sskdf_set_buffer(unsigned char **out, size_t *out_len,
+                            const OSSL_PARAM *p)
+{
+    if (p->data == NULL || p->data_size == 0)
+        return 1;
+    OPENSSL_free(*out);
+    *out = NULL;
+    return OSSL_PARAM_get_octet_string(p, (void **)out, 0, out_len);
+}
+
+static size_t sskdf_size(KDF_SSKDF *ctx)
+{
+    int len;
+    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
+
+    if (md == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
+        return 0;
+    }
+    len = EVP_MD_size(md);
+    return (len <= 0) ? 0 : (size_t)len;
+}
+
+static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen)
+{
+    KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
+    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
+
+    if (ctx->secret == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);
+        return 0;
+    }
+
+    if (ctx->macctx != NULL) {
+        /* H(x) = KMAC or H(x) = HMAC */
+        int ret;
+        const unsigned char *custom = NULL;
+        size_t custom_len = 0;
+        int default_salt_len;
+        EVP_MAC *mac = EVP_MAC_CTX_mac(ctx->macctx);
+
+        /*
+         * TODO(3.0) investigate the necessity to have all these controls.
+         * Why does KMAC require a salt length that's shorter than the MD
+         * block size?
+         */
+        if (EVP_MAC_is_a(mac, OSSL_MAC_NAME_HMAC)) {
+            /* H(x) = HMAC(x, salt, hash) */
+            if (md == NULL) {
+                ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
+                return 0;
+            }
+            default_salt_len = EVP_MD_size(md);
+            if (default_salt_len <= 0)
+                return 0;
+        } else if (EVP_MAC_is_a(mac, OSSL_MAC_NAME_KMAC128)
+                   || EVP_MAC_is_a(mac, OSSL_MAC_NAME_KMAC256)) {
+            /* H(x) = KMACzzz(x, salt, custom) */
+            custom = kmac_custom_str;
+            custom_len = sizeof(kmac_custom_str);
+            if (EVP_MAC_is_a(mac, OSSL_MAC_NAME_KMAC128))
+                default_salt_len = SSKDF_KMAC128_DEFAULT_SALT_SIZE;
+            else
+                default_salt_len = SSKDF_KMAC256_DEFAULT_SALT_SIZE;
+        } else {
+            ERR_raise(ERR_LIB_PROV, PROV_R_UNSUPPORTED_MAC_TYPE);
+            return 0;
+        }
+        /* If no salt is set then use a default_salt of zeros */
+        if (ctx->salt == NULL || ctx->salt_len <= 0) {
+            ctx->salt = OPENSSL_zalloc(default_salt_len);
+            if (ctx->salt == NULL) {
+                ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+                return 0;
+            }
+            ctx->salt_len = default_salt_len;
+        }
+        ret = SSKDF_mac_kdm(ctx->macctx,
+                            custom, custom_len, ctx->out_len,
+                            ctx->salt, ctx->salt_len,
+                            ctx->secret, ctx->secret_len,
+                            ctx->info, ctx->info_len, key, keylen);
+        return ret;
+    } else {
+        /* H(x) = hash */
+        if (md == NULL) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
+            return 0;
+        }
+        return SSKDF_hash_kdm(md, ctx->secret, ctx->secret_len,
+                              ctx->info, ctx->info_len, 0, key, keylen);
+    }
+}
+
+static int x963kdf_derive(void *vctx, unsigned char *key, size_t keylen)
+{
+    KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
+    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
+
+    if (ctx->secret == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);
+        return 0;
+    }
+
+    if (ctx->macctx != NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED);
+        return 0;
+    }
+
+    /* H(x) = hash */
+    if (md == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
+        return 0;
+    }
+
+    return SSKDF_hash_kdm(md, ctx->secret, ctx->secret_len,
+                          ctx->info, ctx->info_len, 1, key, keylen);
+}
+
+static int sskdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    const OSSL_PARAM *p;
+    KDF_SSKDF *ctx = vctx;
+    OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
+    size_t sz;
+
+    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx))
+        return 0;
+
+    if (!ossl_prov_macctx_load_from_params(&ctx->macctx, params,
+                                           NULL, NULL, NULL, libctx))
+        return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL
+        || (p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL)
+        if (!sskdf_set_buffer(&ctx->secret, &ctx->secret_len, p))
+            return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO)) != NULL)
+        if (!sskdf_set_buffer(&ctx->info, &ctx->info_len, p))
+            return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL)
+        if (!sskdf_set_buffer(&ctx->salt, &ctx->salt_len, p))
+            return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MAC_SIZE))
+        != NULL) {
+        if (!OSSL_PARAM_get_size_t(p, &sz) || sz == 0)
+            return 0;
+        ctx->out_len = sz;
+    }
+    return 1;
+}
+
+static const OSSL_PARAM *sskdf_settable_ctx_params(void)
+{
+    static const OSSL_PARAM known_settable_ctx_params[] = {
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MAC, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
+        OSSL_PARAM_size_t(OSSL_KDF_PARAM_MAC_SIZE, NULL),
+        OSSL_PARAM_END
+    };
+    return known_settable_ctx_params;
+}
+
+static int sskdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+    KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, sskdf_size(ctx));
+    return -2;
+}
+
+static const OSSL_PARAM *sskdf_gettable_ctx_params(void)
+{
+    static const OSSL_PARAM known_gettable_ctx_params[] = {
+        OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
+        OSSL_PARAM_END
+    };
+    return known_gettable_ctx_params;
+}
+
+const OSSL_DISPATCH kdf_sskdf_functions[] = {
+    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))sskdf_new },
+    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))sskdf_free },
+    { OSSL_FUNC_KDF_RESET, (void(*)(void))sskdf_reset },
+    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))sskdf_derive },
+    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
+      (void(*)(void))sskdf_settable_ctx_params },
+    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))sskdf_set_ctx_params },
+    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
+      (void(*)(void))sskdf_gettable_ctx_params },
+    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))sskdf_get_ctx_params },
+    { 0, NULL }
+};
+
+const OSSL_DISPATCH kdf_x963_kdf_functions[] = {
+    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))sskdf_new },
+    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))sskdf_free },
+    { OSSL_FUNC_KDF_RESET, (void(*)(void))sskdf_reset },
+    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))x963kdf_derive },
+    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
+      (void(*)(void))sskdf_settable_ctx_params },
+    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))sskdf_set_ctx_params },
+    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
+      (void(*)(void))sskdf_gettable_ctx_params },
+    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))sskdf_get_ctx_params },
+    { 0, NULL }
+};
diff --git a/providers/implementations/kdfs/tls1_prf.c b/providers/implementations/kdfs/tls1_prf.c
new file mode 100644 (file)
index 0000000..af49b1b
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ * Copyright 2016-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
+ */
+
+/*
+ * Refer to "The TLS Protocol Version 1.0" Section 5
+ * (https://tools.ietf.org/html/rfc2246#section-5) and
+ * "The Transport Layer Security (TLS) Protocol Version 1.2" Section 5
+ * (https://tools.ietf.org/html/rfc5246#section-5).
+ *
+ * For TLS v1.0 and TLS v1.1 the TLS PRF algorithm is given by:
+ *
+ *   PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
+ *                              P_SHA-1(S2, label + seed)
+ *
+ * where P_MD5 and P_SHA-1 are defined by P_<hash>, below, and S1 and S2 are
+ * two halves of the secret (with the possibility of one shared byte, in the
+ * case where the length of the original secret is odd).  S1 is taken from the
+ * first half of the secret, S2 from the second half.
+ *
+ * For TLS v1.2 the TLS PRF algorithm is given by:
+ *
+ *   PRF(secret, label, seed) = P_<hash>(secret, label + seed)
+ *
+ * where hash is SHA-256 for all cipher suites defined in RFC 5246 as well as
+ * those published prior to TLS v1.2 while the TLS v1.2 protocol is in effect,
+ * unless defined otherwise by the cipher suite.
+ *
+ * P_<hash> is an expansion function that uses a single hash function to expand
+ * a secret and seed into an arbitrary quantity of output:
+ *
+ *   P_<hash>(secret, seed) = HMAC_<hash>(secret, A(1) + seed) +
+ *                            HMAC_<hash>(secret, A(2) + seed) +
+ *                            HMAC_<hash>(secret, A(3) + seed) + ...
+ *
+ * where + indicates concatenation.  P_<hash> can be iterated as many times as
+ * is necessary to produce the required quantity of data.
+ *
+ * A(i) is defined as:
+ *     A(0) = seed
+ *     A(i) = HMAC_<hash>(secret, A(i-1))
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/kdf.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
+#include "internal/cryptlib.h"
+#include "internal/numbers.h"
+#include "crypto/evp.h"
+#include "internal/provider_ctx.h"
+#include "internal/providercommonerr.h"
+#include "internal/provider_algs.h"
+#include "internal/provider_util.h"
+#include "e_os.h"
+
+static OSSL_OP_kdf_newctx_fn kdf_tls1_prf_new;
+static OSSL_OP_kdf_freectx_fn kdf_tls1_prf_free;
+static OSSL_OP_kdf_reset_fn kdf_tls1_prf_reset;
+static OSSL_OP_kdf_derive_fn kdf_tls1_prf_derive;
+static OSSL_OP_kdf_settable_ctx_params_fn kdf_tls1_prf_settable_ctx_params;
+static OSSL_OP_kdf_set_ctx_params_fn kdf_tls1_prf_set_ctx_params;
+
+static int tls1_prf_alg(EVP_MAC_CTX *mdctx, EVP_MAC_CTX *sha1ctx,
+                        const unsigned char *sec, size_t slen,
+                        const unsigned char *seed, size_t seed_len,
+                        unsigned char *out, size_t olen);
+
+#define TLS1_PRF_MAXBUF 1024
+
+/* TLS KDF kdf context structure */
+typedef struct {
+    void *provctx;
+
+    /* MAC context for the main digest */
+    EVP_MAC_CTX *P_hash;
+    /* MAC context for SHA1 for the MD5/SHA-1 combined PRF */
+    EVP_MAC_CTX *P_sha1;
+
+    /* Secret value to use for PRF */
+    unsigned char *sec;
+    size_t seclen;
+    /* Buffer of concatenated seed data */
+    unsigned char seed[TLS1_PRF_MAXBUF];
+    size_t seedlen;
+} TLS1_PRF;
+
+static void *kdf_tls1_prf_new(void *provctx)
+{
+    TLS1_PRF *ctx;
+
+    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+    ctx->provctx = provctx;
+    return ctx;
+}
+
+static void kdf_tls1_prf_free(void *vctx)
+{
+    TLS1_PRF *ctx = (TLS1_PRF *)vctx;
+
+    kdf_tls1_prf_reset(ctx);
+    OPENSSL_free(ctx);
+}
+
+static void kdf_tls1_prf_reset(void *vctx)
+{
+    TLS1_PRF *ctx = (TLS1_PRF *)vctx;
+
+    EVP_MAC_CTX_free(ctx->P_hash);
+    EVP_MAC_CTX_free(ctx->P_sha1);
+    OPENSSL_clear_free(ctx->sec, ctx->seclen);
+    OPENSSL_cleanse(ctx->seed, ctx->seedlen);
+    memset(ctx, 0, sizeof(*ctx));
+}
+
+static int kdf_tls1_prf_derive(void *vctx, unsigned char *key,
+                               size_t keylen)
+{
+    TLS1_PRF *ctx = (TLS1_PRF *)vctx;
+
+    if (ctx->P_hash == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
+        return 0;
+    }
+    if (ctx->sec == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);
+        return 0;
+    }
+    if (ctx->seedlen == 0) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SEED);
+        return 0;
+    }
+
+    return tls1_prf_alg(ctx->P_hash, ctx->P_sha1,
+                        ctx->sec, ctx->seclen,
+                        ctx->seed, ctx->seedlen,
+                        key, keylen);
+}
+
+static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    const OSSL_PARAM *p;
+    TLS1_PRF *ctx = vctx;
+    OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DIGEST)) != NULL) {
+        if (strcasecmp(p->data, SN_md5_sha1) == 0) {
+            if (!ossl_prov_macctx_load_from_params(&ctx->P_hash, params,
+                                                   OSSL_MAC_NAME_HMAC,
+                                                   NULL, SN_md5, libctx)
+                || !ossl_prov_macctx_load_from_params(&ctx->P_sha1, params,
+                                                      OSSL_MAC_NAME_HMAC,
+                                                      NULL, SN_sha1, libctx))
+                return 0;
+        } else {
+            EVP_MAC_CTX_free(ctx->P_sha1);
+            if (!ossl_prov_macctx_load_from_params(&ctx->P_hash, params,
+                                                   OSSL_MAC_NAME_HMAC,
+                                                   NULL, NULL, libctx))
+                return 0;
+        }
+    }
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL) {
+        OPENSSL_clear_free(ctx->sec, ctx->seclen);
+        ctx->sec = NULL;
+        if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->sec, 0, &ctx->seclen))
+            return 0;
+    }
+    /* The seed fields concatenate, so process them all */
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SEED)) != NULL) {
+        OPENSSL_cleanse(ctx->seed, ctx->seedlen);
+        ctx->seedlen = 0;
+
+        for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1,
+                                                      OSSL_KDF_PARAM_SEED)) {
+            const void *q = ctx->seed + ctx->seedlen;
+            size_t sz = 0;
+
+            if (p->data_size != 0
+                && p->data != NULL
+                && !OSSL_PARAM_get_octet_string(p, (void **)&q,
+                                                TLS1_PRF_MAXBUF - ctx->seedlen,
+                                                &sz))
+                return 0;
+            ctx->seedlen += sz;
+        }
+    }
+    return 1;
+}
+
+static const OSSL_PARAM *kdf_tls1_prf_settable_ctx_params(void)
+{
+    static const OSSL_PARAM known_settable_ctx_params[] = {
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SEED, NULL, 0),
+        OSSL_PARAM_END
+    };
+    return known_settable_ctx_params;
+}
+
+static int kdf_tls1_prf_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, SIZE_MAX);
+    return -2;
+}
+
+static const OSSL_PARAM *kdf_tls1_prf_gettable_ctx_params(void)
+{
+    static const OSSL_PARAM known_gettable_ctx_params[] = {
+        OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
+        OSSL_PARAM_END
+    };
+    return known_gettable_ctx_params;
+}
+
+const OSSL_DISPATCH kdf_tls1_prf_functions[] = {
+    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_tls1_prf_new },
+    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_tls1_prf_free },
+    { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_tls1_prf_reset },
+    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_tls1_prf_derive },
+    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
+      (void(*)(void))kdf_tls1_prf_settable_ctx_params },
+    { OSSL_FUNC_KDF_SET_CTX_PARAMS,
+      (void(*)(void))kdf_tls1_prf_set_ctx_params },
+    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
+      (void(*)(void))kdf_tls1_prf_gettable_ctx_params },
+    { OSSL_FUNC_KDF_GET_CTX_PARAMS,
+      (void(*)(void))kdf_tls1_prf_get_ctx_params },
+    { 0, NULL }
+};
+
+/*
+ * Refer to "The TLS Protocol Version 1.0" Section 5
+ * (https://tools.ietf.org/html/rfc2246#section-5) and
+ * "The Transport Layer Security (TLS) Protocol Version 1.2" Section 5
+ * (https://tools.ietf.org/html/rfc5246#section-5).
+ *
+ * P_<hash> is an expansion function that uses a single hash function to expand
+ * a secret and seed into an arbitrary quantity of output:
+ *
+ *   P_<hash>(secret, seed) = HMAC_<hash>(secret, A(1) + seed) +
+ *                            HMAC_<hash>(secret, A(2) + seed) +
+ *                            HMAC_<hash>(secret, A(3) + seed) + ...
+ *
+ * where + indicates concatenation.  P_<hash> can be iterated as many times as
+ * is necessary to produce the required quantity of data.
+ *
+ * A(i) is defined as:
+ *     A(0) = seed
+ *     A(i) = HMAC_<hash>(secret, A(i-1))
+ */
+static int tls1_prf_P_hash(EVP_MAC_CTX *ctx_init,
+                           const unsigned char *sec, size_t sec_len,
+                           const unsigned char *seed, size_t seed_len,
+                           unsigned char *out, size_t olen)
+{
+    size_t chunk;
+    EVP_MAC_CTX *ctx = NULL, *ctx_Ai = NULL;
+    unsigned char Ai[EVP_MAX_MD_SIZE];
+    size_t Ai_len;
+    int ret = 0;
+    OSSL_PARAM params[2], *p = params;
+
+    *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+                                             (void *)sec, sec_len);
+    *p = OSSL_PARAM_construct_end();
+    if (!EVP_MAC_CTX_set_params(ctx_init, params))
+        goto err;
+    if (!EVP_MAC_init(ctx_init))
+        goto err;
+    chunk = EVP_MAC_size(ctx_init);
+    if (chunk == 0)
+        goto err;
+    /* A(0) = seed */
+    ctx_Ai = EVP_MAC_CTX_dup(ctx_init);
+    if (ctx_Ai == NULL)
+        goto err;
+    if (seed != NULL && !EVP_MAC_update(ctx_Ai, seed, seed_len))
+        goto err;
+
+    for (;;) {
+        /* calc: A(i) = HMAC_<hash>(secret, A(i-1)) */
+        if (!EVP_MAC_final(ctx_Ai, Ai, &Ai_len, sizeof(Ai)))
+            goto err;
+        EVP_MAC_CTX_free(ctx_Ai);
+        ctx_Ai = NULL;
+
+        /* calc next chunk: HMAC_<hash>(secret, A(i) + seed) */
+        ctx = EVP_MAC_CTX_dup(ctx_init);
+        if (ctx == NULL)
+            goto err;
+        if (!EVP_MAC_update(ctx, Ai, Ai_len))
+            goto err;
+        /* save state for calculating next A(i) value */
+        if (olen > chunk) {
+            ctx_Ai = EVP_MAC_CTX_dup(ctx);
+            if (ctx_Ai == NULL)
+                goto err;
+        }
+        if (seed != NULL && !EVP_MAC_update(ctx, seed, seed_len))
+            goto err;
+        if (olen <= chunk) {
+            /* last chunk - use Ai as temp bounce buffer */
+            if (!EVP_MAC_final(ctx, Ai, &Ai_len, sizeof(Ai)))
+                goto err;
+            memcpy(out, Ai, olen);
+            break;
+        }
+        if (!EVP_MAC_final(ctx, out, NULL, olen))
+            goto err;
+        EVP_MAC_CTX_free(ctx);
+        ctx = NULL;
+        out += chunk;
+        olen -= chunk;
+    }
+    ret = 1;
+ err:
+    EVP_MAC_CTX_free(ctx);
+    EVP_MAC_CTX_free(ctx_Ai);
+    OPENSSL_cleanse(Ai, sizeof(Ai));
+    return ret;
+}
+
+/*
+ * Refer to "The TLS Protocol Version 1.0" Section 5
+ * (https://tools.ietf.org/html/rfc2246#section-5) and
+ * "The Transport Layer Security (TLS) Protocol Version 1.2" Section 5
+ * (https://tools.ietf.org/html/rfc5246#section-5).
+ *
+ * For TLS v1.0 and TLS v1.1:
+ *
+ *   PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
+ *                              P_SHA-1(S2, label + seed)
+ *
+ * S1 is taken from the first half of the secret, S2 from the second half.
+ *
+ *   L_S = length in bytes of secret;
+ *   L_S1 = L_S2 = ceil(L_S / 2);
+ *
+ * For TLS v1.2:
+ *
+ *   PRF(secret, label, seed) = P_<hash>(secret, label + seed)
+ */
+static int tls1_prf_alg(EVP_MAC_CTX *mdctx, EVP_MAC_CTX *sha1ctx,
+                        const unsigned char *sec, size_t slen,
+                        const unsigned char *seed, size_t seed_len,
+                        unsigned char *out, size_t olen)
+{
+    if (sha1ctx != NULL) {
+        /* TLS v1.0 and TLS v1.1 */
+        size_t i;
+        unsigned char *tmp;
+        /* calc: L_S1 = L_S2 = ceil(L_S / 2) */
+        size_t L_S1 = (slen + 1) / 2;
+        size_t L_S2 = L_S1;
+
+        if (!tls1_prf_P_hash(mdctx, sec, L_S1,
+                             seed, seed_len, out, olen))
+            return 0;
+
+        if ((tmp = OPENSSL_malloc(olen)) == NULL) {
+            ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+
+        if (!tls1_prf_P_hash(sha1ctx, sec + slen - L_S2, L_S2,
+                             seed, seed_len, tmp, olen)) {
+            OPENSSL_clear_free(tmp, olen);
+            return 0;
+        }
+        for (i = 0; i < olen; i++)
+            out[i] ^= tmp[i];
+        OPENSSL_clear_free(tmp, olen);
+        return 1;
+    }
+
+    /* TLS v1.2 */
+    if (!tls1_prf_P_hash(mdctx, sec, slen, seed, seed_len, out, olen))
+        return 0;
+
+    return 1;
+}
diff --git a/providers/implementations/keymgmt/build.info b/providers/implementations/keymgmt/build.info
new file mode 100644 (file)
index 0000000..dc6039b
--- /dev/null
@@ -0,0 +1,12 @@
+# We make separate GOAL variables for each algorithm, to make it easy to
+# switch each to the Legacy provider when needed.
+
+$DH_GOAL=../../libimplementations.a
+$DSA_GOAL=../../libimplementations.a
+
+IF[{- !$disabled{dh} -}]
+  SOURCE[$DH_GOAL]=dh_kmgmt.c
+ENDIF
+IF[{- !$disabled{dsa} -}]
+  SOURCE[$DSA_GOAL]=dsa_kmgmt.c
+ENDIF
diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c
new file mode 100644 (file)
index 0000000..c13f075
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * 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/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/params.h>
+#include "internal/provider_algs.h"
+
+static OSSL_OP_keymgmt_importkey_fn dh_importkey;
+
+static int params_to_key(DH *dh, const OSSL_PARAM params[])
+{
+    const OSSL_PARAM *param_p, *param_g, *param_priv_key, *param_pub_key;
+    BIGNUM *p = NULL, *g = NULL, *priv_key = NULL, *pub_key = NULL;
+
+    if (dh == NULL)
+        return 0;
+
+    param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P);
+    param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G);
+    param_priv_key =
+        OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_KEY);
+    param_pub_key =
+        OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PUB_KEY);
+
+    /*
+     * DH documentation says that a public key must be present if a
+     * private key is present.
+     * We want to have at least a public key either way, so we end up
+     * requiring it unconditionally.
+     */
+    if (param_pub_key == NULL)
+        return 0;
+
+    if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p))
+        || (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g))
+        || (param_priv_key != NULL
+            && !OSSL_PARAM_get_BN(param_priv_key, &priv_key))
+        || !OSSL_PARAM_get_BN(param_pub_key, &pub_key))
+        goto err;
+
+    if (!DH_set0_pqg(dh, p, NULL, g))
+        goto err;
+    p = g = NULL;
+
+    if (!DH_set0_key(dh, pub_key, priv_key))
+        goto err;
+    priv_key = pub_key = NULL;
+
+    return 1;
+
+ err:
+    BN_free(p);
+    BN_free(g);
+    BN_free(priv_key);
+    BN_free(pub_key);
+    return 0;
+}
+
+static void *dh_importkey(void *provctx, const OSSL_PARAM params[])
+{
+    DH *dh;
+
+    if ((dh = DH_new()) == NULL
+        || !params_to_key(dh, params)) {
+        DH_free(dh);
+        dh = NULL;
+    }
+    return dh;
+}
+
+const OSSL_DISPATCH dh_keymgmt_functions[] = {
+    /*
+     * TODO(3.0) When implementing OSSL_FUNC_KEYMGMT_GENKEY, remember to also
+     * implement OSSL_FUNC_KEYMGMT_EXPORTKEY.
+     */
+    { OSSL_FUNC_KEYMGMT_IMPORTKEY, (void (*)(void))dh_importkey },
+    { OSSL_FUNC_KEYMGMT_FREEKEY, (void (*)(void))DH_free },
+    { 0, NULL }
+};
diff --git a/providers/implementations/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c
new file mode 100644 (file)
index 0000000..a53c0b2
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/params.h>
+#include "internal/provider_algs.h"
+
+static OSSL_OP_keymgmt_importkey_fn dsa_importkey;
+
+static int params_to_key(DSA *dsa, const OSSL_PARAM params[])
+{
+    const OSSL_PARAM *param_p, *param_q, *param_g, *param_priv_key;
+    const OSSL_PARAM *param_pub_key;
+    BIGNUM *p = NULL, *q = NULL, *g = NULL, *priv_key = NULL, *pub_key = NULL;
+
+    if (dsa == NULL)
+        return 0;
+
+    param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P);
+    param_q = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_Q);
+    param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G);
+    param_priv_key =
+        OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DSA_PRIV_KEY);
+    param_pub_key =
+        OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DSA_PUB_KEY);
+
+    /*
+     * DSA documentation says that a public key must be present if a private key
+     * is.
+     */
+    if (param_priv_key != NULL && param_pub_key == NULL)
+        return 0;
+
+    if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p))
+        || (param_q != NULL && !OSSL_PARAM_get_BN(param_q, &q))
+        || (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g))
+        || (param_priv_key != NULL
+            && !OSSL_PARAM_get_BN(param_priv_key, &priv_key))
+        || (param_pub_key != NULL
+            && !OSSL_PARAM_get_BN(param_pub_key, &pub_key)))
+        goto err;
+
+    if (!DSA_set0_pqg(dsa, p, q, g))
+        goto err;
+    p = q = g = NULL;
+
+    if (pub_key != NULL && !DSA_set0_key(dsa, pub_key, priv_key))
+        goto err;
+    priv_key = pub_key = NULL;
+
+    return 1;
+
+ err:
+    BN_free(p);
+    BN_free(q);
+    BN_free(g);
+    BN_free(priv_key);
+    BN_free(pub_key);
+    return 0;
+}
+
+static void *dsa_importkey(void *provctx, const OSSL_PARAM params[])
+{
+    DSA *dsa;
+
+    if ((dsa = DSA_new()) == NULL
+        || !params_to_key(dsa, params)) {
+        DSA_free(dsa);
+        dsa = NULL;
+    }
+    return dsa;
+}
+
+const OSSL_DISPATCH dsa_keymgmt_functions[] = {
+    /*
+     * TODO(3.0) When implementing OSSL_FUNC_KEYMGMT_GENKEY, remember to also
+     * implement OSSL_FUNC_KEYMGMT_EXPORTKEY.
+     */
+    { OSSL_FUNC_KEYMGMT_IMPORTKEY, (void (*)(void))dsa_importkey },
+    { OSSL_FUNC_KEYMGMT_FREEKEY, (void (*)(void))DSA_free },
+    { 0, NULL }
+};
diff --git a/providers/implementations/macs/build.info b/providers/implementations/macs/build.info
new file mode 100644 (file)
index 0000000..d453809
--- /dev/null
@@ -0,0 +1,15 @@
+# We make separate GOAL variables for each algorithm, to make it easy to
+# switch each to the Legacy provider when needed.
+
+$GMAC_GOAL=../../libimplementations.a
+$HMAC_GOAL=../../libimplementations.a
+$KMAC_GOAL=../../libimplementations.a
+$CMAC_GOAL=../../libimplementations.a
+
+SOURCE[$GMAC_GOAL]=gmac_prov.c
+SOURCE[$HMAC_GOAL]=hmac_prov.c
+SOURCE[$KMAC_GOAL]=kmac_prov.c
+
+IF[{- !$disabled{cmac} -}]
+  SOURCE[$CMAC_GOAL]=cmac_prov.c
+ENDIF
diff --git a/providers/implementations/macs/cmac_prov.c b/providers/implementations/macs/cmac_prov.c
new file mode 100644 (file)
index 0000000..c01b2f8
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2018 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/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/cmac.h>
+
+#include "internal/provider_algs.h"
+#include "internal/provider_ctx.h"
+#include "internal/provider_util.h"
+
+/*
+ * Forward declaration of everything implemented here.  This is not strictly
+ * necessary for the compiler, but provides an assurance that the signatures
+ * of the functions in the dispatch table are correct.
+ */
+static OSSL_OP_mac_newctx_fn cmac_new;
+static OSSL_OP_mac_dupctx_fn cmac_dup;
+static OSSL_OP_mac_freectx_fn cmac_free;
+static OSSL_OP_mac_gettable_ctx_params_fn cmac_gettable_ctx_params;
+static OSSL_OP_mac_get_ctx_params_fn cmac_get_ctx_params;
+static OSSL_OP_mac_settable_ctx_params_fn cmac_settable_ctx_params;
+static OSSL_OP_mac_set_ctx_params_fn cmac_set_ctx_params;
+static OSSL_OP_mac_init_fn cmac_init;
+static OSSL_OP_mac_update_fn cmac_update;
+static OSSL_OP_mac_final_fn cmac_final;
+
+/* local CMAC data */
+
+struct cmac_data_st {
+    void *provctx;
+    CMAC_CTX *ctx;
+    PROV_CIPHER cipher;
+};
+
+static void *cmac_new(void *provctx)
+{
+    struct cmac_data_st *macctx;
+
+    if ((macctx = OPENSSL_zalloc(sizeof(*macctx))) == NULL
+        || (macctx->ctx = CMAC_CTX_new()) == NULL) {
+        OPENSSL_free(macctx);
+        macctx = NULL;
+    } else {
+        macctx->provctx = provctx;
+    }
+
+    return macctx;
+}
+
+static void cmac_free(void *vmacctx)
+{
+    struct cmac_data_st *macctx = vmacctx;
+
+    if (macctx != NULL) {
+        CMAC_CTX_free(macctx->ctx);
+        ossl_prov_cipher_reset(&macctx->cipher);
+        OPENSSL_free(macctx);
+    }
+}
+
+static void *cmac_dup(void *vsrc)
+{
+    struct cmac_data_st *src = vsrc;
+    struct cmac_data_st *dst = cmac_new(src->provctx);
+
+    if (!CMAC_CTX_copy(dst->ctx, src->ctx)
+        || !ossl_prov_cipher_copy(&dst->cipher, &src->cipher)) {
+        cmac_free(dst);
+        return NULL;
+    }
+    return dst;
+}
+
+static size_t cmac_size(void *vmacctx)
+{
+    struct cmac_data_st *macctx = vmacctx;
+
+    return EVP_CIPHER_CTX_block_size(CMAC_CTX_get0_cipher_ctx(macctx->ctx));
+}
+
+static int cmac_init(void *vmacctx)
+{
+    struct cmac_data_st *macctx = vmacctx;
+    int rv = CMAC_Init(macctx->ctx, NULL, 0,
+                       ossl_prov_cipher_cipher(&macctx->cipher),
+                       ossl_prov_cipher_engine(&macctx->cipher));
+
+    ossl_prov_cipher_reset(&macctx->cipher);
+    return rv;
+}
+
+static int cmac_update(void *vmacctx, const unsigned char *data,
+                       size_t datalen)
+{
+    struct cmac_data_st *macctx = vmacctx;
+
+    return CMAC_Update(macctx->ctx, data, datalen);
+}
+
+static int cmac_final(void *vmacctx, unsigned char *out, size_t *outl,
+                      size_t outsize)
+{
+    struct cmac_data_st *macctx = vmacctx;
+
+    return CMAC_Final(macctx->ctx, out, outl);
+}
+
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *cmac_gettable_ctx_params(void)
+{
+    return known_gettable_ctx_params;
+}
+
+static int cmac_get_ctx_params(void *vmacctx, OSSL_PARAM params[])
+{
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, cmac_size(vmacctx));
+
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_CIPHER, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *cmac_settable_ctx_params(void)
+{
+    return known_settable_ctx_params;
+}
+
+/*
+ * ALL parameters should be set before init().
+ */
+static int cmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[])
+{
+    struct cmac_data_st *macctx = vmacctx;
+    OPENSSL_CTX *ctx = PROV_LIBRARY_CONTEXT_OF(macctx->provctx);
+    const OSSL_PARAM *p;
+
+    if (!ossl_prov_cipher_load_from_params(&macctx->cipher, params, ctx))
+        return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
+        if (p->data_type != OSSL_PARAM_OCTET_STRING)
+            return 0;
+
+        if (!CMAC_Init(macctx->ctx, p->data, p->data_size,
+                       ossl_prov_cipher_cipher(&macctx->cipher),
+                       ossl_prov_cipher_engine(&macctx->cipher)))
+            return 0;
+
+        ossl_prov_cipher_reset(&macctx->cipher);
+    }
+    return 1;
+}
+
+const OSSL_DISPATCH cmac_functions[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))cmac_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))cmac_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))cmac_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))cmac_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))cmac_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))cmac_final },
+    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
+      (void (*)(void))cmac_gettable_ctx_params },
+    { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))cmac_get_ctx_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))cmac_settable_ctx_params },
+    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))cmac_set_ctx_params },
+    { 0, NULL }
+};
diff --git a/providers/implementations/macs/gmac_prov.c b/providers/implementations/macs/gmac_prov.c
new file mode 100644 (file)
index 0000000..3d81af8
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2018 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 <stdlib.h>
+#include <openssl/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+
+#include "internal/providercommonerr.h"
+#include "internal/provider_algs.h"
+#include "internal/provider_ctx.h"
+#include "internal/provider_util.h"
+
+/*
+ * Forward declaration of everything implemented here.  This is not strictly
+ * necessary for the compiler, but provides an assurance that the signatures
+ * of the functions in the dispatch table are correct.
+ */
+static OSSL_OP_mac_newctx_fn gmac_new;
+static OSSL_OP_mac_dupctx_fn gmac_dup;
+static OSSL_OP_mac_freectx_fn gmac_free;
+static OSSL_OP_mac_gettable_params_fn gmac_gettable_params;
+static OSSL_OP_mac_get_params_fn gmac_get_params;
+static OSSL_OP_mac_settable_ctx_params_fn gmac_settable_ctx_params;
+static OSSL_OP_mac_set_ctx_params_fn gmac_set_ctx_params;
+static OSSL_OP_mac_init_fn gmac_init;
+static OSSL_OP_mac_update_fn gmac_update;
+static OSSL_OP_mac_final_fn gmac_final;
+
+/* local GMAC pkey structure */
+
+struct gmac_data_st {
+    void *provctx;
+    EVP_CIPHER_CTX *ctx;         /* Cipher context */
+    PROV_CIPHER cipher;
+};
+
+static size_t gmac_size(void);
+
+static void gmac_free(void *vmacctx)
+{
+    struct gmac_data_st *macctx = vmacctx;
+
+    if (macctx != NULL) {
+        EVP_CIPHER_CTX_free(macctx->ctx);
+        ossl_prov_cipher_reset(&macctx->cipher);
+        OPENSSL_free(macctx);
+    }
+}
+
+static void *gmac_new(void *provctx)
+{
+    struct gmac_data_st *macctx;
+
+    if ((macctx = OPENSSL_zalloc(sizeof(*macctx))) == NULL
+        || (macctx->ctx = EVP_CIPHER_CTX_new()) == NULL) {
+        gmac_free(macctx);
+        return NULL;
+    }
+    macctx->provctx = provctx;
+
+    return macctx;
+}
+
+static void *gmac_dup(void *vsrc)
+{
+    struct gmac_data_st *src = vsrc;
+    struct gmac_data_st *dst = gmac_new(src->provctx);
+
+    if (dst == NULL)
+        return NULL;
+
+    if (!EVP_CIPHER_CTX_copy(dst->ctx, src->ctx)
+        || !ossl_prov_cipher_copy(&dst->cipher, &src->cipher)) {
+        gmac_free(dst);
+        return NULL;
+    }
+    return dst;
+}
+
+static int gmac_init(void *vmacctx)
+{
+    return 1;
+}
+
+static int gmac_update(void *vmacctx, const unsigned char *data,
+                       size_t datalen)
+{
+    struct gmac_data_st *macctx = vmacctx;
+    EVP_CIPHER_CTX *ctx = macctx->ctx;
+    int outlen;
+
+    while (datalen > INT_MAX) {
+        if (!EVP_EncryptUpdate(ctx, NULL, &outlen, data, INT_MAX))
+            return 0;
+        data += INT_MAX;
+        datalen -= INT_MAX;
+    }
+    return EVP_EncryptUpdate(ctx, NULL, &outlen, data, datalen);
+}
+
+static int gmac_final(void *vmacctx, unsigned char *out, size_t *outl,
+                      size_t outsize)
+{
+    struct gmac_data_st *macctx = vmacctx;
+    int hlen = 0;
+
+    if (!EVP_EncryptFinal_ex(macctx->ctx, out, &hlen))
+        return 0;
+
+    /* TODO(3.0) Use params */
+    hlen = gmac_size();
+    if (!EVP_CIPHER_CTX_ctrl(macctx->ctx, EVP_CTRL_AEAD_GET_TAG,
+                             hlen, out))
+        return 0;
+
+    *outl = hlen;
+    return 1;
+}
+
+static size_t gmac_size(void)
+{
+    return EVP_GCM_TLS_TAG_LEN;
+}
+
+static const OSSL_PARAM known_gettable_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *gmac_gettable_params(void)
+{
+    return known_gettable_params;
+}
+
+static int gmac_get_params(OSSL_PARAM params[])
+{
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, gmac_size());
+
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_CIPHER, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_IV, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *gmac_settable_ctx_params(void)
+{
+    return known_settable_ctx_params;
+}
+
+/*
+ * ALL parameters should be set before init().
+ */
+static int gmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[])
+{
+    struct gmac_data_st *macctx = vmacctx;
+    EVP_CIPHER_CTX *ctx = macctx->ctx;
+    OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(macctx->provctx);
+    const OSSL_PARAM *p;
+
+   if (ctx == NULL
+        || !ossl_prov_cipher_load_from_params(&macctx->cipher, params, provctx))
+        return 0;
+
+    if (EVP_CIPHER_mode(ossl_prov_cipher_cipher(&macctx->cipher))
+        != EVP_CIPH_GCM_MODE) {
+        ERR_raise(ERR_LIB_PROV, EVP_R_CIPHER_NOT_GCM_MODE);
+        return 0;
+    }
+    if (!EVP_EncryptInit_ex(ctx, ossl_prov_cipher_cipher(&macctx->cipher),
+                            ossl_prov_cipher_engine(&macctx->cipher), NULL,
+                            NULL))
+        return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
+        if (p->data_type != OSSL_PARAM_OCTET_STRING)
+            return 0;
+
+        if (p->data_size != (size_t)EVP_CIPHER_CTX_key_length(ctx)) {
+            ERR_raise(ERR_LIB_PROV, EVP_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+        if (!EVP_EncryptInit_ex(ctx, NULL, NULL, p->data, NULL))
+            return 0;
+    }
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_IV)) != NULL) {
+        if (p->data_type != OSSL_PARAM_OCTET_STRING)
+            return 0;
+
+        if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
+                                 p->data_size, NULL)
+            || !EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, p->data))
+            return 0;
+    }
+    return 1;
+}
+
+const OSSL_DISPATCH gmac_functions[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))gmac_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))gmac_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))gmac_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))gmac_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))gmac_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))gmac_final },
+    { OSSL_FUNC_MAC_GETTABLE_PARAMS, (void (*)(void))gmac_gettable_params },
+    { OSSL_FUNC_MAC_GET_PARAMS, (void (*)(void))gmac_get_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))gmac_settable_ctx_params },
+    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))gmac_set_ctx_params },
+    { 0, NULL }
+};
diff --git a/providers/implementations/macs/hmac_prov.c b/providers/implementations/macs/hmac_prov.c
new file mode 100644 (file)
index 0000000..e9d7647
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2018 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/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+
+#include "internal/provider_algs.h"
+#include "internal/provider_ctx.h"
+#include "internal/provider_util.h"
+
+/*
+ * Forward declaration of everything implemented here.  This is not strictly
+ * necessary for the compiler, but provides an assurance that the signatures
+ * of the functions in the dispatch table are correct.
+ */
+static OSSL_OP_mac_newctx_fn hmac_new;
+static OSSL_OP_mac_dupctx_fn hmac_dup;
+static OSSL_OP_mac_freectx_fn hmac_free;
+static OSSL_OP_mac_gettable_ctx_params_fn hmac_gettable_ctx_params;
+static OSSL_OP_mac_get_ctx_params_fn hmac_get_ctx_params;
+static OSSL_OP_mac_settable_ctx_params_fn hmac_settable_ctx_params;
+static OSSL_OP_mac_set_ctx_params_fn hmac_set_ctx_params;
+static OSSL_OP_mac_init_fn hmac_init;
+static OSSL_OP_mac_update_fn hmac_update;
+static OSSL_OP_mac_final_fn hmac_final;
+
+/* local HMAC context structure */
+
+/* typedef EVP_MAC_IMPL */
+struct hmac_data_st {
+    void *provctx;
+    HMAC_CTX *ctx;               /* HMAC context */
+    PROV_DIGEST digest;
+};
+
+static size_t hmac_size(void *vmacctx);
+
+static void *hmac_new(void *provctx)
+{
+    struct hmac_data_st *macctx;
+
+    if ((macctx = OPENSSL_zalloc(sizeof(*macctx))) == NULL
+        || (macctx->ctx = HMAC_CTX_new()) == NULL) {
+        OPENSSL_free(macctx);
+        return NULL;
+    }
+    /* TODO(3.0) Should we do something more with that context? */
+    macctx->provctx = provctx;
+
+    return macctx;
+}
+
+static void hmac_free(void *vmacctx)
+{
+    struct hmac_data_st *macctx = vmacctx;
+
+    if (macctx != NULL) {
+        HMAC_CTX_free(macctx->ctx);
+        ossl_prov_digest_reset(&macctx->digest);
+        OPENSSL_free(macctx);
+    }
+}
+
+static void *hmac_dup(void *vsrc)
+{
+    struct hmac_data_st *src = vsrc;
+    struct hmac_data_st *dst = hmac_new(src->provctx);
+
+    if (dst == NULL)
+        return NULL;
+
+    if (!HMAC_CTX_copy(dst->ctx, src->ctx)
+        || !ossl_prov_digest_copy(&dst->digest, &src->digest)) {
+        hmac_free(dst);
+        return NULL;
+    }
+    return dst;
+}
+
+static size_t hmac_size(void *vmacctx)
+{
+    struct hmac_data_st *macctx = vmacctx;
+
+    return HMAC_size(macctx->ctx);
+}
+
+static int hmac_init(void *vmacctx)
+{
+    struct hmac_data_st *macctx = vmacctx;
+    const EVP_MD *digest = ossl_prov_digest_md(&macctx->digest);
+    int rv = 1;
+
+    /* HMAC_Init_ex doesn't tolerate all zero params, so we must be careful */
+    if (digest != NULL)
+        rv = HMAC_Init_ex(macctx->ctx, NULL, 0, digest,
+                          ossl_prov_digest_engine(&macctx->digest));
+    ossl_prov_digest_reset(&macctx->digest);
+    return rv;
+}
+
+static int hmac_update(void *vmacctx, const unsigned char *data,
+                       size_t datalen)
+{
+    struct hmac_data_st *macctx = vmacctx;
+
+    return HMAC_Update(macctx->ctx, data, datalen);
+}
+
+static int hmac_final(void *vmacctx, unsigned char *out, size_t *outl,
+                      size_t outsize)
+{
+    unsigned int hlen;
+    struct hmac_data_st *macctx = vmacctx;
+
+    if (!HMAC_Final(macctx->ctx, out, &hlen))
+        return 0;
+    if (outl != NULL)
+        *outl = hlen;
+    return 1;
+}
+
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *hmac_gettable_ctx_params(void)
+{
+    return known_gettable_ctx_params;
+}
+
+static int hmac_get_ctx_params(void *vmacctx, OSSL_PARAM params[])
+{
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, hmac_size(vmacctx));
+
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_DIGEST, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
+    OSSL_PARAM_int(OSSL_MAC_PARAM_FLAGS, NULL),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *hmac_settable_ctx_params(void)
+{
+    return known_settable_ctx_params;
+}
+
+/*
+ * ALL parameters should be set before init().
+ */
+static int hmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[])
+{
+    struct hmac_data_st *macctx = vmacctx;
+    OPENSSL_CTX *ctx = PROV_LIBRARY_CONTEXT_OF(macctx->provctx);
+    const OSSL_PARAM *p;
+
+    if (!ossl_prov_digest_load_from_params(&macctx->digest, params, ctx))
+        return 0;
+
+    /* TODO(3.0) formalize the meaning of "flags", perhaps as other params */
+    if ((p = OSSL_PARAM_locate_const(params,
+                                     OSSL_MAC_PARAM_FLAGS)) != NULL) {
+        int flags = 0;
+
+        if (!OSSL_PARAM_get_int(p, &flags))
+            return 0;
+        HMAC_CTX_set_flags(macctx->ctx, flags);
+    }
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
+        if (p->data_type != OSSL_PARAM_OCTET_STRING)
+            return 0;
+
+        if (!HMAC_Init_ex(macctx->ctx, p->data, p->data_size,
+                          ossl_prov_digest_md(&macctx->digest),
+                          NULL /* ENGINE */))
+            return 0;
+
+        ossl_prov_digest_reset(&macctx->digest);
+    }
+    return 1;
+}
+
+const OSSL_DISPATCH hmac_functions[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))hmac_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))hmac_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))hmac_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))hmac_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))hmac_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))hmac_final },
+    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
+      (void (*)(void))hmac_gettable_ctx_params },
+    { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))hmac_get_ctx_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))hmac_settable_ctx_params },
+    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))hmac_set_ctx_params },
+    { 0, NULL }
+};
diff --git a/providers/implementations/macs/kmac_prov.c b/providers/implementations/macs/kmac_prov.c
new file mode 100644 (file)
index 0000000..99bcbf7
--- /dev/null
@@ -0,0 +1,543 @@
+/*
+ * Copyright 2018 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
+ */
+
+/*
+ * See SP800-185 "Appendix A - KMAC, .... in Terms of Keccak[c]"
+ *
+ * Inputs are:
+ *    K = Key                  (len(K) < 2^2040 bits)
+ *    X = Input
+ *    L = Output length        (0 <= L < 2^2040 bits)
+ *    S = Customization String Default="" (len(S) < 2^2040 bits)
+ *
+ * KMAC128(K, X, L, S)
+ * {
+ *     newX = bytepad(encode_string(K), 168) ||  X || right_encode(L).
+ *     T = bytepad(encode_string("KMAC") || encode_string(S), 168).
+ *     return KECCAK[256](T || newX || 00, L).
+ * }
+ *
+ * KMAC256(K, X, L, S)
+ * {
+ *     newX = bytepad(encode_string(K), 136) ||  X || right_encode(L).
+ *     T = bytepad(encode_string("KMAC") || encode_string(S), 136).
+ *     return KECCAK[512](T || newX || 00, L).
+ * }
+ *
+ * KMAC128XOF(K, X, L, S)
+ * {
+ *     newX = bytepad(encode_string(K), 168) ||  X || right_encode(0).
+ *     T = bytepad(encode_string("KMAC") || encode_string(S), 168).
+ *     return KECCAK[256](T || newX || 00, L).
+ * }
+ *
+ * KMAC256XOF(K, X, L, S)
+ * {
+ *     newX = bytepad(encode_string(K), 136) ||  X || right_encode(0).
+ *     T = bytepad(encode_string("KMAC") || encode_string(S), 136).
+ *     return KECCAK[512](T || newX || 00, L).
+ * }
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+
+#include "internal/providercommonerr.h"
+#include "internal/provider_algs.h"
+#include "internal/provider_ctx.h"
+#include "internal/provider_util.h"
+
+/*
+ * Forward declaration of everything implemented here.  This is not strictly
+ * necessary for the compiler, but provides an assurance that the signatures
+ * of the functions in the dispatch table are correct.
+ */
+static OSSL_OP_mac_newctx_fn kmac128_new;
+static OSSL_OP_mac_newctx_fn kmac256_new;
+static OSSL_OP_mac_dupctx_fn kmac_dup;
+static OSSL_OP_mac_freectx_fn kmac_free;
+static OSSL_OP_mac_gettable_ctx_params_fn kmac_gettable_ctx_params;
+static OSSL_OP_mac_get_ctx_params_fn kmac_get_ctx_params;
+static OSSL_OP_mac_settable_ctx_params_fn kmac_settable_ctx_params;
+static OSSL_OP_mac_set_ctx_params_fn kmac_set_ctx_params;
+static OSSL_OP_mac_size_fn kmac_size;
+static OSSL_OP_mac_init_fn kmac_init;
+static OSSL_OP_mac_update_fn kmac_update;
+static OSSL_OP_mac_final_fn kmac_final;
+
+#define KMAC_MAX_BLOCKSIZE ((1600 - 128*2) / 8) /* 168 */
+#define KMAC_MIN_BLOCKSIZE ((1600 - 256*2) / 8) /* 136 */
+
+/* Length encoding will be  a 1 byte size + length in bits (2 bytes max) */
+#define KMAC_MAX_ENCODED_HEADER_LEN 3
+
+/*
+ * Custom string max size is chosen such that:
+ *   len(encoded_string(custom) + len(kmac_encoded_string) <= KMAC_MIN_BLOCKSIZE
+ *   i.e: (KMAC_MAX_CUSTOM + KMAC_MAX_ENCODED_LEN) + 6 <= 136
+ */
+#define KMAC_MAX_CUSTOM 127
+
+/* Maximum size of encoded custom string */
+#define KMAC_MAX_CUSTOM_ENCODED (KMAC_MAX_CUSTOM + KMAC_MAX_ENCODED_HEADER_LEN)
+
+/* Maximum key size in bytes = 2040 / 8 */
+#define KMAC_MAX_KEY 255
+
+/*
+ * Maximum Encoded Key size will be padded to a multiple of the blocksize
+ * i.e KMAC_MAX_KEY + KMAC_MAX_ENCODED_LEN = 258
+ * Padded to a multiple of KMAC_MAX_BLOCKSIZE
+ */
+#define KMAC_MAX_KEY_ENCODED (KMAC_MAX_BLOCKSIZE * 2)
+
+/* Fixed value of encode_string("KMAC") */
+static const unsigned char kmac_string[] = {
+    0x01, 0x20, 0x4B, 0x4D, 0x41, 0x43
+};
+
+
+#define KMAC_FLAG_XOF_MODE          1
+
+struct kmac_data_st {
+    void  *provctx;
+    EVP_MD_CTX *ctx;
+    PROV_DIGEST digest;
+    size_t out_len;
+    int key_len;
+    int custom_len;
+    /* If xof_mode = 1 then we use right_encode(0) */
+    int xof_mode;
+    /* key and custom are stored in encoded form */
+    unsigned char key[KMAC_MAX_KEY_ENCODED];
+    unsigned char custom[KMAC_MAX_CUSTOM_ENCODED];
+};
+
+static int encode_string(unsigned char *out, int *out_len,
+                         const unsigned char *in, int in_len);
+static int right_encode(unsigned char *out, int *out_len, size_t bits);
+static int bytepad(unsigned char *out, int *out_len,
+                   const unsigned char *in1, int in1_len,
+                   const unsigned char *in2, int in2_len,
+                   int w);
+static int kmac_bytepad_encode_key(unsigned char *out, int *out_len,
+                                   const unsigned char *in, int in_len,
+                                   int w);
+
+static void kmac_free(void *vmacctx)
+{
+    struct kmac_data_st *kctx = vmacctx;
+
+    if (kctx != NULL) {
+        EVP_MD_CTX_free(kctx->ctx);
+        ossl_prov_digest_reset(&kctx->digest);
+        OPENSSL_cleanse(kctx->key, kctx->key_len);
+        OPENSSL_cleanse(kctx->custom, kctx->custom_len);
+        OPENSSL_free(kctx);
+    }
+}
+
+/*
+ * We have KMAC implemented as a hash, which we can use instead of
+ * reimplementing the EVP functionality with direct use of
+ * keccak_mac_init() and friends.
+ */
+static struct kmac_data_st *kmac_new(void *provctx)
+{
+    struct kmac_data_st *kctx;
+
+    if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL
+            || (kctx->ctx = EVP_MD_CTX_new()) == NULL) {
+        kmac_free(kctx);
+        return NULL;
+    }
+    kctx->provctx = provctx;
+    return kctx;
+}
+
+static void *kmac_fetch_new(void *provctx, const OSSL_PARAM *params)
+{
+    struct kmac_data_st *kctx = kmac_new(provctx);
+
+    if (kctx == NULL)
+        return 0;
+    if (!ossl_prov_digest_load_from_params(&kctx->digest, params,
+                                      PROV_LIBRARY_CONTEXT_OF(provctx))) {
+        kmac_free(kctx);
+        return 0;
+    }
+
+    kctx->out_len = EVP_MD_size(ossl_prov_digest_md(&kctx->digest));
+    return kctx;
+}
+
+static void *kmac128_new(void *provctx)
+{
+    static const OSSL_PARAM kmac128_params[] = {
+        OSSL_PARAM_utf8_string("digest", OSSL_DIGEST_NAME_KECCAK_KMAC128,
+                               sizeof(OSSL_DIGEST_NAME_KECCAK_KMAC128)),
+        OSSL_PARAM_END
+    };
+    return kmac_fetch_new(provctx, kmac128_params);
+}
+
+static void *kmac256_new(void *provctx)
+{
+    static const OSSL_PARAM kmac256_params[] = {
+        OSSL_PARAM_utf8_string("digest", OSSL_DIGEST_NAME_KECCAK_KMAC256,
+                               sizeof(OSSL_DIGEST_NAME_KECCAK_KMAC256)),
+        OSSL_PARAM_END
+    };
+    return kmac_fetch_new(provctx, kmac256_params);
+}
+
+static void *kmac_dup(void *vsrc)
+{
+    struct kmac_data_st *src = vsrc;
+    struct kmac_data_st *dst = kmac_new(src->provctx);
+
+    if (dst == NULL)
+        return NULL;
+
+    if (!EVP_MD_CTX_copy(dst->ctx, src->ctx)
+        || !ossl_prov_digest_copy(&dst->digest, &src->digest)) {
+        kmac_free(dst);
+        return NULL;
+    }
+
+    dst->out_len = src->out_len;
+    dst->key_len = src->key_len;
+    dst->custom_len = src->custom_len;
+    dst->xof_mode = src->xof_mode;
+    memcpy(dst->key, src->key, src->key_len);
+    memcpy(dst->custom, src->custom, dst->custom_len);
+
+    return dst;
+}
+
+/*
+ * The init() assumes that any ctrl methods are set beforehand for
+ * md, key and custom. Setting the fields afterwards will have no
+ * effect on the output mac.
+ */
+static int kmac_init(void *vmacctx)
+{
+    struct kmac_data_st *kctx = vmacctx;
+    EVP_MD_CTX *ctx = kctx->ctx;
+    unsigned char out[KMAC_MAX_BLOCKSIZE];
+    int out_len, block_len;
+
+
+    /* Check key has been set */
+    if (kctx->key_len == 0) {
+        EVPerr(EVP_F_KMAC_INIT, EVP_R_NO_KEY_SET);
+        return 0;
+    }
+    if (!EVP_DigestInit_ex(kctx->ctx, ossl_prov_digest_md(&kctx->digest),
+                           NULL))
+        return 0;
+
+    block_len = EVP_MD_block_size(ossl_prov_digest_md(&kctx->digest));
+
+    /* Set default custom string if it is not already set */
+    if (kctx->custom_len == 0) {
+        const OSSL_PARAM params[] = {
+            OSSL_PARAM_octet_string(OSSL_MAC_PARAM_CUSTOM, "", 0),
+            OSSL_PARAM_END
+        };
+        (void)kmac_set_ctx_params(kctx, params);
+    }
+
+    return bytepad(out, &out_len, kmac_string, sizeof(kmac_string),
+                   kctx->custom, kctx->custom_len, block_len)
+           && EVP_DigestUpdate(ctx, out, out_len)
+           && EVP_DigestUpdate(ctx, kctx->key, kctx->key_len);
+}
+
+static size_t kmac_size(void *vmacctx)
+{
+    struct kmac_data_st *kctx = vmacctx;
+
+    return kctx->out_len;
+}
+
+static int kmac_update(void *vmacctx, const unsigned char *data,
+                       size_t datalen)
+{
+    struct kmac_data_st *kctx = vmacctx;
+
+    return EVP_DigestUpdate(kctx->ctx, data, datalen);
+}
+
+static int kmac_final(void *vmacctx, unsigned char *out, size_t *outl,
+                      size_t outsize)
+{
+    struct kmac_data_st *kctx = vmacctx;
+    EVP_MD_CTX *ctx = kctx->ctx;
+    int lbits, len;
+    unsigned char encoded_outlen[KMAC_MAX_ENCODED_HEADER_LEN];
+    int ok;
+
+    /* KMAC XOF mode sets the encoded length to 0 */
+    lbits = (kctx->xof_mode ? 0 : (kctx->out_len * 8));
+
+    ok = right_encode(encoded_outlen, &len, lbits)
+        && EVP_DigestUpdate(ctx, encoded_outlen, len)
+        && EVP_DigestFinalXOF(ctx, out, kctx->out_len);
+    if (ok && outl != NULL)
+        *outl = kctx->out_len;
+    return ok;
+}
+
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *kmac_gettable_ctx_params(void)
+{
+    return known_gettable_ctx_params;
+}
+
+static int kmac_get_ctx_params(void *vmacctx, OSSL_PARAM params[])
+{
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, kmac_size(vmacctx));
+
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    OSSL_PARAM_int(OSSL_MAC_PARAM_XOF, NULL),
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_CUSTOM, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *kmac_settable_ctx_params(void)
+{
+    return known_settable_ctx_params;
+}
+
+/*
+ * The following params can be set any time before final():
+ *     - "outlen" or "size":    The requested output length.
+ *     - "xof":                 If set, this indicates that right_encoded(0)
+ *                              is part of the digested data, otherwise it
+ *                              uses right_encoded(requested output length).
+ *
+ * All other params should be set before init().
+ */
+static int kmac_set_ctx_params(void *vmacctx, const OSSL_PARAM *params)
+{
+    struct kmac_data_st *kctx = vmacctx;
+    const OSSL_PARAM *p;
+    const EVP_MD *digest = ossl_prov_digest_md(&kctx->digest);
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_XOF)) != NULL
+        && !OSSL_PARAM_get_int(p, &kctx->xof_mode))
+        return 0;
+    if (((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE)) != NULL)
+        && !OSSL_PARAM_get_size_t(p, &kctx->out_len))
+        return 0;
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
+        if (p->data_size < 4 || p->data_size > KMAC_MAX_KEY) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+        if (!kmac_bytepad_encode_key(kctx->key, &kctx->key_len,
+                                     p->data, p->data_size,
+                                     EVP_MD_block_size(digest)))
+            return 0;
+    }
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_CUSTOM))
+        != NULL) {
+        if (p->data_size > KMAC_MAX_CUSTOM) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CUSTOM_LENGTH);
+            return 0;
+        }
+        if (!encode_string(kctx->custom, &kctx->custom_len,
+                           p->data, p->data_size))
+            return 0;
+    }
+    return 1;
+}
+
+/*
+ * Encoding/Padding Methods.
+ */
+
+/* Returns the number of bytes required to store 'bits' into a byte array */
+static unsigned int get_encode_size(size_t bits)
+{
+    unsigned int cnt = 0, sz = sizeof(size_t);
+
+    while (bits && (cnt < sz)) {
+        ++cnt;
+        bits >>= 8;
+    }
+    /* If bits is zero 1 byte is required */
+    if (cnt == 0)
+        cnt = 1;
+    return cnt;
+}
+
+/*
+ * Convert an integer into bytes . The number of bytes is appended
+ * to the end of the buffer. Returns an array of bytes 'out' of size
+ * *out_len.
+ *
+ * e.g if bits = 32, out[2] = { 0x20, 0x01 }
+ *
+ */
+static int right_encode(unsigned char *out, int *out_len, size_t bits)
+{
+    unsigned int len = get_encode_size(bits);
+    int i;
+
+    /* The length is constrained to a single byte: 2040/8 = 255 */
+    if (len > 0xFF)
+        return 0;
+
+    /* MSB's are at the start of the bytes array */
+    for (i = len - 1; i >= 0; --i) {
+        out[i] = (unsigned char)(bits & 0xFF);
+        bits >>= 8;
+    }
+    /* Tack the length onto the end */
+    out[len] = (unsigned char)len;
+
+    /* The Returned length includes the tacked on byte */
+    *out_len = len + 1;
+    return 1;
+}
+
+/*
+ * Encodes a string with a left encoded length added. Note that the
+ * in_len is converted to bits (*8).
+ *
+ * e.g- in="KMAC" gives out[6] = { 0x01, 0x20, 0x4B, 0x4D, 0x41, 0x43 }
+ *                                 len   bits    K     M     A     C
+ */
+static int encode_string(unsigned char *out, int *out_len,
+                         const unsigned char *in, int in_len)
+{
+    if (in == NULL) {
+        *out_len = 0;
+    } else {
+        int i, bits, len;
+
+        bits = 8 * in_len;
+        len = get_encode_size(bits);
+        if (len > 0xFF)
+            return 0;
+
+        out[0] = len;
+        for (i = len; i > 0; --i) {
+            out[i] = (bits & 0xFF);
+            bits >>= 8;
+        }
+        memcpy(out + len + 1, in, in_len);
+        *out_len = (1 + len + in_len);
+    }
+    return 1;
+}
+
+/*
+ * Returns a zero padded encoding of the inputs in1 and an optional
+ * in2 (can be NULL). The padded output must be a multiple of the blocksize 'w'.
+ * The value of w is in bytes (< 256).
+ *
+ * The returned output is:
+ *    zero_padded(multiple of w, (left_encode(w) || in1 [|| in2])
+ */
+static int bytepad(unsigned char *out, int *out_len,
+                   const unsigned char *in1, int in1_len,
+                   const unsigned char *in2, int in2_len, int w)
+{
+    int len;
+    unsigned char *p = out;
+    int sz = w;
+
+    /* Left encoded w */
+    *p++ = 1;
+    *p++ = w;
+    /* || in1 */
+    memcpy(p, in1, in1_len);
+    p += in1_len;
+    /* [ || in2 ] */
+    if (in2 != NULL && in2_len > 0) {
+        memcpy(p, in2, in2_len);
+        p += in2_len;
+    }
+    /* Figure out the pad size (divisible by w) */
+    len = p - out;
+    while (len > sz) {
+        sz += w;
+    }
+    /* zero pad the end of the buffer */
+    memset(p, 0, sz - len);
+    *out_len = sz;
+    return 1;
+}
+
+/*
+ * Returns out = bytepad(encode_string(in), w)
+ */
+static int kmac_bytepad_encode_key(unsigned char *out, int *out_len,
+                                   const unsigned char *in, int in_len,
+                                   int w)
+{
+    unsigned char tmp[KMAC_MAX_KEY + KMAC_MAX_ENCODED_HEADER_LEN];
+    int tmp_len;
+
+    if (!encode_string(tmp, &tmp_len, in, in_len))
+        return 0;
+
+    return bytepad(out, out_len, tmp, tmp_len, NULL, 0, w);
+}
+
+const OSSL_DISPATCH kmac128_functions[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))kmac128_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))kmac_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))kmac_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))kmac_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))kmac_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))kmac_final },
+    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
+      (void (*)(void))kmac_gettable_ctx_params },
+    { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))kmac_get_ctx_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))kmac_settable_ctx_params },
+    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))kmac_set_ctx_params },
+    { 0, NULL }
+};
+
+const OSSL_DISPATCH kmac256_functions[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))kmac256_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))kmac_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))kmac_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))kmac_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))kmac_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))kmac_final },
+    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
+      (void (*)(void))kmac_gettable_ctx_params },
+    { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))kmac_get_ctx_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))kmac_settable_ctx_params },
+    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))kmac_set_ctx_params },
+    { 0, NULL }
+};
diff --git a/providers/implementations/signature/build.info b/providers/implementations/signature/build.info
new file mode 100644 (file)
index 0000000..a9687fc
--- /dev/null
@@ -0,0 +1,10 @@
+# We make separate GOAL variables for each algorithm, to make it easy to
+# switch each to the Legacy provider when needed.
+
+$DSA_GOAL=../../libimplementations.a
+
+IF[{- !$disabled{dsa} -}]
+  SOURCE[$DSA_GOAL]=dsa.c
+ENDIF
+
+
diff --git a/providers/implementations/signature/dsa.c b/providers/implementations/signature/dsa.c
new file mode 100644 (file)
index 0000000..1d6b565
--- /dev/null
@@ -0,0 +1,407 @@
+/*
+ * 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/crypto.h>
+#include <openssl/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/dsa.h>
+#include <openssl/params.h>
+#include <openssl/evp.h>
+#include "internal/provider_algs.h"
+#include "internal/provider_ctx.h"
+
+static OSSL_OP_signature_newctx_fn dsa_newctx;
+static OSSL_OP_signature_sign_init_fn dsa_signature_init;
+static OSSL_OP_signature_verify_init_fn dsa_signature_init;
+static OSSL_OP_signature_sign_fn dsa_sign;
+static OSSL_OP_signature_verify_fn dsa_verify;
+static OSSL_OP_signature_digest_sign_init_fn dsa_digest_signverify_init;
+static OSSL_OP_signature_digest_sign_update_fn dsa_digest_signverify_update;
+static OSSL_OP_signature_digest_sign_final_fn dsa_digest_sign_final;
+static OSSL_OP_signature_digest_verify_init_fn dsa_digest_signverify_init;
+static OSSL_OP_signature_digest_verify_update_fn dsa_digest_signverify_update;
+static OSSL_OP_signature_digest_verify_final_fn dsa_digest_verify_final;
+static OSSL_OP_signature_freectx_fn dsa_freectx;
+static OSSL_OP_signature_dupctx_fn dsa_dupctx;
+static OSSL_OP_signature_get_ctx_params_fn dsa_get_ctx_params;
+static OSSL_OP_signature_gettable_ctx_params_fn dsa_gettable_ctx_params;
+static OSSL_OP_signature_set_ctx_params_fn dsa_set_ctx_params;
+static OSSL_OP_signature_settable_ctx_params_fn dsa_settable_ctx_params;
+static OSSL_OP_signature_get_ctx_md_params_fn dsa_get_ctx_md_params;
+static OSSL_OP_signature_gettable_ctx_md_params_fn dsa_gettable_ctx_md_params;
+static OSSL_OP_signature_set_ctx_md_params_fn dsa_set_ctx_md_params;
+static OSSL_OP_signature_settable_ctx_md_params_fn dsa_settable_ctx_md_params;
+
+/*
+ * What's passed as an actual key is defined by the KEYMGMT interface.
+ * We happen to know that our KEYMGMT simply passes DSA structures, so
+ * we use that here too.
+ */
+
+typedef struct {
+    OPENSSL_CTX *libctx;
+    DSA *dsa;
+    size_t mdsize;
+    /* Should be big enough */
+    char mdname[80];
+    EVP_MD *md;
+    EVP_MD_CTX *mdctx;
+} PROV_DSA_CTX;
+
+static void *dsa_newctx(void *provctx)
+{
+    PROV_DSA_CTX *pdsactx = OPENSSL_zalloc(sizeof(PROV_DSA_CTX));
+
+    if (pdsactx == NULL)
+        return NULL;
+
+    pdsactx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
+    return pdsactx;
+}
+
+static int dsa_signature_init(void *vpdsactx, void *vdsa)
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+
+    if (pdsactx == NULL || vdsa == NULL || !DSA_up_ref(vdsa))
+        return 0;
+    DSA_free(pdsactx->dsa);
+    pdsactx->dsa = vdsa;
+    return 1;
+}
+
+static int dsa_sign(void *vpdsactx, unsigned char *sig, size_t *siglen,
+                    size_t sigsize, const unsigned char *tbs, size_t tbslen)
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+    int ret;
+    unsigned int sltmp;
+    size_t dsasize = DSA_size(pdsactx->dsa);
+
+    if (sig == NULL) {
+        *siglen = dsasize;
+        return 1;
+    }
+
+    if (sigsize < (size_t)dsasize)
+        return 0;
+
+    if (pdsactx->mdsize != 0 && tbslen != pdsactx->mdsize)
+        return 0;
+
+    ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, pdsactx->dsa);
+
+    if (ret <= 0)
+        return 0;
+
+    *siglen = sltmp;
+    return 1;
+}
+
+static int dsa_verify(void *vpdsactx, const unsigned char *sig, size_t siglen,
+                      const unsigned char *tbs, size_t tbslen)
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+
+    if (pdsactx->mdsize != 0 && tbslen != pdsactx->mdsize)
+        return 0;
+
+    return DSA_verify(0, tbs, tbslen, sig, siglen, pdsactx->dsa);
+}
+
+static int dsa_digest_signverify_init(void *vpdsactx, const char *mdname,
+                                      const char *props, void *vdsa)
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+    EVP_MD *md;
+
+    if (!dsa_signature_init(vpdsactx, vdsa))
+        return 0;
+
+    md = EVP_MD_fetch(pdsactx->libctx, mdname, props);
+    if (md == NULL)
+        return 0;
+    pdsactx->md = md;
+    pdsactx->mdsize = EVP_MD_size(md);
+    pdsactx->mdctx = EVP_MD_CTX_new();
+    if (pdsactx->mdctx == NULL)
+        return 0;
+
+    if (!EVP_DigestInit_ex(pdsactx->mdctx, md, NULL))
+        return 0;
+
+    return 1;
+}
+
+int dsa_digest_signverify_update(void *vpdsactx, const unsigned char *data,
+                                 size_t datalen)
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+
+    if (pdsactx == NULL || pdsactx->mdctx == NULL)
+        return 0;
+
+    return EVP_DigestUpdate(pdsactx->mdctx, data, datalen);
+}
+
+int dsa_digest_sign_final(void *vpdsactx, unsigned char *sig, size_t *siglen,
+                          size_t sigsize)
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+    unsigned char digest[EVP_MAX_MD_SIZE];
+    unsigned int dlen = 0;
+
+    if (pdsactx == NULL || pdsactx->mdctx == NULL)
+        return 0;
+
+    /*
+     * If sig is NULL then we're just finding out the sig size. Other fields
+     * are ignored. Defer to dsa_sign.
+     */
+    if (sig != NULL) {
+        /*
+         * TODO(3.0): There is the possibility that some externally provided
+         * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow -
+         * but that problem is much larger than just in DSA.
+         */
+        if (!EVP_DigestFinal_ex(pdsactx->mdctx, digest, &dlen))
+            return 0;
+    }
+
+    return dsa_sign(vpdsactx, sig, siglen, sigsize, digest, (size_t)dlen);
+}
+
+
+int dsa_digest_verify_final(void *vpdsactx, const unsigned char *sig,
+                            size_t siglen)
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+    unsigned char digest[EVP_MAX_MD_SIZE];
+    unsigned int dlen = 0;
+
+    if (pdsactx == NULL || pdsactx->mdctx == NULL)
+        return 0;
+
+    /*
+     * TODO(3.0): There is the possibility that some externally provided
+     * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow -
+     * but that problem is much larger than just in DSA.
+     */
+    if (!EVP_DigestFinal_ex(pdsactx->mdctx, digest, &dlen))
+        return 0;
+
+    return dsa_verify(vpdsactx, sig, siglen, digest, (size_t)dlen);
+}
+
+static void dsa_freectx(void *vpdsactx)
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+
+    DSA_free(pdsactx->dsa);
+    EVP_MD_CTX_free(pdsactx->mdctx);
+    EVP_MD_free(pdsactx->md);
+
+    OPENSSL_free(pdsactx);
+}
+
+static void *dsa_dupctx(void *vpdsactx)
+{
+    PROV_DSA_CTX *srcctx = (PROV_DSA_CTX *)vpdsactx;
+    PROV_DSA_CTX *dstctx;
+
+    dstctx = OPENSSL_zalloc(sizeof(*srcctx));
+    if (dstctx == NULL)
+        return NULL;
+
+    *dstctx = *srcctx;
+    dstctx->dsa = NULL;
+    dstctx->md = NULL;
+    dstctx->mdctx = NULL;
+
+    if (srcctx->dsa != NULL && !DSA_up_ref(srcctx->dsa))
+        goto err;
+    dstctx->dsa = srcctx->dsa;
+
+    if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md))
+        goto err;
+    dstctx->md = srcctx->md;
+
+    if (srcctx->mdctx != NULL) {
+        dstctx->mdctx = EVP_MD_CTX_new();
+        if (dstctx->mdctx == NULL
+                || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx))
+            goto err;
+    }
+
+    return dstctx;
+ err:
+    dsa_freectx(dstctx);
+    return NULL;
+}
+
+static int dsa_get_ctx_params(void *vpdsactx, OSSL_PARAM *params)
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+    OSSL_PARAM *p;
+
+    if (pdsactx == NULL || params == NULL)
+        return 0;
+
+    p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
+    if (p != NULL && !OSSL_PARAM_set_size_t(p, pdsactx->mdsize))
+        return 0;
+
+    p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST);
+    if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdsactx->md == NULL
+                                                    ? pdsactx->mdname
+                                                    : EVP_MD_name(pdsactx->md)))
+        return 0;
+
+    return 1;
+}
+
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
+    OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
+    OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *dsa_gettable_ctx_params(void)
+{
+    return known_gettable_ctx_params;
+}
+
+static int dsa_set_ctx_params(void *vpdsactx, const OSSL_PARAM params[])
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+    const OSSL_PARAM *p;
+    char *mdname;
+
+    if (pdsactx == NULL || params == NULL)
+        return 0;
+
+    if (pdsactx->md != NULL) {
+        /*
+         * You cannot set the digest name/size when doing a DigestSign or
+         * DigestVerify.
+         */
+        return 1;
+    }
+
+    p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
+    if (p != NULL && !OSSL_PARAM_get_size_t(p, &pdsactx->mdsize))
+        return 0;
+
+    /*
+     * We never actually use the mdname, but we do support getting it later.
+     * This can be useful for applications that want to know the MD that they
+     * previously set.
+     */
+    p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST);
+    mdname = pdsactx->mdname;
+    if (p != NULL
+            && !OSSL_PARAM_get_utf8_string(p, &mdname, sizeof(pdsactx->mdname)))
+        return 0;
+
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
+    OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
+    OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *dsa_settable_ctx_params(void)
+{
+    /*
+     * TODO(3.0): Should this function return a different set of settable ctx
+     * params if the ctx is being used for a DigestSign/DigestVerify? In that
+     * case it is not allowed to set the digest size/digest name because the
+     * digest is explicitly set as part of the init.
+     */
+    return known_settable_ctx_params;
+}
+
+static int dsa_get_ctx_md_params(void *vpdsactx, OSSL_PARAM *params)
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+
+    if (pdsactx->mdctx == NULL)
+        return 0;
+
+    return EVP_MD_CTX_get_params(pdsactx->mdctx, params);
+}
+
+static const OSSL_PARAM *dsa_gettable_ctx_md_params(void *vpdsactx)
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+
+    if (pdsactx->md == NULL)
+        return 0;
+
+    return EVP_MD_gettable_ctx_params(pdsactx->md);
+}
+
+static int dsa_set_ctx_md_params(void *vpdsactx, const OSSL_PARAM params[])
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+
+    if (pdsactx->mdctx == NULL)
+        return 0;
+
+    return EVP_MD_CTX_set_params(pdsactx->mdctx, params);
+}
+
+static const OSSL_PARAM *dsa_settable_ctx_md_params(void *vpdsactx)
+{
+    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+
+    if (pdsactx->md == NULL)
+        return 0;
+
+    return EVP_MD_settable_ctx_params(pdsactx->md);
+}
+
+const OSSL_DISPATCH dsa_signature_functions[] = {
+    { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))dsa_newctx },
+    { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))dsa_signature_init },
+    { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))dsa_sign },
+    { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))dsa_signature_init },
+    { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))dsa_verify },
+    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
+      (void (*)(void))dsa_digest_signverify_init },
+    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE,
+      (void (*)(void))dsa_digest_signverify_update },
+    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL,
+      (void (*)(void))dsa_digest_sign_final },
+    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
+      (void (*)(void))dsa_digest_signverify_init },
+    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE,
+      (void (*)(void))dsa_digest_signverify_update },
+    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL,
+      (void (*)(void))dsa_digest_verify_final },
+    { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))dsa_freectx },
+    { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))dsa_dupctx },
+    { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))dsa_get_ctx_params },
+    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
+      (void (*)(void))dsa_gettable_ctx_params },
+    { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))dsa_set_ctx_params },
+    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
+      (void (*)(void))dsa_settable_ctx_params },
+    { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS,
+      (void (*)(void))dsa_get_ctx_md_params },
+    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS,
+      (void (*)(void))dsa_gettable_ctx_md_params },
+    { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS,
+      (void (*)(void))dsa_set_ctx_md_params },
+    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS,
+      (void (*)(void))dsa_settable_ctx_md_params },
+    { 0, NULL }
+};