Commit Graph

186 Commits (master)

Author SHA1 Message Date
David Garske 6e054800f4 Keep a crypto callback device registered until its outstanding hash contexts are freed 2026-10-28 22:28:54 -07:00
David Garske f0e3918d79 Deep copy crypto callback hashes with wolfCrypt copy functions and use wc_HmacCopy for HMAC digest 2026-10-21 11:18:49 -07:00
David Garske cdfeacd5f2 Give each hash object its own crypto callback context across copy and free 2026-10-19 14:26:42 -07:00
David Garske db57784506 Log crypto callback tracebacks, fail closed on handler errors and document the override contract 2026-10-19 12:53:48 -07:00
David Garske 42fcbc83f5 Track crypto callback device ownership, require full hash overrides and forward device_id in new() 2026-10-19 12:40:54 -07:00
Robert de Vries 483b532bac Add more tests.
* Add parametrized callback test for all Sha classes.
* Add callback test for unsupported algo type AES GCM Stream.
2026-10-19 12:17:21 -07:00
Robert de Vries d884b75c6e Address review comments 2026-10-19 12:17:21 -07:00
Robert de Vries a62c87a770 INVALID_DEVID is always needed as default argument value.
This makes it also no longer necessary to use the hard-coded
magic value -2 as default argument for various cases where it was
already required.
2026-10-19 12:17:21 -07:00
Robert de Vries 26041b75a0 Addressed review comments
* added various tests
* adapted hash interface to allow callbacks
2026-10-19 12:17:21 -07:00
Robert de Vries e943b88b2f Fix ruff errors and add type info. 2026-10-19 12:17:21 -07:00
Robert de Vries 97820a5331 Address review comments. 2026-10-19 12:17:21 -07:00
Robert de Vries 7412dd1306 Address review comments
* Add if _lib.CRYPT_CB_ENABLED guards around code that depends on that
  configuration option being enabled.
2026-10-19 12:17:21 -07:00
Robert de Vries 6a0a525205 Addressed review comments
* Comment out code in build_ffi.py instead of quoted string.
* Check return value of wolfCrypt_init()
* Complete algorithm type hash table
* Change dicts into defaultdicts with a sensible value when key is missing.
* Convert debug print to debug log messages
* Add length checks to produce nicer exceptions.
2026-10-19 12:17:21 -07:00
Robert de Vries e57bcfe097 Add initial support for crypto callbacks. 2026-10-19 12:17:21 -07:00
Juliusz Sosinowicz 2fea30cd32 Validate ctx length in MlDsa.verify (F-4014)
MlDsa.sign/sign_with_seed reject a context longer than 255 bytes with
ValueError, but verify did not. With ctxLen now correctly declared as byte in
the cdef, an over-long ctx would surface as a low-level CFFI OverflowError
instead of the consistent ValueError callers get from the signing paths.

Reject len(ctx) > 255 with ValueError in verify, matching sign.
2026-07-16 13:44:55 +00:00
sebastian-carpenter a59a4f8b96 update license to GPLv3 2026-07-09 18:24:23 +02:00
David Garske 905682a036
Merge pull request #130 from mjdemilliano/add-hashdrbg-reseed
Random: add DRBG reseed support
2026-07-08 12:28:45 -07:00
Robert de Vries 1a2829a4cd Fixed a few type annotations and added bad type tests.
Also added one note to the ChangeLog.
2026-07-08 15:22:37 +02:00
Martijn de Milliano c1be234aa6 Process review comments:
- Update lib.pyi
- Remove obsolete comment from test_reseed_multiple
- Update HASHDRBG detection logic to match random.h
2026-07-07 19:14:59 +02:00
Robert de Vries 397725336e Address more review comments. 2026-07-06 22:27:34 +02:00
Robert de Vries 47b0ac5af9 Fix ruff issues. 2026-07-06 22:13:48 +02:00
Robert de Vries 00c57b5e91 Rebased on master and fixed any (extra) issues found with ruff and ty. 2026-07-06 22:02:48 +02:00
Robert de Vries 7f82b412e3 Address more review comments. 2026-07-06 22:02:48 +02:00
Robert de Vries 97766d708b Address more review comments.
Also added a line to the change log to mention that typing information
has been added.
2026-07-06 22:02:48 +02:00
Robert de Vries 66b2ffb7c8 Addressed more review comments. 2026-07-06 22:02:48 +02:00
Robert de Vries fda2869cce Add py.typed file to indicate that this library has typing annotations. 2026-07-06 22:02:48 +02:00
Robert de Vries 747243cc50 Address more review comments.
Tests are now also type checked as this helps verifying the correctness
of the type annotations.
2026-07-06 22:02:48 +02:00
Robert de Vries 1fb34e5cd8 Address review comments and annotate overrides. 2026-07-06 22:02:48 +02:00
Robert de Vries 2081edd6d7 Add typing information to ciphers.py
This has some fallout in random.py to simplify checks.
Also one test is slightly adapted to produced the desired failure.
2026-07-06 22:02:48 +02:00
Robert de Vries d1ac3d5f37 Add typing: asn, exceptions, hashes, hkdf, pwdbased, utils. 2026-07-06 22:02:46 +02:00
David Garske c69d2f1eea
Merge pull request #134 from mjdemilliano/prepare-v5.9.2
Prepare for v5.9.2 release
2026-07-02 16:42:48 -07:00
Martijn de Milliano 38c541ab42 ML-DSA: Move check on signing/verifying without context to top
This makes it more clear what the requirements for calling this
function are and avoids unnecessary computations for objects
which are not used.
2026-07-02 13:21:58 +02:00
Martijn de Milliano 0124b33202 Process review comments for random and test_random
- add pragma no cover
- format using ruff
- fix module factor in test_random
2026-06-30 20:47:41 +02:00
Martijn de Milliano 319c9200ff Prepare for v5.9.2 release 2026-06-30 16:33:18 +02:00
Martijn de Milliano c4d926950c AES-GCM stream tests
Test response by library explicitly when called with unsupported
number of tag bytes.
2026-06-29 18:41:17 +02:00
Martijn de Milliano afcebbf946 Rename flag to ML_DSA_NO_CTX_ENABLED 2026-06-29 18:41:17 +02:00
Martijn de Milliano e6f4632030 Random: add DRBG reseed support 2026-06-26 14:26:46 +02:00
Martijn de Milliano 8d87cb4d13 ML-DSA: fix wording of message and docstrings 2026-06-26 00:05:15 +02:00
Juliusz Sosinowicz b13aeea62b Address Copilot review on wolfcrypt-py (F-4015, F-4463)
- ChaCha.set_iv(): only mark _iv_set after _set_key() succeeds, and clear
  it first, so a failed re-key cannot leave encrypt()/decrypt() unblocked
  with a stale or partially-applied IV. Add a regression test.
