https://bugs.openldap.org/show_bug.cgi?id=10523
Issue ID: 10523 Summary: LMDBv1.0 encryption tromps on checksums Product: LMDB Version: unspecified Hardware: All OS: All Status: UNCONFIRMED Keywords: needs_review Severity: normal Priority: --- Component: liblmdb Assignee: bugs@openldap.org Reporter: dan@shearer.org Target Milestone: ---
In mdb.c , encryption and checksums cannot be used together even though it looks like that was the intention.
`OVPAGES` accounts for both `me_sumsize` and `me_esumsize`, so that suggests there should be room. However, with checksums on, the authentication-data slot `enckeys[2]` (sized `me_esumsize`, placed at the end of the page) overlaps the region the per-page checksum (`me_sumsize`) already used. So the authentication data overwrites the checksum. There may also be an ordering problem with which of set_checksum and set_encrypt are called first, but that will go away if encryption stops tromping on checksums.
There are use cases for having both turned on, and the one I care about is that implementers of encryption often do a terrible job. I am currently being an implementer of encryption so I want to have a way to see if I'm doing a terrible job. One way is to switch on checksums, because the way LMDB works is that checksums verify that the plain text stays the same having been en/decrypted. It is possible (indeed relatively common) to have silently failing encryption pass tests because the rubbish it generates is consistent rubbish. Besides, it's a great stress test, or would be if LMDB didn't corrupt itself instantly.
https://bugs.openldap.org/show_bug.cgi?id=10523
--- Comment #1 from Howard Chu hyc@openldap.org --- (In reply to Dan Shearer from comment #0)
In mdb.c , encryption and checksums cannot be used together even though it looks like that was the intention.
No. If you want encryption and checksums, you use authenticated encryption and leave it at that. Or you use a non-authenticated cipher, and plain checksum support. It makes no sense to use a plain checksum plus encrypted authentication.
`OVPAGES` accounts for both `me_sumsize` and `me_esumsize`, so that suggests there should be room. However, with checksums on, the authentication-data slot `enckeys[2]` (sized `me_esumsize`, placed at the end of the page) overlaps the region the per-page checksum (`me_sumsize`) already used. So the authentication data overwrites the checksum. There may also be an ordering problem with which of set_checksum and set_encrypt are called first, but that will go away if encryption stops tromping on checksums.
There are use cases for having both turned on, and the one I care about is that implementers of encryption often do a terrible job. I am currently being an implementer of encryption so I want to have a way to see if I'm doing a terrible job. One way is to switch on checksums, because the way LMDB works is that checksums verify that the plain text stays the same having been en/decrypted. It is possible (indeed relatively common) to have silently failing encryption pass tests because the rubbish it generates is consistent rubbish. Besides, it's a great stress test, or would be if LMDB didn't corrupt itself instantly.
https://bugs.openldap.org/show_bug.cgi?id=10523
--- Comment #2 from Howard Chu hyc@openldap.org --- I guess you can do this if you really want to.
diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 9e6fab9ede..503f18c097 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;
Still it doesn't make a lot of sense since any authenticated encryption mechanism *will* return an error code if the decryption fails for any reason. There is no value add here, in routine use.
https://bugs.openldap.org/show_bug.cgi?id=10523
Howard Chu hyc@openldap.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords|needs_review | Resolution|--- |FIXED Status|UNCONFIRMED |RESOLVED
--- Comment #3 from Howard Chu hyc@openldap.org --- Added in git
https://bugs.openldap.org/show_bug.cgi?id=10523
Quanah Gibson-Mount quanah@openldap.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|--- |1.0.0
--- Comment #4 from Quanah Gibson-Mount quanah@openldap.org --- mdb.RE/1.0:
• 019e2ff4 by Howard Chu at 2026-06-16T15:23:38+01:00 ITS#10523 LMDB: allow checksum with authenticated encryption
• ec8ad82c by Howard Chu at 2026-06-16T15:24:58+01:00 ITS#10523 LMDB: add sample for checksum plus authenticated encryption
mdb.master3:
• c9771ceb by Howard Chu at 2026-06-16T15:22:57+01:00 ITS#10523 LMDB: allow checksum with authenticated encryption
• 6224855b by Howard Chu at 2026-06-16T15:24:22+01:00 ITS#10523 LMDB: add sample for checksum plus authenticated encryption
https://bugs.openldap.org/show_bug.cgi?id=10523
Quanah Gibson-Mount quanah@openldap.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |VERIFIED