Prepare for v5.9.1 release#126
Conversation
In the newer wolfSSL signing and verifying without context is not available unless it is explicitly enabled. This change modifies the Python binding and test suite to accommodate this.
Smaller authentication tags may not be supported by the library. This fix makes the test work for the default case that tags should be minimum 12 bytes in size.
| features["RSA_PSS"] = 1 if '#define WC_RSA_PSS' in defines else 0 | ||
| features["CHACHA20_POLY1305"] = 1 if ('#define HAVE_CHACHA' in defines and '#define HAVE_POLY1305' in defines) else 0 | ||
| features["ML_DSA"] = 1 if '#define HAVE_DILITHIUM' in defines else 0 | ||
| features["ML_DSA_NO_CTX"] = 1 if '#define WOLFSSL_DILITHIUM_NO_CTX' in defines else 0 |
There was a problem hiding this comment.
MEDIUM-1: ML_DSA_NO_CTX detection misses indirect define via WOLFSSL_DILITHIUM_FIPS204_DRAFT [SUGGEST] (bug)
File: scripts/build_ffi.py:379
Function: get_features
Confidence: Medium
The new feature detection only checks for a literal #define WOLFSSL_DILITHIUM_NO_CTX in options.h/user_settings.h. However, lib/wolfssl/wolfssl/wolfcrypt/dilithium.h (lines 808-811) defines WOLFSSL_DILITHIUM_NO_CTX internally whenever WOLFSSL_DILITHIUM_FIPS204_DRAFT is enabled. In that configuration the legacy no-context functions (wc_dilithium_sign_msg, wc_dilithium_sign_msg_with_seed, wc_dilithium_verify_msg) are actually compiled into the library and available, but get_features will report ML_DSA_NO_CTX = 0. The cdef will then omit those declarations and MlDsaPrivate.sign(msg) / verify(sig, msg) with ctx=None will raise WolfCryptError("support ... without context is disabled") even though the build supports it. The failure is fail-safe (a clean error rather than a crash), so the impact is a degraded-functionality false negative on FIPS-204-draft builds, not a hard bug.
Code:
features["ML_DSA_NO_CTX"] = 1 if '#define WOLFSSL_DILITHIUM_NO_CTX' in defines else 0
Recommendation: Also treat WOLFSSL_DILITHIUM_FIPS204_DRAFT as implying no-ctx support, mirroring the logic in dilithium.h, so the legacy API is exposed in those builds.
| pub_key3 = mldsa_pub.encode_key() | ||
| assert pub_key == pub_key3 | ||
|
|
||
| def test_sign_verify(mldsa_type, rng): |
There was a problem hiding this comment.
MEDIUM-2: No test exercises the new 'context disabled' raise path [SUGGEST] (test)
File: tests/test_mldsa.py:113-160
Function: test_sign_verify
Confidence: High
The diff introduces three new branches in ciphers.py (verify/sign/sign_with_seed) that raise WolfCryptError("support ... without context is disabled") when ctx is None and _lib.ML_DSA_NO_CTX is false. The tests only ever take the ctx=None path inside if _lib.ML_DSA_NO_CTX: guards or @pytest.mark.skipif(not _lib.ML_DSA_NO_CTX), so when running against a build with no-ctx disabled (the likely default for the bumped wolfSSL 5.9.1 with just --enable-dilithium), the new raise branches are never asserted. The behavior of the new error path is untested.
Code:
elif not _lib.ML_DSA_NO_CTX:
raise WolfCryptError("support for signing without context is disabled")
Recommendation: Add an assertion (guarded by if not _lib.ML_DSA_NO_CTX:) that signing/verifying with ctx=None raises WolfCryptError, so the new branch is covered in no-ctx builds.
| "RSA_PSS": 1, | ||
| "CHACHA20_POLY1305": 1, | ||
| "ML_KEM": 1, | ||
| "ML_DSA": 1, |
There was a problem hiding this comment.
LOW-3: Default features dict omits ML_DSA_NO_CTX while listing peer flags [NIT] (convention)
File: scripts/build_ffi.py:1348-1378
Function: main
Confidence: High
The default features dictionary lists ML_DSA, ML_KEM, HKDF, etc., but the newly introduced ML_DSA_NO_CTX key is not present. In practice this is harmless because get_features() (which always sets ML_DSA_NO_CTX unconditionally at line 379) is always called before build_ffi() in main(), so no KeyError occurs. However, it is inconsistent with how the other ML-DSA/ML-KEM flags are seeded and would break if build_ffi were ever invoked without get_features first.
Code:
"ML_KEM": 1,
"ML_DSA": 1,
"HKDF": 1,
Recommendation: Add "ML_DSA_NO_CTX": 0 to the default features dict for consistency and robustness.
| if ret < 0: # pragma: no cover | ||
| raise WolfCryptApiError("wc_dilithium_verify_ctx_msg() error", ret) | ||
| elif not _lib.ML_DSA_NO_CTX: | ||
| raise WolfCryptError("support verifying without context is disabled") |
There was a problem hiding this comment.
LOW-4: Inconsistent wording between sign and verify 'disabled' error messages [NIT] (style)
File: wolfcrypt/ciphers.py:2268
Function: MlDsaPublic.verify
Confidence: High
The verify path raises "support verifying without context is disabled", while the two sign paths raise "support for signing without context is disabled". The verify message is missing the word "for" and reads awkwardly compared to the sign messages.
Code:
elif not _lib.ML_DSA_NO_CTX:
raise WolfCryptError("support verifying without context is disabled")
Recommendation: Align the verify message wording with the sign messages for consistency.
|
|
||
| return _ffi.buffer(pub_key, out_size[0])[:] | ||
|
|
||
| def verify(self, signature, message, ctx=None): |
There was a problem hiding this comment.
LOW-5: Docstrings still state ctx=None means 'no context' but it can now raise [NIT] (api)
File: wolfcrypt/ciphers.py:2238-2248,2410-2420,2464-2474
Function: MlDsaPublic.verify / MlDsaPrivate.sign / MlDsaPrivate.sign_with_seed
Confidence: Medium
The ctx parameter docstrings still say ":type ctx: None for no context, str or bytes otherwise". After this diff, passing ctx=None raises WolfCryptError on builds where WOLFSSL_DILITHIUM_NO_CTX is not compiled in (likely the default for the bumped wolfSSL 5.9.1). The documentation no longer reflects that ctx=None is conditionally supported, which can confuse callers who follow the docs and hit an exception. Note FIPS-204-compliant empty-context behavior is still reachable via ctx=b"", which is distinct from the legacy ctx=None path.
Code:
:param ctx: context (optional)
:type ctx: None for no context, str or bytes otherwise
Recommendation: Update the docstrings to note that ctx=None requires no-ctx support and that ctx=b"" provides FIPS-204 empty-context signing/verification.
| # Probably this authentication tag size is not supported, | ||
| # the minimum is 12 by default. Ignore. | ||
| continue | ||
| raise |
There was a problem hiding this comment.
gate this on WOLFSSL_MIN_AUTH_TAG_SZ. This try-except loop is too ambiguous.
Read minimum supported tag size from settings and make the test less ambiguous.
Also detect WOLFSSL_DILITHIUM_FIPS204_DRAFT as implying no-ctx support, mirroring the logic in dilithium.h. Add ML_DSA_NO_CTX to the default features dict for consistency with peer flags.
mjdemilliano
left a comment
There was a problem hiding this comment.
Processed all comments
| "RSA_PSS": 1, | ||
| "CHACHA20_POLY1305": 1, | ||
| "ML_KEM": 1, | ||
| "ML_DSA": 1, |
| pub_key3 = mldsa_pub.encode_key() | ||
| assert pub_key == pub_key3 | ||
|
|
||
| def test_sign_verify(mldsa_type, rng): |
|
|
||
| return _ffi.buffer(pub_key, out_size[0])[:] | ||
|
|
||
| def verify(self, signature, message, ctx=None): |
| # Probably this authentication tag size is not supported, | ||
| # the minimum is 12 by default. Ignore. | ||
| continue | ||
| raise |
No description provided.