From 019e2ff4d0c778a3327ae1cc97ec2baa5c723cc7 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 16 Jun 2026 15:22:57 +0100 Subject: [PATCH 1/2] ITS#10523 LMDB: allow checksum with authenticated encryption --- libraries/liblmdb/mdb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index f2dff391ee..0ca6c400d4 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -7307,7 +7307,7 @@ static void mdb_rpage_dispose(MDB_env *env, MDB_ID3 *id3) static void mdb_page_set_checksum(MDB_env *env, MDB_page *mp, size_t size) { MDB_val src, dst, *key; - src.mv_size = size - env->me_sumsize; + src.mv_size = size - env->me_sumsize - env->me_esumsize; src.mv_data = mp; dst.mv_size = env->me_sumsize; dst.mv_data = (char *)src.mv_data + src.mv_size; @@ -7322,7 +7322,7 @@ static int mdb_page_chk_checksum(MDB_env *env, MDB_page *mp, size_t size) { MDB_val src, dst, chk, *key; char sumbuf[256]; - src.mv_size = size - env->me_sumsize; + src.mv_size = size - env->me_sumsize - env->me_esumsize; src.mv_data = mp; chk.mv_size = env->me_sumsize; chk.mv_data = (char *)src.mv_data + src.mv_size; From ec8ad82c4e5c6b709e8bcfebea86a6451fa7aa85 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 16 Jun 2026 15:24:22 +0100 Subject: [PATCH 2/2] ITS#10523 LMDB: add sample for checksum plus authenticated encryption --- libraries/liblmdb/cryptoc.c | 97 +++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 libraries/liblmdb/cryptoc.c diff --git a/libraries/liblmdb/cryptoc.c b/libraries/liblmdb/cryptoc.c new file mode 100644 index 0000000000..4403fe4ee6 --- /dev/null +++ b/libraries/liblmdb/cryptoc.c @@ -0,0 +1,97 @@ +/* crypto.c - LMDB encryption helper module */ +/* + * Copyright 2020-2024 Howard Chu, Symas Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the Symas + * Dual-Use License. + * + * A copy of this license is available in the file LICENSE in the + * source distribution. + */ +#include + +#include + +#include "lmdb.h" + +#define KEYBYTES crypto_aead_chacha20poly1305_ietf_KEYBYTES +#define NONCEBYTES crypto_aead_chacha20poly1305_ietf_NPUBBYTES +#define MACBYTES crypto_aead_chacha20poly1305_ietf_ABYTES +#define SUMBYTES crypto_hash_sha256_BYTES + +MDB_crypto_hooks MDB_crypto; + +static int mcf_str2key(const char *passwd, MDB_val *key) +{ + crypto_hash_sha256_state state; + + crypto_hash_sha256_init(&state); + crypto_hash_sha256_update(&state, (const unsigned char *)"Just a Constant", sizeof("Just a Constant")); + crypto_hash_sha256_update(&state, (const unsigned char *)passwd, strlen(passwd)); + crypto_hash_sha256_final(&state, key->mv_data); + return 0; +} + +static void mcf_sumfunc(const MDB_val *src, MDB_val *dst, const MDB_val *key) +{ + crypto_hash_sha256_state state; + + crypto_hash_sha256_init(&state); + if (key) + crypto_hash_sha256_update(&state, (const unsigned char *)key->mv_data, key->mv_size); + crypto_hash_sha256_update(&state, (const unsigned char *)src->mv_data, src->mv_size); + crypto_hash_sha256_final(&state, dst->mv_data); +} + +#define ENC(dst, src, mac, key, iv) \ + crypto_aead_chacha20poly1305_ietf_encrypt_detached(dst->mv_data, mac, &mlen, \ + src->mv_data, src->mv_size, NULL, 0, NULL, iv, key) + +#define DEC(dst, src, mac, key, iv) \ + crypto_aead_chacha20poly1305_ietf_decrypt_detached(dst->mv_data, NULL, src->mv_data, \ + src->mv_size, mac, NULL, 0, iv, key) + +static int mcf_encfunc(const MDB_val *src, MDB_val *dst, const MDB_val *key, int encdec) +{ + unsigned char iv[NONCEBYTES]; + mdb_size_t *ptr; + int ivl, rc; + unsigned long long mlen; + + /* the nonce is only 12 bytes */ + ptr = key[1].mv_data; + ivl = ptr[0] & 0xffffffff; + memcpy(iv, &ivl, 4); + memcpy(iv+4, ptr+1, sizeof(mdb_size_t)); + + if (encdec) { + rc = ENC(dst, src, key[2].mv_data, key[0].mv_data, iv); + } else { + if (key[2].mv_size) + rc = DEC(dst, src, key[2].mv_data, key[0].mv_data, iv); + else { + /* Decrypting without MAC check: only used when decrypting page + * headers during incremental load. + */ + rc = crypto_stream_chacha20_ietf_xor_ic(dst->mv_data, src->mv_data, + src->mv_size, iv, 1, key[0].mv_data); + } + } + return rc; +} + +static const MDB_crypto_funcs mcf_table = { + mcf_str2key, + mcf_encfunc, + mcf_sumfunc, + KEYBYTES, + MACBYTES, + SUMBYTES +}; + +MDB_crypto_funcs *MDB_crypto() +{ + return (MDB_crypto_funcs *)&mcf_table; +}