From c0f9c22efde417f0542bbb84a6743132300680d5 Mon Sep 17 00:00:00 2001 From: Stephen Waits Date: Tue, 12 May 2026 09:23:29 -0600 Subject: [PATCH] spec(encrypted): clarify zero-padding scheme for AES plaintext Tighten the encryption steps to spell out: - Plaintext is zero-padded on the right to a multiple of 16 bytes before AES-128-ECB encryption. - The padding is NOT PKCS#7 (not unambiguous); the receiver must disambiguate trailing zeros using the inner plaintext format (e.g., for TXT_MSG, by C-string NUL termination scan). - Renumber steps so the padding step is explicit and ordered before encryption, instead of being a parenthetical on the encrypt step. Validated against upstream meshcore-dev/MeshCore @ 1a7b361 (Utils::encrypt / Utils::decrypt, src/Utils.cpp:30-, comment "dest may contain trailing zero bytes in final block"). Co-Authored-By: Claude Opus 4.7 (1M context) --- spec/06-payload-encrypted.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/spec/06-payload-encrypted.md b/spec/06-payload-encrypted.md index e017539..a2d2b5f 100644 --- a/spec/06-payload-encrypted.md +++ b/spec/06-payload-encrypted.md @@ -49,11 +49,16 @@ The ciphertext is produced using the encrypt-then-MAC scheme described in [Section 14](14-crypto.md): 1. Compute the ECDH shared secret between sender and recipient. -2. Encrypt the plaintext using AES-128-ECB with the first 16 bytes of the - shared secret as the key. Zero-pad the final block. -3. Compute HMAC-SHA256 over the ciphertext using the full 32-byte shared secret - as the HMAC key. Truncate to 2 bytes. -4. Prepend the 2-byte MAC to the ciphertext. +2. Zero-pad the plaintext on the right with `0x00` bytes until its length is a + multiple of 16 (AES block size). If the plaintext is already a multiple of + 16, no padding is added (the scheme is not unambiguous PKCS#7-style + padding — the receiver MUST disambiguate trailing zeros using the inner + plaintext format; see "Plaintext Format" below). +3. Encrypt the padded plaintext using AES-128-ECB with the first 16 bytes of + the shared secret as the key. +4. Compute HMAC-SHA256 over the ciphertext using the full 32-byte shared + secret as the HMAC key. Truncate to 2 bytes. +5. Prepend the 2-byte MAC to the ciphertext. ### Decryption