Conversation
mem_usage_benches/src/lib.rs makes every bench source a module of a lib target, so its //! header is rustdoc'd and an indented block compiles as a Rust doctest by default; the valgrind/ms_print shell one-liners here weren't fenced, so `cargo test --workspace` failed to compile them as Rust (CI on PR #139). Fenced as ```text like the other bench binaries, per CLAUDE.md's note on this exact pitfall. Assisted-by: Claude:claude-sonnet-5 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Same issue as PR #139 (tdes): mem_usage_benches/src/lib.rs makes every bench source a module of a lib target, so its //! header is rustdoc'd and an indented block compiles as a Rust doctest by default. Fenced as ```text like the other bench binaries. Assisted-by: Claude:claude-sonnet-5 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
We had agreed not to add more ciphers until we get through reviewing and locking in the overall architecture via the AES work. Closing this PR for now. |
|
Why on earth would anybody want 3DES? NIST deprecated 3DES for new use via SP 800-131A Rev. 2 (disallowed after December 31, 2023) and withdrew SP 800-67 Rev. 2 effective January 1, 2024. |
|
Fair question, even though, as much as I hate to say it, I could point you at people still using DES, some of who should definitely know better... We still support it in BC-FIPS as well, as far as I can tell it's mainly used for dealing with legacy encrypted data these days. In this case this one is simply here as it's on the OpenSSL provider list, so it's one of the algorithms they'll want to invoke (at least for a while). |
…on says to avoid -- a weak or semi-weak key, or a bundle whose component keys are not distinct
…and CHUNK_LEN is a fixed 1 KiB, so the shared encrypt/decrypt loops serve block ciphers other than AES
…permutation kept for decrypting legacy data only, so a mode can refuse to encrypt with it at compile time
…s P::ENCRYPTION_APPROVED in an inline const, so building an encryptor over a decryption-only permutation is a compile error
…SP 800-67r2) whose S-box layer is an ANF circuit derived from the spec tables at compile time -- three-key TDES with TDES_* mode aliases, decryption-only two-key TDES2Key with TDES2_* decryptors, tdes-*/tdes2-* CLI subcommands, CAVP MMT vectors from bc-test-data
summary.md duplicated the crate docs' content and added a "Where the plan changed" section citing decisions from an internal design session that isn't part of this repo, plus several bc-java class-name references not needed once the doc itself is gone. The crate docs in src/lib.rs already cover the design, verification and the decisions a reviewer would want to revisit. No behavioural change; cargo fmt --check is clean. Assisted-by: Claude:claude-sonnet-5 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
mem_usage_benches/src/lib.rs makes every bench source a module of a lib target, so its //! header is rustdoc'd and an indented block compiles as a Rust doctest by default; the valgrind/ms_print shell one-liners here weren't fenced, so `cargo test --workspace` failed to compile them as Rust (CI on PR #139). Fenced as ```text like the other bench binaries, per CLAUDE.md's note on this exact pitfall. Assisted-by: Claude:claude-sonnet-5 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ptor::encrypt/encrypt_rng now returning (usize, [u8; INIT_DATA_LEN]) instead of just [u8; INIT_DATA_LEN] -- TDES_CFB, TDES_CFB8 (twice) and TDES_CTR each destructure the tuple instead of binding the old array-only return; no other TDES code is affected since these files are only type aliases over the generic Cfb/Cfb8/Ctr in crypto/modes, not their own trait impls Assisted-by: Claude:claude-sonnet-5 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…absorbed through its merges (SymmetricCipher/BlockCipherPadding renames, the ElectronicCodeBook batch methods, AES*Internal, core::security_strength, PaddedBlockCipher* adapters and the rest), restored in one commit after the linear rebase dropped those merges; the tree is identical to merging d1994a9 with 2d4d038 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
d1994a9 to
d7e98cf
Compare
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…R and TDES2_* examples take the renamed in-place one-shots (encrypt_in_place/decrypt_in_place) and import the SymmetricCipher* supertraits their do_*_init calls now come from; and a compile_fail example pins that Ctr<TDES2Key, Encrypting, ..> is still refused, now through KeyStream::ENCRYPTION_APPROVED (which CtrKeyStream takes from its permutation, carried in the merge) since CTR's encrypting constructor moved into core's StreamCipher adapter Assisted-by: Claude:claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # cli/src/aes_cbc_cmd.rs # cli/src/aes_ccm_cmd.rs # cli/src/aes_cfb8_cmd.rs # cli/src/aes_cfb_cmd.rs # cli/src/aes_ctr_cmd.rs # cli/src/aes_ecb_cmd.rs # cli/src/helpers/block_mode_helpers.rs # cli/src/main.rs
Implements the KeyWrapper / KeyUnwrapper traits from the previous commit for the two 128-bit-block key-wrap algorithms of NIST SP 800-38F, KW (Sec 6.2; RFC 3394) and KWP (Sec 6.3; RFC 5649), generically over any ElectronicCodeBook permutation, and publishes the AES instantiations. modes: - kw.rs: Kw<P, KEK_LEN>. The wrapping function W and its inverse (Algorithms 1 and 2) run in place on the caller's buffer, visiting the registers in the order the spec's shift register would present them, which RFC 3394 Sec 2.2.1 gives as the equivalent index-based form; the one block of scratch is a Secret. KW-AE/AD are Algorithms 3 and 4. - kwp.rs: Kwp<P, KEK_LEN>. KWP-AE/AD are Algorithms 5 and 6, including the single-block path for plaintexts of at most one semiblock. The ICV, length-field and padding checks of Algorithm 6 steps 4, 7 and 8 are all made, combined bitwise, and reported as the one DecryptionFailed. - The fixed-length API rejects invalid (KEY_LEN, CT_LEN) pairs at compile time via const assertions on the Table 1 limits; the run-time API returns InvalidInputLength outside them. Output buffers are zeroized on every failure. TKW (TDEA) is not included: it needs a 64-bit-block engine (PR bcgit#139). aes: - kw.rs: AES_KW_128/192/256 and AES_KWP_128/192/256 aliases, with the RFC 3394 Sec 4.1 and RFC 5649 7-octet vectors as doctests. No OIDs yet, in line with the other AES mode aliases. tests: - modes/tests/kw_tests.rs: all six RFC 3394 Sec 4 vectors and both RFC 5649 Sec 6 examples via TestFrameworkKeyWrap::test_kat, the shared framework for every AES key length at 26 payload lengths (every padding length of the single-block case included), and pins for the properties that distinguish KW, KWP and a raw block encryption. - modes/tests/acvp_kw_tests.rs: the NIST ACVP-AES-KW and ACVP-AES-KWP sets from bc-test-data, 1800 cases each, through both APIs, including the 171 + 178 forged ciphertexts that must be rejected. - aes/tests/kw_alias_tests.rs: the aliases name the right permutation and pass the framework. benches: KW/KWP wrap and unwrap of a 256-bit key, and KWP over 4 KiB. cli: aes{128,192,256}-kw and -kwp with wrap|unwrap, reading all of stdin (key wrap is one-shot), sharing key loading with the other AES commands; cli/tests/aes_kw_cli_tests.rs replays the RFC vectors in both directions and pins the length rules, the fail-closed unwrap and the help text. Assisted-by: Claude:claude-fable-5-1
# Conflicts: # cli/src/aes_cbc_cmd.rs # cli/src/aes_ccm_cmd.rs # cli/src/aes_cfb8_cmd.rs # cli/src/aes_cfb_cmd.rs # cli/src/aes_ctr_cmd.rs # cli/src/aes_ecb_cmd.rs # cli/src/main.rs # crypto/core/src/traits.rs # crypto/modes/src/ctr.rs
TDES, the decryption-only TDES2Key and the TDES_ECB / TDES2_ECB aliases move to bouncycastle_tdes::hazmat, with BLOCK_LEN, KEY_LEN and KEY_LEN_2KEY defined at the crate root; the merge ahead of this ported ENCRYPTION_APPROVED onto the moved trait and CtrKeyStream files. No logic change, no mutation run owed. Assisted-by: Claude Code:claude-fable-5-1 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…Select Follows aes 160ac18; the crate's own PaddedMode copy goes with it. Type aliases only, no behaviour change, no mutation run owed. Assisted-by: Claude Code:claude-fable-5-1 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Brings in 8dff255 (bouncycastle-modes and bouncycastle-padding folded into the new bouncycastle-cipher crate) and a27d9e6 (StreamCipher and the direction markers moved out of core), so the TDES crate, its CLI commands and tests are rewritten onto the new paths: bouncycastle_cipher::modes::*, bouncycastle_cipher::padding::*, and bouncycastle_cipher::{Direction, Encrypting, Decrypting}. Import rewrite only, no behaviour change. The ENCRYPTION_APPROVED gates followed the mode files into the new crate under git's rename detection; only the core KeyStream doc's link to StreamCipher, now in another crate, is rewritten as plain text. Assisted-by: Claude Code:claude-fable-5-1 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Summary
Adds
bouncycastle-tdes: a constant-time, table-free Triple DES (TDEA) engine per SP 800-67r2, with three-keyTDESand decryption-only two-keyTDES2Key.Description
TDES::newrejects non-distinct component keys and any of the 64 weak/semi-weak/possibly-weak DES keys (structural check, not a table).TDES2KeysetsElectronicCodeBook::ENCRYPTION_APPROVED = false(added in this PR) so itsEncryptingmode aliases fail to compile, per SP 800-131A Rev 2's "disallowed for encryption, legacy use for decryption".tdes-*/tdes2-*for every mode.Scope and Risk
New crate only; the
core/modes/clichanges it depends on (ENCRYPTION_APPROVED,KeyMaterialError::WeakKey, generic block length in the CLI plumbing) are additive and covered by existing suites. No behavioural change to AES or other existing ciphers.Validation
T{E,C}{CB,BC,FB64,FB8}MMT{2,3}vectors (bc-test-data), both key sizes, both directions.cargo test -p bouncycastle-tdes: all passing.cargo mutants -p bouncycastle-tdes: 467 mutants, 407 caught, 21 unviable, 33 missed (bit-permutation XOR/OR equivalences), 6 timeouts (compile-time ANF constant derivation).AI Usage Statement
Assisted-by: Claude:claude-sonnet-5
🤖 Generated with Claude Code