Providers: move default kdfs,macs
authorRichard Levitte <levitte@openssl.org>
Fri, 4 Oct 2019 09:28:20 +0000 (11:28 +0200)
committerRichard Levitte <levitte@openssl.org>
Thu, 10 Oct 2019 12:12:15 +0000 (14:12 +0200)
From providers/default/ to providers/implementations/

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

21 files changed:
providers/default/build.info
providers/default/kdfs/build.info [deleted file]
providers/default/kdfs/scrypt.c [deleted file]
providers/default/kdfs/sshkdf.c [deleted file]
providers/default/kdfs/x942kdf.c [deleted file]
providers/default/macs/blake2_mac_impl.c [deleted file]
providers/default/macs/blake2b_mac.c [deleted file]
providers/default/macs/blake2s_mac.c [deleted file]
providers/default/macs/build.info [deleted file]
providers/default/macs/poly1305_prov.c [deleted file]
providers/default/macs/siphash_prov.c [deleted file]
providers/implementations/kdfs/build.info
providers/implementations/kdfs/scrypt.c [new file with mode: 0644]
providers/implementations/kdfs/sshkdf.c [new file with mode: 0644]
providers/implementations/kdfs/x942kdf.c [new file with mode: 0644]
providers/implementations/macs/blake2_mac_impl.c [new file with mode: 0644]
providers/implementations/macs/blake2b_mac.c [new file with mode: 0644]
providers/implementations/macs/blake2s_mac.c [new file with mode: 0644]
providers/implementations/macs/build.info
providers/implementations/macs/poly1305_prov.c [new file with mode: 0644]
providers/implementations/macs/siphash_prov.c [new file with mode: 0644]

index 31ae5079653c12a7832d6bf05a306576ce6fa73f..67b4d3a977d24f288f27c0fc88c5fc4791b9a838 100644 (file)
@@ -1,4 +1,4 @@
-SUBDIRS=digests kdfs macs ciphers
+SUBDIRS=digests ciphers
 $GOAL=../../libcrypto
 SOURCE[$GOAL]=defltprov.c
 INCLUDE[$GOAL]=include
