mbedtls_base64_decode: assert sloppy behavior with bad number of =

Add unit tests covering cases where the number of digits plus equal signs is
not a multiple of 4. These are invalid inputs, but they are currently
accepted as long as the number of equal signs is at most 2.

The tests assert the current behavior, not behavior that is desirable.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
Gilles Peskine
2025-06-03 22:01:33 +02:00
parent 715bbf3e0c
commit 683a46e6c1
2 changed files with 115 additions and 0 deletions

View File

@@ -76,6 +76,110 @@ mbedtls_base64_decode:"zm=masd":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode (Space inside string)
mbedtls_base64_decode:"zm masd":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
# Validate the weird behavior of mbedtls_base64_decode() on some
# invalid inputs (number of digts + equals not a multiple of 4).
# In the reference output, "!" characters at the end are needed to
# pad the output buffer, but the actual output omits those. E.g. if
# dst_string is "ab!" then mbedtls_base64_decode() reports a 3-byte
# 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, 1 equals (sloppily accepted)
mbedtls_base64_decode:"Y":"!":0
Base64 decode: 1 digit, 2 equals (sloppily accepted)
mbedtls_base64_decode:"Y==":"!":0
Base64 decode: 1 digit, 3 equals (bad)
mbedtls_base64_decode:"Y===":"!":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 2 digits, 0 equals (sloppily accepted)
mbedtls_base64_decode:"Yw":"!!":0
Base64 decode: 2 digits, 1 equals (sloppily accepted)
mbedtls_base64_decode:"Yw=":"!!":0
Base64 decode: 2 digits, 2 equals (good)
mbedtls_base64_decode:"Yw==":"c":0
Base64 decode: 2 digits, 3 equals (bad)
mbedtls_base64_decode:"Yw===":"c":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 3 digits, 0 equals (sloppily accepted)
mbedtls_base64_decode:"Y28":"!!!":0
Base64 decode: 3 digits, 1 equals (good)
mbedtls_base64_decode:"Y28=":"co":0
Base64 decode: 3 digits, 2 equals (sloppily accepted)
mbedtls_base64_decode:"Y28==":"co":0
Base64 decode: 3 digits, 3 equals (bad)
mbedtls_base64_decode:"Y28===":"co":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 4 digits, 0 equals (good)
mbedtls_base64_decode:"Y29t":"com":0
Base64 decode: 4 digits, 1 equals (sloppily accepted)
mbedtls_base64_decode:"Y29t=":"com":0
Base64 decode: 4 digits, 2 equals (sloppily accepted)
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, 1 equals (sloppily accepted)
mbedtls_base64_decode:"Y29tc=":"com!":0
Base64 decode: 5 digits, 2 equals (sloppily accepted)
mbedtls_base64_decode:"Y29tc==":"com!":0
Base64 decode: 5 digits, 3 equals (bad)
mbedtls_base64_decode:"Y29tc===":"com!":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 6 digits, 0 equals (sloppily accepted)
mbedtls_base64_decode:"Y29tcA":"com!!":0
Base64 decode: 6 digits, 1 equals (sloppily accepted)
mbedtls_base64_decode:"Y29tcA=":"com!!":0
Base64 decode: 6 digits, 2 equals (good)
mbedtls_base64_decode:"Y29tcA==":"comp":0
Base64 decode: 6 digits, 3 equals (bad)
mbedtls_base64_decode:"Y29tcA===":"comp":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 7 digits, 0 equals (sloppily accepted)
mbedtls_base64_decode:"Y29tcG8":"com!!!":0
Base64 decode: 7 digits, 1 equals (good)
mbedtls_base64_decode:"Y29tcG8=":"compo":0
Base64 decode: 7 digits, 2 equals (sloppily accepted)
mbedtls_base64_decode:"Y29tcG8==":"compo":0
Base64 decode: 7 digits, 3 equals (bad)
mbedtls_base64_decode:"Y29tcG8===":"compo":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 8 digits, 0 equals (good)
mbedtls_base64_decode:"Y29tcG9z":"compos":0
Base64 decode: 8 digits, 1 equals (sloppily accepted)
mbedtls_base64_decode:"Y29tcG9z=":"compos":0
Base64 decode: 8 digits, 2 equals (sloppily accepted)
mbedtls_base64_decode:"Y29tcG9z==":"compos":0
Base64 decode: 8 digits, 3 equals (bad)
mbedtls_base64_decode:"Y29tcG9z===":"compos":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode "Zm9vYmFy" (no newline nor '\0' at end)
base64_decode_hex_src:"5a6d3976596d4679":"foobar":0

View File

@@ -99,7 +99,18 @@ void mbedtls_base64_decode(char *src_string, char *dst_string, int result)
TEST_CALLOC(dst, dst_size);
/* Validate broken behavior observed on Mbed TLS 3.6.3:
* some invalid inputs are accepted, and asking for the decoded length
* gives a figure that's longer than the decoded output.
* In the test data, trailing "!" characters in dst_string indicate
* padding that must be present in the output buffer length, but
* will not be present in the actual output when the output buffer
* is large enough.
*/
size_t expected_dst_len = correct_dst_len;
while (expected_dst_len > 0 && dst_string[expected_dst_len - 1] == '!') {
--expected_dst_len;
}
/* Test normal operation */
TEST_EQUAL(mbedtls_base64_decode(dst, dst_size, &len,