From: Howard Chu Date: Tue, 26 Dec 2023 01:43:42 +0000 (+0000) Subject: More crypto fixups X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b36e177c5ab41f5c22e4165358ac2df11bc6f7a7;p=thirdparty%2Fopenldap.git More crypto fixups --- diff --git a/libraries/liblmdb/Makefile b/libraries/liblmdb/Makefile index c252b50e21..fa9789223a 100644 --- a/libraries/liblmdb/Makefile +++ b/libraries/liblmdb/Makefile @@ -96,7 +96,7 @@ mtest_enc2: mtest_enc2.o module.o liblmdb.a crypto.lm $(CC) $(LDFLAGS) -pthread -o $@ mtest_enc2.o module.o liblmdb.a $(LDL) crypto.lm: crypto.c - $(CC) -shared -o $@ -lcrypto + $(CC) -shared $(CFLAGS) -o $@ $^ -lcrypto mdb.o: mdb.c lmdb.h midl.h $(CC) $(CFLAGS) $(CPPFLAGS) -c mdb.c diff --git a/libraries/liblmdb/crypto.c b/libraries/liblmdb/crypto.c index 198e7a805b..fe98d3b979 100644 --- a/libraries/liblmdb/crypto.c +++ b/libraries/liblmdb/crypto.c @@ -32,8 +32,14 @@ static int mcf_str2key(const char *passwd, MDB_val *key) return 0; } -/* cheats - internal OpenSSL 1.1 structures */ -typedef struct evp_cipher_ctx_st { +/* cheats - internal OpenSSL 1.1 structures + * These are copied from the OpenSSL source code. + * + * We use these to allow stack allocation of these structures + * and to prevent OpenSSL from malloc'ing and free'ing them, + * which would be too slow. + */ +typedef struct my_cipher_ctx_st { const EVP_CIPHER *cipher; ENGINE *engine; /* functional reference if 'cipher' is * ENGINE-provided */ @@ -63,7 +69,17 @@ typedef struct evp_cipher_ctx_st { void *algctx; EVP_CIPHER *fetched_cipher; #endif -} EVP_CIPHER_CTX; +} MY_CIPHER_CTX; + +typedef struct evp_cipher_head { + int nid; + int block_size; + int key_len; + int iv_len; + unsigned long flags; + int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +} evp_cipher_head; #define CHACHA_KEY_SIZE 32 #define CHACHA_CTR_SIZE 16 @@ -78,41 +94,67 @@ typedef struct { unsigned int counter[CHACHA_CTR_SIZE / 4]; unsigned char buf[CHACHA_BLK_SIZE]; unsigned int partial_len; -} EVP_CHACHA_KEY; +} MY_CHACHA_KEY; typedef struct { - EVP_CHACHA_KEY key; + MY_CHACHA_KEY key; unsigned int nonce[12/4]; unsigned char tag[POLY1305_BLOCK_SIZE]; unsigned char tls_aad[POLY1305_BLOCK_SIZE]; struct { uint64_t aad, text; } len; int aad, mac_inited, tag_len, nonce_len; size_t tls_payload_length; -} EVP_CHACHA_AEAD_CTX; +} MY_CHACHA_AEAD_CTX; + +typedef struct { + double opaque[24]; + unsigned int nonce[4]; + unsigned char data[POLY1305_BLOCK_SIZE]; + size_t num; + struct { + void (*foo1)(); + void (*foo2)(); + } func; +} my_poly1305_ctx; + +typedef struct my_cipherdata { + MY_CHACHA_AEAD_CTX aead_ctx; + my_poly1305_ctx poly_ctx; +} my_cipherdata; static int mcf_encfunc(const MDB_val *src, MDB_val *dst, const MDB_val *key, int encdec) { unsigned char iv[12]; int ivl, outl, rc; mdb_size_t *ptr; - EVP_CIPHER_CTX ctx = {0}; - EVP_CHACHA_AEAD_CTX cactx; + MY_CIPHER_CTX myctx = {0}; + EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *)&myctx; + my_cipherdata cactx; + evp_cipher_head *eh = (evp_cipher_head *)cipher; - ctx.cipher_data = &cactx; ptr = key[1].mv_data; ivl = ptr[0] & 0xffffffff; memcpy(iv, &ivl, 4); memcpy(iv+4, ptr+1, sizeof(mdb_size_t)); - EVP_CipherInit_ex(&ctx, cipher, NULL, key[0].mv_data, iv, encdec); - EVP_CIPHER_CTX_set_padding(&ctx, 0); + EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, encdec); + + /* we can't set cipher_data before calling CipherInit because + * that will just try to free it. So set it now, and then finish + * up the other two Init calls that we disabled before. + */ + myctx.cipher_data = &cactx; + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL); + eh->init(ctx, key[0].mv_data, iv, encdec); + + EVP_CIPHER_CTX_set_padding(ctx, 0); if (!encdec) { - EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_AEAD_SET_TAG, key[2].mv_size, key[2].mv_data); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, key[2].mv_size, key[2].mv_data); } - rc = EVP_CipherUpdate(&ctx, dst->mv_data, &outl, src->mv_data, src->mv_size); + rc = EVP_CipherUpdate(ctx, dst->mv_data, &outl, src->mv_data, src->mv_size); if (rc) - rc = EVP_CipherFinal_ex(&ctx, key[2].mv_data, &outl); + rc = EVP_CipherFinal_ex(ctx, key[2].mv_data, &outl); if (rc && encdec) { - EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_AEAD_GET_TAG, key[2].mv_size, key[2].mv_data); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, key[2].mv_size, key[2].mv_data); } return rc == 0; } @@ -128,6 +170,12 @@ static const MDB_crypto_funcs mcf_table = { MDB_crypto_funcs *MDB_crypto() { + evp_cipher_head *eh; cipher = (EVP_CIPHER *)EVP_chacha20_poly1305(); + + /* We must disable the implicit init calls */ + eh = (evp_cipher_head *)cipher; + eh->flags &= ~(EVP_CIPH_CTRL_INIT|EVP_CIPH_ALWAYS_CALL_INIT); + return (MDB_crypto_funcs *)&mcf_table; }