diff --git a/providers/default/kdfs/build.info b/providers/default/kdfs/build.info
deleted file mode 100644 (file)
index 90b127d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-$GOAL=../../libimplementations.a
-SOURCE[$GOAL]=scrypt.c sshkdf.c x942kdf.c
diff --git a/providers/default/kdfs/scrypt.c b/providers/default/kdfs/scrypt.c
deleted file mode 100644 (file)
index 505963e..0000000
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * Copyright 2017-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/evp.h>
-#include <openssl/kdf.h>
-#include <openssl/err.h>
-#include <openssl/core_names.h>
-#include "crypto/evp.h"
-#include "internal/numbers.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
-
-#ifndef OPENSSL_NO_SCRYPT
-
-static OSSL_OP_kdf_newctx_fn kdf_scrypt_new;
-static OSSL_OP_kdf_freectx_fn kdf_scrypt_free;
-static OSSL_OP_kdf_reset_fn kdf_scrypt_reset;
-static OSSL_OP_kdf_derive_fn kdf_scrypt_derive;
-static OSSL_OP_kdf_settable_ctx_params_fn kdf_scrypt_settable_ctx_params;
-static OSSL_OP_kdf_set_ctx_params_fn kdf_scrypt_set_ctx_params;
-
-static int scrypt_alg(const char *pass, size_t passlen,
-                      const unsigned char *salt, size_t saltlen,
-                      uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
-                      unsigned char *key, size_t keylen, EVP_MD *sha256);
-
-typedef struct {
-    void *provctx;
-    unsigned char *pass;
-    size_t pass_len;
-    unsigned char *salt;
-    size_t salt_len;
-    uint64_t N;
-    uint64_t r, p;
-    uint64_t maxmem_bytes;
-    EVP_MD *sha256;
-} KDF_SCRYPT;
-
-static void kdf_scrypt_init(KDF_SCRYPT *ctx);
-
-static void *kdf_scrypt_new(void *provctx)
-{
-    KDF_SCRYPT *ctx;
-
-    ctx = OPENSSL_zalloc(sizeof(*ctx));
-    if (ctx == NULL) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-        return NULL;
-    }
-    ctx->provctx = provctx;
-    ctx->sha256 = EVP_MD_fetch(PROV_LIBRARY_CONTEXT_OF(provctx),
-                               "sha256", NULL);
-    if (ctx->sha256 == NULL) {
-        OPENSSL_free(ctx);
-        ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_LOAD_SHA256);
-        return NULL;
-    }
-    kdf_scrypt_init(ctx);
-    return ctx;
-}
-
-static void kdf_scrypt_free(void *vctx)
-{
-    KDF_SCRYPT *ctx = (KDF_SCRYPT *)vctx;
-
-    EVP_MD_meth_free(ctx->sha256);
-    kdf_scrypt_reset(ctx);
-    OPENSSL_free(ctx);
-}
-
-static void kdf_scrypt_reset(void *vctx)
-{
-    KDF_SCRYPT *ctx = (KDF_SCRYPT *)vctx;
-
-    OPENSSL_free(ctx->salt);
-    OPENSSL_clear_free(ctx->pass, ctx->pass_len);
-    kdf_scrypt_init(ctx);
-}
-
-static void kdf_scrypt_init(KDF_SCRYPT *ctx)
-{
-    /* Default values are the most conservative recommendation given in the
-     * original paper of C. Percival. Derivation uses roughly 1 GiB of memory
-     * for this parameter choice (approx. 128 * r * N * p bytes).
-     */
-    ctx->N = 1 << 20;
-    ctx->r = 8;
-    ctx->p = 1;
-    ctx->maxmem_bytes = 1025 * 1024 * 1024;
-}
-
-static int scrypt_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_scrypt_derive(void *vctx, unsigned char *key,
-                             size_t keylen)
-{
-    KDF_SCRYPT *ctx = (KDF_SCRYPT *)vctx;
-
-    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 scrypt_alg((char *)ctx->pass, ctx->pass_len, ctx->salt,
-                      ctx->salt_len, ctx->N, ctx->r, ctx->p,
-                      ctx->maxmem_bytes, key, keylen, ctx->sha256);
-}
-
-static int is_power_of_two(uint64_t value)
-{
-    return (value != 0) && ((value & (value - 1)) == 0);
-}
-
-static int kdf_scrypt_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    const OSSL_PARAM *p;
-    KDF_SCRYPT *ctx = vctx;
-    uint64_t u64_value;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL)
-        if (!scrypt_set_membuf(&ctx->pass, &ctx->pass_len, p))
-            return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL)
-        if (!scrypt_set_membuf(&ctx->salt, &ctx->salt_len, p))
-            return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SCRYPT_N))
-        != NULL) {
-        if (!OSSL_PARAM_get_uint64(p, &u64_value)
-            || u64_value <= 1
-            || !is_power_of_two(u64_value))
-            return 0;
-        ctx->N = u64_value;
-    }
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SCRYPT_R))
-        != NULL) {
-        if (!OSSL_PARAM_get_uint64(p, &u64_value) || u64_value < 1)
-            return 0;
-        ctx->r = u64_value;
-    }
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SCRYPT_P))
-        != NULL) {
-        if (!OSSL_PARAM_get_uint64(p, &u64_value) || u64_value < 1)
-            return 0;
-        ctx->p = u64_value;
-    }
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SCRYPT_MAXMEM))
-        != NULL) {
-        if (!OSSL_PARAM_get_uint64(p, &u64_value) || u64_value < 1)
-            return 0;
-        ctx->maxmem_bytes = u64_value;
-    }
-    return 1;
-}
-
-static const OSSL_PARAM *kdf_scrypt_settable_ctx_params(void)
-{
-    static const OSSL_PARAM known_settable_ctx_params[] = {
-        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_SCRYPT_N, NULL),
-        OSSL_PARAM_uint32(OSSL_KDF_PARAM_SCRYPT_R, NULL),
-        OSSL_PARAM_uint32(OSSL_KDF_PARAM_SCRYPT_P, NULL),
-        OSSL_PARAM_uint64(OSSL_KDF_PARAM_SCRYPT_MAXMEM, NULL),
-        OSSL_PARAM_END
-    };
-    return known_settable_ctx_params;
-}
-
-static int kdf_scrypt_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_scrypt_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_scrypt_functions[] = {
-    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_scrypt_new },
-    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_scrypt_free },
-    { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_scrypt_reset },
-    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_scrypt_derive },
-    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
-      (void(*)(void))kdf_scrypt_settable_ctx_params },
-    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_scrypt_set_ctx_params },
-    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
-      (void(*)(void))kdf_scrypt_gettable_ctx_params },
-    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_scrypt_get_ctx_params },
-    { 0, NULL }
-};
-
-#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
-static void salsa208_word_specification(uint32_t inout[16])
-{
-    int i;
-    uint32_t x[16];
-
-    memcpy(x, inout, sizeof(x));
-    for (i = 8; i > 0; i -= 2) {
-        x[4] ^= R(x[0] + x[12], 7);
-        x[8] ^= R(x[4] + x[0], 9);
-        x[12] ^= R(x[8] + x[4], 13);
-        x[0] ^= R(x[12] + x[8], 18);
-        x[9] ^= R(x[5] + x[1], 7);
-        x[13] ^= R(x[9] + x[5], 9);
-        x[1] ^= R(x[13] + x[9], 13);
-        x[5] ^= R(x[1] + x[13], 18);
-        x[14] ^= R(x[10] + x[6], 7);
-        x[2] ^= R(x[14] + x[10], 9);
-        x[6] ^= R(x[2] + x[14], 13);
-        x[10] ^= R(x[6] + x[2], 18);
-        x[3] ^= R(x[15] + x[11], 7);
-        x[7] ^= R(x[3] + x[15], 9);
-        x[11] ^= R(x[7] + x[3], 13);
-        x[15] ^= R(x[11] + x[7], 18);
-        x[1] ^= R(x[0] + x[3], 7);
-        x[2] ^= R(x[1] + x[0], 9);
-        x[3] ^= R(x[2] + x[1], 13);
-        x[0] ^= R(x[3] + x[2], 18);
-        x[6] ^= R(x[5] + x[4], 7);
-        x[7] ^= R(x[6] + x[5], 9);
-        x[4] ^= R(x[7] + x[6], 13);
-        x[5] ^= R(x[4] + x[7], 18);
-        x[11] ^= R(x[10] + x[9], 7);
-        x[8] ^= R(x[11] + x[10], 9);
-        x[9] ^= R(x[8] + x[11], 13);
-        x[10] ^= R(x[9] + x[8], 18);
-        x[12] ^= R(x[15] + x[14], 7);
-        x[13] ^= R(x[12] + x[15], 9);
-        x[14] ^= R(x[13] + x[12], 13);
-        x[15] ^= R(x[14] + x[13], 18);
-    }
-    for (i = 0; i < 16; ++i)
-        inout[i] += x[i];
-    OPENSSL_cleanse(x, sizeof(x));
-}
-
-static void scryptBlockMix(uint32_t *B_, uint32_t *B, uint64_t r)
-{
-    uint64_t i, j;
-    uint32_t X[16], *pB;
-
-    memcpy(X, B + (r * 2 - 1) * 16, sizeof(X));
-    pB = B;
-    for (i = 0; i < r * 2; i++) {
-        for (j = 0; j < 16; j++)
-            X[j] ^= *pB++;
-        salsa208_word_specification(X);
-        memcpy(B_ + (i / 2 + (i & 1) * r) * 16, X, sizeof(X));
-    }
-    OPENSSL_cleanse(X, sizeof(X));
-}
-
-static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N,
-                        uint32_t *X, uint32_t *T, uint32_t *V)
-{
-    unsigned char *pB;
-    uint32_t *pV;
-    uint64_t i, k;
-
-    /* Convert from little endian input */
-    for (pV = V, i = 0, pB = B; i < 32 * r; i++, pV++) {
-        *pV = *pB++;
-        *pV |= *pB++ << 8;
-        *pV |= *pB++ << 16;
-        *pV |= (uint32_t)*pB++ << 24;
-    }
-
-    for (i = 1; i < N; i++, pV += 32 * r)
-        scryptBlockMix(pV, pV - 32 * r, r);
-
-    scryptBlockMix(X, V + (N - 1) * 32 * r, r);
-
-    for (i = 0; i < N; i++) {
-        uint32_t j;
-        j = X[16 * (2 * r - 1)] % N;
-        pV = V + 32 * r * j;
-        for (k = 0; k < 32 * r; k++)
-            T[k] = X[k] ^ *pV++;
-        scryptBlockMix(X, T, r);
-    }
-    /* Convert output to little endian */
-    for (i = 0, pB = B; i < 32 * r; i++) {
-        uint32_t xtmp = X[i];
-        *pB++ = xtmp & 0xff;
-        *pB++ = (xtmp >> 8) & 0xff;
-        *pB++ = (xtmp >> 16) & 0xff;
-        *pB++ = (xtmp >> 24) & 0xff;
-    }
-}
-
-#ifndef SIZE_MAX
-# define SIZE_MAX    ((size_t)-1)
-#endif
-
-/*
- * Maximum power of two that will fit in uint64_t: this should work on
- * most (all?) platforms.
- */
-
-#define LOG2_UINT64_MAX         (sizeof(uint64_t) * 8 - 1)
-
-/*
- * Maximum value of p * r:
- * p <= ((2^32-1) * hLen) / MFLen =>
- * p <= ((2^32-1) * 32) / (128 * r) =>
- * p * r <= (2^30-1)
- */
-
-#define SCRYPT_PR_MAX   ((1 << 30) - 1)
-
-static int scrypt_alg(const char *pass, size_t passlen,
-                      const unsigned char *salt, size_t saltlen,
-                      uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
-                      unsigned char *key, size_t keylen, EVP_MD *sha256)
-{
-    int rv = 0;
-    unsigned char *B;
-    uint32_t *X, *V, *T;
-    uint64_t i, Blen, Vlen;
-
-    /* Sanity check parameters */
-    /* initial check, r,p must be non zero, N >= 2 and a power of 2 */
-    if (r == 0 || p == 0 || N < 2 || (N & (N - 1)))
-        return 0;
-    /* Check p * r < SCRYPT_PR_MAX avoiding overflow */
-    if (p > SCRYPT_PR_MAX / r) {
-        EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
-        return 0;
-    }
-
-    /*
-     * Need to check N: if 2^(128 * r / 8) overflows limit this is
-     * automatically satisfied since N <= UINT64_MAX.
-     */
-
-    if (16 * r <= LOG2_UINT64_MAX) {
-        if (N >= (((uint64_t)1) << (16 * r))) {
-            EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
-            return 0;
-        }
-    }
-
-    /* Memory checks: check total allocated buffer size fits in uint64_t */
-
-    /*
-     * B size in section 5 step 1.S
-     * Note: we know p * 128 * r < UINT64_MAX because we already checked
-     * p * r < SCRYPT_PR_MAX
-     */
-    Blen = p * 128 * r;
-    /*
-     * Yet we pass it as integer to PKCS5_PBKDF2_HMAC... [This would
-     * have to be revised when/if PKCS5_PBKDF2_HMAC accepts size_t.]
-     */
-    if (Blen > INT_MAX) {
-        EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
-        return 0;
-    }
-
-    /*
-     * Check 32 * r * (N + 2) * sizeof(uint32_t) fits in uint64_t
-     * This is combined size V, X and T (section 4)
-     */
-    i = UINT64_MAX / (32 * sizeof(uint32_t));
-    if (N + 2 > i / r) {
-        EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
-        return 0;
-    }
-    Vlen = 32 * r * (N + 2) * sizeof(uint32_t);
-
-    /* check total allocated size fits in uint64_t */
-    if (Blen > UINT64_MAX - Vlen) {
-        EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
-        return 0;
-    }
-
-    /* Check that the maximum memory doesn't exceed a size_t limits */
-    if (maxmem > SIZE_MAX)
-        maxmem = SIZE_MAX;
-
-    if (Blen + Vlen > maxmem) {
-        EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
-        return 0;
-    }
-
-    /* If no key return to indicate parameters are OK */
-    if (key == NULL)
-        return 1;
-
-    B = OPENSSL_malloc((size_t)(Blen + Vlen));
-    if (B == NULL) {
-        EVPerr(EVP_F_SCRYPT_ALG, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-    X = (uint32_t *)(B + Blen);
-    T = X + 32 * r;
-    V = T + 32 * r;
-    if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, sha256,
-                          (int)Blen, B) == 0)
-        goto err;
-
-    for (i = 0; i < p; i++)
-        scryptROMix(B + 128 * r * i, r, N, X, T, V);
-
-    if (PKCS5_PBKDF2_HMAC(pass, passlen, B, (int)Blen, 1, sha256,
-                          keylen, key) == 0)
-        goto err;
-    rv = 1;
- err:
-    if (rv == 0)
-        EVPerr(EVP_F_SCRYPT_ALG, EVP_R_PBKDF2_ERROR);
-
-    OPENSSL_clear_free(B, (size_t)(Blen + Vlen));
-    return rv;
-}
-
-#endif
diff --git a/providers/default/kdfs/sshkdf.c b/providers/default/kdfs/sshkdf.c
deleted file mode 100644 (file)
index 7e6445d..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (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/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"
-
-/* See RFC 4253, Section 7.2 */
-static OSSL_OP_kdf_newctx_fn kdf_sshkdf_new;
-static OSSL_OP_kdf_freectx_fn kdf_sshkdf_free;
-static OSSL_OP_kdf_reset_fn kdf_sshkdf_reset;
-static OSSL_OP_kdf_derive_fn kdf_sshkdf_derive;
-static OSSL_OP_kdf_settable_ctx_params_fn kdf_sshkdf_settable_ctx_params;
-static OSSL_OP_kdf_set_ctx_params_fn kdf_sshkdf_set_ctx_params;
-static OSSL_OP_kdf_gettable_ctx_params_fn kdf_sshkdf_gettable_ctx_params;
-static OSSL_OP_kdf_get_ctx_params_fn kdf_sshkdf_get_ctx_params;
-
-static int SSHKDF(const EVP_MD *evp_md,
-                  const unsigned char *key, size_t key_len,
-                  const unsigned char *xcghash, size_t xcghash_len,
-                  const unsigned char *session_id, size_t session_id_len,
-                  char type, unsigned char *okey, size_t okey_len);
-
-typedef struct {
-    void *provctx;
-    PROV_DIGEST digest;
-    unsigned char *key; /* K */
-    size_t key_len;
-    unsigned char *xcghash; /* H */
-    size_t xcghash_len;
-    char type; /* X */
-    unsigned char *session_id;
-    size_t session_id_len;
-} KDF_SSHKDF;
-
-static void *kdf_sshkdf_new(void *provctx)
-{
-    KDF_SSHKDF *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_sshkdf_free(void *vctx)
-{
-    KDF_SSHKDF *ctx = (KDF_SSHKDF *)vctx;
-
-    kdf_sshkdf_reset(ctx);
-    OPENSSL_free(ctx);
-}
-
-static void kdf_sshkdf_reset(void *vctx)
-{
-    KDF_SSHKDF *ctx = (KDF_SSHKDF *)vctx;
-
-    ossl_prov_digest_reset(&ctx->digest);
-    OPENSSL_clear_free(ctx->key, ctx->key_len);
-    OPENSSL_clear_free(ctx->xcghash, ctx->xcghash_len);
-    OPENSSL_clear_free(ctx->session_id, ctx->session_id_len);
-    memset(ctx, 0, sizeof(*ctx));
-}
-
-static int sshkdf_set_membuf(unsigned char **dst, size_t *dst_len,
-                             const OSSL_PARAM *p)
-{
-    OPENSSL_clear_free(*dst, *dst_len);
-    *dst = NULL;
-    return OSSL_PARAM_get_octet_string(p, (void **)dst, 0, dst_len);
-}
-
-static int kdf_sshkdf_derive(void *vctx, unsigned char *key,
-                             size_t keylen)
-{
-    KDF_SSHKDF *ctx = (KDF_SSHKDF *)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;
-    }
-    if (ctx->xcghash == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_XCGHASH);
-        return 0;
-    }
-    if (ctx->session_id == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SESSION_ID);
-        return 0;
-    }
-    if (ctx->type == 0) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_TYPE);
-        return 0;
-    }
-    return SSHKDF(md, ctx->key, ctx->key_len,
-                  ctx->xcghash, ctx->xcghash_len,
-                  ctx->session_id, ctx->session_id_len,
-                  ctx->type, key, keylen);
-}
-
-static int kdf_sshkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    const OSSL_PARAM *p;
-    KDF_SSHKDF *ctx = vctx;
-    OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
-    int t;
-
-    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
-        return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL)
-        if (!sshkdf_set_membuf(&ctx->key, &ctx->key_len, p))
-            return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SSHKDF_XCGHASH))
-        != NULL)
-        if (!sshkdf_set_membuf(&ctx->xcghash, &ctx->xcghash_len, p))
-            return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SSHKDF_SESSION_ID))
-        != NULL)
-        if (!sshkdf_set_membuf(&ctx->session_id, &ctx->session_id_len, p))
-            return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SSHKDF_TYPE))
-        != NULL) {
-        if (p->data == NULL || p->data_size == 0)
-            return 0;
-        t = *(unsigned char *)p->data;
-        if (t < 65 || t > 70) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_VALUE_ERROR);
-            return 0;
-        }
-        ctx->type = (char)t;
-    }
-    return 1;
-}
-
-static const OSSL_PARAM *kdf_sshkdf_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_KEY, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SSHKDF_XCGHASH, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SSHKDF_SESSION_ID, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_SSHKDF_TYPE, NULL, 0),
-        OSSL_PARAM_END
-    };
-    return known_settable_ctx_params;
-}
-
-static int kdf_sshkdf_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_sshkdf_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_sshkdf_functions[] = {
-    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_sshkdf_new },
-    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_sshkdf_free },
-    { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_sshkdf_reset },
-    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_sshkdf_derive },
-    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
-      (void(*)(void))kdf_sshkdf_settable_ctx_params },
-    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_sshkdf_set_ctx_params },
-    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
-      (void(*)(void))kdf_sshkdf_gettable_ctx_params },
-    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_sshkdf_get_ctx_params },
-    { 0, NULL }
-};
-
-static int SSHKDF(const EVP_MD *evp_md,
-                  const unsigned char *key, size_t key_len,
-                  const unsigned char *xcghash, size_t xcghash_len,
-                  const unsigned char *session_id, size_t session_id_len,
-                  char type, unsigned char *okey, size_t okey_len)
-{
-    EVP_MD_CTX *md = NULL;
-    unsigned char digest[EVP_MAX_MD_SIZE];
-    unsigned int dsize = 0;
-    size_t cursize = 0;
-    int ret = 0;
-
-    md = EVP_MD_CTX_new();
-    if (md == NULL)
-        return 0;
-
-    if (!EVP_DigestInit_ex(md, evp_md, NULL))
-        goto out;
-
-    if (!EVP_DigestUpdate(md, key, key_len))
-        goto out;
-
-    if (!EVP_DigestUpdate(md, xcghash, xcghash_len))
-        goto out;
-
-    if (!EVP_DigestUpdate(md, &type, 1))
-        goto out;
-
-    if (!EVP_DigestUpdate(md, session_id, session_id_len))
-        goto out;
-
-    if (!EVP_DigestFinal_ex(md, digest, &dsize))
-        goto out;
-
-    if (okey_len < dsize) {
-        memcpy(okey, digest, okey_len);
-        ret = 1;
-        goto out;
-    }
-
-    memcpy(okey, digest, dsize);
-
-    for (cursize = dsize; cursize < okey_len; cursize += dsize) {
-
-        if (!EVP_DigestInit_ex(md, evp_md, NULL))
-            goto out;
-
-        if (!EVP_DigestUpdate(md, key, key_len))
-            goto out;
-
-        if (!EVP_DigestUpdate(md, xcghash, xcghash_len))
-            goto out;
-
-        if (!EVP_DigestUpdate(md, okey, cursize))
-            goto out;
-
-        if (!EVP_DigestFinal_ex(md, digest, &dsize))
-            goto out;
-
-        if (okey_len < cursize + dsize) {
-            memcpy(okey + cursize, digest, okey_len - cursize);
-            ret = 1;
-            goto out;
-        }
-
-        memcpy(okey + cursize, digest, dsize);
-    }
-
-    ret = 1;
-
-out:
-    EVP_MD_CTX_free(md);
-    OPENSSL_cleanse(digest, EVP_MAX_MD_SIZE);
-    return ret;
-}
-
diff --git a/providers/default/kdfs/x942kdf.c b/providers/default/kdfs/x942kdf.c
deleted file mode 100644 (file)
index 65c586f..0000000
+++ /dev/null
@@ -1,424 +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
- */
-
-#include "e_os.h"
-
-#ifndef OPENSSL_NO_CMS
-
-# include <stdlib.h>
-# include <stdarg.h>
-# include <string.h>
-# include <openssl/hmac.h>
-# include <openssl/cms.h>
-# include <openssl/evp.h>
-# include <openssl/kdf.h>
-# include <openssl/x509.h>
-# include <openssl/obj_mac.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"
-
-# define X942KDF_MAX_INLEN (1 << 30)
-
-static OSSL_OP_kdf_newctx_fn x942kdf_new;
-static OSSL_OP_kdf_freectx_fn x942kdf_free;
-static OSSL_OP_kdf_reset_fn x942kdf_reset;
-static OSSL_OP_kdf_derive_fn x942kdf_derive;
-static OSSL_OP_kdf_settable_ctx_params_fn x942kdf_settable_ctx_params;
-static OSSL_OP_kdf_set_ctx_params_fn x942kdf_set_ctx_params;
-static OSSL_OP_kdf_gettable_ctx_params_fn x942kdf_gettable_ctx_params;
-static OSSL_OP_kdf_get_ctx_params_fn x942kdf_get_ctx_params;
-
-typedef struct {
-    void *provctx;
-    PROV_DIGEST digest;
-    unsigned char *secret;
-    size_t secret_len;
-    int cek_nid;
-    unsigned char *ukm;
-    size_t ukm_len;
-    size_t dkm_len;
-} KDF_X942;
-
-/* A table of allowed wrapping algorithms and the associated output lengths */
-static const struct {
-    int nid;
-    size_t keklen; /* size in bytes */
-} kek_algs[] = {
-    { NID_id_smime_alg_CMS3DESwrap, 24 },
-    { NID_id_smime_alg_CMSRC2wrap, 16 },
-    { NID_id_aes128_wrap, 16 },
-    { NID_id_aes192_wrap, 24 },
-    { NID_id_aes256_wrap, 32 },
-    { NID_id_camellia128_wrap, 16 },
-    { NID_id_camellia192_wrap, 24 },
-    { NID_id_camellia256_wrap, 32 }
-};
-
-/* Skip past an ASN1 structure: for OBJECT skip content octets too */
-static int skip_asn1(unsigned char **pp, long *plen, int exptag)
-{
-    int i, tag, xclass;
-    long tmplen;
-    const unsigned char *q = *pp;
-
-    i = ASN1_get_object(&q, &tmplen, &tag, &xclass, *plen);
-    if ((i & 0x80) != 0 || tag != exptag || xclass != V_ASN1_UNIVERSAL)
-        return 0;
-    if (tag == V_ASN1_OBJECT)
-        q += tmplen;
-    *pp = (unsigned char *)q;
-    *plen -= q - *pp;
-    return 1;
-}
-
-/*
- * Encode the other info structure.
- *
- *  RFC2631 Section 2.1.2 Contains the following definition for otherinfo
- *
- *  OtherInfo ::= SEQUENCE {
- *      keyInfo KeySpecificInfo,
- *      partyAInfo [0] OCTET STRING OPTIONAL,
- *      suppPubInfo [2] OCTET STRING
- *  }
- *
- *  KeySpecificInfo ::= SEQUENCE {
- *      algorithm OBJECT IDENTIFIER,
- *      counter OCTET STRING SIZE (4..4)
- *  }
- *
- * |nid| is the algorithm object identifier.
- * |keylen| is the length (in bytes) of the generated KEK. It is stored into
- * suppPubInfo (in bits).
- * |ukm| is the optional user keying material that is stored into partyAInfo. It
- * can be NULL.
- * |ukmlen| is the user keying material length (in bytes).
- * |der| is the returned encoded data. It must be freed by the caller.
- * |der_len| is the returned size of the encoded data.
- * |out_ctr| returns a pointer to the counter data which is embedded inside the
- * encoded data. This allows the counter bytes to be updated without re-encoding.
- *
- * Returns: 1 if successfully encoded, or 0 otherwise.
- * Assumptions: |der|, |der_len| & |out_ctr| are not NULL.
- */
-static int x942_encode_otherinfo(int nid, size_t keylen,
-                                 const unsigned char *ukm, size_t ukmlen,
-                                 unsigned char **der, size_t *der_len,
-                                 unsigned char **out_ctr)
-{
-    unsigned char *p, *encoded = NULL;
-    int ret = 0, encoded_len;
-    long tlen;
-    /* "magic" value to check offset is sane */
-    static unsigned char ctr[4] = { 0x00, 0x00, 0x00, 0x01 };
-    X509_ALGOR *ksi = NULL;
-    ASN1_OBJECT *alg_oid = NULL;
-    ASN1_OCTET_STRING *ctr_oct = NULL, *ukm_oct = NULL;
-
-    /* set the KeySpecificInfo - which contains an algorithm oid and counter */
-    ksi = X509_ALGOR_new();
-    alg_oid = OBJ_dup(OBJ_nid2obj(nid));
-    ctr_oct = ASN1_OCTET_STRING_new();
-    if (ksi == NULL
-        || alg_oid == NULL
-        || ctr_oct == NULL
-        || !ASN1_OCTET_STRING_set(ctr_oct, ctr, sizeof(ctr))
-        || !X509_ALGOR_set0(ksi, alg_oid, V_ASN1_OCTET_STRING, ctr_oct))
-        goto err;
-    /* NULL these as they now belong to ksi */
-    alg_oid = NULL;
-    ctr_oct = NULL;
-
-    /* Set the optional partyAInfo */
-    if (ukm != NULL) {
-        ukm_oct = ASN1_OCTET_STRING_new();
-        if (ukm_oct == NULL)
-            goto err;
-        ASN1_OCTET_STRING_set(ukm_oct, (unsigned char *)ukm, ukmlen);
-    }
-    /* Generate the OtherInfo DER data */
-    encoded_len = CMS_SharedInfo_encode(&encoded, ksi, ukm_oct, keylen);
-    if (encoded_len <= 0)
-        goto err;
-
-    /* Parse the encoded data to find the offset of the counter data */
-    p = encoded;
-    tlen = (long)encoded_len;
-    if (skip_asn1(&p, &tlen, V_ASN1_SEQUENCE)
-        && skip_asn1(&p, &tlen, V_ASN1_SEQUENCE)
-        && skip_asn1(&p, &tlen, V_ASN1_OBJECT)
-        && skip_asn1(&p, &tlen, V_ASN1_OCTET_STRING)
-        && CRYPTO_memcmp(p, ctr, 4) == 0) {
-        *out_ctr = p;
-        *der = encoded;
-        *der_len = (size_t)encoded_len;
-        ret = 1;
-    }
-err:
-    if (ret != 1)
-        OPENSSL_free(encoded);
-    ASN1_OCTET_STRING_free(ctr_oct);
-    ASN1_OCTET_STRING_free(ukm_oct);
-    ASN1_OBJECT_free(alg_oid);
-    X509_ALGOR_free(ksi);
-    return ret;
-}
-
-static int x942kdf_hash_kdm(const EVP_MD *kdf_md,
-                            const unsigned char *z, size_t z_len,
-                            const unsigned char *other, size_t other_len,
-                            unsigned char *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 mac[EVP_MAX_MD_SIZE];
-    unsigned char *out = derived_key;
-    EVP_MD_CTX *ctx = NULL, *ctx_init = NULL;
-
-    if (z_len > X942KDF_MAX_INLEN || other_len > X942KDF_MAX_INLEN
-            || derived_key_len > X942KDF_MAX_INLEN
-            || derived_key_len == 0) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH);
-        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++) {
-        /* updating the ctr modifies 4 bytes in the 'other' buffer */
-        ctr[0] = (unsigned char)((counter >> 24) & 0xff);
-        ctr[1] = (unsigned char)((counter >> 16) & 0xff);
-        ctr[2] = (unsigned char)((counter >> 8) & 0xff);
-        ctr[3] = (unsigned char)(counter & 0xff);
-
-        if (!EVP_MD_CTX_copy_ex(ctx, ctx_init)
-            || !EVP_DigestUpdate(ctx, z, z_len)
-            || !EVP_DigestUpdate(ctx, other, other_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_free(ctx);
-    EVP_MD_CTX_free(ctx_init);
-    OPENSSL_cleanse(mac, sizeof(mac));
-    return ret;
-}
-
-static void *x942kdf_new(void *provctx)
-{
-    KDF_X942 *ctx;
-
-    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-    ctx->provctx = provctx;
-    return ctx;
-}
-
-static void x942kdf_reset(void *vctx)
-{
-    KDF_X942 *ctx = (KDF_X942 *)vctx;
-
-    ossl_prov_digest_reset(&ctx->digest);
-    OPENSSL_clear_free(ctx->secret, ctx->secret_len);
-    OPENSSL_clear_free(ctx->ukm, ctx->ukm_len);
-    memset(ctx, 0, sizeof(*ctx));
-}
-
-static void x942kdf_free(void *vctx)
-{
-    KDF_X942 *ctx = (KDF_X942 *)vctx;
-
-    x942kdf_reset(ctx);
-    OPENSSL_free(ctx);
-}
-
-static int x942kdf_set_buffer(unsigned char **out, size_t *out_len,
-                              const OSSL_PARAM *p)
-{
-    if (p->data_size == 0 || p->data == NULL)
-        return 1;
-
-    OPENSSL_free(*out);
-    *out = NULL;
-    return OSSL_PARAM_get_octet_string(p, (void **)out, 0, out_len);
-}
-
-static size_t x942kdf_size(KDF_X942 *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 x942kdf_derive(void *vctx, unsigned char *key, size_t keylen)
-{
-    KDF_X942 *ctx = (KDF_X942 *)vctx;
-    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
-    int ret = 0;
-    unsigned char *ctr;
-    unsigned char *der = NULL;
-    size_t der_len = 0;
-
-    if (ctx->secret == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);
-        return 0;
-    }
-    if (md == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
-        return 0;
-    }
-    if (ctx->cek_nid == NID_undef) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CEK_ALG);
-        return 0;
-    }
-    if (ctx->ukm != NULL && ctx->ukm_len >= X942KDF_MAX_INLEN) {
-        /*
-         * Note the ukm length MUST be 512 bits.
-         * For backwards compatibility the old check is being done.
-         */
-        ERR_raise(ERR_LIB_PROV, PROV_R_INAVLID_UKM_LENGTH);
-        return 0;
-    }
-    if (keylen != ctx->dkm_len) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CEK_ALG);
-        return 0;
-    }
-    /* generate the otherinfo der */
-    if (!x942_encode_otherinfo(ctx->cek_nid, ctx->dkm_len,
-                               ctx->ukm, ctx->ukm_len,
-                               &der, &der_len, &ctr)) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_BAD_ENCODING);
-        return 0;
-    }
-    ret = x942kdf_hash_kdm(md, ctx->secret, ctx->secret_len,
-                           der, der_len, ctr, key, keylen);
-    OPENSSL_free(der);
-    return ret;
-}
-
-static int x942kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    const OSSL_PARAM *p;
-    KDF_X942 *ctx = vctx;
-    OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
-    size_t i;
-
-    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
-        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 (!x942kdf_set_buffer(&ctx->secret, &ctx->secret_len, p))
-            return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_UKM)) != NULL)
-        if (!x942kdf_set_buffer(&ctx->ukm, &ctx->ukm_len, p))
-            return 0;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_CEK_ALG)) != NULL) {
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
-            return 0;
-        ctx->cek_nid = OBJ_sn2nid(p->data);
-        for (i = 0; i < OSSL_NELEM(kek_algs); i++)
-            if (kek_algs[i].nid == ctx->cek_nid)
-                goto cek_found;
-        ERR_raise(ERR_LIB_PROV, PROV_R_UNSUPPORTED_CEK_ALG);
-        return 0;
-cek_found:
-        ctx->dkm_len = kek_algs[i].keklen;
-    }
-    return 1;
-}
-
-static const OSSL_PARAM *x942kdf_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_KEY, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_UKM, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0),
-        OSSL_PARAM_END
-    };
-    return known_settable_ctx_params;
-}
-
-static int x942kdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
-{
-    KDF_X942 *ctx = (KDF_X942 *)vctx;
-    OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
-        return OSSL_PARAM_set_size_t(p, x942kdf_size(ctx));
-    return -2;
-}
-
-static const OSSL_PARAM *x942kdf_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_x942_kdf_functions[] = {
-    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))x942kdf_new },
-    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))x942kdf_free },
-    { OSSL_FUNC_KDF_RESET, (void(*)(void))x942kdf_reset },
-    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))x942kdf_derive },
-    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
-      (void(*)(void))x942kdf_settable_ctx_params },
-    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))x942kdf_set_ctx_params },
-    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
-      (void(*)(void))x942kdf_gettable_ctx_params },
-    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))x942kdf_get_ctx_params },
-    { 0, NULL }
-};
-
-#endif /* OPENSSL_NO_CMS */
diff --git a/providers/default/macs/blake2_mac_impl.c b/providers/default/macs/blake2_mac_impl.c
deleted file mode 100644 (file)
index a190b91..0000000
+++ /dev/null
@@ -1,220 +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 "internal/blake2.h"
-#include "internal/cryptlib.h"
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.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 blake2_mac_new;
-static OSSL_OP_mac_dupctx_fn blake2_mac_dup;
-static OSSL_OP_mac_freectx_fn blake2_mac_free;
-static OSSL_OP_mac_gettable_ctx_params_fn blake2_gettable_ctx_params;
-static OSSL_OP_mac_get_ctx_params_fn blake2_get_ctx_params;
-static OSSL_OP_mac_settable_ctx_params_fn blake2_mac_settable_ctx_params;
-static OSSL_OP_mac_set_ctx_params_fn blake2_mac_set_ctx_params;
-static OSSL_OP_mac_init_fn blake2_mac_init;
-static OSSL_OP_mac_update_fn blake2_mac_update;
-static OSSL_OP_mac_final_fn blake2_mac_final;
-
-struct blake2_mac_data_st {
-    BLAKE2_CTX ctx;
-    BLAKE2_PARAM params;
-    unsigned char key[BLAKE2_KEYBYTES];
-};
-
-static size_t blake2_mac_size(void *vmacctx);
-
-static void *blake2_mac_new(void *unused_provctx)
-{
-    struct blake2_mac_data_st *macctx = OPENSSL_zalloc(sizeof(*macctx));
-
-    if (macctx != NULL) {
-        BLAKE2_PARAM_INIT(&macctx->params);
-        /* ctx initialization is deferred to BLAKE2b_Init() */
-    }
-    return macctx;
-}
-
-static void *blake2_mac_dup(void *vsrc)
-{
-    struct blake2_mac_data_st *dst;
-    struct blake2_mac_data_st *src = vsrc;
-
-    dst = OPENSSL_zalloc(sizeof(*dst));
-    if (dst == NULL)
-        return NULL;
-
-    *dst = *src;
-    return dst;
-}
-
-static void blake2_mac_free(void *vmacctx)
-{
-    struct blake2_mac_data_st *macctx = vmacctx;
-
-    if (macctx != NULL) {
-        OPENSSL_cleanse(macctx->key, sizeof(macctx->key));
-        OPENSSL_free(macctx);
-    }
-}
-
-static int blake2_mac_init(void *vmacctx)
-{
-    struct blake2_mac_data_st *macctx = vmacctx;
-
-    /* Check key has been set */
-    if (macctx->params.key_length == 0) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
-        return 0;
-    }
-
-    return BLAKE2_INIT_KEY(&macctx->ctx, &macctx->params, macctx->key);
-}
-
-static int blake2_mac_update(void *vmacctx,
-                             const unsigned char *data, size_t datalen)
-{
-    struct blake2_mac_data_st *macctx = vmacctx;
-
-    return BLAKE2_UPDATE(&macctx->ctx, data, datalen);
-}
-
-static int blake2_mac_final(void *vmacctx,
-                            unsigned char *out, size_t *outl,
-                            size_t outsize)
-{
-    struct blake2_mac_data_st *macctx = vmacctx;
-
-    return BLAKE2_FINAL(out, &macctx->ctx);
-}
-
-static const OSSL_PARAM known_gettable_ctx_params[] = {
-    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
-    OSSL_PARAM_END
-};
-static const OSSL_PARAM *blake2_gettable_ctx_params(void)
-{
-    return known_gettable_ctx_params;
-}
-
-static int blake2_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, blake2_mac_size(vmacctx));
-
-    return 1;
-}
-
-static const OSSL_PARAM known_settable_ctx_params[] = {
-    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_octet_string(OSSL_MAC_PARAM_SALT, NULL, 0),
-    OSSL_PARAM_END
-};
-static const OSSL_PARAM *blake2_mac_settable_ctx_params()
-{
-    return known_settable_ctx_params;
-}
-
-/*
- * ALL parameters should be set before init().
- */
-static int blake2_mac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[])
-{
-    struct blake2_mac_data_st *macctx = vmacctx;
-    const OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE)) != NULL) {
-        size_t size;
-
-        if (!OSSL_PARAM_get_size_t(p, &size)
-            || size < 1
-            || size > BLAKE2_OUTBYTES) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_XOF_OR_INVALID_LENGTH);
-            return 0;
-        }
-        BLAKE2_PARAM_SET_DIGEST_LENGTH(&macctx->params, (uint8_t)size);
-    }
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
-        size_t len;
-        void *key_p = macctx->key;
-
-        if (!OSSL_PARAM_get_octet_string(p, &key_p, BLAKE2_KEYBYTES, &len)) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
-            return 0;
-        }
-        /* Pad with zeroes at the end */
-        memset(macctx->key + len, 0, BLAKE2_KEYBYTES - len);
-
-        BLAKE2_PARAM_SET_KEY_LENGTH(&macctx->params, (uint8_t)len);
-    }
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_CUSTOM))
-        != NULL) {
-        /*
-         * The OSSL_PARAM API doesn't provide direct pointer use, so we
-         * must handle the OSSL_PARAM structure ourselves here
-         */
-        if (p->data_size > BLAKE2_PERSONALBYTES) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CUSTOM_LENGTH);
-            return 0;
-        }
-        BLAKE2_PARAM_SET_PERSONAL(&macctx->params, p->data, p->data_size);
-    }
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SALT)) != NULL) {
-        /*
-         * The OSSL_PARAM API doesn't provide direct pointer use, so we
-         * must handle the OSSL_PARAM structure ourselves here as well
-         */
-        if (p->data_size > BLAKE2_SALTBYTES) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
-            return 0;
-        }
-        BLAKE2_PARAM_SET_SALT(&macctx->params, p->data, p->data_size);
-    }
-    return 1;
-}
-
-static size_t blake2_mac_size(void *vmacctx)
-{
-    struct blake2_mac_data_st *macctx = vmacctx;
-
-    return macctx->params.digest_length;
-}
-
-const OSSL_DISPATCH BLAKE2_FUNCTIONS[] = {
-    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))blake2_mac_new },
-    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))blake2_mac_dup },
-    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))blake2_mac_free },
-    { OSSL_FUNC_MAC_INIT, (void (*)(void))blake2_mac_init },
-    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))blake2_mac_update },
-    { OSSL_FUNC_MAC_FINAL, (void (*)(void))blake2_mac_final },
-    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
-      (void (*)(void))blake2_gettable_ctx_params },
-    { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))blake2_get_ctx_params },
-    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
-      (void (*)(void))blake2_mac_settable_ctx_params },
-    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))blake2_mac_set_ctx_params },
-    { 0, NULL }
-};
diff --git a/providers/default/macs/blake2b_mac.c b/providers/default/macs/blake2b_mac.c
deleted file mode 100644 (file)
index aa1a8de..0000000
+++ /dev/null
@@ -1,32 +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
- */
-
-/* Constants */
-#define BLAKE2_CTX BLAKE2B_CTX
-#define BLAKE2_PARAM BLAKE2B_PARAM
-#define BLAKE2_KEYBYTES BLAKE2B_KEYBYTES
-#define BLAKE2_OUTBYTES BLAKE2B_OUTBYTES
-#define BLAKE2_PERSONALBYTES BLAKE2B_PERSONALBYTES
-#define BLAKE2_SALTBYTES BLAKE2B_SALTBYTES
-
-/* Function names */
-#define BLAKE2_PARAM_INIT blake2b_param_init
-#define BLAKE2_INIT_KEY blake2b_init_key
-#define BLAKE2_UPDATE blake2b_update
-#define BLAKE2_FINAL blake2b_final
-#define BLAKE2_PARAM_SET_DIGEST_LENGTH blake2b_param_set_digest_length
-#define BLAKE2_PARAM_SET_KEY_LENGTH blake2b_param_set_key_length
-#define BLAKE2_PARAM_SET_PERSONAL blake2b_param_set_personal
-#define BLAKE2_PARAM_SET_SALT blake2b_param_set_salt
-
-/* OSSL_DISPATCH symbol */
-#define BLAKE2_FUNCTIONS blake2bmac_functions
-
-#include "blake2_mac_impl.c"
-
diff --git a/providers/default/macs/blake2s_mac.c b/providers/default/macs/blake2s_mac.c
deleted file mode 100644 (file)
index ccd7035..0000000
+++ /dev/null
@@ -1,31 +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
- */
-
-/* Constants */
-#define BLAKE2_CTX BLAKE2S_CTX
-#define BLAKE2_PARAM BLAKE2S_PARAM
-#define BLAKE2_KEYBYTES BLAKE2S_KEYBYTES
-#define BLAKE2_OUTBYTES BLAKE2S_OUTBYTES
-#define BLAKE2_PERSONALBYTES BLAKE2S_PERSONALBYTES
-#define BLAKE2_SALTBYTES BLAKE2S_SALTBYTES
-
-/* Function names */
-#define BLAKE2_PARAM_INIT blake2s_param_init
-#define BLAKE2_INIT_KEY blake2s_init_key
-#define BLAKE2_UPDATE blake2s_update
-#define BLAKE2_FINAL blake2s_final
-#define BLAKE2_PARAM_SET_DIGEST_LENGTH blake2s_param_set_digest_length
-#define BLAKE2_PARAM_SET_KEY_LENGTH blake2s_param_set_key_length
-#define BLAKE2_PARAM_SET_PERSONAL blake2s_param_set_personal
-#define BLAKE2_PARAM_SET_SALT blake2s_param_set_salt
-
-/* OSSL_DISPATCH symbol */
-#define BLAKE2_FUNCTIONS blake2smac_functions
-
-#include "blake2_mac_impl.c"
diff --git a/providers/default/macs/build.info b/providers/default/macs/build.info
deleted file mode 100644 (file)
index 821a3d4..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-$GOAL=../../libimplementations.a
-
-IF[{- !$disabled{blake2} -}]
-  SOURCE[$GOAL]=blake2b_mac.c blake2s_mac.c
-ENDIF
-
-IF[{- !$disabled{siphash} -}]
-  SOURCE[$GOAL]=siphash_prov.c
-ENDIF
-
-IF[{- !$disabled{poly1305} -}]
-  SOURCE[$GOAL]=poly1305_prov.c
-ENDIF
diff --git a/providers/default/macs/poly1305_prov.c b/providers/default/macs/poly1305_prov.c
deleted file mode 100644 (file)
index 8800571..0000000
+++ /dev/null
@@ -1,162 +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/evp.h>
-#include <openssl/err.h>
-
-#include "crypto/poly1305.h"
-/*
- * TODO(3.0) when poly1305 has moved entirely to our providers, this
- * header should be moved to the provider include directory.  For the
- * moment, crypto/poly1305/poly1305_ameth.c has us stuck.
- */
-#include "../../../crypto/poly1305/poly1305_local.h"
-
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.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 poly1305_new;
-static OSSL_OP_mac_dupctx_fn poly1305_dup;
-static OSSL_OP_mac_freectx_fn poly1305_free;
-static OSSL_OP_mac_gettable_params_fn poly1305_gettable_params;
-static OSSL_OP_mac_get_params_fn poly1305_get_params;
-static OSSL_OP_mac_settable_ctx_params_fn poly1305_settable_ctx_params;
-static OSSL_OP_mac_set_ctx_params_fn poly1305_set_ctx_params;
-static OSSL_OP_mac_init_fn poly1305_init;
-static OSSL_OP_mac_update_fn poly1305_update;
-static OSSL_OP_mac_final_fn poly1305_final;
-
-struct poly1305_data_st {
-    void *provctx;
-    POLY1305 poly1305;           /* Poly1305 data */
-};
-
-static size_t poly1305_size(void);
-
-static void *poly1305_new(void *provctx)
-{
-    struct poly1305_data_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
-
-    ctx->provctx = provctx;
-    return ctx;
-}
-
-static void poly1305_free(void *vmacctx)
-{
-    OPENSSL_free(vmacctx);
-}
-
-static void *poly1305_dup(void *vsrc)
-{
-    struct poly1305_data_st *src = vsrc;
-    struct poly1305_data_st *dst = poly1305_new(src->provctx);
-
-    if (dst == NULL)
-        return NULL;
-
-    dst->poly1305 = src->poly1305;
-    return dst;
-}
-
-static size_t poly1305_size(void)
-{
-    return POLY1305_DIGEST_SIZE;
-}
-
-static int poly1305_init(void *vmacctx)
-{
-    /* initialize the context in MAC_ctrl function */
-    return 1;
-}
-
-static int poly1305_update(void *vmacctx, const unsigned char *data,
-                       size_t datalen)
-{
-    struct poly1305_data_st *ctx = vmacctx;
-
-    /* poly1305 has nothing to return in its update function */
-    Poly1305_Update(&ctx->poly1305, data, datalen);
-    return 1;
-}
-
-static int poly1305_final(void *vmacctx, unsigned char *out, size_t *outl,
-                          size_t outsize)
-{
-    struct poly1305_data_st *ctx = vmacctx;
-
-    Poly1305_Final(&ctx->poly1305, out);
-    return 1;
-}
-
-static const OSSL_PARAM known_gettable_params[] = {
-    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
-    OSSL_PARAM_END
-};
-static const OSSL_PARAM *poly1305_gettable_params(void)
-{
-    return known_gettable_params;
-}
-
-static int poly1305_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, poly1305_size());
-
-    return 1;
-}
-
-static const OSSL_PARAM known_settable_ctx_params[] = {
-    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
-    OSSL_PARAM_END
-};
-static const OSSL_PARAM *poly1305_settable_ctx_params(void)
-{
-    return known_settable_ctx_params;
-}
-
-static int poly1305_set_ctx_params(void *vmacctx, const OSSL_PARAM *params)
-{
-    struct poly1305_data_st *ctx = vmacctx;
-    const OSSL_PARAM *p = NULL;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
-        if (p->data_type != OSSL_PARAM_OCTET_STRING
-            || p->data_size != POLY1305_KEY_SIZE) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
-            return 0;
-        }
-        Poly1305_Init(&ctx->poly1305, p->data);
-    }
-    return 1;
-}
-
-const OSSL_DISPATCH poly1305_functions[] = {
-    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))poly1305_new },
-    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))poly1305_dup },
-    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))poly1305_free },
-    { OSSL_FUNC_MAC_INIT, (void (*)(void))poly1305_init },
-    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))poly1305_update },
-    { OSSL_FUNC_MAC_FINAL, (void (*)(void))poly1305_final },
-    { OSSL_FUNC_MAC_GETTABLE_PARAMS, (void (*)(void))poly1305_gettable_params },
-    { OSSL_FUNC_MAC_GET_PARAMS, (void (*)(void))poly1305_get_params },
-    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
-      (void (*)(void))poly1305_settable_ctx_params },
-    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))poly1305_set_ctx_params },
-    { 0, NULL }
-};
diff --git a/providers/default/macs/siphash_prov.c b/providers/default/macs/siphash_prov.c
deleted file mode 100644 (file)
index a951192..0000000
+++ /dev/null
@@ -1,173 +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 <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 "crypto/siphash.h"
-/*
- * TODO(3.0) when siphash has moved entirely to our providers, this
- * header should be moved to the provider include directory.  For the
- * moment, crypto/siphash/siphash_ameth.c has us stuck.
- */
-#include "../../../crypto/siphash/siphash_local.h"
-
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.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 siphash_new;
-static OSSL_OP_mac_dupctx_fn siphash_dup;
-static OSSL_OP_mac_freectx_fn siphash_free;
-static OSSL_OP_mac_gettable_ctx_params_fn siphash_gettable_ctx_params;
-static OSSL_OP_mac_get_ctx_params_fn siphash_get_ctx_params;
-static OSSL_OP_mac_settable_ctx_params_fn siphash_settable_params;
-static OSSL_OP_mac_set_ctx_params_fn siphash_set_params;
-static OSSL_OP_mac_size_fn siphash_size;
-static OSSL_OP_mac_init_fn siphash_init;
-static OSSL_OP_mac_update_fn siphash_update;
-static OSSL_OP_mac_final_fn siphash_final;
-
-struct siphash_data_st {
-    void *provctx;
-    SIPHASH siphash;             /* Siphash data */
-};
-
-static void *siphash_new(void *provctx)
-{
-    struct siphash_data_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
-
-    ctx->provctx = provctx;
-    return ctx;
-}
-
-static void siphash_free(void *vmacctx)
-{
-    OPENSSL_free(vmacctx);
-}
-
-static void *siphash_dup(void *vsrc)
-{
-    struct siphash_data_st *ssrc = vsrc;
-    struct siphash_data_st *sdst = siphash_new(ssrc->provctx);
-
-    if (sdst == NULL)
-        return NULL;
-
-    sdst->siphash = ssrc->siphash;
-    return sdst;
-}
-
-static size_t siphash_size(void *vmacctx)
-{
-    struct siphash_data_st *ctx = vmacctx;
-
-    return SipHash_hash_size(&ctx->siphash);
-}
-
-static int siphash_init(void *vmacctx)
-{
-    /* Not much to do here, actual initialization happens through controls */
-    return 1;
-}
-
-static int siphash_update(void *vmacctx, const unsigned char *data,
-                       size_t datalen)
-{
-    struct siphash_data_st *ctx = vmacctx;
-
-    SipHash_Update(&ctx->siphash, data, datalen);
-    return 1;
-}
-
-static int siphash_final(void *vmacctx, unsigned char *out, size_t *outl,
-                         size_t outsize)
-{
-    struct siphash_data_st *ctx = vmacctx;
-    size_t hlen = siphash_size(ctx);
-
-    if (outsize < hlen)
-        return 0;
-
-    *outl = hlen;
-    return SipHash_Final(&ctx->siphash, out, hlen);
-}
-
-static const OSSL_PARAM known_gettable_ctx_params[] = {
-    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
-    OSSL_PARAM_END
-};
-static const OSSL_PARAM *siphash_gettable_ctx_params(void)
-{
-    return known_gettable_ctx_params;
-}
-
-static int siphash_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, siphash_size(vmacctx));
-
-    return 1;
-}
-
-static const OSSL_PARAM known_settable_ctx_params[] = {
-    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
-    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
-    OSSL_PARAM_END
-};
-static const OSSL_PARAM *siphash_settable_params(void)
-{
-    return known_settable_ctx_params;
-}
-
-static int siphash_set_params(void *vmacctx, const OSSL_PARAM *params)
-{
-    struct siphash_data_st *ctx = vmacctx;
-    const OSSL_PARAM *p = NULL;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE)) != NULL) {
-        size_t size;
-
-        if (!OSSL_PARAM_get_size_t(p, &size)
-            || !SipHash_set_hash_size(&ctx->siphash, size))
-            return 0;
-    }
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL)
-        if (p->data_type != OSSL_PARAM_OCTET_STRING
-            || p->data_size != SIPHASH_KEY_SIZE
-            || !SipHash_Init(&ctx->siphash, p->data, 0, 0))
-            return 0;
-    return 1;
-}
-
-const OSSL_DISPATCH siphash_functions[] = {
-    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))siphash_new },
-    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))siphash_dup },
-    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))siphash_free },
-    { OSSL_FUNC_MAC_INIT, (void (*)(void))siphash_init },
-    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))siphash_update },
-    { OSSL_FUNC_MAC_FINAL, (void (*)(void))siphash_final },
-    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
-      (void (*)(void))siphash_gettable_ctx_params },
-    { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))siphash_get_ctx_params },
-    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
-      (void (*)(void))siphash_settable_params },
-    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))siphash_set_params },
-    { 0, NULL }
-};
index 8800b12f7e366694f427e00263926ca781ed8a06..dee8f532fa3edaa335449bca023a1041f7c227e6 100644 (file)
@@ -6,6 +6,9 @@ $HKDF_GOAL=../../libimplementations.a
 $KBKDF_GOAL=../../libimplementations.a
 $PBKDF2_GOAL=../../libimplementations.a
 $SSKDF_GOAL=../../libimplementations.a
