Unsigned-underflow-dependent bounds check in mbedtls_nist_kw_unwrap() (robustness only, verified not exploitable)
tf-psa-crypto/extras/nist_kw.c:331:
if (output_size < input_length - KW_SEMIBLOCK_LENGTH) {
ret = PSA_ERROR_BUFFER_TOO_SMALL;
goto cleanup;
}input_length - KW_SEMIBLOCK_LENGTH (8) unsigned-underflows to a huge size_t for input_length < 8, and runs before the mode-specific input_length < 24 guard a few lines later.
I verified this is not currently exploitable, including under deliberate caller misuse: with a realistic output_size (e.g. 256), the underflowed comparison always still rejects. With an adversarial output_size = SIZE_MAX (e.g. from a miscomputed caller-side size variable), the check does fall through, but the independent, non-underflow-dependent input_length < 24 guard downstream still rejects the same too-short input — confirmed clean under AddressSanitizer/UBSan in both scenarios, no memory corruption in either case.
This is filed as a robustness/defensive-coding improvement, not an active vulnerability report — the bounds check's correctness currently depends on output_size happening to be smaller than a near-SIZE_MAX underflowed value, which is fragile even though nothing exploits it today.
Suggested fix:
--- a/tf-psa-crypto/extras/nist_kw.c
+++ b/tf-psa-crypto/extras/nist_kw.c
@@ -328,7 +328,8 @@ psa_status_t mbedtls_nist_kw_unwrap(mbedtls_svc_key_id_t key,
if (ret != PSA_SUCCESS) {
goto cleanup;
}
- if (output_size < input_length - KW_SEMIBLOCK_LENGTH) {
+ if (input_length < KW_SEMIBLOCK_LENGTH ||
+ output_size < input_length - KW_SEMIBLOCK_LENGTH) {
ret = PSA_ERROR_BUFFER_TOO_SMALL;
goto cleanup;
}Found during an independent CERT-C static-analysis audit of library/** (AI-tool-assisted triage/drafting; manually re-verified, including the adversarial-misuse case, under AddressSanitizer/UBSan before filing). Happy to open this as a PR instead if preferred.
Source: Mbed-TLS/mbedtls