mirror of https://github.com/openssl/openssl.git
1826 lines
52 KiB
C
1826 lines
52 KiB
C
/*
|
|
* Copyright 2025 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
|
|
*/
|
|
|
|
/**
|
|
* @file p_ossltest.c
|
|
* @brief a test provider for use in several of our unit tests
|
|
*
|
|
* This file implements a provider that goes through the motions of implementing
|
|
* various algorithms, but then discards the actual results of that work in favor
|
|
* of predictable return data for the purposes of having known data to compare against
|
|
* in our various tls tests.
|
|
*
|
|
* It implements the following algorithms
|
|
*
|
|
* The AES-128-CBC cipher
|
|
* The AES-128-GCM cipher
|
|
* The AES-128-CBC-HMAC-SHA1 cipher
|
|
* The MD5 digest
|
|
* The SHA1, SHA256, SHA384 and SHA512 digests
|
|
* The CTR-DRBG random number generator
|
|
*
|
|
* Note that the implementations of the above algorithms are designed not to
|
|
* actually follow the prescribed algorithms themselves, but rather just to
|
|
* returns known/predictable data values for the purposes of testing. As such
|
|
* DO NOT USE THIS PROVIDER FOR ANY PRODUCTION PURPOSE. TESTING ONLY!!!!
|
|
*
|
|
* The digests all return incremental data in accordance with the size of their message
|
|
* digest
|
|
*
|
|
* The ciphers all return data that is a copy of their input plaintext, padded and augmented
|
|
* according to the specific ciphers needs
|
|
*
|
|
* The random number generator just returns incremental data of the requested size
|
|
*/
|
|
#include "internal/deprecated.h"
|
|
|
|
#include <openssl/core_dispatch.h>
|
|
#include <openssl/core_names.h>
|
|
#include <openssl/params.h>
|
|
#include <openssl/rand.h> /* RAND_get0_public() */
|
|
#include <openssl/proverr.h>
|
|
#include <openssl/md5.h>
|
|
#include <openssl/sha.h>
|
|
#include <openssl/prov_ssl.h>
|
|
#include "prov/provider_ctx.h"
|
|
#include "prov/digestcommon.h"
|
|
#include "prov/ciphercommon.h"
|
|
#include "prov/names.h"
|
|
#include "prov/implementations.h"
|
|
#include "ciphers/cipher_aes.h"
|
|
#include "internal/cryptlib.h"
|
|
#include "internal/provider.h"
|
|
#include "crypto/context.h"
|
|
#include "internal/core.h"
|
|
|
|
/**
|
|
* @brief Release resources and clean up the context.
|
|
*
|
|
* @param provctx void *provctx.
|
|
* @return void.
|
|
*/
|
|
|
|
static void ossltest_teardown(void *provctx)
|
|
{
|
|
OSSL_LIB_CTX_free(PROV_LIBCTX_OF(provctx));
|
|
ossl_prov_ctx_free(provctx);
|
|
}
|
|
|
|
static const OSSL_PARAM ossltest_param_types[] = {
|
|
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0),
|
|
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0),
|
|
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0),
|
|
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0),
|
|
OSSL_PARAM_END
|
|
};
|
|
|
|
/**
|
|
* @brief Describe parameters that can be queried.
|
|
*
|
|
* Just returns the standard provider query-able parameters
|
|
* OSSL_PROV_PARAM_NAME - The name of our provider
|
|
* OSSL_PROV_PARAM_VERSION - The version of this provider build
|
|
* OSSL_PROV_PARAM_BUILDINFO - The configuration it was built with
|
|
* OSSL_PROV_PARAM_STATUS - Weather or not its currently activated
|
|
*
|
|
* @param provctx void *provctx.
|
|
* @return const OSSL_PARAM *.
|
|
*/
|
|
|
|
static const OSSL_PARAM *ossltest_gettable_params(void *provctx)
|
|
{
|
|
return ossltest_param_types;
|
|
}
|
|
|
|
/**
|
|
* @brief Return provider parameters.
|
|
*
|
|
* @param provctx void *provctx.
|
|
* @param params OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossltest_get_params(void *provctx, OSSL_PARAM params[])
|
|
{
|
|
OSSL_PARAM *p;
|
|
|
|
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME);
|
|
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "OpenSSL ossltest Provider"))
|
|
return 0;
|
|
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_VERSION);
|
|
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR))
|
|
return 0;
|
|
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO);
|
|
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_FULL_VERSION_STR))
|
|
return 0;
|
|
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS);
|
|
if (p != NULL && !OSSL_PARAM_set_int(p, ossl_prov_is_running()))
|
|
return 0;
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Fill a buffer with deterministic test bytes.
|
|
*
|
|
* @param md unsigned char *md.
|
|
* @param len unsigned int len.
|
|
* @return void.
|
|
*/
|
|
|
|
static void fill_known_data(unsigned char *md, unsigned int len)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < len; i++)
|
|
md[i] = (unsigned char)(i & 0xff);
|
|
}
|
|
|
|
/**
|
|
* @brief Initialize the context state for our digests.
|
|
*
|
|
* Because all our digests return known data in this provider
|
|
* this can just be a no-op function. Its used for each digest we support
|
|
*
|
|
* @param ctx void *ctx.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossltest_dgst_init(void *ctx)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Process input data to update the digest state.
|
|
* Since this provider returns fixed data for each digest
|
|
* we don't actually have to do any work here, just return 1.
|
|
* This is used for all our provided digests
|
|
*
|
|
* @param ctx void *ctx.
|
|
* @param data const void *data.
|
|
* @param count size_t count.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossltest_dgst_update(void *ctx, const void *data,
|
|
size_t count)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Finalize the digest output.
|
|
*
|
|
* provide pre-set data (increasing count) for the MD5 DIGEST
|
|
*
|
|
* @param md unsigned char *md.
|
|
* @param ctx void *ctx.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossltest_MD5_final(unsigned char *md, void *ctx)
|
|
{
|
|
fill_known_data(md, MD5_DIGEST_LENGTH);
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Finalize the digest output.
|
|
*
|
|
* provide pre-set data (increasing count) for the SHA1 DIGEST
|
|
*
|
|
* @param md unsigned char *md.
|
|
* @param ctx void *ctx.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossltest_SHA1_final(unsigned char *md, void *ctx)
|
|
{
|
|
fill_known_data(md, SHA_DIGEST_LENGTH);
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Finalize the digest output.
|
|
*
|
|
* provide pre-set data (increasing count) for the SHA256 DIGEST
|
|
*
|
|
* @param md unsigned char *md.
|
|
* @param ctx void *ctx.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossltest_SHA256_final(unsigned char *md, void *ctx)
|
|
{
|
|
fill_known_data(md, SHA256_DIGEST_LENGTH);
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Finalize the digest output.
|
|
*
|
|
* provide pre-set data (increasing count) for the SHA384 DIGEST
|
|
*
|
|
* @param md unsigned char *md.
|
|
* @param ctx void *ctx.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossltest_SHA384_final(unsigned char *md, void *ctx)
|
|
{
|
|
fill_known_data(md, SHA384_DIGEST_LENGTH);
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Finalize the digest output.
|
|
*
|
|
* provide pre-set data (increasing count) for the SHA512 DIGEST
|
|
*
|
|
* @param md unsigned char *md.
|
|
* @param ctx void *ctx.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossltest_SHA512_final(unsigned char *md, void *ctx)
|
|
{
|
|
fill_known_data(md, SHA512_DIGEST_LENGTH);
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* NOTE: These externs are just here to make the compiler happy
|
|
* The IMPLEMENT_digest_functions macros below define these arrays
|
|
* as non-static so that real providers can pick them up in other C files
|
|
* And they get externed in other header files. But we only use them internally
|
|
* to this provider here. To avoid having to re-implement and co-ordinate the below
|
|
* macros in what is already a large C file, just define them as extern to prevent some
|
|
* compilers from complaining about a non-static definition with no prior extern declaration
|
|
* mark them as such here. They won't get exported anyway as p_ossltest only gets built as
|
|
* a DSO, and the linker map we use doesn't list them as exported
|
|
*/
|
|
extern const OSSL_DISPATCH ossl_testmd5_functions[];
|
|
extern const OSSL_DISPATCH ossl_testsha1_functions[];
|
|
extern const OSSL_DISPATCH ossl_testsha256_functions[];
|
|
extern const OSSL_DISPATCH ossl_testsha384_functions[];
|
|
extern const OSSL_DISPATCH ossl_testsha512_functions[];
|
|
|
|
IMPLEMENT_digest_functions(testmd5, MD5_CTX, MD5_CBLOCK, MD5_DIGEST_LENGTH, 0,
|
|
ossltest_dgst_init, ossltest_dgst_update, ossltest_MD5_final)
|
|
|
|
#define SHA2_FLAGS PROV_DIGEST_FLAG_ALGID_ABSENT
|
|
IMPLEMENT_digest_functions(testsha1, SHA_CTX, SHA_CBLOCK, SHA_DIGEST_LENGTH, SHA2_FLAGS,
|
|
ossltest_dgst_init, ossltest_dgst_update, ossltest_SHA1_final)
|
|
|
|
IMPLEMENT_digest_functions(testsha256, SHA256_CTX,
|
|
SHA256_CBLOCK, SHA256_DIGEST_LENGTH, SHA2_FLAGS,
|
|
ossltest_dgst_init, ossltest_dgst_update, ossltest_SHA256_final)
|
|
|
|
IMPLEMENT_digest_functions(testsha384, SHA512_CTX,
|
|
SHA512_CBLOCK, SHA512_DIGEST_LENGTH, SHA2_FLAGS,
|
|
ossltest_dgst_init, ossltest_dgst_update, ossltest_SHA384_final)
|
|
|
|
IMPLEMENT_digest_functions(testsha512, SHA512_CTX,
|
|
SHA512_CBLOCK, SHA512_DIGEST_LENGTH, SHA2_FLAGS,
|
|
ossltest_dgst_init, ossltest_dgst_update, ossltest_SHA512_final)
|
|
|
|
#define ALG(NAMES, FUNC) \
|
|
{ NAMES, "provider=p_ossltest", FUNC }
|
|
|
|
static const OSSL_ALGORITHM ossltest_digests[] = {
|
|
ALG(PROV_NAMES_MD5, ossl_testmd5_functions),
|
|
ALG(PROV_NAMES_SHA1, ossl_testsha1_functions),
|
|
ALG(PROV_NAMES_SHA2_256, ossl_testsha256_functions),
|
|
ALG(PROV_NAMES_SHA2_384, ossl_testsha384_functions),
|
|
ALG(PROV_NAMES_SHA2_512, ossl_testsha512_functions),
|
|
{NULL, NULL, NULL}
|
|
};
|
|
|
|
typedef struct {
|
|
OSSL_LIB_CTX *libctx;
|
|
EVP_CIPHER_CTX *sub_ctx;
|
|
} PROV_EVP_AES128_CBC_CTX;
|
|
|
|
/**
|
|
* @brief Allocate and initialize a new aes-128-cbc context.
|
|
*
|
|
* @param provctx void *provctx.
|
|
* @return void *.
|
|
*/
|
|
|
|
static void *ossl_testaes128_cbc_newctx(void *provctx)
|
|
{
|
|
PROV_EVP_AES128_CBC_CTX *new;
|
|
EVP_CIPHER *cph = NULL;
|
|
int ret;
|
|
|
|
if (!ossl_prov_is_running())
|
|
return NULL;
|
|
|
|
new = OPENSSL_zalloc(sizeof(PROV_EVP_AES128_CBC_CTX));
|
|
if (new == NULL)
|
|
return NULL;
|
|
new->sub_ctx = EVP_CIPHER_CTX_new();
|
|
if (new->sub_ctx == NULL)
|
|
goto err;
|
|
|
|
new->libctx = PROV_LIBCTX_OF(provctx);
|
|
|
|
cph = EVP_CIPHER_fetch(new->libctx, "AES-128-CBC", "provider=default");
|
|
if (cph == NULL)
|
|
goto err;
|
|
|
|
ret = EVP_CipherInit_ex2(new->sub_ctx, cph, NULL, NULL, 1, NULL);
|
|
|
|
EVP_CIPHER_free(cph);
|
|
|
|
if (ret <= 0)
|
|
goto err;
|
|
|
|
return new;
|
|
err:
|
|
EVP_CIPHER_CTX_free(new->sub_ctx);
|
|
OPENSSL_free(new);
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* @brief Release resources and clean up an aes-128-cbc context.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @return void.
|
|
*/
|
|
|
|
static void ossl_test_aes128cbc_freectx(void *vprovctx)
|
|
{
|
|
PROV_EVP_AES128_CBC_CTX *ctx = (PROV_EVP_AES128_CBC_CTX *)vprovctx;
|
|
|
|
EVP_CIPHER_CTX_free(ctx->sub_ctx);
|
|
OPENSSL_free(ctx);
|
|
}
|
|
|
|
/**
|
|
* @brief Duplicate an aes-128-cbc context.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @return void *.
|
|
*/
|
|
|
|
static void *ossl_test_aes128cbc_dupctx(void *vprovctx)
|
|
{
|
|
PROV_EVP_AES128_CBC_CTX *ctx = (PROV_EVP_AES128_CBC_CTX *)vprovctx;
|
|
PROV_EVP_AES128_CBC_CTX *dup;
|
|
|
|
dup = OPENSSL_memdup(ctx, sizeof(PROV_EVP_AES128_CBC_CTX));
|
|
|
|
if (dup != NULL) {
|
|
dup->sub_ctx = EVP_CIPHER_CTX_dup(ctx->sub_ctx);
|
|
if (dup->sub_ctx == NULL) {
|
|
OPENSSL_free(dup);
|
|
dup = NULL;
|
|
}
|
|
}
|
|
return dup;
|
|
}
|
|
|
|
/**
|
|
* @brief Initialize an aes-129-cbc context for encryption.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param key const unsigned char *key.
|
|
* @param keylen size_t keylen.
|
|
* @param iv const unsigned char *iv.
|
|
* @param ivlen size_t ivlen.
|
|
* @param params const OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbc_einit(void *vprovctx, const unsigned char *key,
|
|
size_t keylen, const unsigned char *iv,
|
|
size_t ivlen, const OSSL_PARAM params[])
|
|
{
|
|
PROV_EVP_AES128_CBC_CTX *ctx = (PROV_EVP_AES128_CBC_CTX *)vprovctx;
|
|
|
|
return EVP_CipherInit_ex2(ctx->sub_ctx, NULL, key, iv, 1, params);
|
|
}
|
|
|
|
/**
|
|
* @brief Initialize an aes-128-cbc context for decryption
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param key const unsigned char *key.
|
|
* @param keylen size_t keylen.
|
|
* @param iv const unsigned char *iv.
|
|
* @param ivlen size_t ivlen.
|
|
* @param params const OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbc_dinit(void *vprovctx, const unsigned char *key,
|
|
size_t keylen, const unsigned char *iv,
|
|
size_t ivlen, const OSSL_PARAM params[])
|
|
{
|
|
PROV_EVP_AES128_CBC_CTX *ctx = (PROV_EVP_AES128_CBC_CTX *)vprovctx;
|
|
|
|
return EVP_CipherInit_ex2(ctx->sub_ctx, NULL, key, iv, 0, params);
|
|
}
|
|
|
|
/**
|
|
* @brief en/decrypt data for aes-128-cbc.
|
|
*
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param out char *out.
|
|
* @param outl size_t *outl.
|
|
* @param outsize size_t outsize.
|
|
* @param in const unsigned char *in.
|
|
* @param inl size_t inl.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbc_update(void *vprovctx, char *out, size_t *outl,
|
|
size_t outsize, const unsigned char *in,
|
|
size_t inl)
|
|
{
|
|
PROV_EVP_AES128_CBC_CTX *ctx = (PROV_EVP_AES128_CBC_CTX *)vprovctx;
|
|
int soutl;
|
|
int padnum;
|
|
unsigned char padval;
|
|
size_t loop;
|
|
uint8_t *inbuf = NULL;
|
|
int ret = 0;
|
|
|
|
*outl = 0;
|
|
|
|
if (EVP_CIPHER_CTX_is_encrypting(ctx->sub_ctx)) {
|
|
/*
|
|
* On encrypt, Make sure output buffer is large enough to hold the
|
|
* crypto result plus any needed padding, keeping in mind that for
|
|
* inputs less than the block size (16), we pad to the remainder of this
|
|
* block (i.e. up to 15 bytes). For inputs equal to the block size, we
|
|
* add an additional block of padding (16 bytes).
|
|
*/
|
|
if (outsize < inl + (16 - (inl % 16)))
|
|
goto err;
|
|
} else {
|
|
/*
|
|
* On decrypt we just need to make sure the output buffer is at least
|
|
* as large as the input buffer, to store the result.
|
|
*/
|
|
if (outsize < inl)
|
|
goto err;
|
|
}
|
|
|
|
/*
|
|
* record our input buffer
|
|
*/
|
|
inbuf = OPENSSL_zalloc(inl);
|
|
if (inbuf == NULL)
|
|
return 0;
|
|
|
|
memcpy(inbuf, in, inl);
|
|
|
|
soutl = EVP_Cipher(ctx->sub_ctx, (unsigned char *)out, in, (unsigned int)inl);
|
|
|
|
if (soutl <= 0)
|
|
goto err;
|
|
|
|
/*
|
|
* replace the ciphertext with our plain text
|
|
*/
|
|
memcpy(out, inbuf, inl);
|
|
|
|
if (EVP_CIPHER_CTX_is_encrypting(ctx->sub_ctx)) {
|
|
padnum = (int)(16 - (inl % 16));
|
|
padval = (unsigned char)(padnum - 1);
|
|
if (((size_t)(soutl + padnum)) > outsize)
|
|
goto err;
|
|
|
|
for (loop = inl; loop < inl + padnum; loop++)
|
|
out[loop] = padval;
|
|
soutl += padnum;
|
|
} else {
|
|
/*
|
|
* on decrypt the last byte in the buffer should be
|
|
* padval, which is the number of padding bytes - 1;
|
|
*/
|
|
padnum = out[inl - 1];
|
|
|
|
/*
|
|
* Make sure the soutl doesn't go negative
|
|
*/
|
|
if (soutl <= padnum + 16)
|
|
goto err;
|
|
|
|
soutl -= padnum + 1;
|
|
/*
|
|
* shorten by explicit iv length
|
|
*/
|
|
soutl -= 16;
|
|
}
|
|
|
|
ret = 1;
|
|
*outl = soutl;
|
|
err:
|
|
OPENSSL_free(inbuf);
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Finalize the operation and produce any remaining output for aes-cbc-128
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param out unsigned char *out.
|
|
* @param outl size_t *outl.
|
|
* @param outsize size_t outsize.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbc_final(void *vprovctx, unsigned char *out, size_t *outl,
|
|
size_t outsize)
|
|
{
|
|
PROV_EVP_AES128_CBC_CTX *ctx = (PROV_EVP_AES128_CBC_CTX *)vprovctx;
|
|
int soutl;
|
|
int ret;
|
|
|
|
ret = EVP_CipherFinal_ex(ctx->sub_ctx, out, &soutl);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Implement ossl test aes128cbc cipher.
|
|
*
|
|
* Note, nothing in TLS should be using this function, as we are a provider
|
|
* we just need it for completeness.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param out unsigned char *out.
|
|
* @param outl size_t *outl.
|
|
* @param outsize size_t outsize.
|
|
* @param in const unsigned char *in.
|
|
* @param inl size_t inl.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbc_cipher(void *vprovctx, unsigned char *out, size_t *outl,
|
|
size_t outsize, const unsigned char *in, size_t inl)
|
|
{
|
|
PROV_EVP_AES128_CBC_CTX *ctx = (PROV_EVP_AES128_CBC_CTX *)vprovctx;
|
|
|
|
return EVP_Cipher(ctx->sub_ctx, out, in, (int) inl);
|
|
}
|
|
|
|
/**
|
|
* @brief Return provider or algorithm parameters.
|
|
*
|
|
* @param params OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbc_get_params(OSSL_PARAM params[])
|
|
{
|
|
return ossl_cipher_generic_get_params(params, EVP_CIPH_CBC_MODE, 0, 128, 128, 128);
|
|
}
|
|
|
|
/**
|
|
* @brief Query parameters from the aes-128-cbc context.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param params OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbc_get_ctx_params(void *vprovctx, OSSL_PARAM params[])
|
|
{
|
|
PROV_EVP_AES128_CBC_CTX *ctx = (PROV_EVP_AES128_CBC_CTX *)vprovctx;
|
|
|
|
return EVP_CIPHER_CTX_get_params(ctx->sub_ctx, params);
|
|
}
|
|
|
|
/**
|
|
* @brief Set parameters on the aes-128-cbc context.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param params const OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbc_set_ctx_params(void *vprovctx, const OSSL_PARAM params[])
|
|
{
|
|
/*
|
|
* Normally this gets called to set
|
|
* OSSL_CIPHER_PARAM_TLS_VERSION
|
|
* OSSL_CIPHER_PARAM_TLS_MAC_SIZE
|
|
* but we don't want the underlying cipher to do that, we will
|
|
* handle that padding in cbc_update on our own, so intercept and
|
|
* squash that here
|
|
*/
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Describe parameters that can be queried for aes-128-cbc
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @return const OSSL_PARAM *.
|
|
*/
|
|
|
|
static const OSSL_PARAM *ossl_test_aes128cbc_gettable_params(void *vprovctx)
|
|
{
|
|
PROV_EVP_AES128_CBC_CTX *ctx = (PROV_EVP_AES128_CBC_CTX *)vprovctx;
|
|
|
|
return EVP_CIPHER_gettable_params(EVP_CIPHER_CTX_get0_cipher(ctx->sub_ctx));
|
|
}
|
|
|
|
/**
|
|
* @brief Describe context parameters that can be queried for aes-128-cbc.
|
|
*
|
|
* @param cctx void *cctx.
|
|
* @param vprovctx void *vprovctx.
|
|
* @return const OSSL_PARAM *.
|
|
*/
|
|
|
|
static const OSSL_PARAM *ossl_test_aes128cbc_gettable_ctx_params(void *cctx, void *vprovctx)
|
|
{
|
|
return ossl_cipher_generic_gettable_ctx_params(cctx, vprovctx);
|
|
}
|
|
|
|
/**
|
|
* @brief Describe context parameters that can be set for aes-128-cbc.
|
|
*
|
|
* @param cctx void *cctx.
|
|
* @param vprovctx void *vprovctx.
|
|
* @return const OSSL_PARAM *.
|
|
*/
|
|
|
|
static const OSSL_PARAM *ossl_test_aes128cbc_settable_ctx_params(void *cctx, void *vprovctx)
|
|
{
|
|
PROV_EVP_AES128_CBC_CTX *ctx = (PROV_EVP_AES128_CBC_CTX *)vprovctx;
|
|
|
|
return EVP_CIPHER_CTX_settable_params(ctx->sub_ctx);
|
|
}
|
|
|
|
static const OSSL_DISPATCH ossl_testaes128_cbc_functions[] = {
|
|
{ OSSL_FUNC_CIPHER_NEWCTX,
|
|
(void (*)(void)) ossl_testaes128_cbc_newctx },
|
|
{ OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) ossl_test_aes128cbc_freectx },
|
|
{ OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) ossl_test_aes128cbc_dupctx },
|
|
{ OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_test_aes128cbc_einit },
|
|
{ OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_test_aes128cbc_dinit },
|
|
{ OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_test_aes128cbc_update },
|
|
{ OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_test_aes128cbc_final },
|
|
{ OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_test_aes128cbc_cipher },
|
|
{ OSSL_FUNC_CIPHER_GET_PARAMS,
|
|
(void (*)(void)) ossl_test_aes128cbc_get_params },
|
|
{ OSSL_FUNC_CIPHER_GET_CTX_PARAMS,
|
|
(void (*)(void))ossl_test_aes128cbc_get_ctx_params },
|
|
{ OSSL_FUNC_CIPHER_SET_CTX_PARAMS,
|
|
(void (*)(void))ossl_test_aes128cbc_set_ctx_params },
|
|
{ OSSL_FUNC_CIPHER_GETTABLE_PARAMS,
|
|
(void (*)(void))ossl_test_aes128cbc_gettable_params },
|
|
{ OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,
|
|
(void (*)(void))ossl_test_aes128cbc_gettable_ctx_params },
|
|
{ OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,
|
|
(void (*)(void))ossl_test_aes128cbc_settable_ctx_params },
|
|
OSSL_DISPATCH_END
|
|
};
|
|
|
|
typedef struct {
|
|
OSSL_LIB_CTX *libctx;
|
|
EVP_CIPHER_CTX *sub_ctx;
|
|
} PROV_EVP_AES128_GCM_CTX;
|
|
|
|
/**
|
|
* @brief Allocate and initialize a new algorithm context for aes-128-gcm.
|
|
*
|
|
* @param provctx void *provctx.
|
|
* @return void *.
|
|
*/
|
|
|
|
static void *ossl_testaes128_gcm_newctx(void *provctx)
|
|
{
|
|
PROV_EVP_AES128_GCM_CTX *new;
|
|
EVP_CIPHER *cph = NULL;
|
|
int ret;
|
|
|
|
if (!ossl_prov_is_running())
|
|
return NULL;
|
|
|
|
new = OPENSSL_zalloc(sizeof(PROV_EVP_AES128_GCM_CTX));
|
|
if (new == NULL)
|
|
return NULL;
|
|
|
|
new->sub_ctx = EVP_CIPHER_CTX_new();
|
|
if (new->sub_ctx == NULL)
|
|
goto err;
|
|
|
|
new->libctx = PROV_LIBCTX_OF(provctx);
|
|
|
|
cph = EVP_CIPHER_fetch(new->libctx, "aes-128-gcm", "provider=default");
|
|
if (cph == NULL)
|
|
goto err;
|
|
|
|
ret = EVP_EncryptInit_ex2(new->sub_ctx, cph, NULL, NULL, NULL);
|
|
EVP_CIPHER_free(cph);
|
|
|
|
if (ret <= 0)
|
|
goto err;
|
|
|
|
return new;
|
|
err:
|
|
EVP_CIPHER_CTX_free(new->sub_ctx);
|
|
OPENSSL_free(new);
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief Release resources and clean up the context for aes-128-gcm.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @return void.
|
|
*/
|
|
|
|
static void ossl_test_aes128gcm_freectx(void *vprovctx)
|
|
{
|
|
PROV_EVP_AES128_GCM_CTX *ctx = (PROV_EVP_AES128_GCM_CTX *)vprovctx;
|
|
|
|
EVP_CIPHER_CTX_free(ctx->sub_ctx);
|
|
OPENSSL_free(ctx);
|
|
}
|
|
|
|
/**
|
|
* @brief Duplicate an aes-128-gcm context.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @return void *.
|
|
*/
|
|
|
|
static void *ossl_test_aes128gcm_dupctx(void *vprovctx)
|
|
{
|
|
PROV_EVP_AES128_GCM_CTX *ctx = (PROV_EVP_AES128_GCM_CTX *)vprovctx;
|
|
PROV_EVP_AES128_GCM_CTX *dup;
|
|
|
|
dup = OPENSSL_memdup(ctx, sizeof(PROV_EVP_AES128_GCM_CTX));
|
|
|
|
if (dup != NULL) {
|
|
dup->sub_ctx = EVP_CIPHER_CTX_dup(ctx->sub_ctx);
|
|
if (dup->sub_ctx == NULL) {
|
|
OPENSSL_free(dup);
|
|
dup = NULL;
|
|
}
|
|
}
|
|
return dup;
|
|
}
|
|
|
|
/**
|
|
* @brief Initialize the aes-128-gcm encryption operation context.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param key const unsigned char *key.
|
|
* @param keylen size_t keylen.
|
|
* @param iv const unsigned char *iv.
|
|
* @param ivlen size_t ivlen.
|
|
* @param params const OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128gcm_einit(void *vprovctx, const unsigned char *key,
|
|
size_t keylen, const unsigned char *iv,
|
|
size_t ivlen, const OSSL_PARAM params[])
|
|
{
|
|
PROV_EVP_AES128_GCM_CTX *ctx = (PROV_EVP_AES128_GCM_CTX *)vprovctx;
|
|
|
|
return EVP_EncryptInit_ex2(ctx->sub_ctx, NULL, key, iv, params);
|
|
}
|
|
|
|
/**
|
|
* @brief Initialize the aes-128-gcm decryption operation context.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param key const unsigned char *key.
|
|
* @param keylen size_t keylen.
|
|
* @param iv const unsigned char *iv.
|
|
* @param ivlen size_t ivlen.
|
|
* @param params const OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128gcm_dinit(void *vprovctx, const unsigned char *key,
|
|
size_t keylen, const unsigned char *iv,
|
|
size_t ivlen, const OSSL_PARAM params[])
|
|
{
|
|
PROV_EVP_AES128_GCM_CTX *ctx = (PROV_EVP_AES128_GCM_CTX *)vprovctx;
|
|
|
|
return EVP_DecryptInit_ex2(ctx->sub_ctx, NULL, key, iv, params);
|
|
}
|
|
|
|
/**
|
|
* @brief en/decrypt aes-128-gcm data.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param out char *out.
|
|
* @param outl size_t *outl.
|
|
* @param outsize size_t outsize.
|
|
* @param in const unsigned char *in.
|
|
* @param inl size_t inl.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128gcm_update(void *vprovctx, char *out, size_t *outl,
|
|
size_t outsize, const unsigned char *in,
|
|
size_t inl)
|
|
{
|
|
PROV_EVP_AES128_GCM_CTX *ctx = (PROV_EVP_AES128_GCM_CTX *)vprovctx;
|
|
int ret, soutl;
|
|
uint8_t *inbuf;
|
|
|
|
inbuf = OPENSSL_memdup(in, inl);
|
|
|
|
if (EVP_CIPHER_CTX_is_encrypting(ctx->sub_ctx))
|
|
ret = EVP_EncryptUpdate(ctx->sub_ctx, (unsigned char *)out,
|
|
&soutl, in, (int)inl);
|
|
else
|
|
ret = EVP_DecryptUpdate(ctx->sub_ctx, (unsigned char *)out,
|
|
&soutl, in, (int)inl);
|
|
*outl = soutl;
|
|
|
|
/*
|
|
* Once the cipher is complete, throw it away and use the
|
|
* plaintext as our output
|
|
*/
|
|
if (inbuf != NULL && out != NULL)
|
|
memcpy(out, inbuf, inl);
|
|
OPENSSL_free(inbuf);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Finalize the aes-128-gcm en/decryption and produce any remaining output.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param out unsigned char *out.
|
|
* @param outl size_t *outl.
|
|
* @param outsize size_t outsize.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128gcm_final(void *vprovctx, unsigned char *out, size_t *outl,
|
|
size_t outsize)
|
|
{
|
|
int ret;
|
|
|
|
*outl = 0;
|
|
ret = 1;
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Implement ossl test aes128gcm cipher.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param out unsigned char *out.
|
|
* @param outl size_t *outl.
|
|
* @param outsize size_t outsize.
|
|
* @param in const unsigned char *in.
|
|
* @param inl size_t inl.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128gcm_cipher(void *vprovctx, unsigned char *out, size_t *outl,
|
|
size_t outsize, const unsigned char *in, size_t inl)
|
|
{
|
|
PROV_EVP_AES128_GCM_CTX *ctx = (PROV_EVP_AES128_GCM_CTX *)vprovctx;
|
|
|
|
return EVP_Cipher(ctx->sub_ctx, out, in, (int) inl);
|
|
}
|
|
|
|
#define AEAD_FLAGS (PROV_CIPHER_FLAG_AEAD | PROV_CIPHER_FLAG_CUSTOM_IV)
|
|
|
|
/**
|
|
* @brief Return aes-128-gcm parameters.
|
|
*
|
|
* @param params OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128gcm_get_params(OSSL_PARAM params[])
|
|
{
|
|
return ossl_cipher_generic_get_params(params, EVP_CIPH_GCM_MODE, AEAD_FLAGS, 128, 8, 96);
|
|
}
|
|
|
|
/**
|
|
* @brief Query parameters from the aes-128-gcm context.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param params OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128gcm_get_ctx_params(void *vprovctx, OSSL_PARAM params[])
|
|
{
|
|
PROV_EVP_AES128_GCM_CTX *ctx = (PROV_EVP_AES128_GCM_CTX *)vprovctx;
|
|
OSSL_PARAM *p;
|
|
int ret;
|
|
uint8_t *tagval = NULL;
|
|
size_t taglen;
|
|
|
|
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG);
|
|
if (p != NULL) {
|
|
if (OSSL_PARAM_get_octet_string_ptr(p, (void *)&tagval, &taglen))
|
|
memset(tagval, 0, taglen);
|
|
ret = 1;
|
|
} else {
|
|
ret = EVP_CIPHER_CTX_get_params(ctx->sub_ctx, params);
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief Set parameters on the aes-128-gcm context.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param params const OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128gcm_set_ctx_params(void *vprovctx, const OSSL_PARAM params[])
|
|
{
|
|
PROV_EVP_AES128_GCM_CTX *ctx = (PROV_EVP_AES128_GCM_CTX *)vprovctx;
|
|
|
|
return EVP_CIPHER_CTX_set_params(ctx->sub_ctx, params);
|
|
}
|
|
|
|
/**
|
|
* @brief Describe parameters that can be queried aes-128-gcm.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @return const OSSL_PARAM *.
|
|
*/
|
|
|
|
static const OSSL_PARAM *ossl_test_aes128gcm_gettable_params(void *vprovctx)
|
|
{
|
|
PROV_EVP_AES128_GCM_CTX *ctx = (PROV_EVP_AES128_GCM_CTX *)vprovctx;
|
|
|
|
return EVP_CIPHER_gettable_params(EVP_CIPHER_CTX_get0_cipher(ctx->sub_ctx));
|
|
}
|
|
|
|
/**
|
|
* @brief aes-128-gcm context parameters that can be queried.
|
|
*
|
|
* @param cctx void *cctx.
|
|
* @param vprovctx void *vprovctx.
|
|
* @return const OSSL_PARAM *.
|
|
*/
|
|
|
|
static const OSSL_PARAM *ossl_test_aes128gcm_gettable_ctx_params(void *cctx, void *vprovctx)
|
|
{
|
|
return ossl_cipher_generic_gettable_ctx_params(cctx, vprovctx);
|
|
}
|
|
|
|
/**
|
|
* @brief Describe aes-128-gcm context parameters that can be set.
|
|
*
|
|
* @param cctx void *cctx.
|
|
* @param vprovctx void *vprovctx.
|
|
* @return const OSSL_PARAM *.
|
|
*/
|
|
|
|
static const OSSL_PARAM *ossl_test_aes128gcm_settable_ctx_params(void *cctx, void *vprovctx)
|
|
{
|
|
PROV_EVP_AES128_GCM_CTX *ctx = (PROV_EVP_AES128_GCM_CTX *)vprovctx;
|
|
|
|
return EVP_CIPHER_CTX_settable_params(ctx->sub_ctx);
|
|
}
|
|
|
|
static const OSSL_DISPATCH ossl_testaes128_gcm_functions[] = {
|
|
{ OSSL_FUNC_CIPHER_NEWCTX,
|
|
(void (*)(void)) ossl_testaes128_gcm_newctx },
|
|
{ OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) ossl_test_aes128gcm_freectx },
|
|
{ OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) ossl_test_aes128gcm_dupctx },
|
|
{ OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_test_aes128gcm_einit },
|
|
{ OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_test_aes128gcm_dinit },
|
|
{ OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_test_aes128gcm_update },
|
|
{ OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_test_aes128gcm_final },
|
|
{ OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_test_aes128gcm_cipher },
|
|
{ OSSL_FUNC_CIPHER_GET_PARAMS,
|
|
(void (*)(void)) ossl_test_aes128gcm_get_params },
|
|
{ OSSL_FUNC_CIPHER_GET_CTX_PARAMS,
|
|
(void (*)(void))ossl_test_aes128gcm_get_ctx_params },
|
|
{ OSSL_FUNC_CIPHER_SET_CTX_PARAMS,
|
|
(void (*)(void))ossl_test_aes128gcm_set_ctx_params },
|
|
{ OSSL_FUNC_CIPHER_GETTABLE_PARAMS,
|
|
(void (*)(void))ossl_test_aes128gcm_gettable_params },
|
|
{ OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,
|
|
(void (*)(void))ossl_test_aes128gcm_gettable_ctx_params },
|
|
{ OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,
|
|
(void (*)(void))ossl_test_aes128gcm_settable_ctx_params },
|
|
OSSL_DISPATCH_END
|
|
};
|
|
|
|
#define NO_PAYLOAD_LENGTH ((size_t)-1)
|
|
|
|
typedef struct {
|
|
OSSL_LIB_CTX *libctx;
|
|
int encrypting;
|
|
size_t payload_length;
|
|
unsigned int tls_ver;
|
|
size_t pad_size;
|
|
} PROV_EVP_AES128_CBC_HMAC_SHA1_CTX;
|
|
|
|
/**
|
|
* @brief Allocate and initialize a new aes-128-cbc-hmac-sha1 algorithm context.
|
|
*
|
|
* @param provctx void *provctx.
|
|
* @return a provider aes-128-cbc-hmac-sha1 context as a void pointer.
|
|
*/
|
|
|
|
static void *ossl_testaes128cbchmacsha1_newctx(void *provctx)
|
|
{
|
|
PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *new;
|
|
|
|
if (!ossl_prov_is_running())
|
|
return NULL;
|
|
|
|
new = OPENSSL_zalloc(sizeof(PROV_EVP_AES128_CBC_HMAC_SHA1_CTX));
|
|
if (new == NULL)
|
|
return NULL;
|
|
|
|
new->libctx = PROV_LIBCTX_OF(provctx);
|
|
new->payload_length = NO_PAYLOAD_LENGTH;
|
|
|
|
return new;
|
|
}
|
|
|
|
/**
|
|
* @brief Release resources and clean up the aes-128-cbc-hmac-sha1 context.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @return void.
|
|
*/
|
|
|
|
static void ossl_test_aes128cbchmacsha1_freectx(void *vprovctx)
|
|
{
|
|
PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *ctx = (PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *)vprovctx;
|
|
|
|
OPENSSL_free(ctx);
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief Duplicate an aes-128-cbc-hmac-sha1 algorithm context.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @return a new aes-128-cbc-hmac-sha1 context as a void pointer.
|
|
*/
|
|
|
|
static void *ossl_test_aes128cbchmacsha1_dupctx(void *vprovctx)
|
|
{
|
|
PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *ctx = (PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *)vprovctx;
|
|
|
|
return OPENSSL_memdup(ctx, sizeof(PROV_EVP_AES128_CBC_HMAC_SHA1_CTX));
|
|
}
|
|
|
|
/**
|
|
* @brief Initialize the aes-128-cbc-hmac-sha1 context for encryption.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param key const unsigned char *key.
|
|
* @param keylen size_t keylen.
|
|
* @param iv const unsigned char *iv.
|
|
* @param ivlen size_t ivlen.
|
|
* @param params const OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbchmacsha1_einit(void *vprovctx, const unsigned char *key,
|
|
size_t keylen, const unsigned char *iv,
|
|
size_t ivlen, const OSSL_PARAM params[])
|
|
{
|
|
PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *ctx = (PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *)vprovctx;
|
|
|
|
ctx->payload_length = NO_PAYLOAD_LENGTH;
|
|
ctx->encrypting = 1;
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Initialize the aes-128-cbc-hmac-sha1 context for encryption.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param key const unsigned char *key.
|
|
* @param keylen size_t keylen.
|
|
* @param iv const unsigned char *iv.
|
|
* @param ivlen size_t ivlen.
|
|
* @param params const OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbchmacsha1_dinit(void *vprovctx, const unsigned char *key,
|
|
size_t keylen, const unsigned char *iv,
|
|
size_t ivlen, const OSSL_PARAM params[])
|
|
{
|
|
PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *ctx = (PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *)vprovctx;
|
|
|
|
ctx->payload_length = NO_PAYLOAD_LENGTH;
|
|
ctx->encrypting = 0;
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief do en/decryption for aes-128-cbc-hmac-sha1
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param out unsigned char *out.
|
|
* @param outl size_t *outl.
|
|
* @param outsize size_t outsize.
|
|
* @param in const unsigned char *in.
|
|
* @param inl size_t inl.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbchmacsha1_update(void *vprovctx, unsigned char *out, size_t *outl,
|
|
size_t outsize, const unsigned char *in,
|
|
size_t inl)
|
|
{
|
|
PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *ctx = (PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *)vprovctx;
|
|
size_t l;
|
|
size_t plen = ctx->payload_length;
|
|
size_t orig_inl = inl;
|
|
const unsigned char *outtmp;
|
|
|
|
if (ctx->encrypting) {
|
|
if (plen == NO_PAYLOAD_LENGTH)
|
|
plen = inl;
|
|
else if (inl !=
|
|
((plen + SHA_DIGEST_LENGTH +
|
|
AES_BLOCK_SIZE) & (-AES_BLOCK_SIZE)))
|
|
return 0;
|
|
|
|
memmove(out, in, plen);
|
|
|
|
if (plen != inl) { /* "TLS" mode of operation */
|
|
/* calculate HMAC and append it to payload */
|
|
fill_known_data(out + plen, SHA_DIGEST_LENGTH);
|
|
|
|
/* pad the payload|hmac */
|
|
plen += SHA_DIGEST_LENGTH;
|
|
for (l = (unsigned int)(inl - plen - 1); plen < inl; plen++)
|
|
out[plen] = (unsigned char)l;
|
|
}
|
|
} else {
|
|
/* decrypt HMAC|padding at once */
|
|
memmove(out, in, inl);
|
|
|
|
if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
|
|
unsigned int maxpad, pad;
|
|
|
|
if (ctx->tls_ver >= TLS1_1_VERSION) {
|
|
if (inl < (AES_BLOCK_SIZE + SHA_DIGEST_LENGTH + 1))
|
|
return 0;
|
|
|
|
/* omit explicit iv */
|
|
in += AES_BLOCK_SIZE;
|
|
inl -= AES_BLOCK_SIZE;
|
|
} else {
|
|
if (inl < (SHA_DIGEST_LENGTH + 1))
|
|
return 0;
|
|
}
|
|
|
|
outtmp = out + AES_BLOCK_SIZE;
|
|
/* figure out payload length */
|
|
pad = outtmp[inl - 1];
|
|
maxpad = (unsigned int)(inl - (SHA_DIGEST_LENGTH + 1));
|
|
if (pad > maxpad)
|
|
return 0;
|
|
for (plen = inl - pad - 1; plen < inl; plen++)
|
|
if (outtmp[plen] != pad)
|
|
return 0;
|
|
/*
|
|
* We need to return the actual dummied up payload of this
|
|
* operation, so reduce the length of the output by the padding
|
|
* size that we just stripped as well as the leading IV, which
|
|
* is the first AES_BLOCK_SIZE bytes
|
|
*/
|
|
orig_inl -= pad + 1 + SHA_DIGEST_LENGTH;
|
|
orig_inl -= AES_BLOCK_SIZE;
|
|
}
|
|
}
|
|
*outl = orig_inl;
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief finalize aes-128-cbc-hmac-sha1 en/decrypt operation
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param out unsigned char *out.
|
|
* @param outl size_t *outl.
|
|
* @param outsize size_t outsize.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbchmacsha1_final(void *vprovctx, unsigned char *out, size_t *outl,
|
|
size_t outsize)
|
|
{
|
|
/*
|
|
* Since we don't do any real en/decryption in this alg, this is a no-op
|
|
* so just return success
|
|
*/
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Implement ossl test aes128cbchmacsha1 cipher.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param out unsigned char *out.
|
|
* @param outl size_t *outl.
|
|
* @param outsize size_t outsize.
|
|
* @param in const unsigned char *in.
|
|
* @param inl size_t inl.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbchmacsha1_cipher(void *vprovctx,
|
|
unsigned char *out, size_t *outl,
|
|
size_t outsize, const unsigned char *in, size_t inl)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
#define AES_CBC_HMAC_SHA_FLAGS (PROV_CIPHER_FLAG_AEAD | PROV_CIPHER_FLAG_TLS1_MULTIBLOCK)
|
|
/**
|
|
* @brief Return aes-128-cbc-hmac-sha1 gettable parameters.
|
|
*
|
|
* @param params OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbchmacsha1_get_params(OSSL_PARAM params[])
|
|
{
|
|
int ret;
|
|
|
|
ret = ossl_cipher_generic_get_params(params, EVP_CIPH_CBC_MODE,
|
|
AES_CBC_HMAC_SHA_FLAGS, 128, 128, 128);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Query aes-128-cbc-hmac-sha1 context parameters.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param params OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbchmacsha1_get_ctx_params(void *vprovctx, OSSL_PARAM params[])
|
|
{
|
|
PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *ctx = (PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *)vprovctx;
|
|
OSSL_PARAM *p;
|
|
|
|
/*
|
|
* lifted from aes_get_ctx_params
|
|
*/
|
|
#if !defined(OPENSSL_NO_MULTIBLOCK)
|
|
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE);
|
|
if (p != NULL) {
|
|
/*
|
|
* Don't know how to handle any of these
|
|
*/
|
|
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
|
return 0;
|
|
}
|
|
|
|
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE);
|
|
if (p != NULL) {
|
|
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
|
return 0;
|
|
}
|
|
|
|
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN);
|
|
if (p != NULL) {
|
|
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
|
return 0;
|
|
}
|
|
|
|
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN);
|
|
if (p != NULL) {
|
|
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
|
return 0;
|
|
}
|
|
#endif /* !defined(OPENSSL_NO_MULTIBLOCK) */
|
|
|
|
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD);
|
|
if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->pad_size)) {
|
|
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
|
return 0;
|
|
}
|
|
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
|
|
if (p != NULL && !OSSL_PARAM_set_size_t(p, 128 / 8)) {
|
|
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
|
return 0;
|
|
}
|
|
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
|
|
if (p != NULL && !OSSL_PARAM_set_size_t(p, 128 / 8)) {
|
|
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
|
return 0;
|
|
}
|
|
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
|
|
if (p != NULL) {
|
|
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
|
return 0;
|
|
}
|
|
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV);
|
|
if (p != NULL) {
|
|
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Set aes-128-cbc-hmac-sha1 context parameters.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @param params const OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_test_aes128cbchmacsha1_set_ctx_params(void *vprovctx, const OSSL_PARAM params[])
|
|
{
|
|
PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *ctx = (PROV_EVP_AES128_CBC_HMAC_SHA1_CTX *)vprovctx;
|
|
OSSL_PARAM *p;
|
|
uint8_t *val;
|
|
size_t vlen;
|
|
unsigned int len;
|
|
|
|
p = OSSL_PARAM_locate((OSSL_PARAM *)params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD);
|
|
if (p != NULL) {
|
|
if (OSSL_PARAM_get_octet_string_ptr(p, (const void **)&val, &vlen) != 1)
|
|
return 0;
|
|
len = val[EVP_AEAD_TLS1_AAD_LEN - 2] << 8 | val[EVP_AEAD_TLS1_AAD_LEN - 1];
|
|
ctx->tls_ver = val[EVP_AEAD_TLS1_AAD_LEN - 4] << 8 | val[EVP_AEAD_TLS1_AAD_LEN -3];
|
|
|
|
if (ctx->encrypting) {
|
|
ctx->payload_length = len;
|
|
if (ctx->tls_ver >= TLS1_1_VERSION) {
|
|
if (len < AES_BLOCK_SIZE)
|
|
return 0;
|
|
len -= AES_BLOCK_SIZE;
|
|
val[EVP_AEAD_TLS1_AAD_LEN - 2] = len >> 8;
|
|
val[EVP_AEAD_TLS1_AAD_LEN - 1] = len;
|
|
ctx->pad_size = ((len + SHA_DIGEST_LENGTH +
|
|
AES_BLOCK_SIZE) & (-AES_BLOCK_SIZE)) - len;
|
|
}
|
|
} else {
|
|
ctx->payload_length = EVP_AEAD_TLS1_AAD_LEN;
|
|
ctx->pad_size = SHA_DIGEST_LENGTH;
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Describe parameters that can be queried for aes-128-cbc-hmac-sha1.
|
|
*
|
|
* @param vprovctx void *vprovctx.
|
|
* @return const OSSL_PARAM *.
|
|
*/
|
|
|
|
static const OSSL_PARAM *ossl_test_aes128cbchmacsha1_gettable_params(void *vprovctx)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* @brief Describe context parameters that can be queried for an aes-128-cbc-hamc-sha1 ctx.
|
|
*
|
|
* @param cctx void *cctx.
|
|
* @param vprovctx void *vprovctx.
|
|
* @return const OSSL_PARAM *.
|
|
*/
|
|
|
|
static const OSSL_PARAM *ossl_test_aes128cbchmacsha1_gettable_ctx_params(void *cctx, void *vprovctx)
|
|
{
|
|
return ossl_cipher_generic_gettable_ctx_params(cctx, vprovctx);
|
|
}
|
|
|
|
/**
|
|
* @brief Describe context parameters that can be set on an aes-128-cbc-hmac-sha1 ctx.
|
|
*
|
|
* @param cctx void *cctx.
|
|
* @param vprovctx void *vprovctx.
|
|
* @return const OSSL_PARAM *.
|
|
*/
|
|
|
|
static const OSSL_PARAM *ossl_test_aes128cbchmacsha1_settable_ctx_params(void *cctx, void *vprovctx)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static const OSSL_DISPATCH ossl_testaes128cbchmacsha1_functions[] = {
|
|
{ OSSL_FUNC_CIPHER_NEWCTX,
|
|
(void (*)(void)) ossl_testaes128cbchmacsha1_newctx },
|
|
{ OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) ossl_test_aes128cbchmacsha1_freectx },
|
|
{ OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) ossl_test_aes128cbchmacsha1_dupctx },
|
|
{ OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_test_aes128cbchmacsha1_einit },
|
|
{ OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_test_aes128cbchmacsha1_dinit },
|
|
{ OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_test_aes128cbchmacsha1_update },
|
|
{ OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_test_aes128cbchmacsha1_final },
|
|
{ OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_test_aes128cbchmacsha1_cipher },
|
|
{ OSSL_FUNC_CIPHER_GET_PARAMS,
|
|
(void (*)(void)) ossl_test_aes128cbchmacsha1_get_params },
|
|
{ OSSL_FUNC_CIPHER_GET_CTX_PARAMS,
|
|
(void (*)(void))ossl_test_aes128cbchmacsha1_get_ctx_params },
|
|
{ OSSL_FUNC_CIPHER_SET_CTX_PARAMS,
|
|
(void (*)(void))ossl_test_aes128cbchmacsha1_set_ctx_params },
|
|
{ OSSL_FUNC_CIPHER_GETTABLE_PARAMS,
|
|
(void (*)(void))ossl_test_aes128cbchmacsha1_gettable_params },
|
|
{ OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,
|
|
(void (*)(void))ossl_test_aes128cbchmacsha1_gettable_ctx_params },
|
|
{ OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,
|
|
(void (*)(void))ossl_test_aes128cbchmacsha1_settable_ctx_params },
|
|
OSSL_DISPATCH_END
|
|
};
|
|
|
|
static const OSSL_ALGORITHM ossltest_ciphers[] = {
|
|
ALG(PROV_NAMES_AES_128_CBC, ossl_testaes128_cbc_functions),
|
|
ALG(PROV_NAMES_AES_128_GCM, ossl_testaes128_gcm_functions),
|
|
ALG(PROV_NAMES_AES_128_CBC_HMAC_SHA1, ossl_testaes128cbchmacsha1_functions),
|
|
{NULL, NULL, NULL}
|
|
};
|
|
|
|
typedef struct ossl_test_rand_ctx {
|
|
size_t unused;
|
|
} OSSL_TEST_RAND_CTX;
|
|
|
|
/**
|
|
* @brief Implement drbg ctr new wrapper.
|
|
*
|
|
* @param provctx void *provctx.
|
|
* @param parent void *parent.
|
|
* @param parent_dispatch const OSSL_DISPATCH *parent_dispatch.
|
|
* @return void *.
|
|
*/
|
|
|
|
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
|
|
const OSSL_DISPATCH *parent_dispatch)
|
|
{
|
|
return OPENSSL_zalloc(sizeof(OSSL_TEST_RAND_CTX));
|
|
}
|
|
|
|
/**
|
|
* @brief Release resources and clean up the context.
|
|
*
|
|
* @param vdrbg void *vdrbg.
|
|
* @return void.
|
|
*/
|
|
|
|
static void drbg_ctr_free(void *vdrbg)
|
|
{
|
|
OPENSSL_free(vdrbg);
|
|
}
|
|
|
|
/**
|
|
* @brief Instantiate the CTR DRBG with the given inputs.
|
|
*
|
|
* @param vdrbg void *vdrbg.
|
|
* @param strength unsigned int strength.
|
|
* @param prediction_resistance int prediction_resistance.
|
|
* @param pstr const unsigned char *pstr.
|
|
* @param pstr_len size_t pstr_len.
|
|
* @param params const OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int drbg_ctr_instantiate_wrapper(void *vdrbg, unsigned int strength,
|
|
int prediction_resistance,
|
|
const unsigned char *pstr,
|
|
size_t pstr_len,
|
|
const OSSL_PARAM params[])
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Instantiate the CTR DRBG with the given inputs.
|
|
*
|
|
* @param vdrbg void *vdrbg.
|
|
* @return int.
|
|
*/
|
|
|
|
static int drbg_ctr_uninstantiate_wrapper(void *vdrbg)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Generate pseudo-random bytes from the CTR DRBG.
|
|
*
|
|
* @param vdrbg void *vdrbg.
|
|
* @param out unsigned char *out.
|
|
* @param outlen size_t outlen.
|
|
* @param strength unsigned int strength.
|
|
* @param prediction_resistance int prediction_resistance.
|
|
* @param adin const unsigned char *adin.
|
|
* @param adin_len size_t adin_len.
|
|
* @return int.
|
|
*/
|
|
|
|
static int drbg_ctr_generate_wrapper(void *vdrbg, unsigned char *out,
|
|
size_t outlen, unsigned int strength,
|
|
int prediction_resistance,
|
|
const unsigned char *adin, size_t adin_len)
|
|
{
|
|
unsigned char val = 1;
|
|
size_t copylen = 0;
|
|
|
|
while (copylen < outlen) {
|
|
*out++ = val++;
|
|
copylen++;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Reseed the CTR DRBG with fresh entropy.
|
|
*
|
|
* @param vdrbg void *vdrbg.
|
|
* @param prediction_resistance int prediction_resistance.
|
|
* @param ent const unsigned char *ent.
|
|
* @param ent_len size_t ent_len.
|
|
* @param adin const unsigned char *adin.
|
|
* @param adin_len size_t adin_len.
|
|
* @return int.
|
|
*/
|
|
|
|
static int drbg_ctr_reseed_wrapper(void *vdrbg, int prediction_resistance,
|
|
const unsigned char *ent, size_t ent_len,
|
|
const unsigned char *adin, size_t adin_len)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Enable internal locking for thread safety.
|
|
*
|
|
* @param vctx void *vctx.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_drbg_enable_locking(void *vctx)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Acquire the internal lock.
|
|
*
|
|
* @param vctx void *vctx.
|
|
* @return int.
|
|
*/
|
|
|
|
static int ossl_drbg_lock(void *vctx)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Release the internal lock.
|
|
*
|
|
* @param vctx void *vctx.
|
|
* @return void.
|
|
*/
|
|
|
|
static void ossl_drbg_unlock(void *vctx)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief Describe context parameters that can be set.
|
|
*
|
|
* @param vctx ossl_unused void *vctx.
|
|
* @param provctx ossl_unused void *provctx.
|
|
* @return const OSSL_PARAM *.
|
|
*/
|
|
|
|
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
|
|
ossl_unused void *provctx)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* @brief Set parameters on the algorithm context.
|
|
*
|
|
* @param vctx void *vctx.
|
|
* @param params const OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Describe context parameters that can be queried.
|
|
*
|
|
* @param vctx ossl_unused void *vctx.
|
|
* @param provctx ossl_unused void *provctx.
|
|
* @return const OSSL_PARAM *.
|
|
*/
|
|
|
|
static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx,
|
|
ossl_unused void *provctx)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* @brief Query parameters from the algorithm context.
|
|
*
|
|
* @param vdrbg void *vdrbg.
|
|
* @param params OSSL_PARAM params[].
|
|
* @return int.
|
|
*/
|
|
|
|
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
|
|
{
|
|
OSSL_PARAM *p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST);
|
|
|
|
if (p != NULL && !OSSL_PARAM_set_size_t(p, (size_t)(1 << 16))) {
|
|
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Verify that sensitive buffers are cleared to zero.
|
|
*
|
|
* @param vdrbg void *vdrbg.
|
|
* @return int.
|
|
*/
|
|
|
|
static int drbg_ctr_verify_zeroization(void *vdrbg)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief Return the stored test seed buffer if present.
|
|
*
|
|
* @param vdrbg void *vdrbg.
|
|
* @param pout unsigned char **pout.
|
|
* @param entropy int entropy.
|
|
* @param min_len size_t min_len.
|
|
* @param max_len size_t max_len.
|
|
* @param prediction_resistance int prediction_resistance.
|
|
* @param adin const unsigned char *adin.
|
|
* @param adin_len size_t adin_len.
|
|
* @return size_t.
|
|
*/
|
|
|
|
static size_t ossl_drbg_get_seed(void *vdrbg, unsigned char **pout,
|
|
int entropy, size_t min_len,
|
|
size_t max_len, int prediction_resistance,
|
|
const unsigned char *adin, size_t adin_len)
|
|
{
|
|
size_t needed = entropy;
|
|
|
|
if (needed < min_len)
|
|
needed = min_len;
|
|
if (needed > max_len)
|
|
needed = max_len;
|
|
return needed;
|
|
}
|
|
|
|
/**
|
|
* @brief Clear any stored test seed buffer.
|
|
*
|
|
* @param vdrbg ossl_unused void *vdrbg.
|
|
* @param out unsigned char *out.
|
|
* @param outlen size_t outlen.
|
|
* @return void.
|
|
*/
|
|
|
|
static void ossl_drbg_clear_seed(ossl_unused void *vdrbg,
|
|
unsigned char *out, size_t outlen)
|
|
{
|
|
return;
|
|
}
|
|
|
|
static const OSSL_DISPATCH ossl_test_drbg_ctr_functions[] = {
|
|
{ OSSL_FUNC_RAND_NEWCTX, (void(*)(void))drbg_ctr_new_wrapper },
|
|
{ OSSL_FUNC_RAND_FREECTX, (void(*)(void))drbg_ctr_free },
|
|
{ OSSL_FUNC_RAND_INSTANTIATE,
|
|
(void(*)(void))drbg_ctr_instantiate_wrapper },
|
|
{ OSSL_FUNC_RAND_UNINSTANTIATE,
|
|
(void(*)(void))drbg_ctr_uninstantiate_wrapper },
|
|
{ OSSL_FUNC_RAND_GENERATE, (void(*)(void))drbg_ctr_generate_wrapper },
|
|
{ OSSL_FUNC_RAND_RESEED, (void(*)(void))drbg_ctr_reseed_wrapper },
|
|
{ OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))ossl_drbg_enable_locking },
|
|
{ OSSL_FUNC_RAND_LOCK, (void(*)(void))ossl_drbg_lock },
|
|
{ OSSL_FUNC_RAND_UNLOCK, (void(*)(void))ossl_drbg_unlock },
|
|
{ OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
|
|
(void(*)(void))drbg_ctr_settable_ctx_params },
|
|
{ OSSL_FUNC_RAND_SET_CTX_PARAMS, (void(*)(void))drbg_ctr_set_ctx_params },
|
|
{ OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
|
|
(void(*)(void))drbg_ctr_gettable_ctx_params },
|
|
{ OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_ctr_get_ctx_params },
|
|
{ OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
|
|
(void(*)(void))drbg_ctr_verify_zeroization },
|
|
{ OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed },
|
|
{ OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed },
|
|
OSSL_DISPATCH_END
|
|
};
|
|
|
|
static const OSSL_ALGORITHM ossltest_rands[] = {
|
|
ALG(PROV_NAMES_CTR_DRBG, ossl_test_drbg_ctr_functions),
|
|
{NULL, NULL, NULL}
|
|
};
|
|
|
|
/**
|
|
* @brief Implement ossltest query.
|
|
*
|
|
* @param provctx void *provctx.
|
|
* @param operation_id int operation_id.
|
|
* @param no_cache int *no_cache.
|
|
* @return const OSSL_ALGORITHM *.
|
|
*/
|
|
|
|
static const OSSL_ALGORITHM *ossltest_query(void *provctx, int operation_id,
|
|
int *no_cache)
|
|
{
|
|
*no_cache = 0;
|
|
switch (operation_id) {
|
|
case OSSL_OP_DIGEST:
|
|
return ossltest_digests;
|
|
case OSSL_OP_CIPHER:
|
|
return ossltest_ciphers;
|
|
case OSSL_OP_RAND:
|
|
return ossltest_rands;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static const OSSL_DISPATCH ossltest_dispatch_table[] = {
|
|
{ OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))ossltest_teardown },
|
|
{ OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))ossltest_gettable_params },
|
|
{ OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))ossltest_get_params },
|
|
{ OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))ossltest_query },
|
|
OSSL_DISPATCH_END
|
|
};
|
|
|
|
OSSL_provider_init_fn OSSL_provider_init_int;
|
|
/**
|
|
* @brief Initialize the context or operation state.
|
|
*
|
|
* @param handle const OSSL_CORE_HANDLE *handle.
|
|
* @param in const OSSL_DISPATCH *in.
|
|
* @param out const OSSL_DISPATCH **out.
|
|
* @param provctx void **provctx.
|
|
* @return int.
|
|
*/
|
|
int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
|
|
const OSSL_DISPATCH *in,
|
|
const OSSL_DISPATCH **out,
|
|
void **provctx)
|
|
{
|
|
OSSL_LIB_CTX *libctx = NULL;
|
|
|
|
if ((*provctx = ossl_prov_ctx_new()) == NULL
|
|
|| (libctx = OSSL_LIB_CTX_new_child(handle, in)) == NULL) {
|
|
OSSL_LIB_CTX_free(libctx);
|
|
ossltest_teardown(*provctx);
|
|
*provctx = NULL;
|
|
return 0;
|
|
}
|
|
|
|
ossl_prov_ctx_set0_libctx(*provctx, libctx);
|
|
ossl_prov_ctx_set0_handle(*provctx, handle);
|
|
|
|
*out = ossltest_dispatch_table;
|
|
|
|
return 1;
|
|
}
|