From 84999d1a7bd0068c08e623a17cddb11674312f61 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 4 Jun 2025 10:33:31 +0200 Subject: [PATCH] Fix mbedtls_base64_decode() accepting invalid inputs with 4n+1 digits The last digit was ignored. Signed-off-by: Gilles Peskine --- ChangeLog.d/base64_decode.txt | 3 +++ library/base64.c | 6 ++++++ tests/suites/test_suite_base64.data | 24 ++++++++++++------------ 3 files changed, 21 insertions(+), 12 deletions(-) create mode 100644 ChangeLog.d/base64_decode.txt diff --git a/ChangeLog.d/base64_decode.txt b/ChangeLog.d/base64_decode.txt new file mode 100644 index 0000000000..93dfef12ff --- /dev/null +++ b/ChangeLog.d/base64_decode.txt @@ -0,0 +1,3 @@ +Bugfix + * Fix mbedtls_base64_decode() accepting invalid inputs with 4n+1 digits + (the last digit was ignored). diff --git a/library/base64.c b/library/base64.c index 9677dee5b2..bff9123398 100644 --- a/library/base64.c +++ b/library/base64.c @@ -183,6 +183,12 @@ int mbedtls_base64_decode(unsigned char *dst, size_t dlen, size_t *olen, n++; } + /* In valid base64, the number of digits is always of the form + * 4n, 4n+2 or 4n+3. */ + if ((n - equals) % 4 == 1) { + return MBEDTLS_ERR_BASE64_INVALID_CHARACTER; + } + if (n == 0) { *olen = 0; return 0; diff --git a/tests/suites/test_suite_base64.data b/tests/suites/test_suite_base64.data index 9488df3a21..4d3b5b9a1a 100644 --- a/tests/suites/test_suite_base64.data +++ b/tests/suites/test_suite_base64.data @@ -84,14 +84,14 @@ mbedtls_base64_decode:"zm masd":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER # output when dlen < 3, but actually outputs 2 bytes if given a # buffer of 3 bytes or more. -Base64 decode: 1 digit, 0 equals (sloppily accepted) -mbedtls_base64_decode:"Y":"!":0 +Base64 decode: 1 digit, 0 equals (bad) +mbedtls_base64_decode:"Y":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER -Base64 decode: 1 digit, 1 equals (sloppily accepted) -mbedtls_base64_decode:"Y":"!":0 +Base64 decode: 1 digit, 1 equals (bad) +mbedtls_base64_decode:"Y":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER -Base64 decode: 1 digit, 2 equals (sloppily accepted) -mbedtls_base64_decode:"Y==":"!":0 +Base64 decode: 1 digit, 2 equals (bad) +mbedtls_base64_decode:"Y==":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER Base64 decode: 1 digit, 3 equals (bad) mbedtls_base64_decode:"Y===":"!":MBEDTLS_ERR_BASE64_INVALID_CHARACTER @@ -132,14 +132,14 @@ mbedtls_base64_decode:"Y29t==":"com":0 Base64 decode: 4 digits, 3 equals (bad) mbedtls_base64_decode:"Y29t===":"com":MBEDTLS_ERR_BASE64_INVALID_CHARACTER -Base64 decode: 5 digits, 0 equals (sloppily accepted) -mbedtls_base64_decode:"Y29tc":"com!":0 +Base64 decode: 5 digits, 0 equals (bad) +mbedtls_base64_decode:"Y29tc":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER -Base64 decode: 5 digits, 1 equals (sloppily accepted) -mbedtls_base64_decode:"Y29tc=":"com!":0 +Base64 decode: 5 digits, 1 equals (bad) +mbedtls_base64_decode:"Y29tc=":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER -Base64 decode: 5 digits, 2 equals (sloppily accepted) -mbedtls_base64_decode:"Y29tc==":"com!":0 +Base64 decode: 5 digits, 2 equals (bad) +mbedtls_base64_decode:"Y29tc==":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER Base64 decode: 5 digits, 3 equals (bad) mbedtls_base64_decode:"Y29tc===":"com!":MBEDTLS_ERR_BASE64_INVALID_CHARACTER