- Update _Cipher.new()/encrypt()/decrypt() docstrings that still referred
  to CFB/segment-size behavior to match the actually supported modes
  (MODE_CBC, MODE_CTR) and their IV requirements.
2026-06-24 08:48:54 +00:00
Juliusz Sosinowicz 2ecf721695 Reject unsafe HMAC copy() (F-5428)
_Hmac inherited _Hash.copy(), which - lacking a wolfCrypt copy function
for Hmac - fell back to a byte-level memmove and returned an object
marked _shallow_copy that aliases the original's internal C state. In
async or hardware-accelerated builds those internal pointers are shared,
so freeing the original leaves the copy with stale state
(use-after-free, wrong MACs, or corruption). wolfCrypt exposes no safe
public Hmac copy, so override copy() to raise NotImplementedError.
digest()/hexdigest() are unaffected. Update the shared hash tests to
expect this for HMAC.
2026-06-23 12:43:03 +00:00
Juliusz Sosinowicz 39acd415fc Reject ChaCha encrypt/decrypt before set_iv (F-4463)
ChaCha.__init__ leaves _IV_nonce empty and requires set_iv() before
use, but encrypt()/decrypt() (inherited from _Cipher) did not check
this. The first call ran _set_key(), which passed the empty nonce to
wc_Chacha_SetIV() - a function that unconditionally reads 12 bytes -
reading past the buffer and silently producing output with an
undefined IV. Track an _iv_set flag and override encrypt()/decrypt()
to raise WolfCryptError until set_iv() has been called.
2026-06-23 11:35:58 +00:00
Juliusz Sosinowicz 53b3f6cef9 Remove contradictory cipher mode validation (F-4015)
_FEEDBACK_MODES advertised MODE_ECB/MODE_CFB/MODE_OFB as supported, but
_Cipher.__init__ then rejected every mode other than CBC/CTR with a
contradictory 'not supported by this cipher' error after they had
already passed the 'is supported' check. Prune _FEEDBACK_MODES to the
modes the cipher actually implements (CBC, CTR) so unsupported modes
get a single, accurate rejection, and drop the now-dead else branch.
2026-06-23 11:30:00 +00:00
Martijn de Milliano 52886c4034 ML-DSA: Deal with signing without context not always supported
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.
2026-06-04 18:03:35 +02:00
Martijn de Milliano 1e20bc9b80 Prepare for v5.9.1 release 2026-06-04 16:59:24 +02:00
Robert de Vries 18701e3b62 Use format specifiers instead of percent format.
printf-style string formatting has a number of quirks, and leads to less
readable code than using str.format calls or f-strings.
In general, prefer the newer str.format and f-strings constructs over
printf-style string formatting.
2026-05-17 16:14:52 +02:00
Andrew Hutchings ef4195f99a Address Fenrir findings
F-3340: AesGcmStream.final decrypt path passed len(authTag) straight to
wc_AesGcmDecryptFinal, letting a caller truncate the verification window
(forgery probability ~2^-32 instead of 2^-128 for a 4-byte tag against a
16-byte configuration). Reject len(authTag) != self._tag_bytes and pass
self._tag_bytes to wolfSSL, mirroring ChaCha20Poly1305.decrypt. Added
test_decrypt_rejects_wrong_tag_length. Also fixed test_encrypt_short_tag
which was relying on the bug (decrypt side defaulted to tag_bytes=16
against a 12-byte tag).

