From 51dccfb2a6edbebce791387041c65071b29545ca Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 11 Jun 2025 18:47:31 +0200 Subject: [PATCH] Improve some explanations Signed-off-by: Gilles Peskine --- library/base64.c | 25 ++++++++++++++++++++----- tests/suites/test_suite_base64.function | 6 +++++- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/library/base64.c b/library/base64.c index cc6a73d150..388fa9f388 100644 --- a/library/base64.c +++ b/library/base64.c @@ -195,13 +195,28 @@ int mbedtls_base64_decode(unsigned char *dst, size_t dlen, size_t *olen, } /* We've determined that the input is valid, and that it contains - * n digits-plus-trailing-equal-signs, which means (n - equals) digits. - * Now set *olen to the exact length of the output. */ - /* Each block of 4 digits in the input map to 3 bytes of output. - * The last block can have one or two equal signs, in which case - * there are that many fewer output bytes. */ + * exactly k blocks of digits-or-equals, with n = 4 * k, + * and equals only present at the end of the last block if at all. + * Now we can calculate the length of the output. + * + * Each block of 4 digits in the input map to 3 bytes of output. + * For the last block: + * - abcd (where abcd are digits) is a full 3-byte block; + * - abc= means 1 byte less than a full 3-byte block of output; + * - ab== means 2 bytes less than a full 3-byte block of output; + * - a==== and ==== is rejected above. + */ *olen = (n / 4) * 3 - equals; + /* If the output buffer is too small, signal this and stop here. + * Also, as documented, stop here if `dst` is null, independently of + * `dlen`. + * + * There is an edge case when the output is empty: in this case, + * `dlen == 0` with `dst == NULL` is valid (on some platforms, + * `malloc(0)` returns `NULL`). Since the call is valid, we return + * 0 in this case. + */ if ((*olen != 0 && dst == NULL) || dlen < *olen) { return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL; } diff --git a/tests/suites/test_suite_base64.function b/tests/suites/test_suite_base64.function index 3bd9932408..095f980f3f 100644 --- a/tests/suites/test_suite_base64.function +++ b/tests/suites/test_suite_base64.function @@ -123,7 +123,11 @@ void mbedtls_base64_decode(char *src_string, char *dst_string, int result) TEST_EQUAL(correct_dst_len, len); } - /* Test an empty output buffer */ + /* Test an empty output buffer. `mbedtls_base64_decode()` must return + * `BUFFER_TOO_SMALL` but report the correct output length. + * Skip this when dst_size==0 since that would be a valid call to + * `mbedtls_base64_decode()` which should return 0. + */ if (result == 0 && dst_size != 0) { TEST_EQUAL(mbedtls_base64_decode(NULL, 0, &len, src, src_len),