]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
More crypto fixups
authorHoward Chu <hyc@openldap.org>
Tue, 26 Dec 2023 01:43:42 +0000 (01:43 +0000)
committerHoward Chu <hyc@openldap.org>
Tue, 26 Dec 2023 01:43:42 +0000 (01:43 +0000)
libraries/liblmdb/Makefile
libraries/liblmdb/crypto.c

index c252b50e21e5251e8e1eb2b0a293464349745cf5..fa9789223ab66e9b7cd77bb4918a30b71e34637d 100644 (file)
@@ -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
index 198e7a805bbd54d1886d663caf6dd246556338cd..fe98d3b9790db77499e5be7d9a71b8c6e6dc95c8 100644 (file)
@@ -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;
 }