| 
									
										
										
										
											2025-08-26 20:08:01 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 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) { | 
					
						
							| 
									
										
										
										
											2025-09-17 18:41:58 +08:00
										 |  |  |         if (OSSL_PARAM_get_octet_string_ptr(p, (const void **)&val, &vlen) != 1) | 
					
						
							|  |  |  |             return 0; | 
					
						
							| 
									
										
										
										
											2025-08-26 20:08:01 +08:00
										 |  |  |         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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-17 18:41:58 +08:00
										 |  |  |     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; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-08-26 20:08:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  | } |