+$SCRYPT_GOAL=../../libimplementations.a
+$SSHKDF_GOAL=../../libimplementations.a
+$X942KDF_GOAL=../../libimplementations.a
 
 SOURCE[$TLS1_PRF_GOAL]=tls1_prf.c
 
@@ -20,3 +23,7 @@ SOURCE[../../libfips.a]=pbkdf2_fips.c
 SOURCE[../../libnonfips.a]=pbkdf2_fips.c
 
 SOURCE[$SSKDF_GOAL]=sskdf.c
+
+SOURCE[$SCRYPT_GOAL]=scrypt.c
+SOURCE[$SSHKDF_GOAL]=sshkdf.c
+SOURCE[$X942KDF_GOAL]=x942kdf.c
diff --git a/providers/implementations/kdfs/scrypt.c b/providers/implementations/kdfs/scrypt.c
new file mode 100644 (file)
index 0000000..505963e
--- /dev/null
@@ -0,0 +1,463 @@
+/*
+ * Copyright 2017-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/evp.h>
+#include <openssl/kdf.h>
+#include <openssl/err.h>
+#include <openssl/core_names.h>
+#include "crypto/evp.h"
+#include "internal/numbers.h"
+#include "internal/provider_algs.h"
+#include "internal/provider_ctx.h"
+#include "internal/providercommonerr.h"
+#include "internal/provider_algs.h"
+
+#ifndef OPENSSL_NO_SCRYPT
+
+static OSSL_OP_kdf_newctx_fn kdf_scrypt_new;
+static OSSL_OP_kdf_freectx_fn kdf_scrypt_free;
+static OSSL_OP_kdf_reset_fn kdf_scrypt_reset;
+static OSSL_OP_kdf_derive_fn kdf_scrypt_derive;
+static OSSL_OP_kdf_settable_ctx_params_fn kdf_scrypt_settable_ctx_params;
+static OSSL_OP_kdf_set_ctx_params_fn kdf_scrypt_set_ctx_params;
+
+static int scrypt_alg(const char *pass, size_t passlen,
+                      const unsigned char *salt, size_t saltlen,
+                      uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
+                      unsigned char *key, size_t keylen, EVP_MD *sha256);
+
+typedef struct {
+    void *provctx;
+    unsigned char *pass;
+    size_t pass_len;
+    unsigned char *salt;
+    size_t salt_len;
+    uint64_t N;
+    uint64_t r, p;
+    uint64_t maxmem_bytes;
+    EVP_MD *sha256;
+} KDF_SCRYPT;
+
+static void kdf_scrypt_init(KDF_SCRYPT *ctx);
+
+static void *kdf_scrypt_new(void *provctx)
+{
+    KDF_SCRYPT *ctx;
+
+    ctx = OPENSSL_zalloc(sizeof(*ctx));
+    if (ctx == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    ctx->provctx = provctx;
+    ctx->sha256 = EVP_MD_fetch(PROV_LIBRARY_CONTEXT_OF(provctx),
+                               "sha256", NULL);
+    if (ctx->sha256 == NULL) {
+        OPENSSL_free(ctx);
+        ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_LOAD_SHA256);
+        return NULL;
+    }
+    kdf_scrypt_init(ctx);
+    return ctx;
+}
+
+static void kdf_scrypt_free(void *vctx)
+{
+    KDF_SCRYPT *ctx = (KDF_SCRYPT *)vctx;
+
+    EVP_MD_meth_free(ctx->sha256);
+    kdf_scrypt_reset(ctx);
+    OPENSSL_free(ctx);
+}
+
+static void kdf_scrypt_reset(void *vctx)
+{
+    KDF_SCRYPT *ctx = (KDF_SCRYPT *)vctx;
+
+    OPENSSL_free(ctx->salt);
+    OPENSSL_clear_free(ctx->pass, ctx->pass_len);
+    kdf_scrypt_init(ctx);
+}
+
+static void kdf_scrypt_init(KDF_SCRYPT *ctx)
+{
+    /* Default values are the most conservative recommendation given in the
+     * original paper of C. Percival. Derivation uses roughly 1 GiB of memory
+     * for this parameter choice (approx. 128 * r * N * p bytes).
+     */
+    ctx->N = 1 << 20;
+    ctx->r = 8;
+    ctx->p = 1;
+    ctx->maxmem_bytes = 1025 * 1024 * 1024;
+}
+
+static int scrypt_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_scrypt_derive(void *vctx, unsigned char *key,
+                             size_t keylen)
+{
+    KDF_SCRYPT *ctx = (KDF_SCRYPT *)vctx;
+
+    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 scrypt_alg((char *)ctx->pass, ctx->pass_len, ctx->salt,
+                      ctx->salt_len, ctx->N, ctx->r, ctx->p,
+                      ctx->maxmem_bytes, key, keylen, ctx->sha256);
+}
+
+static int is_power_of_two(uint64_t value)
+{
+    return (value != 0) && ((value & (value - 1)) == 0);
+}
+
+static int kdf_scrypt_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    const OSSL_PARAM *p;
+    KDF_SCRYPT *ctx = vctx;
+    uint64_t u64_value;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL)
+        if (!scrypt_set_membuf(&ctx->pass, &ctx->pass_len, p))
+            return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL)
+        if (!scrypt_set_membuf(&ctx->salt, &ctx->salt_len, p))
+            return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SCRYPT_N))
+        != NULL) {
+        if (!OSSL_PARAM_get_uint64(p, &u64_value)
+            || u64_value <= 1
+            || !is_power_of_two(u64_value))
+            return 0;
+        ctx->N = u64_value;
+    }
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SCRYPT_R))
+        != NULL) {
+        if (!OSSL_PARAM_get_uint64(p, &u64_value) || u64_value < 1)
+            return 0;
+        ctx->r = u64_value;
+    }
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SCRYPT_P))
+        != NULL) {
+        if (!OSSL_PARAM_get_uint64(p, &u64_value) || u64_value < 1)
+            return 0;
+        ctx->p = u64_value;
+    }
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SCRYPT_MAXMEM))
+        != NULL) {
+        if (!OSSL_PARAM_get_uint64(p, &u64_value) || u64_value < 1)
+            return 0;
+        ctx->maxmem_bytes = u64_value;
+    }
+    return 1;
+}
+
+static const OSSL_PARAM *kdf_scrypt_settable_ctx_params(void)
+{
+    static const OSSL_PARAM known_settable_ctx_params[] = {
+        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_SCRYPT_N, NULL),
+        OSSL_PARAM_uint32(OSSL_KDF_PARAM_SCRYPT_R, NULL),
+        OSSL_PARAM_uint32(OSSL_KDF_PARAM_SCRYPT_P, NULL),
+        OSSL_PARAM_uint64(OSSL_KDF_PARAM_SCRYPT_MAXMEM, NULL),
+        OSSL_PARAM_END
+    };
+    return known_settable_ctx_params;
+}
+
+static int kdf_scrypt_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_scrypt_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_scrypt_functions[] = {
+    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_scrypt_new },
+    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_scrypt_free },
+    { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_scrypt_reset },
+    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_scrypt_derive },
+    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
+      (void(*)(void))kdf_scrypt_settable_ctx_params },
+    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_scrypt_set_ctx_params },
+    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
+      (void(*)(void))kdf_scrypt_gettable_ctx_params },
+    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_scrypt_get_ctx_params },
+    { 0, NULL }
+};
+
+#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
+static void salsa208_word_specification(uint32_t inout[16])
+{
+    int i;
+    uint32_t x[16];
+
+    memcpy(x, inout, sizeof(x));
+    for (i = 8; i > 0; i -= 2) {
+        x[4] ^= R(x[0] + x[12], 7);
+        x[8] ^= R(x[4] + x[0], 9);
+        x[12] ^= R(x[8] + x[4], 13);
+        x[0] ^= R(x[12] + x[8], 18);
+        x[9] ^= R(x[5] + x[1], 7);
+        x[13] ^= R(x[9] + x[5], 9);
+        x[1] ^= R(x[13] + x[9], 13);
+        x[5] ^= R(x[1] + x[13], 18);
+        x[14] ^= R(x[10] + x[6], 7);
+        x[2] ^= R(x[14] + x[10], 9);
+        x[6] ^= R(x[2] + x[14], 13);
+        x[10] ^= R(x[6] + x[2], 18);
+        x[3] ^= R(x[15] + x[11], 7);
+        x[7] ^= R(x[3] + x[15], 9);
+        x[11] ^= R(x[7] + x[3], 13);
+        x[15] ^= R(x[11] + x[7], 18);
+        x[1] ^= R(x[0] + x[3], 7);
+        x[2] ^= R(x[1] + x[0], 9);
+        x[3] ^= R(x[2] + x[1], 13);
+        x[0] ^= R(x[3] + x[2], 18);
+        x[6] ^= R(x[5] + x[4], 7);
+        x[7] ^= R(x[6] + x[5], 9);
+        x[4] ^= R(x[7] + x[6], 13);
+        x[5] ^= R(x[4] + x[7], 18);
+        x[11] ^= R(x[10] + x[9], 7);
+        x[8] ^= R(x[11] + x[10], 9);
+        x[9] ^= R(x[8] + x[11], 13);
+        x[10] ^= R(x[9] + x[8], 18);
+        x[12] ^= R(x[15] + x[14], 7);
+        x[13] ^= R(x[12] + x[15], 9);
+        x[14] ^= R(x[13] + x[12], 13);
+        x[15] ^= R(x[14] + x[13], 18);
+    }
+    for (i = 0; i < 16; ++i)
+        inout[i] += x[i];
+    OPENSSL_cleanse(x, sizeof(x));
+}
+
+static void scryptBlockMix(uint32_t *B_, uint32_t *B, uint64_t r)
+{
+    uint64_t i, j;
+    uint32_t X[16], *pB;
+
+    memcpy(X, B + (r * 2 - 1) * 16, sizeof(X));
+    pB = B;
+    for (i = 0; i < r * 2; i++) {
+        for (j = 0; j < 16; j++)
+            X[j] ^= *pB++;
+        salsa208_word_specification(X);
+        memcpy(B_ + (i / 2 + (i & 1) * r) * 16, X, sizeof(X));
+    }
+    OPENSSL_cleanse(X, sizeof(X));
+}
+
+static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N,
+                        uint32_t *X, uint32_t *T, uint32_t *V)
+{
+    unsigned char *pB;
+    uint32_t *pV;
+    uint64_t i, k;
+
+    /* Convert from little endian input */
+    for (pV = V, i = 0, pB = B; i < 32 * r; i++, pV++) {
+        *pV = *pB++;
+        *pV |= *pB++ << 8;
+        *pV |= *pB++ << 16;
+        *pV |= (uint32_t)*pB++ << 24;
+    }
+
+    for (i = 1; i < N; i++, pV += 32 * r)
+        scryptBlockMix(pV, pV - 32 * r, r);
+
+    scryptBlockMix(X, V + (N - 1) * 32 * r, r);
+
+    for (i = 0; i < N; i++) {
+        uint32_t j;
+        j = X[16 * (2 * r - 1)] % N;
+        pV = V + 32 * r * j;
+        for (k = 0; k < 32 * r; k++)
+            T[k] = X[k] ^ *pV++;
+        scryptBlockMix(X, T, r);
+    }
+    /* Convert output to little endian */
+    for (i = 0, pB = B; i < 32 * r; i++) {
+        uint32_t xtmp = X[i];
+        *pB++ = xtmp & 0xff;
+        *pB++ = (xtmp >> 8) & 0xff;
+        *pB++ = (xtmp >> 16) & 0xff;
+        *pB++ = (xtmp >> 24) & 0xff;
+    }
+}
+
+#ifndef SIZE_MAX
+# define SIZE_MAX    ((size_t)-1)
+#endif
+
+/*
+ * Maximum power of two that will fit in uint64_t: this should work on
+ * most (all?) platforms.
+ */
+
+#define LOG2_UINT64_MAX         (sizeof(uint64_t) * 8 - 1)
+
+/*
+ * Maximum value of p * r:
+ * p <= ((2^32-1) * hLen) / MFLen =>
+ * p <= ((2^32-1) * 32) / (128 * r) =>
+ * p * r <= (2^30-1)
+ */
+
+#define SCRYPT_PR_MAX   ((1 << 30) - 1)
+
+static int scrypt_alg(const char *pass, size_t passlen,
+                      const unsigned char *salt, size_t saltlen,
+                      uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
+                      unsigned char *key, size_t keylen, EVP_MD *sha256)
+{
+    int rv = 0;
+    unsigned char *B;
+    uint32_t *X, *V, *T;
+    uint64_t i, Blen, Vlen;
+
+    /* Sanity check parameters */
+    /* initial check, r,p must be non zero, N >= 2 and a power of 2 */
+    if (r == 0 || p == 0 || N < 2 || (N & (N - 1)))
+        return 0;
+    /* Check p * r < SCRYPT_PR_MAX avoiding overflow */
+    if (p > SCRYPT_PR_MAX / r) {
+        EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
+        return 0;
+    }
+
+    /*
+     * Need to check N: if 2^(128 * r / 8) overflows limit this is
+     * automatically satisfied since N <= UINT64_MAX.
+     */
+
+    if (16 * r <= LOG2_UINT64_MAX) {
+        if (N >= (((uint64_t)1) << (16 * r))) {
+            EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
+            return 0;
+        }
+    }
+
+    /* Memory checks: check total allocated buffer size fits in uint64_t */
+
+    /*
+     * B size in section 5 step 1.S
+     * Note: we know p * 128 * r < UINT64_MAX because we already checked
+     * p * r < SCRYPT_PR_MAX
+     */
+    Blen = p * 128 * r;
+    /*
+     * Yet we pass it as integer to PKCS5_PBKDF2_HMAC... [This would
+     * have to be revised when/if PKCS5_PBKDF2_HMAC accepts size_t.]
+     */
+    if (Blen > INT_MAX) {
+        EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
+        return 0;
+    }
+
+    /*
+     * Check 32 * r * (N + 2) * sizeof(uint32_t) fits in uint64_t
+     * This is combined size V, X and T (section 4)
+     */
+    i = UINT64_MAX / (32 * sizeof(uint32_t));
+    if (N + 2 > i / r) {
+        EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
+        return 0;
+    }
+    Vlen = 32 * r * (N + 2) * sizeof(uint32_t);
+
+    /* check total allocated size fits in uint64_t */
+    if (Blen > UINT64_MAX - Vlen) {
+        EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
+        return 0;
+    }
+
+    /* Check that the maximum memory doesn't exceed a size_t limits */
+    if (maxmem > SIZE_MAX)
+        maxmem = SIZE_MAX;
+
+    if (Blen + Vlen > maxmem) {
+        EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
+        return 0;
+    }
+
+    /* If no key return to indicate parameters are OK */
+    if (key == NULL)
+        return 1;
+
+    B = OPENSSL_malloc((size_t)(Blen + Vlen));
+    if (B == NULL) {
+        EVPerr(EVP_F_SCRYPT_ALG, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    X = (uint32_t *)(B + Blen);
+    T = X + 32 * r;
+    V = T + 32 * r;
+    if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, sha256,
+                          (int)Blen, B) == 0)
+        goto err;
+
+    for (i = 0; i < p; i++)
+        scryptROMix(B + 128 * r * i, r, N, X, T, V);
+
+    if (PKCS5_PBKDF2_HMAC(pass, passlen, B, (int)Blen, 1, sha256,
+                          keylen, key) == 0)
+        goto err;
+    rv = 1;
+ err:
+    if (rv == 0)
+        EVPerr(EVP_F_SCRYPT_ALG, EVP_R_PBKDF2_ERROR);
+
+    OPENSSL_clear_free(B, (size_t)(Blen + Vlen));
+    return rv;
+}
+
+#endif
diff --git a/providers/implementations/kdfs/sshkdf.c b/providers/implementations/kdfs/sshkdf.c
new file mode 100644 (file)
index 0000000..7e6445d
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (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/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"
+
+/* See RFC 4253, Section 7.2 */
+static OSSL_OP_kdf_newctx_fn kdf_sshkdf_new;
+static OSSL_OP_kdf_freectx_fn kdf_sshkdf_free;
+static OSSL_OP_kdf_reset_fn kdf_sshkdf_reset;
+static OSSL_OP_kdf_derive_fn kdf_sshkdf_derive;
+static OSSL_OP_kdf_settable_ctx_params_fn kdf_sshkdf_settable_ctx_params;
+static OSSL_OP_kdf_set_ctx_params_fn kdf_sshkdf_set_ctx_params;
+static OSSL_OP_kdf_gettable_ctx_params_fn kdf_sshkdf_gettable_ctx_params;
+static OSSL_OP_kdf_get_ctx_params_fn kdf_sshkdf_get_ctx_params;
+
+static int SSHKDF(const EVP_MD *evp_md,
+                  const unsigned char *key, size_t key_len,
+                  const unsigned char *xcghash, size_t xcghash_len,
+                  const unsigned char *session_id, size_t session_id_len,
+                  char type, unsigned char *okey, size_t okey_len);
+
+typedef struct {
+    void *provctx;
+    PROV_DIGEST digest;
+    unsigned char *key; /* K */
+    size_t key_len;
+    unsigned char *xcghash; /* H */
+    size_t xcghash_len;
+    char type; /* X */
+    unsigned char *session_id;
+    size_t session_id_len;
+} KDF_SSHKDF;
+
+static void *kdf_sshkdf_new(void *provctx)
+{
+    KDF_SSHKDF *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_sshkdf_free(void *vctx)
+{
+    KDF_SSHKDF *ctx = (KDF_SSHKDF *)vctx;
+
+    kdf_sshkdf_reset(ctx);
+    OPENSSL_free(ctx);
+}
+
+static void kdf_sshkdf_reset(void *vctx)
+{
+    KDF_SSHKDF *ctx = (KDF_SSHKDF *)vctx;
+
+    ossl_prov_digest_reset(&ctx->digest);
+    OPENSSL_clear_free(ctx->key, ctx->key_len);
+    OPENSSL_clear_free(ctx->xcghash, ctx->xcghash_len);
+    OPENSSL_clear_free(ctx->session_id, ctx->session_id_len);
+    memset(ctx, 0, sizeof(*ctx));
+}
+
+static int sshkdf_set_membuf(unsigned char **dst, size_t *dst_len,
+                             const OSSL_PARAM *p)
+{
+    OPENSSL_clear_free(*dst, *dst_len);
+    *dst = NULL;
+    return OSSL_PARAM_get_octet_string(p, (void **)dst, 0, dst_len);
+}
+
+static int kdf_sshkdf_derive(void *vctx, unsigned char *key,
+                             size_t keylen)
+{
+    KDF_SSHKDF *ctx = (KDF_SSHKDF *)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;
+    }
+    if (ctx->xcghash == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_XCGHASH);
+        return 0;
+    }
+    if (ctx->session_id == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SESSION_ID);
+        return 0;
+    }
+    if (ctx->type == 0) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_TYPE);
+        return 0;
+    }
+    return SSHKDF(md, ctx->key, ctx->key_len,
+                  ctx->xcghash, ctx->xcghash_len,
+                  ctx->session_id, ctx->session_id_len,
+                  ctx->type, key, keylen);
+}
+
+static int kdf_sshkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    const OSSL_PARAM *p;
+    KDF_SSHKDF *ctx = vctx;
+    OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
+    int t;
+
+    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
+        return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL)
+        if (!sshkdf_set_membuf(&ctx->key, &ctx->key_len, p))
+            return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SSHKDF_XCGHASH))
+        != NULL)
+        if (!sshkdf_set_membuf(&ctx->xcghash, &ctx->xcghash_len, p))
+            return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SSHKDF_SESSION_ID))
+        != NULL)
+        if (!sshkdf_set_membuf(&ctx->session_id, &ctx->session_id_len, p))
+            return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SSHKDF_TYPE))
+        != NULL) {
+        if (p->data == NULL || p->data_size == 0)
+            return 0;
+        t = *(unsigned char *)p->data;
+        if (t < 65 || t > 70) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_VALUE_ERROR);
+            return 0;
+        }
+        ctx->type = (char)t;
+    }
+    return 1;
+}
+
+static const OSSL_PARAM *kdf_sshkdf_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_KEY, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SSHKDF_XCGHASH, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SSHKDF_SESSION_ID, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_SSHKDF_TYPE, NULL, 0),
+        OSSL_PARAM_END
+    };
+    return known_settable_ctx_params;
+}
+
+static int kdf_sshkdf_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_sshkdf_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_sshkdf_functions[] = {
+    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_sshkdf_new },
+    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_sshkdf_free },
+    { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_sshkdf_reset },
+    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_sshkdf_derive },
+    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
+      (void(*)(void))kdf_sshkdf_settable_ctx_params },
+    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_sshkdf_set_ctx_params },
+    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
+      (void(*)(void))kdf_sshkdf_gettable_ctx_params },
+    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_sshkdf_get_ctx_params },
+    { 0, NULL }
+};
+
+static int SSHKDF(const EVP_MD *evp_md,
+                  const unsigned char *key, size_t key_len,
+                  const unsigned char *xcghash, size_t xcghash_len,
+                  const unsigned char *session_id, size_t session_id_len,
+                  char type, unsigned char *okey, size_t okey_len)
+{
+    EVP_MD_CTX *md = NULL;
+    unsigned char digest[EVP_MAX_MD_SIZE];
+    unsigned int dsize = 0;
+    size_t cursize = 0;
+    int ret = 0;
+
+    md = EVP_MD_CTX_new();
+    if (md == NULL)
+        return 0;
+
+    if (!EVP_DigestInit_ex(md, evp_md, NULL))
+        goto out;
+
+    if (!EVP_DigestUpdate(md, key, key_len))
+        goto out;
+
+    if (!EVP_DigestUpdate(md, xcghash, xcghash_len))
+        goto out;
+
+    if (!EVP_DigestUpdate(md, &type, 1))
+        goto out;
+
+    if (!EVP_DigestUpdate(md, session_id, session_id_len))
+        goto out;
+
+    if (!EVP_DigestFinal_ex(md, digest, &dsize))
+        goto out;
+
+    if (okey_len < dsize) {
+        memcpy(okey, digest, okey_len);
+        ret = 1;
+        goto out;
+    }
+
+    memcpy(okey, digest, dsize);
+
+    for (cursize = dsize; cursize < okey_len; cursize += dsize) {
+
+        if (!EVP_DigestInit_ex(md, evp_md, NULL))
+            goto out;
+
+        if (!EVP_DigestUpdate(md, key, key_len))
+            goto out;
+
+        if (!EVP_DigestUpdate(md, xcghash, xcghash_len))
+            goto out;
+
+        if (!EVP_DigestUpdate(md, okey, cursize))
+            goto out;
+
+        if (!EVP_DigestFinal_ex(md, digest, &dsize))
+            goto out;
+
+        if (okey_len < cursize + dsize) {
+            memcpy(okey + cursize, digest, okey_len - cursize);
+            ret = 1;
+            goto out;
+        }
+
+        memcpy(okey + cursize, digest, dsize);
+    }
+
+    ret = 1;
+
+out:
+    EVP_MD_CTX_free(md);
+    OPENSSL_cleanse(digest, EVP_MAX_MD_SIZE);
+    return ret;
+}
+
diff --git a/providers/implementations/kdfs/x942kdf.c b/providers/implementations/kdfs/x942kdf.c
new file mode 100644 (file)
index 0000000..65c586f
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * 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
+ */
+
+#include "e_os.h"
+
+#ifndef OPENSSL_NO_CMS
+
+# include <stdlib.h>
+# include <stdarg.h>
+# include <string.h>
+# include <openssl/hmac.h>
+# include <openssl/cms.h>
+# include <openssl/evp.h>
+# include <openssl/kdf.h>
+# include <openssl/x509.h>
+# include <openssl/obj_mac.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"
+
+# define X942KDF_MAX_INLEN (1 << 30)
+
+static OSSL_OP_kdf_newctx_fn x942kdf_new;
+static OSSL_OP_kdf_freectx_fn x942kdf_free;
+static OSSL_OP_kdf_reset_fn x942kdf_reset;
+static OSSL_OP_kdf_derive_fn x942kdf_derive;
+static OSSL_OP_kdf_settable_ctx_params_fn x942kdf_settable_ctx_params;
+static OSSL_OP_kdf_set_ctx_params_fn x942kdf_set_ctx_params;
+static OSSL_OP_kdf_gettable_ctx_params_fn x942kdf_gettable_ctx_params;
+static OSSL_OP_kdf_get_ctx_params_fn x942kdf_get_ctx_params;
+
+typedef struct {
+    void *provctx;
+    PROV_DIGEST digest;
+    unsigned char *secret;
+    size_t secret_len;
+    int cek_nid;
+    unsigned char *ukm;
+    size_t ukm_len;
+    size_t dkm_len;
+} KDF_X942;
+
+/* A table of allowed wrapping algorithms and the associated output lengths */
+static const struct {
+    int nid;
+    size_t keklen; /* size in bytes */
+} kek_algs[] = {
+    { NID_id_smime_alg_CMS3DESwrap, 24 },
+    { NID_id_smime_alg_CMSRC2wrap, 16 },
+    { NID_id_aes128_wrap, 16 },
+    { NID_id_aes192_wrap, 24 },
+    { NID_id_aes256_wrap, 32 },
+    { NID_id_camellia128_wrap, 16 },
+    { NID_id_camellia192_wrap, 24 },
+    { NID_id_camellia256_wrap, 32 }
+};
+
+/* Skip past an ASN1 structure: for OBJECT skip content octets too */
+static int skip_asn1(unsigned char **pp, long *plen, int exptag)
+{
+    int i, tag, xclass;
+    long tmplen;
+    const unsigned char *q = *pp;
+
+    i = ASN1_get_object(&q, &tmplen, &tag, &xclass, *plen);
+    if ((i & 0x80) != 0 || tag != exptag || xclass != V_ASN1_UNIVERSAL)
+        return 0;
+    if (tag == V_ASN1_OBJECT)
+        q += tmplen;
+    *pp = (unsigned char *)q;
+    *plen -= q - *pp;
+    return 1;
+}
+
+/*
+ * Encode the other info structure.
+ *
+ *  RFC2631 Section 2.1.2 Contains the following definition for otherinfo
+ *
+ *  OtherInfo ::= SEQUENCE {
+ *      keyInfo KeySpecificInfo,
+ *      partyAInfo [0] OCTET STRING OPTIONAL,
+ *      suppPubInfo [2] OCTET STRING
+ *  }
+ *
+ *  KeySpecificInfo ::= SEQUENCE {
+ *      algorithm OBJECT IDENTIFIER,
+ *      counter OCTET STRING SIZE (4..4)
+ *  }
+ *
+ * |nid| is the algorithm object identifier.
+ * |keylen| is the length (in bytes) of the generated KEK. It is stored into
+ * suppPubInfo (in bits).
+ * |ukm| is the optional user keying material that is stored into partyAInfo. It
+ * can be NULL.
+ * |ukmlen| is the user keying material length (in bytes).
+ * |der| is the returned encoded data. It must be freed by the caller.
+ * |der_len| is the returned size of the encoded data.
+ * |out_ctr| returns a pointer to the counter data which is embedded inside the
+ * encoded data. This allows the counter bytes to be updated without re-encoding.
+ *
+ * Returns: 1 if successfully encoded, or 0 otherwise.
+ * Assumptions: |der|, |der_len| & |out_ctr| are not NULL.
+ */
+static int x942_encode_otherinfo(int nid, size_t keylen,
+                                 const unsigned char *ukm, size_t ukmlen,
+                                 unsigned char **der, size_t *der_len,
+                                 unsigned char **out_ctr)
+{
+    unsigned char *p, *encoded = NULL;
+    int ret = 0, encoded_len;
+    long tlen;
+    /* "magic" value to check offset is sane */
+    static unsigned char ctr[4] = { 0x00, 0x00, 0x00, 0x01 };
+    X509_ALGOR *ksi = NULL;
+    ASN1_OBJECT *alg_oid = NULL;
+    ASN1_OCTET_STRING *ctr_oct = NULL, *ukm_oct = NULL;
+
+    /* set the KeySpecificInfo - which contains an algorithm oid and counter */
+    ksi = X509_ALGOR_new();
+    alg_oid = OBJ_dup(OBJ_nid2obj(nid));
+    ctr_oct = ASN1_OCTET_STRING_new();
+    if (ksi == NULL
+        || alg_oid == NULL
+        || ctr_oct == NULL
+        || !ASN1_OCTET_STRING_set(ctr_oct, ctr, sizeof(ctr))
+        || !X509_ALGOR_set0(ksi, alg_oid, V_ASN1_OCTET_STRING, ctr_oct))
+        goto err;
+    /* NULL these as they now belong to ksi */
+    alg_oid = NULL;
+    ctr_oct = NULL;
+
+    /* Set the optional partyAInfo */
+    if (ukm != NULL) {
+        ukm_oct = ASN1_OCTET_STRING_new();
+        if (ukm_oct == NULL)
+            goto err;
+        ASN1_OCTET_STRING_set(ukm_oct, (unsigned char *)ukm, ukmlen);
+    }
+    /* Generate the OtherInfo DER data */
+    encoded_len = CMS_SharedInfo_encode(&encoded, ksi, ukm_oct, keylen);
+    if (encoded_len <= 0)
+        goto err;
+
+    /* Parse the encoded data to find the offset of the counter data */
+    p = encoded;
+    tlen = (long)encoded_len;
+    if (skip_asn1(&p, &tlen, V_ASN1_SEQUENCE)
+        && skip_asn1(&p, &tlen, V_ASN1_SEQUENCE)
+        && skip_asn1(&p, &tlen, V_ASN1_OBJECT)
+        && skip_asn1(&p, &tlen, V_ASN1_OCTET_STRING)
+        && CRYPTO_memcmp(p, ctr, 4) == 0) {
+        *out_ctr = p;
+        *der = encoded;
+        *der_len = (size_t)encoded_len;
+        ret = 1;
+    }
+err:
+    if (ret != 1)
+        OPENSSL_free(encoded);
+    ASN1_OCTET_STRING_free(ctr_oct);
+    ASN1_OCTET_STRING_free(ukm_oct);
+    ASN1_OBJECT_free(alg_oid);
+    X509_ALGOR_free(ksi);
+    return ret;
+}
+
+static int x942kdf_hash_kdm(const EVP_MD *kdf_md,
+                            const unsigned char *z, size_t z_len,
+                            const unsigned char *other, size_t other_len,
+                            unsigned char *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 mac[EVP_MAX_MD_SIZE];
+    unsigned char *out = derived_key;
+    EVP_MD_CTX *ctx = NULL, *ctx_init = NULL;
+
+    if (z_len > X942KDF_MAX_INLEN || other_len > X942KDF_MAX_INLEN
+            || derived_key_len > X942KDF_MAX_INLEN
+            || derived_key_len == 0) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH);
+        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++) {
+        /* updating the ctr modifies 4 bytes in the 'other' buffer */
+        ctr[0] = (unsigned char)((counter >> 24) & 0xff);
+        ctr[1] = (unsigned char)((counter >> 16) & 0xff);
+        ctr[2] = (unsigned char)((counter >> 8) & 0xff);
+        ctr[3] = (unsigned char)(counter & 0xff);
+
+        if (!EVP_MD_CTX_copy_ex(ctx, ctx_init)
+            || !EVP_DigestUpdate(ctx, z, z_len)
+            || !EVP_DigestUpdate(ctx, other, other_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_free(ctx);
+    EVP_MD_CTX_free(ctx_init);
+    OPENSSL_cleanse(mac, sizeof(mac));
+    return ret;
+}
+
+static void *x942kdf_new(void *provctx)
+{
+    KDF_X942 *ctx;
+
+    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL)
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+    ctx->provctx = provctx;
+    return ctx;
+}
+
+static void x942kdf_reset(void *vctx)
+{
+    KDF_X942 *ctx = (KDF_X942 *)vctx;
+
+    ossl_prov_digest_reset(&ctx->digest);
+    OPENSSL_clear_free(ctx->secret, ctx->secret_len);
+    OPENSSL_clear_free(ctx->ukm, ctx->ukm_len);
+    memset(ctx, 0, sizeof(*ctx));
+}
+
+static void x942kdf_free(void *vctx)
+{
+    KDF_X942 *ctx = (KDF_X942 *)vctx;
+
+    x942kdf_reset(ctx);
+    OPENSSL_free(ctx);
+}
+
+static int x942kdf_set_buffer(unsigned char **out, size_t *out_len,
+                              const OSSL_PARAM *p)
+{
+    if (p->data_size == 0 || p->data == NULL)
+        return 1;
+
+    OPENSSL_free(*out);
+    *out = NULL;
+    return OSSL_PARAM_get_octet_string(p, (void **)out, 0, out_len);
+}
+
+static size_t x942kdf_size(KDF_X942 *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 x942kdf_derive(void *vctx, unsigned char *key, size_t keylen)
+{
+    KDF_X942 *ctx = (KDF_X942 *)vctx;
+    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
+    int ret = 0;
+    unsigned char *ctr;
+    unsigned char *der = NULL;
+    size_t der_len = 0;
+
+    if (ctx->secret == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);
+        return 0;
+    }
+    if (md == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
+        return 0;
+    }
+    if (ctx->cek_nid == NID_undef) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CEK_ALG);
+        return 0;
+    }
+    if (ctx->ukm != NULL && ctx->ukm_len >= X942KDF_MAX_INLEN) {
+        /*
+         * Note the ukm length MUST be 512 bits.
+         * For backwards compatibility the old check is being done.
+         */
+        ERR_raise(ERR_LIB_PROV, PROV_R_INAVLID_UKM_LENGTH);
+        return 0;
+    }
+    if (keylen != ctx->dkm_len) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CEK_ALG);
+        return 0;
+    }
+    /* generate the otherinfo der */
+    if (!x942_encode_otherinfo(ctx->cek_nid, ctx->dkm_len,
+                               ctx->ukm, ctx->ukm_len,
+                               &der, &der_len, &ctr)) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_BAD_ENCODING);
+        return 0;
+    }
+    ret = x942kdf_hash_kdm(md, ctx->secret, ctx->secret_len,
+                           der, der_len, ctr, key, keylen);
+    OPENSSL_free(der);
+    return ret;
+}
+
+static int x942kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    const OSSL_PARAM *p;
+    KDF_X942 *ctx = vctx;
+    OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
+    size_t i;
+
+    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
+        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 (!x942kdf_set_buffer(&ctx->secret, &ctx->secret_len, p))
+            return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_UKM)) != NULL)
+        if (!x942kdf_set_buffer(&ctx->ukm, &ctx->ukm_len, p))
+            return 0;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_CEK_ALG)) != NULL) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+            return 0;
+        ctx->cek_nid = OBJ_sn2nid(p->data);
+        for (i = 0; i < OSSL_NELEM(kek_algs); i++)
+            if (kek_algs[i].nid == ctx->cek_nid)
+                goto cek_found;
+        ERR_raise(ERR_LIB_PROV, PROV_R_UNSUPPORTED_CEK_ALG);
+        return 0;
+cek_found:
+        ctx->dkm_len = kek_algs[i].keklen;
+    }
+    return 1;
+}
+
+static const OSSL_PARAM *x942kdf_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_KEY, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_UKM, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0),
+        OSSL_PARAM_END
+    };
+    return known_settable_ctx_params;
+}
+
+static int x942kdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+    KDF_X942 *ctx = (KDF_X942 *)vctx;
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, x942kdf_size(ctx));
+    return -2;
+}
+
+static const OSSL_PARAM *x942kdf_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_x942_kdf_functions[] = {
+    { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))x942kdf_new },
+    { OSSL_FUNC_KDF_FREECTX, (void(*)(void))x942kdf_free },
+    { OSSL_FUNC_KDF_RESET, (void(*)(void))x942kdf_reset },
+    { OSSL_FUNC_KDF_DERIVE, (void(*)(void))x942kdf_derive },
+    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
+      (void(*)(void))x942kdf_settable_ctx_params },
+    { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))x942kdf_set_ctx_params },
+    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
+      (void(*)(void))x942kdf_gettable_ctx_params },
+    { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))x942kdf_get_ctx_params },
+    { 0, NULL }
+};
+
+#endif /* OPENSSL_NO_CMS */
diff --git a/providers/implementations/macs/blake2_mac_impl.c b/providers/implementations/macs/blake2_mac_impl.c
new file mode 100644 (file)
index 0000000..a190b91
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * 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 "internal/blake2.h"
+#include "internal/cryptlib.h"
+#include "internal/providercommonerr.h"
+#include "internal/provider_algs.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 blake2_mac_new;
+static OSSL_OP_mac_dupctx_fn blake2_mac_dup;
+static OSSL_OP_mac_freectx_fn blake2_mac_free;
+static OSSL_OP_mac_gettable_ctx_params_fn blake2_gettable_ctx_params;
+static OSSL_OP_mac_get_ctx_params_fn blake2_get_ctx_params;
+static OSSL_OP_mac_settable_ctx_params_fn blake2_mac_settable_ctx_params;
+static OSSL_OP_mac_set_ctx_params_fn blake2_mac_set_ctx_params;
+static OSSL_OP_mac_init_fn blake2_mac_init;
+static OSSL_OP_mac_update_fn blake2_mac_update;
+static OSSL_OP_mac_final_fn blake2_mac_final;
+
+struct blake2_mac_data_st {
+    BLAKE2_CTX ctx;
+    BLAKE2_PARAM params;
+    unsigned char key[BLAKE2_KEYBYTES];
+};
+
+static size_t blake2_mac_size(void *vmacctx);
+
+static void *blake2_mac_new(void *unused_provctx)
+{
+    struct blake2_mac_data_st *macctx = OPENSSL_zalloc(sizeof(*macctx));
+
+    if (macctx != NULL) {
+        BLAKE2_PARAM_INIT(&macctx->params);
+        /* ctx initialization is deferred to BLAKE2b_Init() */
+    }
+    return macctx;
+}
+
+static void *blake2_mac_dup(void *vsrc)
+{
+    struct blake2_mac_data_st *dst;
+    struct blake2_mac_data_st *src = vsrc;
+
+    dst = OPENSSL_zalloc(sizeof(*dst));
+    if (dst == NULL)
+        return NULL;
+
+    *dst = *src;
+    return dst;
+}
+
+static void blake2_mac_free(void *vmacctx)
+{
+    struct blake2_mac_data_st *macctx = vmacctx;
+
+    if (macctx != NULL) {
+        OPENSSL_cleanse(macctx->key, sizeof(macctx->key));
+        OPENSSL_free(macctx);
+    }
+}
+
+static int blake2_mac_init(void *vmacctx)
+{
+    struct blake2_mac_data_st *macctx = vmacctx;
+
+    /* Check key has been set */
+    if (macctx->params.key_length == 0) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
+        return 0;
+    }
+
+    return BLAKE2_INIT_KEY(&macctx->ctx, &macctx->params, macctx->key);
+}
+
+static int blake2_mac_update(void *vmacctx,
+                             const unsigned char *data, size_t datalen)
+{
+    struct blake2_mac_data_st *macctx = vmacctx;
+
+    return BLAKE2_UPDATE(&macctx->ctx, data, datalen);
+}
+
+static int blake2_mac_final(void *vmacctx,
+                            unsigned char *out, size_t *outl,
+                            size_t outsize)
+{
+    struct blake2_mac_data_st *macctx = vmacctx;
+
+    return BLAKE2_FINAL(out, &macctx->ctx);
+}
+
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *blake2_gettable_ctx_params(void)
+{
+    return known_gettable_ctx_params;
+}
+
+static int blake2_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, blake2_mac_size(vmacctx));
+
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    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_octet_string(OSSL_MAC_PARAM_SALT, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *blake2_mac_settable_ctx_params()
+{
+    return known_settable_ctx_params;
+}
+
+/*
+ * ALL parameters should be set before init().
+ */
+static int blake2_mac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[])
+{
+    struct blake2_mac_data_st *macctx = vmacctx;
+    const OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE)) != NULL) {
+        size_t size;
+
+        if (!OSSL_PARAM_get_size_t(p, &size)
+            || size < 1
+            || size > BLAKE2_OUTBYTES) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_XOF_OR_INVALID_LENGTH);
+            return 0;
+        }
+        BLAKE2_PARAM_SET_DIGEST_LENGTH(&macctx->params, (uint8_t)size);
+    }
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
+        size_t len;
+        void *key_p = macctx->key;
+
+        if (!OSSL_PARAM_get_octet_string(p, &key_p, BLAKE2_KEYBYTES, &len)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+        /* Pad with zeroes at the end */
+        memset(macctx->key + len, 0, BLAKE2_KEYBYTES - len);
+
+        BLAKE2_PARAM_SET_KEY_LENGTH(&macctx->params, (uint8_t)len);
+    }
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_CUSTOM))
+        != NULL) {
+        /*
+         * The OSSL_PARAM API doesn't provide direct pointer use, so we
+         * must handle the OSSL_PARAM structure ourselves here
+         */
+        if (p->data_size > BLAKE2_PERSONALBYTES) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CUSTOM_LENGTH);
+            return 0;
+        }
+        BLAKE2_PARAM_SET_PERSONAL(&macctx->params, p->data, p->data_size);
+    }
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SALT)) != NULL) {
+        /*
+         * The OSSL_PARAM API doesn't provide direct pointer use, so we
+         * must handle the OSSL_PARAM structure ourselves here as well
+         */
+        if (p->data_size > BLAKE2_SALTBYTES) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
+            return 0;
+        }
+        BLAKE2_PARAM_SET_SALT(&macctx->params, p->data, p->data_size);
+    }
+    return 1;
+}
+
+static size_t blake2_mac_size(void *vmacctx)
+{
+    struct blake2_mac_data_st *macctx = vmacctx;
+
+    return macctx->params.digest_length;
+}
+
+const OSSL_DISPATCH BLAKE2_FUNCTIONS[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))blake2_mac_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))blake2_mac_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))blake2_mac_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))blake2_mac_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))blake2_mac_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))blake2_mac_final },
+    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
+      (void (*)(void))blake2_gettable_ctx_params },
+    { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))blake2_get_ctx_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))blake2_mac_settable_ctx_params },
+    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))blake2_mac_set_ctx_params },
+    { 0, NULL }
+};
diff --git a/providers/implementations/macs/blake2b_mac.c b/providers/implementations/macs/blake2b_mac.c
new file mode 100644 (file)
index 0000000..aa1a8de
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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
+ */
+
+/* Constants */
+#define BLAKE2_CTX BLAKE2B_CTX
+#define BLAKE2_PARAM BLAKE2B_PARAM
+#define BLAKE2_KEYBYTES BLAKE2B_KEYBYTES
+#define BLAKE2_OUTBYTES BLAKE2B_OUTBYTES
+#define BLAKE2_PERSONALBYTES BLAKE2B_PERSONALBYTES
+#define BLAKE2_SALTBYTES BLAKE2B_SALTBYTES
+
+/* Function names */
+#define BLAKE2_PARAM_INIT blake2b_param_init
+#define BLAKE2_INIT_KEY blake2b_init_key
+#define BLAKE2_UPDATE blake2b_update
+#define BLAKE2_FINAL blake2b_final
+#define BLAKE2_PARAM_SET_DIGEST_LENGTH blake2b_param_set_digest_length
+#define BLAKE2_PARAM_SET_KEY_LENGTH blake2b_param_set_key_length
+#define BLAKE2_PARAM_SET_PERSONAL blake2b_param_set_personal
+#define BLAKE2_PARAM_SET_SALT blake2b_param_set_salt
+
+/* OSSL_DISPATCH symbol */
+#define BLAKE2_FUNCTIONS blake2bmac_functions
+
+#include "blake2_mac_impl.c"
+
diff --git a/providers/implementations/macs/blake2s_mac.c b/providers/implementations/macs/blake2s_mac.c
new file mode 100644 (file)
index 0000000..ccd7035
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+/* Constants */
+#define BLAKE2_CTX BLAKE2S_CTX
+#define BLAKE2_PARAM BLAKE2S_PARAM
+#define BLAKE2_KEYBYTES BLAKE2S_KEYBYTES
+#define BLAKE2_OUTBYTES BLAKE2S_OUTBYTES
+#define BLAKE2_PERSONALBYTES BLAKE2S_PERSONALBYTES
+#define BLAKE2_SALTBYTES BLAKE2S_SALTBYTES
+
+/* Function names */
+#define BLAKE2_PARAM_INIT blake2s_param_init
+#define BLAKE2_INIT_KEY blake2s_init_key
+#define BLAKE2_UPDATE blake2s_update
+#define BLAKE2_FINAL blake2s_final
+#define BLAKE2_PARAM_SET_DIGEST_LENGTH blake2s_param_set_digest_length
+#define BLAKE2_PARAM_SET_KEY_LENGTH blake2s_param_set_key_length
+#define BLAKE2_PARAM_SET_PERSONAL blake2s_param_set_personal
+#define BLAKE2_PARAM_SET_SALT blake2s_param_set_salt
+
+/* OSSL_DISPATCH symbol */
+#define BLAKE2_FUNCTIONS blake2smac_functions
+
+#include "blake2_mac_impl.c"
index d4538098e0e6b8816cbad079154a46136856206a..07c40d354bddb7964badc2689431f8f91945903c 100644 (file)
@@ -5,6 +5,9 @@ $GMAC_GOAL=../../libimplementations.a
 $HMAC_GOAL=../../libimplementations.a
 $KMAC_GOAL=../../libimplementations.a
 $CMAC_GOAL=../../libimplementations.a