F-3089: Declare label as const byte* in the wc_RsaPublicEncrypt_ex and
wc_RsaPrivateDecrypt_ex cdefs so CFFI can accept Python bytes without
exposing a writable pointer into immutable memory. wolfSSL does not
modify label.

F-3090: Declare nonce as const byte* in the wc_InitRngNonce and
wc_InitRngNonce_ex cdefs for the same reason.

F-1983, F-1984: Add minimum + upper bounds to requirements/{prod,test,
docs}.txt so a hijacked release of cffi, tox, pytest, types-cffi,
Sphinx, or sphinx_rtd_theme does not get pulled silently on the next
pip install. setup.txt resolves transitively via prod.txt.
2026-05-12 13:15:35 +01:00
Andrew Hutchings 98215b60f6 Address Copilot concerns 2026-05-11 13:05:23 +01:00
Andrew Hutchings 57cca0e90d Validate raw element lengths in EccPublic/EccPrivate.decode_key_raw
wc_ecc_import_unsigned takes no length parameters for qx/qy/d: it
reads exactly curve_size bytes from each pointer based on curve_id,
via mp_read_unsigned_bin in wc_ecc_import_raw_private. The Python
decode_key_raw wrappers handed the user-supplied buffers straight
through without any length check, so a shorter buffer caused the C
library to read past the end of the Python buffer (OOB read of
adjacent memory, potentially leaking it into the imported key or
segfaulting). A longer buffer silently dropped the extra bytes.

Add wc_ecc_get_curve_size_from_id to the CFFI cdef, then in both
decode_key_raw methods t2b the inputs, look up the expected curve
size, and raise ValueError if any of qx/qy/d does not match. Reject
unknown curve_id values with a clear message rather than falling
through to wolfSSL with a bogus size.

Add test_ecc_decode_key_raw_rejects_wrong_length covering short qx,
long qy, short d, unknown curve_id, and the happy path on both
EccPublic and EccPrivate.

F-3088
2026-05-11 12:33:41 +01:00
Andrew Hutchings 000472761c Fix Ed448 ctx cdef to match wolfSSL header signature
scripts/build_ffi.py declared wc_ed448_sign_msg and wc_ed448_verify_msg
with two cdef discrepancies vs the wolfSSL header (ed448.h):

  - ctx was typed `byte*` instead of `const byte*`. CFFI was therefore
    happy to forward a writable pointer into Python bytes storage.
    The wolfSSL functions are const-correct and do not mutate ctx, so
    this had no runtime impact, but it widened the surface CFFI was
    willing to permit.

  - ctx_len was typed `word32` instead of `byte`. RFC 8032 caps Ed448
    context at 255 bytes, and wolfSSL's prototype reflects that with a
    1-byte parameter. The mismatch happens to work on x86_64 SysV
    because the low byte is what the callee reads, but it is still a
    real ABI discrepancy and would not be guaranteed on other
    platforms or calling conventions.

Update the cdef to const byte* / byte to match the header on both
functions. Add a guard in Ed448Public.verify and Ed448Private.sign so
callers passing a ctx longer than 255 bytes get a clear ValueError
rather than relying on CFFI's narrowing behavior.

ML-DSA's wc_dilithium_sign_ctx_msg / wc_dilithium_verify_ctx_msg cdefs
were also reviewed and already match the wolfSSL header.

F-3086
2026-05-11 12:27:23 +01:00
Andrew Hutchings e961e83656 Avoid passing Python bytes to non-const wc_GetPkcs8TraditionalOffset
wc_GetPkcs8TraditionalOffset is declared in the wolfSSL public header
as taking byte* input (non-const), even though the current
implementation only reads from the buffer via ToTraditionalInline_ex.
RsaPrivate.__init__ was passing a Python bytes object directly into
that non-const parameter on the PKCS#8 fallback path, which lets CFFI
hand the C library a writable pointer into immutable storage. There is
no observable mutation today, but the contract permits it, and any
future wolfSSL change to actually write through the parameter would
silently corrupt the caller's bytes object.

Copy the key into a CFFI-owned byte array for that one call. The
adjacent wc_RsaPrivateKeyDecode calls are unaffected since their cdef
is already const byte*. PKCS#8 key load is a one-time cost at
construction, so the extra allocation is negligible.

Not changing the cdef to const byte* because the wolfSSL public header
itself declares the parameter non-const; diverging from the header
would cause compile warnings in the CFFI-generated glue code. If
wolfSSL ever const-corrects the header upstream, this copy can be
dropped.

F-2664
2026-05-11 12:15:51 +01:00