Path: blob/main/crypto/openssl/engines/e_ossltest.c
34865 views
/*1* Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89/*10* This is the OSSLTEST engine. It provides deliberately crippled digest11* implementations for test purposes. It is highly insecure and must NOT be12* used for any purpose except testing13*/1415/* We need to use some engine deprecated APIs */16#define OPENSSL_SUPPRESS_DEPRECATED1718/*19* SHA low level APIs are deprecated for public use, but still ok for20* internal use. Note, that due to symbols not being exported, only the21* #defines and type definitions can be accessed, function calls are not22* available. The digest lengths, block sizes and sizeof(CTX) are used herein23* for several different digests.24*/25#include "internal/deprecated.h"2627#include <stdio.h>28#include <string.h>29#include "internal/common.h" /* for CHECK_AND_SKIP_CASE_PREFIX */3031#include <openssl/engine.h>32#include <openssl/sha.h>33#include <openssl/md5.h>34#include <openssl/rsa.h>35#include <openssl/evp.h>36#include <openssl/modes.h>37#include <openssl/aes.h>38#include <openssl/rand.h>39#include <openssl/crypto.h>40#include <openssl/pem.h>41#include <crypto/evp.h>4243#include "e_ossltest_err.c"4445/* Engine Id and Name */46static const char *engine_ossltest_id = "ossltest";47static const char *engine_ossltest_name = "OpenSSL Test engine support";484950/* Engine Lifetime functions */51static int ossltest_destroy(ENGINE *e);52static int ossltest_init(ENGINE *e);53static int ossltest_finish(ENGINE *e);54void ENGINE_load_ossltest(void);555657/* Set up digests */58static int ossltest_digests(ENGINE *e, const EVP_MD **digest,59const int **nids, int nid);60static const RAND_METHOD *ossltest_rand_method(void);6162/* MD5 */63static int digest_md5_init(EVP_MD_CTX *ctx);64static int digest_md5_update(EVP_MD_CTX *ctx, const void *data,65size_t count);66static int digest_md5_final(EVP_MD_CTX *ctx, unsigned char *md);6768static EVP_MD *_hidden_md5_md = NULL;69static const EVP_MD *digest_md5(void)70{71if (_hidden_md5_md == NULL) {72EVP_MD *md;7374if ((md = EVP_MD_meth_new(NID_md5, NID_md5WithRSAEncryption)) == NULL75|| !EVP_MD_meth_set_result_size(md, MD5_DIGEST_LENGTH)76|| !EVP_MD_meth_set_input_blocksize(md, MD5_CBLOCK)77|| !EVP_MD_meth_set_app_datasize(md,78sizeof(EVP_MD *) + sizeof(MD5_CTX))79|| !EVP_MD_meth_set_flags(md, 0)80|| !EVP_MD_meth_set_init(md, digest_md5_init)81|| !EVP_MD_meth_set_update(md, digest_md5_update)82|| !EVP_MD_meth_set_final(md, digest_md5_final)) {83EVP_MD_meth_free(md);84md = NULL;85}86_hidden_md5_md = md;87}88return _hidden_md5_md;89}9091/* SHA1 */92static int digest_sha1_init(EVP_MD_CTX *ctx);93static int digest_sha1_update(EVP_MD_CTX *ctx, const void *data,94size_t count);95static int digest_sha1_final(EVP_MD_CTX *ctx, unsigned char *md);9697static EVP_MD *_hidden_sha1_md = NULL;98static const EVP_MD *digest_sha1(void)99{100if (_hidden_sha1_md == NULL) {101EVP_MD *md;102103if ((md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption)) == NULL104|| !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH)105|| !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK)106|| !EVP_MD_meth_set_app_datasize(md,107sizeof(EVP_MD *) + sizeof(SHA_CTX))108|| !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)109|| !EVP_MD_meth_set_init(md, digest_sha1_init)110|| !EVP_MD_meth_set_update(md, digest_sha1_update)111|| !EVP_MD_meth_set_final(md, digest_sha1_final)) {112EVP_MD_meth_free(md);113md = NULL;114}115_hidden_sha1_md = md;116}117return _hidden_sha1_md;118}119120/* SHA256 */121static int digest_sha256_init(EVP_MD_CTX *ctx);122static int digest_sha256_update(EVP_MD_CTX *ctx, const void *data,123size_t count);124static int digest_sha256_final(EVP_MD_CTX *ctx, unsigned char *md);125126static EVP_MD *_hidden_sha256_md = NULL;127static const EVP_MD *digest_sha256(void)128{129if (_hidden_sha256_md == NULL) {130EVP_MD *md;131132if ((md = EVP_MD_meth_new(NID_sha256, NID_sha256WithRSAEncryption)) == NULL133|| !EVP_MD_meth_set_result_size(md, SHA256_DIGEST_LENGTH)134|| !EVP_MD_meth_set_input_blocksize(md, SHA256_CBLOCK)135|| !EVP_MD_meth_set_app_datasize(md,136sizeof(EVP_MD *) + sizeof(SHA256_CTX))137|| !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)138|| !EVP_MD_meth_set_init(md, digest_sha256_init)139|| !EVP_MD_meth_set_update(md, digest_sha256_update)140|| !EVP_MD_meth_set_final(md, digest_sha256_final)) {141EVP_MD_meth_free(md);142md = NULL;143}144_hidden_sha256_md = md;145}146return _hidden_sha256_md;147}148149/* SHA384/SHA512 */150static int digest_sha384_init(EVP_MD_CTX *ctx);151static int digest_sha384_update(EVP_MD_CTX *ctx, const void *data,152size_t count);153static int digest_sha384_final(EVP_MD_CTX *ctx, unsigned char *md);154155static int digest_sha512_init(EVP_MD_CTX *ctx);156static int digest_sha512_update(EVP_MD_CTX *ctx, const void *data,157size_t count);158static int digest_sha512_final(EVP_MD_CTX *ctx, unsigned char *md);159160static EVP_MD *_hidden_sha384_md = NULL;161static const EVP_MD *digest_sha384(void)162{163if (_hidden_sha384_md == NULL) {164EVP_MD *md;165166if ((md = EVP_MD_meth_new(NID_sha384, NID_sha384WithRSAEncryption)) == NULL167|| !EVP_MD_meth_set_result_size(md, SHA384_DIGEST_LENGTH)168|| !EVP_MD_meth_set_input_blocksize(md, SHA512_CBLOCK)169|| !EVP_MD_meth_set_app_datasize(md,170sizeof(EVP_MD *) + sizeof(SHA512_CTX))171|| !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)172|| !EVP_MD_meth_set_init(md, digest_sha384_init)173|| !EVP_MD_meth_set_update(md, digest_sha384_update)174|| !EVP_MD_meth_set_final(md, digest_sha384_final)) {175EVP_MD_meth_free(md);176md = NULL;177}178_hidden_sha384_md = md;179}180return _hidden_sha384_md;181}182static EVP_MD *_hidden_sha512_md = NULL;183static const EVP_MD *digest_sha512(void)184{185if (_hidden_sha512_md == NULL) {186EVP_MD *md;187188if ((md = EVP_MD_meth_new(NID_sha512, NID_sha512WithRSAEncryption)) == NULL189|| !EVP_MD_meth_set_result_size(md, SHA512_DIGEST_LENGTH)190|| !EVP_MD_meth_set_input_blocksize(md, SHA512_CBLOCK)191|| !EVP_MD_meth_set_app_datasize(md,192sizeof(EVP_MD *) + sizeof(SHA512_CTX))193|| !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)194|| !EVP_MD_meth_set_init(md, digest_sha512_init)195|| !EVP_MD_meth_set_update(md, digest_sha512_update)196|| !EVP_MD_meth_set_final(md, digest_sha512_final)) {197EVP_MD_meth_free(md);198md = NULL;199}200_hidden_sha512_md = md;201}202return _hidden_sha512_md;203}204static void destroy_digests(void)205{206EVP_MD_meth_free(_hidden_md5_md);207_hidden_md5_md = NULL;208EVP_MD_meth_free(_hidden_sha1_md);209_hidden_sha1_md = NULL;210EVP_MD_meth_free(_hidden_sha256_md);211_hidden_sha256_md = NULL;212EVP_MD_meth_free(_hidden_sha384_md);213_hidden_sha384_md = NULL;214EVP_MD_meth_free(_hidden_sha512_md);215_hidden_sha512_md = NULL;216}217static int ossltest_digest_nids(const int **nids)218{219static int digest_nids[6] = { 0, 0, 0, 0, 0, 0 };220static int pos = 0;221static int init = 0;222223if (!init) {224const EVP_MD *md;225if ((md = digest_md5()) != NULL)226digest_nids[pos++] = EVP_MD_get_type(md);227if ((md = digest_sha1()) != NULL)228digest_nids[pos++] = EVP_MD_get_type(md);229if ((md = digest_sha256()) != NULL)230digest_nids[pos++] = EVP_MD_get_type(md);231if ((md = digest_sha384()) != NULL)232digest_nids[pos++] = EVP_MD_get_type(md);233if ((md = digest_sha512()) != NULL)234digest_nids[pos++] = EVP_MD_get_type(md);235digest_nids[pos] = 0;236init = 1;237}238*nids = digest_nids;239return pos;240}241242/* Setup ciphers */243static int ossltest_ciphers(ENGINE *, const EVP_CIPHER **,244const int **, int);245246static int ossltest_cipher_nids[] = {247NID_aes_128_cbc, NID_aes_128_gcm,248NID_aes_128_cbc_hmac_sha1, 0249};250251/* AES128 */252253static int ossltest_aes128_init_key(EVP_CIPHER_CTX *ctx,254const unsigned char *key,255const unsigned char *iv, int enc);256static int ossltest_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,257const unsigned char *in, size_t inl);258static int ossltest_aes128_gcm_init_key(EVP_CIPHER_CTX *ctx,259const unsigned char *key,260const unsigned char *iv, int enc);261static int ossltest_aes128_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,262const unsigned char *in, size_t inl);263static int ossltest_aes128_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,264void *ptr);265static int ossltest_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,266const unsigned char *key,267const unsigned char *iv,268int enc);269static int ossltest_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx,270unsigned char *out,271const unsigned char *in,272size_t inl);273static int ossltest_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,274int arg, void *ptr);275276typedef struct {277size_t payload_length; /* AAD length in decrypt case */278unsigned int tls_ver;279} EVP_AES_HMAC_SHA1;280281static EVP_CIPHER *_hidden_aes_128_cbc = NULL;282static const EVP_CIPHER *ossltest_aes_128_cbc(void)283{284if (_hidden_aes_128_cbc == NULL285&& ((_hidden_aes_128_cbc = EVP_CIPHER_meth_new(NID_aes_128_cbc,28616 /* block size */,28716 /* key len */)) == NULL288|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc,16)289|| !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc,290EVP_CIPH_FLAG_DEFAULT_ASN1291| EVP_CIPH_CBC_MODE)292|| !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc,293ossltest_aes128_init_key)294|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc,295ossltest_aes128_cbc_cipher)296|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc,297EVP_CIPHER_impl_ctx_size(EVP_aes_128_cbc())))) {298EVP_CIPHER_meth_free(_hidden_aes_128_cbc);299_hidden_aes_128_cbc = NULL;300}301return _hidden_aes_128_cbc;302}303304static EVP_CIPHER *_hidden_aes_128_gcm = NULL;305306#define AES_GCM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \307| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \308| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \309| EVP_CIPH_CUSTOM_COPY |EVP_CIPH_FLAG_AEAD_CIPHER \310| EVP_CIPH_GCM_MODE)311312static const EVP_CIPHER *ossltest_aes_128_gcm(void)313{314if (_hidden_aes_128_gcm == NULL315&& ((_hidden_aes_128_gcm = EVP_CIPHER_meth_new(NID_aes_128_gcm,3161 /* block size */,31716 /* key len */)) == NULL318|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_gcm,12)319|| !EVP_CIPHER_meth_set_flags(_hidden_aes_128_gcm, AES_GCM_FLAGS)320|| !EVP_CIPHER_meth_set_init(_hidden_aes_128_gcm,321ossltest_aes128_gcm_init_key)322|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_gcm,323ossltest_aes128_gcm_cipher)324|| !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_gcm,325ossltest_aes128_gcm_ctrl)326|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_gcm,327EVP_CIPHER_impl_ctx_size(EVP_aes_128_gcm())))) {328EVP_CIPHER_meth_free(_hidden_aes_128_gcm);329_hidden_aes_128_gcm = NULL;330}331return _hidden_aes_128_gcm;332}333334static EVP_CIPHER *_hidden_aes_128_cbc_hmac_sha1 = NULL;335336static const EVP_CIPHER *ossltest_aes_128_cbc_hmac_sha1(void)337{338if (_hidden_aes_128_cbc_hmac_sha1 == NULL339&& ((_hidden_aes_128_cbc_hmac_sha1340= EVP_CIPHER_meth_new(NID_aes_128_cbc_hmac_sha1,34116 /* block size */,34216 /* key len */)) == NULL343|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc_hmac_sha1,16)344|| !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc_hmac_sha1,345EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |346EVP_CIPH_FLAG_AEAD_CIPHER)347|| !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc_hmac_sha1,348ossltest_aes128_cbc_hmac_sha1_init_key)349|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc_hmac_sha1,350ossltest_aes128_cbc_hmac_sha1_cipher)351|| !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_cbc_hmac_sha1,352ossltest_aes128_cbc_hmac_sha1_ctrl)353|| !EVP_CIPHER_meth_set_set_asn1_params(_hidden_aes_128_cbc_hmac_sha1,354EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv)355|| !EVP_CIPHER_meth_set_get_asn1_params(_hidden_aes_128_cbc_hmac_sha1,356EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv)357|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc_hmac_sha1,358sizeof(EVP_AES_HMAC_SHA1)))) {359EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);360_hidden_aes_128_cbc_hmac_sha1 = NULL;361}362return _hidden_aes_128_cbc_hmac_sha1;363}364365static void destroy_ciphers(void)366{367EVP_CIPHER_meth_free(_hidden_aes_128_cbc);368EVP_CIPHER_meth_free(_hidden_aes_128_gcm);369EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);370_hidden_aes_128_cbc = NULL;371_hidden_aes_128_gcm = NULL;372_hidden_aes_128_cbc_hmac_sha1 = NULL;373}374375/* Key loading */376static EVP_PKEY *load_key(ENGINE *eng, const char *key_id, int pub,377UI_METHOD *ui_method, void *ui_data)378{379BIO *in;380EVP_PKEY *key;381382if (!CHECK_AND_SKIP_CASE_PREFIX(key_id, "ot:"))383return NULL;384385fprintf(stderr, "[ossltest]Loading %s key %s\n",386pub ? "Public" : "Private", key_id);387in = BIO_new_file(key_id, "r");388if (!in)389return NULL;390if (pub)391key = PEM_read_bio_PUBKEY(in, NULL, 0, NULL);392else393key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);394BIO_free(in);395return key;396}397398static EVP_PKEY *ossltest_load_privkey(ENGINE *eng, const char *key_id,399UI_METHOD *ui_method, void *ui_data)400{401return load_key(eng, key_id, 0, ui_method, ui_data);402}403404static EVP_PKEY *ossltest_load_pubkey(ENGINE *eng, const char *key_id,405UI_METHOD *ui_method, void *ui_data)406{407return load_key(eng, key_id, 1, ui_method, ui_data);408}409410411static int bind_ossltest(ENGINE *e)412{413/* Ensure the ossltest error handling is set up */414ERR_load_OSSLTEST_strings();415416if (!ENGINE_set_id(e, engine_ossltest_id)417|| !ENGINE_set_name(e, engine_ossltest_name)418|| !ENGINE_set_digests(e, ossltest_digests)419|| !ENGINE_set_ciphers(e, ossltest_ciphers)420|| !ENGINE_set_RAND(e, ossltest_rand_method())421|| !ENGINE_set_destroy_function(e, ossltest_destroy)422|| !ENGINE_set_load_privkey_function(e, ossltest_load_privkey)423|| !ENGINE_set_load_pubkey_function(e, ossltest_load_pubkey)424|| !ENGINE_set_init_function(e, ossltest_init)425|| !ENGINE_set_finish_function(e, ossltest_finish)) {426OSSLTESTerr(OSSLTEST_F_BIND_OSSLTEST, OSSLTEST_R_INIT_FAILED);427return 0;428}429430return 1;431}432433#ifndef OPENSSL_NO_DYNAMIC_ENGINE434static int bind_helper(ENGINE *e, const char *id)435{436if (id && (strcmp(id, engine_ossltest_id) != 0))437return 0;438if (!bind_ossltest(e))439return 0;440return 1;441}442443IMPLEMENT_DYNAMIC_CHECK_FN()444IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)445#endif446447static ENGINE *engine_ossltest(void)448{449ENGINE *ret = ENGINE_new();450if (ret == NULL)451return NULL;452if (!bind_ossltest(ret)) {453ENGINE_free(ret);454return NULL;455}456return ret;457}458459void ENGINE_load_ossltest(void)460{461/* Copied from eng_[openssl|dyn].c */462ENGINE *toadd = engine_ossltest();463if (!toadd)464return;465ENGINE_add(toadd);466ENGINE_free(toadd);467ERR_clear_error();468}469470471static int ossltest_init(ENGINE *e)472{473return 1;474}475476477static int ossltest_finish(ENGINE *e)478{479return 1;480}481482483static int ossltest_destroy(ENGINE *e)484{485destroy_digests();486destroy_ciphers();487ERR_unload_OSSLTEST_strings();488return 1;489}490491static int ossltest_digests(ENGINE *e, const EVP_MD **digest,492const int **nids, int nid)493{494int ok = 1;495if (!digest) {496/* We are returning a list of supported nids */497return ossltest_digest_nids(nids);498}499/* We are being asked for a specific digest */500switch (nid) {501case NID_md5:502*digest = digest_md5();503break;504case NID_sha1:505*digest = digest_sha1();506break;507case NID_sha256:508*digest = digest_sha256();509break;510case NID_sha384:511*digest = digest_sha384();512break;513case NID_sha512:514*digest = digest_sha512();515break;516default:517ok = 0;518*digest = NULL;519break;520}521return ok;522}523524static int ossltest_ciphers(ENGINE *e, const EVP_CIPHER **cipher,525const int **nids, int nid)526{527int ok = 1;528if (!cipher) {529/* We are returning a list of supported nids */530*nids = ossltest_cipher_nids;531return (sizeof(ossltest_cipher_nids) - 1)532/ sizeof(ossltest_cipher_nids[0]);533}534/* We are being asked for a specific cipher */535switch (nid) {536case NID_aes_128_cbc:537*cipher = ossltest_aes_128_cbc();538break;539case NID_aes_128_gcm:540*cipher = ossltest_aes_128_gcm();541break;542case NID_aes_128_cbc_hmac_sha1:543*cipher = ossltest_aes_128_cbc_hmac_sha1();544break;545default:546ok = 0;547*cipher = NULL;548break;549}550return ok;551}552553static void fill_known_data(unsigned char *md, unsigned int len)554{555unsigned int i;556557for (i=0; i<len; i++) {558md[i] = (unsigned char)(i & 0xff);559}560}561562/*563* MD5 implementation. We go through the motions of doing MD5 by deferring to564* the standard implementation. Then we overwrite the result with a will defined565* value, so that all "MD5" digests using the test engine always end up with566* the same value.567*/568static int digest_md5_init(EVP_MD_CTX *ctx)569{570return EVP_MD_meth_get_init(EVP_md5())(ctx);571}572573static int digest_md5_update(EVP_MD_CTX *ctx, const void *data,574size_t count)575{576return EVP_MD_meth_get_update(EVP_md5())(ctx, data, count);577}578579static int digest_md5_final(EVP_MD_CTX *ctx, unsigned char *md)580{581int ret = EVP_MD_meth_get_final(EVP_md5())(ctx, md);582583if (ret > 0) {584fill_known_data(md, MD5_DIGEST_LENGTH);585}586return ret;587}588589/*590* SHA1 implementation.591*/592static int digest_sha1_init(EVP_MD_CTX *ctx)593{594return EVP_MD_meth_get_init(EVP_sha1())(ctx);595}596597static int digest_sha1_update(EVP_MD_CTX *ctx, const void *data,598size_t count)599{600return EVP_MD_meth_get_update(EVP_sha1())(ctx, data, count);601}602603static int digest_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)604{605int ret = EVP_MD_meth_get_final(EVP_sha1())(ctx, md);606607if (ret > 0) {608fill_known_data(md, SHA_DIGEST_LENGTH);609}610return ret;611}612613/*614* SHA256 implementation.615*/616static int digest_sha256_init(EVP_MD_CTX *ctx)617{618return EVP_MD_meth_get_init(EVP_sha256())(ctx);619}620621static int digest_sha256_update(EVP_MD_CTX *ctx, const void *data,622size_t count)623{624return EVP_MD_meth_get_update(EVP_sha256())(ctx, data, count);625}626627static int digest_sha256_final(EVP_MD_CTX *ctx, unsigned char *md)628{629int ret = EVP_MD_meth_get_final(EVP_sha256())(ctx, md);630631if (ret > 0) {632fill_known_data(md, SHA256_DIGEST_LENGTH);633}634return ret;635}636637/*638* SHA384 implementation.639*/640static int digest_sha384_init(EVP_MD_CTX *ctx)641{642return EVP_MD_meth_get_init(EVP_sha384())(ctx);643}644645static int digest_sha384_update(EVP_MD_CTX *ctx, const void *data,646size_t count)647{648return EVP_MD_meth_get_update(EVP_sha384())(ctx, data, count);649}650651static int digest_sha384_final(EVP_MD_CTX *ctx, unsigned char *md)652{653int ret = EVP_MD_meth_get_final(EVP_sha384())(ctx, md);654655if (ret > 0) {656fill_known_data(md, SHA384_DIGEST_LENGTH);657}658return ret;659}660661/*662* SHA512 implementation.663*/664static int digest_sha512_init(EVP_MD_CTX *ctx)665{666return EVP_MD_meth_get_init(EVP_sha512())(ctx);667}668669static int digest_sha512_update(EVP_MD_CTX *ctx, const void *data,670size_t count)671{672return EVP_MD_meth_get_update(EVP_sha512())(ctx, data, count);673}674675static int digest_sha512_final(EVP_MD_CTX *ctx, unsigned char *md)676{677int ret = EVP_MD_meth_get_final(EVP_sha512())(ctx, md);678679if (ret > 0) {680fill_known_data(md, SHA512_DIGEST_LENGTH);681}682return ret;683}684685/*686* AES128 Implementation687*/688689static int ossltest_aes128_init_key(EVP_CIPHER_CTX *ctx,690const unsigned char *key,691const unsigned char *iv, int enc)692{693return EVP_CIPHER_meth_get_init(EVP_aes_128_cbc()) (ctx, key, iv, enc);694}695696static int ossltest_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,697const unsigned char *in, size_t inl)698{699unsigned char *tmpbuf;700int ret;701702tmpbuf = OPENSSL_malloc(inl);703704/* OPENSSL_malloc will return NULL if inl == 0 */705if (tmpbuf == NULL && inl > 0)706return -1;707708/* Remember what we were asked to encrypt */709if (tmpbuf != NULL)710memcpy(tmpbuf, in, inl);711712/* Go through the motions of encrypting it */713ret = EVP_CIPHER_meth_get_do_cipher(EVP_aes_128_cbc())(ctx, out, in, inl);714715/* Throw it all away and just use the plaintext as the output */716if (tmpbuf != NULL)717memcpy(out, tmpbuf, inl);718OPENSSL_free(tmpbuf);719720return ret;721}722723static int ossltest_aes128_gcm_init_key(EVP_CIPHER_CTX *ctx,724const unsigned char *key,725const unsigned char *iv, int enc)726{727return EVP_CIPHER_meth_get_init(EVP_aes_128_gcm()) (ctx, key, iv, enc);728}729730static int ossltest_aes128_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,731const unsigned char *in, size_t inl)732{733unsigned char *tmpbuf = OPENSSL_malloc(inl);734735/* OPENSSL_malloc will return NULL if inl == 0 */736if (tmpbuf == NULL && inl > 0)737return -1;738739/* Remember what we were asked to encrypt */740if (tmpbuf != NULL)741memcpy(tmpbuf, in, inl);742743/* Go through the motions of encrypting it */744EVP_CIPHER_meth_get_do_cipher(EVP_aes_128_gcm())(ctx, out, in, inl);745746/* Throw it all away and just use the plaintext as the output */747if (tmpbuf != NULL && out != NULL)748memcpy(out, tmpbuf, inl);749OPENSSL_free(tmpbuf);750751return inl;752}753754static int ossltest_aes128_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,755void *ptr)756{757/* Pass the ctrl down */758int ret = EVP_CIPHER_meth_get_ctrl(EVP_aes_128_gcm())(ctx, type, arg, ptr);759760if (ret <= 0)761return ret;762763switch (type) {764case EVP_CTRL_AEAD_GET_TAG:765/* Always give the same tag */766memset(ptr, 0, EVP_GCM_TLS_TAG_LEN);767break;768769default:770break;771}772773return 1;774}775776#define NO_PAYLOAD_LENGTH ((size_t)-1)777# define data(ctx) ((EVP_AES_HMAC_SHA1 *)EVP_CIPHER_CTX_get_cipher_data(ctx))778779static int ossltest_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,780const unsigned char *inkey,781const unsigned char *iv,782int enc)783{784EVP_AES_HMAC_SHA1 *key = data(ctx);785key->payload_length = NO_PAYLOAD_LENGTH;786return 1;787}788789static int ossltest_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx,790unsigned char *out,791const unsigned char *in,792size_t len)793{794EVP_AES_HMAC_SHA1 *key = data(ctx);795unsigned int l;796size_t plen = key->payload_length;797798key->payload_length = NO_PAYLOAD_LENGTH;799800if (len % AES_BLOCK_SIZE)801return 0;802803if (EVP_CIPHER_CTX_is_encrypting(ctx)) {804if (plen == NO_PAYLOAD_LENGTH)805plen = len;806else if (len !=807((plen + SHA_DIGEST_LENGTH +808AES_BLOCK_SIZE) & -AES_BLOCK_SIZE))809return 0;810811memmove(out, in, plen);812813if (plen != len) { /* "TLS" mode of operation */814/* calculate HMAC and append it to payload */815fill_known_data(out + plen, SHA_DIGEST_LENGTH);816817/* pad the payload|hmac */818plen += SHA_DIGEST_LENGTH;819for (l = len - plen - 1; plen < len; plen++)820out[plen] = l;821}822} else {823/* decrypt HMAC|padding at once */824memmove(out, in, len);825826if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */827unsigned int maxpad, pad;828829if (key->tls_ver >= TLS1_1_VERSION) {830if (len < (AES_BLOCK_SIZE + SHA_DIGEST_LENGTH + 1))831return 0;832833/* omit explicit iv */834in += AES_BLOCK_SIZE;835out += AES_BLOCK_SIZE;836len -= AES_BLOCK_SIZE;837} else if (len < (SHA_DIGEST_LENGTH + 1))838return 0;839840/* figure out payload length */841pad = out[len - 1];842maxpad = len - (SHA_DIGEST_LENGTH + 1);843if (pad > maxpad)844return 0;845for (plen = len - pad - 1; plen < len; plen++)846if (out[plen] != pad)847return 0;848}849}850851return 1;852}853854static int ossltest_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,855int arg, void *ptr)856{857EVP_AES_HMAC_SHA1 *key = data(ctx);858859switch (type) {860case EVP_CTRL_AEAD_SET_MAC_KEY:861return 1;862863case EVP_CTRL_AEAD_TLS1_AAD:864{865unsigned char *p = ptr;866unsigned int len;867868if (arg != EVP_AEAD_TLS1_AAD_LEN)869return -1;870871len = p[arg - 2] << 8 | p[arg - 1];872key->tls_ver = p[arg - 4] << 8 | p[arg - 3];873874if (EVP_CIPHER_CTX_is_encrypting(ctx)) {875key->payload_length = len;876if (key->tls_ver >= TLS1_1_VERSION) {877if (len < AES_BLOCK_SIZE)878return 0;879len -= AES_BLOCK_SIZE;880p[arg - 2] = len >> 8;881p[arg - 1] = len;882}883884return (int)(((len + SHA_DIGEST_LENGTH +885AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)886- len);887} else {888key->payload_length = arg;889890return SHA_DIGEST_LENGTH;891}892}893default:894return -1;895}896}897898static int ossltest_rand_bytes(unsigned char *buf, int num)899{900unsigned char val = 1;901902while (--num >= 0)903*buf++ = val++;904return 1;905}906907static int ossltest_rand_status(void)908{909return 1;910}911912static const RAND_METHOD *ossltest_rand_method(void)913{914915static RAND_METHOD osslt_rand_meth = {916NULL,917ossltest_rand_bytes,918NULL,919NULL,920ossltest_rand_bytes,921ossltest_rand_status922};923924return &osslt_rand_meth;925}926927928