+$BLAKE2_GOAL=../../libimplementations.a
+$SIPHASH_GOAL=../../libimplementations.a
+$POLY1305_GOAL=../../libimplementations.a
 
 SOURCE[$GMAC_GOAL]=gmac_prov.c
 SOURCE[$HMAC_GOAL]=hmac_prov.c
@@ -13,3 +16,17 @@ SOURCE[$KMAC_GOAL]=kmac_prov.c
 IF[{- !$disabled{cmac} -}]
   SOURCE[$CMAC_GOAL]=cmac_prov.c
 ENDIF
+
+$GOAL=../../libimplementations.a
+
+IF[{- !$disabled{blake2} -}]
+  SOURCE[$BLAKE2_GOAL]=blake2b_mac.c blake2s_mac.c
+ENDIF
+
+IF[{- !$disabled{siphash} -}]
+  SOURCE[$SIPHASH_GOAL]=siphash_prov.c
+ENDIF
+
+IF[{- !$disabled{poly1305} -}]
+  SOURCE[$POLY1305_GOAL]=poly1305_prov.c
+ENDIF
diff --git a/providers/implementations/macs/poly1305_prov.c b/providers/implementations/macs/poly1305_prov.c
new file mode 100644 (file)
index 0000000..8800571
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * 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/evp.h>
+#include <openssl/err.h>
+
+#include "crypto/poly1305.h"
+/*
+ * TODO(3.0) when poly1305 has moved entirely to our providers, this
+ * header should be moved to the provider include directory.  For the
+ * moment, crypto/poly1305/poly1305_ameth.c has us stuck.
+ */
+#include "../../../crypto/poly1305/poly1305_local.h"
+
+#include "internal/providercommonerr.h"
+#include "internal/provider_algs.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 poly1305_new;
+static OSSL_OP_mac_dupctx_fn poly1305_dup;
+static OSSL_OP_mac_freectx_fn poly1305_free;
+static OSSL_OP_mac_gettable_params_fn poly1305_gettable_params;
+static OSSL_OP_mac_get_params_fn poly1305_get_params;
+static OSSL_OP_mac_settable_ctx_params_fn poly1305_settable_ctx_params;
+static OSSL_OP_mac_set_ctx_params_fn poly1305_set_ctx_params;
+static OSSL_OP_mac_init_fn poly1305_init;
+static OSSL_OP_mac_update_fn poly1305_update;
+static OSSL_OP_mac_final_fn poly1305_final;
+
+struct poly1305_data_st {
+    void *provctx;
+    POLY1305 poly1305;           /* Poly1305 data */
+};
+
+static size_t poly1305_size(void);
+
+static void *poly1305_new(void *provctx)
+{
+    struct poly1305_data_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    ctx->provctx = provctx;
+    return ctx;
+}
+
+static void poly1305_free(void *vmacctx)
+{
+    OPENSSL_free(vmacctx);
+}
+
+static void *poly1305_dup(void *vsrc)
+{
+    struct poly1305_data_st *src = vsrc;
+    struct poly1305_data_st *dst = poly1305_new(src->provctx);
+
+    if (dst == NULL)
+        return NULL;
+
+    dst->poly1305 = src->poly1305;
+    return dst;
+}
+
+static size_t poly1305_size(void)
+{
+    return POLY1305_DIGEST_SIZE;
+}
+
+static int poly1305_init(void *vmacctx)
+{
+    /* initialize the context in MAC_ctrl function */
+    return 1;
+}
+
+static int poly1305_update(void *vmacctx, const unsigned char *data,
+                       size_t datalen)
+{
+    struct poly1305_data_st *ctx = vmacctx;
+
+    /* poly1305 has nothing to return in its update function */
+    Poly1305_Update(&ctx->poly1305, data, datalen);
+    return 1;
+}
+
+static int poly1305_final(void *vmacctx, unsigned char *out, size_t *outl,
+                          size_t outsize)
+{
+    struct poly1305_data_st *ctx = vmacctx;
+
+    Poly1305_Final(&ctx->poly1305, out);
+    return 1;
+}
+
+static const OSSL_PARAM known_gettable_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *poly1305_gettable_params(void)
+{
+    return known_gettable_params;
+}
+
+static int poly1305_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, poly1305_size());
+
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *poly1305_settable_ctx_params(void)
+{
+    return known_settable_ctx_params;
+}
+
+static int poly1305_set_ctx_params(void *vmacctx, const OSSL_PARAM *params)
+{
+    struct poly1305_data_st *ctx = vmacctx;
+    const OSSL_PARAM *p = NULL;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
+        if (p->data_type != OSSL_PARAM_OCTET_STRING
+            || p->data_size != POLY1305_KEY_SIZE) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+        Poly1305_Init(&ctx->poly1305, p->data);
+    }
+    return 1;
+}
+
+const OSSL_DISPATCH poly1305_functions[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))poly1305_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))poly1305_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))poly1305_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))poly1305_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))poly1305_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))poly1305_final },
+    { OSSL_FUNC_MAC_GETTABLE_PARAMS, (void (*)(void))poly1305_gettable_params },
+    { OSSL_FUNC_MAC_GET_PARAMS, (void (*)(void))poly1305_get_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))poly1305_settable_ctx_params },
+    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))poly1305_set_ctx_params },
+    { 0, NULL }
+};
diff --git a/providers/implementations/macs/siphash_prov.c b/providers/implementations/macs/siphash_prov.c
new file mode 100644 (file)
index 0000000..a951192
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * 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 <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 "crypto/siphash.h"
+/*
+ * TODO(3.0) when siphash has moved entirely to our providers, this
+ * header should be moved to the provider include directory.  For the
+ * moment, crypto/siphash/siphash_ameth.c has us stuck.
+ */
+#include "../../../crypto/siphash/siphash_local.h"
+
+#include "internal/providercommonerr.h"
+#include "internal/provider_algs.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 siphash_new;
+static OSSL_OP_mac_dupctx_fn siphash_dup;
+static OSSL_OP_mac_freectx_fn siphash_free;
+static OSSL_OP_mac_gettable_ctx_params_fn siphash_gettable_ctx_params;
+static OSSL_OP_mac_get_ctx_params_fn siphash_get_ctx_params;
+static OSSL_OP_mac_settable_ctx_params_fn siphash_settable_params;
+static OSSL_OP_mac_set_ctx_params_fn siphash_set_params;
+static OSSL_OP_mac_size_fn siphash_size;
+static OSSL_OP_mac_init_fn siphash_init;
+static OSSL_OP_mac_update_fn siphash_update;
+static OSSL_OP_mac_final_fn siphash_final;
+
+struct siphash_data_st {
+    void *provctx;
+    SIPHASH siphash;             /* Siphash data */
+};
+
+static void *siphash_new(void *provctx)
+{
+    struct siphash_data_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    ctx->provctx = provctx;
+    return ctx;
+}
+
+static void siphash_free(void *vmacctx)
+{
+    OPENSSL_free(vmacctx);
+}
+
+static void *siphash_dup(void *vsrc)
+{
+    struct siphash_data_st *ssrc = vsrc;
+    struct siphash_data_st *sdst = siphash_new(ssrc->provctx);
+
+    if (sdst == NULL)
+        return NULL;
+
+    sdst->siphash = ssrc->siphash;
+    return sdst;
+}
+
+static size_t siphash_size(void *vmacctx)
+{
+    struct siphash_data_st *ctx = vmacctx;
+
+    return SipHash_hash_size(&ctx->siphash);
+}
+
+static int siphash_init(void *vmacctx)
+{
+    /* Not much to do here, actual initialization happens through controls */
+    return 1;
+}
+
+static int siphash_update(void *vmacctx, const unsigned char *data,
+                       size_t datalen)
+{
+    struct siphash_data_st *ctx = vmacctx;
+
+    SipHash_Update(&ctx->siphash, data, datalen);
+    return 1;
+}
+
+static int siphash_final(void *vmacctx, unsigned char *out, size_t *outl,
+                         size_t outsize)
+{
+    struct siphash_data_st *ctx = vmacctx;
+    size_t hlen = siphash_size(ctx);
+
+    if (outsize < hlen)
+        return 0;
+
+    *outl = hlen;
+    return SipHash_Final(&ctx->siphash, out, hlen);
+}
+
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *siphash_gettable_ctx_params(void)
+{
+    return known_gettable_ctx_params;
+}
+
+static int siphash_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, siphash_size(vmacctx));
+
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *siphash_settable_params(void)
+{
+    return known_settable_ctx_params;
+}
+
+static int siphash_set_params(void *vmacctx, const OSSL_PARAM *params)
+{
+    struct siphash_data_st *ctx = vmacctx;
+    const OSSL_PARAM *p = NULL;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE)) != NULL) {
+        size_t size;
+
+        if (!OSSL_PARAM_get_size_t(p, &size)
+            || !SipHash_set_hash_size(&ctx->siphash, size))
+            return 0;
+    }
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL)
+        if (p->data_type != OSSL_PARAM_OCTET_STRING
+            || p->data_size != SIPHASH_KEY_SIZE
+            || !SipHash_Init(&ctx->siphash, p->data, 0, 0))
+            return 0;
+    return 1;
+}
+
+const OSSL_DISPATCH siphash_functions[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))siphash_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))siphash_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))siphash_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))siphash_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))siphash_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))siphash_final },
+    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
+      (void (*)(void))siphash_gettable_ctx_params },
+    { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))siphash_get_ctx_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))siphash_settable_params },
+    { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))siphash_set_params },
+    { 0, NULL }
+};