From 3f463202bdd8684c649ee9eb5d9ba867dc6e8f08 Mon Sep 17 00:00:00 2001 From: =?utf8?q?P=C3=A1draig=20Brady?= Date: Thu, 26 Oct 2023 16:25:03 +0100 Subject: [PATCH] base32, base64: disallow non-canonical encodings Unconditionally disallow encodings that don't have appropriate zero bits before padding characters. This handles one class of encoding variations discussed at: https://eprint.iacr.org/2022/361.pdf Note the other variations discussed there, due to optional padding characters are already disallowed. * lib/base32.c: Check that discarded bits in the encoding are zero. * lib/base64.c: Likewise. * tests/test-base32.c: Add test cases. * tests/test-base64.c: Likewise. --- ChangeLog | 8 ++++++++ lib/base32.c | 18 ++++++++++++++++++ lib/base64.c | 8 ++++++++ tests/test-base32.c | 15 +++++++++++++++ tests/test-base64.c | 9 +++++++++ 5 files changed, 58 insertions(+) diff --git a/ChangeLog b/ChangeLog index 82e7021279..c9f4186f82 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2023-10-26 Pádraig Brady + + base32, base64: disallow non-canonical encodings + * lib/base32.c: Check that discarded bits in the encoding are zero. + * lib/base64.c: Likewise. + * tests/test-base32.c: Add test cases. + * tests/test-base64.c: Likewise. + 2023-10-26 Bruno Haible fenv: Add tests. diff --git a/lib/base32.c b/lib/base32.c index 2d692a2b38..777328f56d 100644 --- a/lib/base32.c +++ b/lib/base32.c @@ -354,6 +354,10 @@ decode_8 (char const *restrict in, idx_t inlen, if (in[3] != '=' || in[4] != '=' || in[5] != '=' || in[6] != '=' || in[7] != '=') return_false; + + /* Reject non-canonical encodings. */ + if (base32_to_int[to_uchar (in[1])] & 0x03) + return_false; } else { @@ -372,6 +376,10 @@ decode_8 (char const *restrict in, idx_t inlen, { if (in[5] != '=' || in[6] != '=' || in[7] != '=') return_false; + + /* Reject non-canonical encodings. */ + if (base32_to_int[to_uchar (in[3])] & 0x0f) + return_false; } else { @@ -389,6 +397,10 @@ decode_8 (char const *restrict in, idx_t inlen, { if (in[6] != '=' || in[7] != '=') return_false; + + /* Reject non-canonical encodings. */ + if (base32_to_int[to_uchar (in[4])] & 0x01) + return_false; } else { @@ -415,6 +427,12 @@ decode_8 (char const *restrict in, idx_t inlen, --*outleft; } } + else + { + /* Reject non-canonical encodings. */ + if (base32_to_int[to_uchar (in[6])] & 0x07) + return_false; + } } } } diff --git a/lib/base64.c b/lib/base64.c index 59a2135bf1..da3e8aefb8 100644 --- a/lib/base64.c +++ b/lib/base64.c @@ -396,6 +396,10 @@ decode_4 (char const *restrict in, idx_t inlen, if (in[3] != '=') return_false; + + /* Reject non-canonical encodings. */ + if (base64_to_int[to_uchar (in[1])] & 0x0f) + return_false; } else { @@ -416,6 +420,10 @@ decode_4 (char const *restrict in, idx_t inlen, { if (inlen != 4) return_false; + + /* Reject non-canonical encodings. */ + if (base64_to_int[to_uchar (in[2])] & 0x03) + return_false; } else { diff --git a/tests/test-base32.c b/tests/test-base32.c index 2e7d3c53b3..16fb982edb 100644 --- a/tests/test-base32.c +++ b/tests/test-base32.c @@ -256,5 +256,20 @@ main (void) ok = base32_decode_alloc_ctx (NULL, "AABBAA=A", 8, &p, &len); ASSERT (!ok); + ok = base32_decode_alloc_ctx (NULL, "FZ======", 8, &p, &len); + ASSERT (!ok); + + ok = base32_decode_alloc_ctx (NULL, "FYXB====", 8, &p, &len); + ASSERT (!ok); + + ok = base32_decode_alloc_ctx (NULL, "FYXC5===", 8, &p, &len); + ASSERT (!ok); + + ok = base32_decode_alloc_ctx (NULL, "FYXC4LR=", 8, &p, &len); + ASSERT (!ok); + + ok = base32_decode_alloc_ctx (NULL, "FZ======FY======", 16, &p, &len); + ASSERT (!ok); + return 0; } diff --git a/tests/test-base64.c b/tests/test-base64.c index 5196db09f4..0da5f99054 100644 --- a/tests/test-base64.c +++ b/tests/test-base64.c @@ -233,5 +233,14 @@ main (void) ok = base64_decode_alloc_ctx (NULL, "aax=X", 5, &p, &len); ASSERT (!ok); + ok = base64_decode_alloc_ctx (NULL, "SGVsbG9=", 8, &p, &len); + ASSERT (!ok); + + ok = base64_decode_alloc_ctx (NULL, "TR==", 4, &p, &len); + ASSERT (!ok); + + ok = base64_decode_alloc_ctx (NULL, "TWF=TWE=", 8, &p, &len); + ASSERT (!ok); + return 0; } -- 2.39.5