├── .github
├── dependabot.yml
└── workflows
│ ├── belt-ctr.yaml
│ ├── cbc.yaml
│ ├── cfb-mode.yaml
│ ├── cfb8.yaml
│ ├── ctr.yaml
│ ├── cts.yaml
│ ├── ige.yaml
│ ├── ofb.yaml
│ ├── pcbc.yaml
│ ├── security-audit.yml
│ └── workspace.yml
├── .gitignore
├── Cargo.lock
├── Cargo.toml
├── README.md
├── belt-ctr
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── benches
│ └── belt-ctr.rs
├── src
│ └── lib.rs
└── tests
│ ├── data
│ └── belt-ctr.blb
│ └── mod.rs
├── cbc
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── benches
│ └── aes128.rs
├── src
│ ├── decrypt.rs
│ ├── encrypt.rs
│ └── lib.rs
└── tests
│ ├── aes.rs
│ └── data
│ ├── aes128.blb
│ ├── aes192.blb
│ └── aes256.blb
├── cfb-mode
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── benches
│ └── aes128.rs
├── src
│ ├── decrypt.rs
│ ├── encrypt.rs
│ ├── encrypt
│ │ └── buf.rs
│ └── lib.rs
└── tests
│ ├── aes.rs
│ ├── belt.rs
│ └── data
│ ├── aes128.blb
│ ├── aes192.blb
│ ├── aes256.blb
│ └── belt.blb
├── cfb8
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── benches
│ └── aes128.rs
├── src
│ ├── decrypt.rs
│ ├── encrypt.rs
│ └── lib.rs
└── tests
│ ├── aes.rs
│ └── data
│ ├── aes128.blb
│ ├── aes192.blb
│ └── aes256.blb
├── ctr
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── benches
│ └── aes128.rs
├── src
│ ├── ctr_core.rs
│ ├── flavors.rs
│ ├── flavors
│ │ ├── ctr128.rs
│ │ ├── ctr32.rs
│ │ └── ctr64.rs
│ └── lib.rs
└── tests
│ ├── ctr128
│ ├── data
│ │ ├── aes128-ctr.blb
│ │ └── aes256-ctr.blb
│ └── mod.rs
│ ├── ctr32
│ ├── be.rs
│ ├── le.rs
│ └── mod.rs
│ ├── gost
│ └── mod.rs
│ └── mod.rs
├── cts
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── src
│ ├── cbc_cs1.rs
│ ├── cbc_cs2.rs
│ ├── cbc_cs3.rs
│ ├── ecb_cs1.rs
│ ├── ecb_cs2.rs
│ ├── ecb_cs3.rs
│ └── lib.rs
└── tests
│ ├── aes128_roundtrip.rs
│ ├── belt_ecb.rs
│ └── rfc3962.rs
├── ige
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── benches
│ └── aes128.rs
├── src
│ ├── decrypt.rs
│ ├── encrypt.rs
│ └── lib.rs
└── tests
│ ├── aes.rs
│ └── data
│ └── aes128.blb
├── ofb
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── benches
│ └── aes128.rs
├── src
│ └── lib.rs
└── tests
│ ├── aes.rs
│ └── data
│ ├── aes128.blb
│ ├── aes192.blb
│ └── aes256.blb
└── pcbc
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── benches
└── aes128.rs
├── src
├── decrypt.rs
├── encrypt.rs
└── lib.rs
└── tests
├── aes.rs
└── data
└── aes128.blb
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: cargo
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | open-pull-requests-limit: 10
8 | - package-ecosystem: github-actions
9 | directory: "/"
10 | schedule:
11 | interval: weekly
12 | open-pull-requests-limit: 10
13 |
--------------------------------------------------------------------------------
/.github/workflows/belt-ctr.yaml:
--------------------------------------------------------------------------------
1 | name: belt-ctr
2 |
3 | on:
4 | pull_request:
5 | paths:
6 | - "belt-ctr/**"
7 | - "Cargo.*"
8 | push:
9 | branches: master
10 |
11 | defaults:
12 | run:
13 | working-directory: belt-ctr
14 |
15 | env:
16 | CARGO_INCREMENTAL: 0
17 | RUSTFLAGS: "-Dwarnings"
18 |
19 | jobs:
20 | build:
21 | runs-on: ubuntu-latest
22 | strategy:
23 | matrix:
24 | rust:
25 | - 1.85.0 # MSRV
26 | - stable
27 | target:
28 | - thumbv7em-none-eabi
29 | - wasm32-unknown-unknown
30 | steps:
31 | - uses: actions/checkout@v4
32 | - uses: RustCrypto/actions/cargo-cache@master
33 | - uses: actions-rs/toolchain@v1
34 | with:
35 | toolchain: ${{ matrix.rust }}
36 | target: ${{ matrix.target }}
37 | override: true
38 | profile: minimal
39 | - run: cargo build --no-default-features --release --target ${{ matrix.target }}
40 |
41 | minimal-versions:
42 | # disabled until belt-block gets published
43 | if: false
44 | uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
45 | with:
46 | working-directory: ${{ github.workflow }}
47 |
48 | test:
49 | runs-on: ubuntu-latest
50 | strategy:
51 | matrix:
52 | rust:
53 | - 1.85.0 # MSRV
54 | - stable
55 | steps:
56 | - uses: actions/checkout@v4
57 | - uses: RustCrypto/actions/cargo-cache@master
58 | - uses: actions-rs/toolchain@v1
59 | with:
60 | toolchain: ${{ matrix.rust }}
61 | override: true
62 | profile: minimal
63 | - run: cargo test
64 | - run: cargo test --all-features
65 |
--------------------------------------------------------------------------------
/.github/workflows/cbc.yaml:
--------------------------------------------------------------------------------
1 | name: cbc
2 |
3 | on:
4 | pull_request:
5 | paths:
6 | - "cbc/**"
7 | - "Cargo.*"
8 | push:
9 | branches: master
10 |
11 | defaults:
12 | run:
13 | working-directory: cbc
14 |
15 | env:
16 | CARGO_INCREMENTAL: 0
17 | RUSTFLAGS: "-Dwarnings"
18 |
19 | jobs:
20 | build:
21 | runs-on: ubuntu-latest
22 | strategy:
23 | matrix:
24 | rust:
25 | - 1.85.0 # MSRV
26 | - stable
27 | target:
28 | - thumbv7em-none-eabi
29 | - wasm32-unknown-unknown
30 | steps:
31 | - uses: actions/checkout@v4
32 | - uses: RustCrypto/actions/cargo-cache@master
33 | - uses: dtolnay/rust-toolchain@master
34 | with:
35 | toolchain: ${{ matrix.rust }}
36 | targets: ${{ matrix.target }}
37 | - run: cargo build --no-default-features --release --target ${{ matrix.target }}
38 |
39 | minimal-versions:
40 | # disabled until belt-block gets published
41 | if: false
42 | uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
43 | with:
44 | working-directory: ${{ github.workflow }}
45 |
46 | test:
47 | runs-on: ubuntu-latest
48 | strategy:
49 | matrix:
50 | rust:
51 | - 1.85.0 # MSRV
52 | - stable
53 | steps:
54 | - uses: actions/checkout@v4
55 | - uses: RustCrypto/actions/cargo-cache@master
56 | - uses: dtolnay/rust-toolchain@master
57 | with:
58 | toolchain: ${{ matrix.rust }}
59 | - run: cargo test
60 | - run: cargo test --all-features
61 |
--------------------------------------------------------------------------------
/.github/workflows/cfb-mode.yaml:
--------------------------------------------------------------------------------
1 | name: cfb-mode
2 |
3 | on:
4 | pull_request:
5 | paths:
6 | - "cfb-mode/**"
7 | - "Cargo.*"
8 | push:
9 | branches: master
10 |
11 | defaults:
12 | run:
13 | working-directory: cfb-mode
14 |
15 | env:
16 | CARGO_INCREMENTAL: 0
17 | RUSTFLAGS: "-Dwarnings"
18 |
19 | jobs:
20 | build:
21 | runs-on: ubuntu-latest
22 | strategy:
23 | matrix:
24 | rust:
25 | - 1.85.0 # MSRV
26 | - stable
27 | target:
28 | - thumbv7em-none-eabi
29 | - wasm32-unknown-unknown
30 | steps:
31 | - uses: actions/checkout@v4
32 | - uses: RustCrypto/actions/cargo-cache@master
33 | - uses: dtolnay/rust-toolchain@master
34 | with:
35 | toolchain: ${{ matrix.rust }}
36 | targets: ${{ matrix.target }}
37 | - run: cargo build --no-default-features --release --target ${{ matrix.target }}
38 |
39 | minimal-versions:
40 | # disabled until aes gets published
41 | if: false
42 | uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
43 | with:
44 | working-directory: ${{ github.workflow }}
45 |
46 | test:
47 | runs-on: ubuntu-latest
48 | strategy:
49 | matrix:
50 | rust:
51 | - 1.85.0 # MSRV
52 | - stable
53 | steps:
54 | - uses: actions/checkout@v4
55 | - uses: RustCrypto/actions/cargo-cache@master
56 | - uses: dtolnay/rust-toolchain@master
57 | with:
58 | toolchain: ${{ matrix.rust }}
59 | - run: cargo test
60 | - run: cargo test --all-features
61 |
--------------------------------------------------------------------------------
/.github/workflows/cfb8.yaml:
--------------------------------------------------------------------------------
1 | name: cfb8
2 |
3 | on:
4 | pull_request:
5 | paths:
6 | - "cfb8/**"
7 | - "Cargo.*"
8 | push:
9 | branches: master
10 |
11 | defaults:
12 | run:
13 | working-directory: cfb8
14 |
15 | env:
16 | CARGO_INCREMENTAL: 0
17 | RUSTFLAGS: "-Dwarnings"
18 |
19 | jobs:
20 | build:
21 | runs-on: ubuntu-latest
22 | strategy:
23 | matrix:
24 | rust:
25 | - 1.85.0 # MSRV
26 | - stable
27 | target:
28 | - thumbv7em-none-eabi
29 | - wasm32-unknown-unknown
30 | steps:
31 | - uses: actions/checkout@v4
32 | - uses: RustCrypto/actions/cargo-cache@master
33 | - uses: dtolnay/rust-toolchain@master
34 | with:
35 | toolchain: ${{ matrix.rust }}
36 | targets: ${{ matrix.target }}
37 | - run: cargo build --no-default-features --release --target ${{ matrix.target }}
38 |
39 | minimal-versions:
40 | # disabled until aes gets published
41 | if: false
42 | uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
43 | with:
44 | working-directory: ${{ github.workflow }}
45 |
46 | test:
47 | runs-on: ubuntu-latest
48 | strategy:
49 | matrix:
50 | rust:
51 | - 1.85.0 # MSRV
52 | - stable
53 | steps:
54 | - uses: actions/checkout@v4
55 | - uses: RustCrypto/actions/cargo-cache@master
56 | - uses: dtolnay/rust-toolchain@master
57 | with:
58 | toolchain: ${{ matrix.rust }}
59 | - run: cargo test
60 | - run: cargo test --all-features
61 |
--------------------------------------------------------------------------------
/.github/workflows/ctr.yaml:
--------------------------------------------------------------------------------
1 | name: ctr
2 |
3 | on:
4 | pull_request:
5 | paths:
6 | - "ctr/**"
7 | - "Cargo.*"
8 | push:
9 | branches: master
10 |
11 | defaults:
12 | run:
13 | working-directory: ctr
14 |
15 | env:
16 | CARGO_INCREMENTAL: 0
17 | RUSTFLAGS: "-Dwarnings"
18 |
19 | jobs:
20 | build:
21 | runs-on: ubuntu-latest
22 | strategy:
23 | matrix:
24 | rust:
25 | - 1.85.0 # MSRV
26 | - stable
27 | target:
28 | - thumbv7em-none-eabi
29 | - wasm32-unknown-unknown
30 | steps:
31 | - uses: actions/checkout@v4
32 | - uses: RustCrypto/actions/cargo-cache@master
33 | - uses: dtolnay/rust-toolchain@master
34 | with:
35 | toolchain: ${{ matrix.rust }}
36 | targets: ${{ matrix.target }}
37 | - run: cargo build --no-default-features --release --target ${{ matrix.target }}
38 |
39 | minimal-versions:
40 | # disabled until aes gets published
41 | if: false
42 | uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
43 | with:
44 | working-directory: ${{ github.workflow }}
45 |
46 | test:
47 | runs-on: ubuntu-latest
48 | strategy:
49 | matrix:
50 | rust:
51 | - 1.85.0 # MSRV
52 | - stable
53 | steps:
54 | - uses: actions/checkout@v4
55 | - uses: RustCrypto/actions/cargo-cache@master
56 | - uses: dtolnay/rust-toolchain@master
57 | with:
58 | toolchain: ${{ matrix.rust }}
59 | - run: cargo test
60 | - run: cargo test --all-features
61 |
--------------------------------------------------------------------------------
/.github/workflows/cts.yaml:
--------------------------------------------------------------------------------
1 | name: cts
2 |
3 | on:
4 | pull_request:
5 | paths:
6 | - "cts/**"
7 | - "Cargo.*"
8 | push:
9 | branches: master
10 |
11 | defaults:
12 | run:
13 | working-directory: cts
14 |
15 | env:
16 | CARGO_INCREMENTAL: 0
17 | RUSTFLAGS: "-Dwarnings"
18 |
19 | jobs:
20 | build:
21 | runs-on: ubuntu-latest
22 | strategy:
23 | matrix:
24 | rust:
25 | - 1.85.0 # MSRV
26 | - stable
27 | target:
28 | - thumbv7em-none-eabi
29 | - wasm32-unknown-unknown
30 | steps:
31 | - uses: actions/checkout@v4
32 | - uses: RustCrypto/actions/cargo-cache@master
33 | - uses: dtolnay/rust-toolchain@master
34 | with:
35 | toolchain: ${{ matrix.rust }}
36 | targets: ${{ matrix.target }}
37 | - run: cargo build --no-default-features --release --target ${{ matrix.target }}
38 |
39 | minimal-versions:
40 | # disabled until belt-block gets published
41 | if: false
42 | uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
43 | with:
44 | working-directory: ${{ github.workflow }}
45 |
46 | test:
47 | runs-on: ubuntu-latest
48 | strategy:
49 | matrix:
50 | rust:
51 | - 1.85.0 # MSRV
52 | - stable
53 | steps:
54 | - uses: actions/checkout@v4
55 | - uses: RustCrypto/actions/cargo-cache@master
56 | - uses: dtolnay/rust-toolchain@master
57 | with:
58 | toolchain: ${{ matrix.rust }}
59 | - run: cargo test
60 | - run: cargo test --all-features
61 |
--------------------------------------------------------------------------------
/.github/workflows/ige.yaml:
--------------------------------------------------------------------------------
1 | name: ige
2 |
3 | on:
4 | pull_request:
5 | paths:
6 | - "ige/**"
7 | - "Cargo.*"
8 | push:
9 | branches: master
10 |
11 | defaults:
12 | run:
13 | working-directory: ige
14 |
15 | env:
16 | CARGO_INCREMENTAL: 0
17 | RUSTFLAGS: "-Dwarnings"
18 |
19 | jobs:
20 | build:
21 | runs-on: ubuntu-latest
22 | strategy:
23 | matrix:
24 | rust:
25 | - 1.85.0 # MSRV
26 | - stable
27 | target:
28 | - thumbv7em-none-eabi
29 | - wasm32-unknown-unknown
30 | steps:
31 | - uses: actions/checkout@v4
32 | - uses: RustCrypto/actions/cargo-cache@master
33 | - uses: dtolnay/rust-toolchain@master
34 | with:
35 | toolchain: ${{ matrix.rust }}
36 | targets: ${{ matrix.target }}
37 | - run: cargo build --no-default-features --release --target ${{ matrix.target }}
38 |
39 | minimal-versions:
40 | # disabled until aes gets published
41 | if: false
42 | uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
43 | with:
44 | working-directory: ${{ github.workflow }}
45 |
46 | test:
47 | runs-on: ubuntu-latest
48 | strategy:
49 | matrix:
50 | rust:
51 | - 1.85.0 # MSRV
52 | - stable
53 | steps:
54 | - uses: actions/checkout@v4
55 | - uses: RustCrypto/actions/cargo-cache@master
56 | - uses: dtolnay/rust-toolchain@master
57 | with:
58 | toolchain: ${{ matrix.rust }}
59 | - run: cargo test
60 | - run: cargo test --all-features
61 |
--------------------------------------------------------------------------------
/.github/workflows/ofb.yaml:
--------------------------------------------------------------------------------
1 | name: ofb
2 |
3 | on:
4 | pull_request:
5 | paths:
6 | - "ofb/**"
7 | - "Cargo.*"
8 | push:
9 | branches: master
10 |
11 | defaults:
12 | run:
13 | working-directory: ofb
14 |
15 | env:
16 | CARGO_INCREMENTAL: 0
17 | RUSTFLAGS: "-Dwarnings"
18 |
19 | jobs:
20 | build:
21 | runs-on: ubuntu-latest
22 | strategy:
23 | matrix:
24 | rust:
25 | - 1.85.0 # MSRV
26 | - stable
27 | target:
28 | - thumbv7em-none-eabi
29 | - wasm32-unknown-unknown
30 | steps:
31 | - uses: actions/checkout@v4
32 | - uses: RustCrypto/actions/cargo-cache@master
33 | - uses: dtolnay/rust-toolchain@master
34 | with:
35 | toolchain: ${{ matrix.rust }}
36 | targets: ${{ matrix.target }}
37 | - run: cargo build --no-default-features --release --target ${{ matrix.target }}
38 |
39 | minimal-versions:
40 | # disabled until aes gets published
41 | if: false
42 | uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
43 | with:
44 | working-directory: ${{ github.workflow }}
45 |
46 | test:
47 | runs-on: ubuntu-latest
48 | strategy:
49 | matrix:
50 | rust:
51 | - 1.85.0 # MSRV
52 | - stable
53 | steps:
54 | - uses: actions/checkout@v4
55 | - uses: RustCrypto/actions/cargo-cache@master
56 | - uses: dtolnay/rust-toolchain@master
57 | with:
58 | toolchain: ${{ matrix.rust }}
59 | - run: cargo test
60 | - run: cargo test --all-features
61 |
--------------------------------------------------------------------------------
/.github/workflows/pcbc.yaml:
--------------------------------------------------------------------------------
1 | name: pcbc
2 |
3 | on:
4 | pull_request:
5 | paths:
6 | - "pcbc/**"
7 | - "Cargo.*"
8 | push:
9 | branches: master
10 |
11 | defaults:
12 | run:
13 | working-directory: pcbc
14 |
15 | env:
16 | CARGO_INCREMENTAL: 0
17 | RUSTFLAGS: "-Dwarnings"
18 |
19 | jobs:
20 | build:
21 | runs-on: ubuntu-latest
22 | strategy:
23 | matrix:
24 | rust:
25 | - 1.85.0 # MSRV
26 | - stable
27 | target:
28 | - thumbv7em-none-eabi
29 | - wasm32-unknown-unknown
30 | steps:
31 | - uses: actions/checkout@v4
32 | - uses: RustCrypto/actions/cargo-cache@master
33 | - uses: dtolnay/rust-toolchain@master
34 | with:
35 | toolchain: ${{ matrix.rust }}
36 | targets: ${{ matrix.target }}
37 | - run: cargo build --no-default-features --release --target ${{ matrix.target }}
38 |
39 | minimal-versions:
40 | # disabled until aes gets published
41 | if: false
42 | uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
43 | with:
44 | working-directory: ${{ github.workflow }}
45 |
46 | test:
47 | runs-on: ubuntu-latest
48 | strategy:
49 | matrix:
50 | rust:
51 | - 1.85.0 # MSRV
52 | - stable
53 | steps:
54 | - uses: actions/checkout@v4
55 | - uses: RustCrypto/actions/cargo-cache@master
56 | - uses: dtolnay/rust-toolchain@master
57 | with:
58 | toolchain: ${{ matrix.rust }}
59 | - run: cargo test
60 | - run: cargo test --all-features
61 |
--------------------------------------------------------------------------------
/.github/workflows/security-audit.yml:
--------------------------------------------------------------------------------
1 | name: Security Audit
2 | on:
3 | pull_request:
4 | paths: Cargo.lock
5 | push:
6 | branches: master
7 | paths: Cargo.lock
8 | schedule:
9 | - cron: "0 0 * * *"
10 |
11 | jobs:
12 | security_audit:
13 | name: Security Audit
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v4
17 | - name: Cache cargo bin
18 | uses: actions/cache@v4
19 | with:
20 | path: ~/.cargo/bin
21 | key: ${{ runner.os }}-cargo-audit-v0.12.0
22 | - uses: actions-rs/audit-check@v1
23 | with:
24 | token: ${{ secrets.GITHUB_TOKEN }}
25 |
--------------------------------------------------------------------------------
/.github/workflows/workspace.yml:
--------------------------------------------------------------------------------
1 | name: Workspace
2 |
3 | on:
4 | pull_request:
5 | paths-ignore:
6 | - README.md
7 | push:
8 | branches: master
9 | paths-ignore:
10 | - README.md
11 |
12 | jobs:
13 | clippy:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v4
17 | - uses: RustCrypto/actions/cargo-cache@master
18 | - uses: dtolnay/rust-toolchain@master
19 | with:
20 | toolchain: 1.85.0
21 | components: clippy
22 | - run: cargo clippy --all --all-features -- -D warnings
23 |
24 | rustfmt:
25 | runs-on: ubuntu-latest
26 | steps:
27 | - name: Checkout sources
28 | uses: actions/checkout@v4
29 |
30 | - name: Install stable toolchain
31 | uses: dtolnay/rust-toolchain@master
32 | with:
33 | toolchain: stable
34 | components: rustfmt
35 | - name: Run cargo fmt
36 | run: cargo fmt --all -- --check
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | resolver = "3"
3 | members = [
4 | "belt-ctr",
5 | "cbc",
6 | "cts",
7 | "cfb8",
8 | "cfb-mode",
9 | "ctr",
10 | "ige",
11 | "ofb",
12 | "pcbc"
13 | ]
14 |
15 | [profile.dev]
16 | opt-level = 2
17 |
--------------------------------------------------------------------------------
/belt-ctr/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## 0.1.0 (2023-04-02)
9 | - Initial release
10 |
--------------------------------------------------------------------------------
/belt-ctr/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "belt-ctr"
3 | version = "0.2.0-rc.0"
4 | description = "CTR block mode of operation specified by the BelT standard"
5 | authors = ["RustCrypto Developers"]
6 | license = "MIT OR Apache-2.0"
7 | edition = "2024"
8 | rust-version = "1.85"
9 | readme = "README.md"
10 | documentation = "https://docs.rs/belt-ctr"
11 | repository = "https://github.com/RustCrypto/block-modes"
12 | keywords = ["crypto", "block-mode", "stream-cipher", "ciphers", "belt"]
13 | categories = ["cryptography", "no-std"]
14 |
15 | [dependencies]
16 | cipher = "0.5.0-rc.0"
17 | belt-block = "0.2.0-rc.0"
18 |
19 | [dev-dependencies]
20 | hex-literal = "1"
21 | belt-block = "0.2.0-rc.0"
22 | cipher = { version = "0.5.0-rc.0", features = ["dev"] }
23 |
24 | [features]
25 | alloc = ["cipher/alloc"]
26 | zeroize = ["cipher/zeroize"]
27 |
28 | [package.metadata.docs.rs]
29 | all-features = true
30 | rustdoc-args = ["--cfg", "docsrs"]
31 |
--------------------------------------------------------------------------------
/belt-ctr/LICENSE-MIT:
--------------------------------------------------------------------------------
1 | Copyright (c) 2023 The RustCrypto Project Developers
2 |
3 | Permission is hereby granted, free of charge, to any
4 | person obtaining a copy of this software and associated
5 | documentation files (the "Software"), to deal in the
6 | Software without restriction, including without
7 | limitation the rights to use, copy, modify, merge,
8 | publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software
10 | is furnished to do so, subject to the following
11 | conditions:
12 |
13 | The above copyright notice and this permission notice
14 | shall be included in all copies or substantial portions
15 | of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 | DEALINGS IN THE SOFTWARE.
26 |
--------------------------------------------------------------------------------
/belt-ctr/README.md:
--------------------------------------------------------------------------------
1 | # RustCrypto: belt-ctr
2 |
3 | [![crate][crate-image]][crate-link]
4 | [![Docs][docs-image]][docs-link]
5 | [![Build Status][build-image]][build-link]
6 | ![Apache2/MIT licensed][license-image]
7 | ![Rust Version][rustc-image]
8 | [![Project Chat][chat-image]][chat-link]
9 |
10 | Generic implementation of the [`belt-ctr`] block mode of operation.
11 |
12 | Mode functionality is accessed using traits from the [`cipher`] crate.
13 |
14 | # ⚠️ Security Warning: Hazmat!
15 |
16 | This crate does not ensure ciphertexts are authentic! Thus ciphertext integrity
17 | is not verified, which can lead to serious vulnerabilities!
18 | [AEADs] provide simple authenticated encryption,
19 | which is much less error-prone than manual integrity verification.
20 |
21 | # Example
22 | ```rust
23 | use hex_literal::hex;
24 | use belt_ctr::{BeltCtr, cipher::{KeyIvInit, StreamCipher, StreamCipherSeek}};
25 |
26 | let key = &[0x42; 32];
27 | let iv = &[0x24; 16];
28 | let plaintext: &[u8; 34] = b"hello world! this is my plaintext.";
29 | let ciphertext: &[u8; 34] = &hex!(
30 | "38DF06243BD85DA1CAE597CE680D3AFE"
31 | "0EBB372A4F6A858DB2DBE20A63567EED"
32 | "7D1B"
33 | );
34 |
35 | let mut cipher: BeltCtr = BeltCtr::new_from_slices(key, iv).unwrap();
36 |
37 | // encrypt in-place
38 | let mut buf = plaintext.clone();
39 | cipher.apply_keystream(&mut buf);
40 | assert_eq!(buf[..], ciphertext[..]);
41 |
42 | cipher.seek(0);
43 | cipher.apply_keystream(&mut buf);
44 | assert_eq!(buf[..], plaintext[..]);
45 | ```
46 |
47 | ## License
48 |
49 | Licensed under either of:
50 |
51 | * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
52 | * [MIT license](http://opensource.org/licenses/MIT)
53 |
54 | at your option.
55 |
56 | ### Contribution
57 |
58 | Unless you explicitly state otherwise, any contribution intentionally submitted
59 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
60 | dual licensed as above, without any additional terms or conditions.
61 |
62 | [//]: # (badges)
63 |
64 | [crate-image]: https://img.shields.io/crates/v/belt-ctr.svg?logo=rust
65 | [crate-link]: https://crates.io/crates/belt-ctr
66 | [docs-image]: https://docs.rs/belt-ctr/badge.svg
67 | [docs-link]: https://docs.rs/belt-ctr/
68 | [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
69 | [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg
70 | [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
71 | [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/308460-block-modes
72 | [build-image]: https://github.com/RustCrypto/block-modes/actions/workflows/belt-ctr.yaml/badge.svg
73 | [build-link]: https://github.com/RustCrypto/block-modes/actions/workflows/belt-ctr.yaml
74 |
75 | [//]: # (general links)
76 |
77 | [`cipher`]: https://docs.rs/cipher/
78 | [`belt-ctr`]: https://apmi.bsu.by/assets/files/std/belt-spec371.pdf
79 | [AEADs]: https://github.com/RustCrypto/AEADs
80 |
--------------------------------------------------------------------------------
/belt-ctr/benches/belt-ctr.rs:
--------------------------------------------------------------------------------
1 | #![feature(test)]
2 | extern crate test;
3 |
4 | cipher::stream_cipher_bench!(
5 | belt_ctr::BeltCtr;
6 | belt_ctr_bench1_16b 16;
7 | belt_ctr_bench2_256b 256;
8 | belt_ctr_bench3_1kib 1024;
9 | belt_ctr_bench4_16kib 16384;
10 | );
11 |
--------------------------------------------------------------------------------
/belt-ctr/tests/data/belt-ctr.blb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RustCrypto/block-modes/e52ed9c70aa22b8dd07285f4b15981f137960cd5/belt-ctr/tests/data/belt-ctr.blb
--------------------------------------------------------------------------------
/belt-ctr/tests/mod.rs:
--------------------------------------------------------------------------------
1 | use belt_ctr::{BeltCtr, BeltCtrCore};
2 |
3 | // Test vectors from the BelT standard (tables A.15 and A.16):
4 | // https://apmi.bsu.by/assets/files/std/belt-spec371.pdf
5 | cipher::stream_cipher_test!(belt_ctr_core, "belt-ctr", BeltCtr);
6 | cipher::stream_cipher_seek_test!(belt_ctr_seek, BeltCtr);
7 | cipher::iv_state_test!(belt_ctr_iv_state, BeltCtrCore, apply_ks);
8 |
--------------------------------------------------------------------------------
/cbc/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## 0.2.0 (UNRELEASED)
9 | ### Removed
10 | - `std` feature ([#76])
11 |
12 | ### Changed
13 | - Bump `cipher` from `0.4` to `0.5` ([#56])
14 | - Edition changed to 2024 and MSRV bumped to 1.85 ([#76])
15 | - Relax MSRV policy and allow MSRV bumps in patch releases
16 |
17 | [#56]: https://github.com/RustCrypto/block-modes/pull/56
18 | [#76]: https://github.com/RustCrypto/block-modes/pull/76
19 |
20 | ## 0.1.2 (2022-03-24)
21 | ### Changed
22 | - Minor code tweaks to help compiler with codegen ([#15])
23 |
24 | [#15]: https://github.com/RustCrypto/block-modes/pull/15
25 |
26 | ## 0.1.1 (2022-02-17)
27 | ### Fixed
28 | - Minimal versions build ([#9])
29 |
30 | [#9]: https://github.com/RustCrypto/block-modes/pull/9
31 |
32 | ## 0.1.0 (2022-02-10)
33 | - Initial release ([#2])
34 |
35 | [#2]: https://github.com/RustCrypto/block-modes/pull/2
36 |
--------------------------------------------------------------------------------
/cbc/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "cbc"
3 | version = "0.2.0-rc.0"
4 | description = "Cipher Block Chaining (CBC) block cipher mode of operation"
5 | authors = ["RustCrypto Developers"]
6 | license = "MIT OR Apache-2.0"
7 | edition = "2024"
8 | rust-version = "1.85"
9 | readme = "README.md"
10 | documentation = "https://docs.rs/cbc"
11 | repository = "https://github.com/RustCrypto/block-modes"
12 | keywords = ["crypto", "block-mode", "ciphers"]
13 | categories = ["cryptography", "no-std"]
14 |
15 | [dependencies]
16 | cipher = "0.5.0-rc.0"
17 |
18 | [dev-dependencies]
19 | aes = "0.9.0-rc.0"
20 | cipher = { version = "0.5.0-rc.0", features = ["dev"] }
21 | hex-literal = "1"
22 |
23 | [features]
24 | default = ["block-padding"]
25 | alloc = ["cipher/alloc"]
26 | block-padding = ["cipher/block-padding"]
27 | zeroize = ["cipher/zeroize"]
28 |
29 | [package.metadata.docs.rs]
30 | all-features = true
31 | rustdoc-args = ["--cfg", "docsrs"]
32 |
--------------------------------------------------------------------------------
/cbc/LICENSE-MIT:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018-2022 RustCrypto Developers
2 | Copyright (c) 2018 Artyom Pavlov
3 |
4 | Permission is hereby granted, free of charge, to any
5 | person obtaining a copy of this software and associated
6 | documentation files (the "Software"), to deal in the
7 | Software without restriction, including without
8 | limitation the rights to use, copy, modify, merge,
9 | publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software
11 | is furnished to do so, subject to the following
12 | conditions:
13 |
14 | The above copyright notice and this permission notice
15 | shall be included in all copies or substantial portions
16 | of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
19 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
20 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
21 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
22 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
25 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 | DEALINGS IN THE SOFTWARE.
27 |
--------------------------------------------------------------------------------
/cbc/README.md:
--------------------------------------------------------------------------------
1 | # RustCrypto: CBC
2 |
3 | [![crate][crate-image]][crate-link]
4 | [![Docs][docs-image]][docs-link]
5 | [![Build Status][build-image]][build-link]
6 | ![Apache2/MIT licensed][license-image]
7 | ![Rust Version][rustc-image]
8 | [![Project Chat][chat-image]][chat-link]
9 |
10 | Generic implementation of the [Cipher Block Chaining][CBC] (CBC) block cipher
11 | mode of operation.
12 |
13 | 
14 |
15 | See [documentation][cipher-doc] of the `cipher` crate for additional information.
16 |
17 | ## License
18 |
19 | Licensed under either of:
20 |
21 | * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
22 | * [MIT license](http://opensource.org/licenses/MIT)
23 |
24 | at your option.
25 |
26 | ### Contribution
27 |
28 | Unless you explicitly state otherwise, any contribution intentionally submitted
29 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
30 | dual licensed as above, without any additional terms or conditions.
31 |
32 | [//]: # (badges)
33 |
34 | [crate-image]: https://img.shields.io/crates/v/cbc.svg?logo=rust
35 | [crate-link]: https://crates.io/crates/cbc
36 | [docs-image]: https://docs.rs/cbc/badge.svg
37 | [docs-link]: https://docs.rs/cbc/
38 | [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
39 | [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg
40 | [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
41 | [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/308460-block-modes
42 | [build-image]: https://github.com/RustCrypto/block-modes/actions/workflows/cbc.yaml/badge.svg
43 | [build-link]: https://github.com/RustCrypto/block-modes/actions/workflows/cbc.yaml
44 |
45 | [//]: # (general links)
46 |
47 | [CBC]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#CBC
48 | [cipher-doc]: https://docs.rs/cipher/
49 |
--------------------------------------------------------------------------------
/cbc/benches/aes128.rs:
--------------------------------------------------------------------------------
1 | #![feature(test)]
2 | extern crate test;
3 |
4 | use aes::Aes128;
5 |
6 | cipher::block_encryptor_bench!(
7 | KeyIv: cbc::Encryptor,
8 | cbc_aes128_encrypt_block,
9 | cbc_aes128_encrypt_blocks,
10 | );
11 |
12 | cipher::block_decryptor_bench!(
13 | KeyIv: cbc::Decryptor,
14 | cbc_aes128_decrypt_block,
15 | cbc_aes128_decrypt_blocks,
16 | );
17 |
--------------------------------------------------------------------------------
/cbc/src/decrypt.rs:
--------------------------------------------------------------------------------
1 | use crate::xor;
2 | use cipher::{
3 | AlgorithmName, Block, BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherDecrypt,
4 | BlockModeDecBackend, BlockModeDecClosure, BlockModeDecrypt, BlockSizeUser, InnerIvInit, Iv,
5 | IvState, ParBlocks, ParBlocksSizeUser,
6 | array::Array,
7 | crypto_common::{BlockSizes, InnerUser, IvSizeUser},
8 | inout::InOut,
9 | };
10 | use core::fmt;
11 |
12 | #[cfg(feature = "zeroize")]
13 | use cipher::zeroize::{Zeroize, ZeroizeOnDrop};
14 |
15 | /// CBC mode decryptor.
16 | #[derive(Clone)]
17 | pub struct Decryptor
18 | where
19 | C: BlockCipherDecrypt,
20 | {
21 | cipher: C,
22 | iv: Block,
23 | }
24 |
25 | impl BlockSizeUser for Decryptor
26 | where
27 | C: BlockCipherDecrypt,
28 | {
29 | type BlockSize = C::BlockSize;
30 | }
31 |
32 | impl BlockModeDecrypt for Decryptor
33 | where
34 | C: BlockCipherDecrypt,
35 | {
36 | fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure) {
37 | struct Closure<'a, BS, BC>
38 | where
39 | BS: BlockSizes,
40 | BC: BlockModeDecClosure,
41 | {
42 | iv: &'a mut Array,
43 | f: BC,
44 | }
45 |
46 | impl BlockSizeUser for Closure<'_, BS, BC>
47 | where
48 | BS: BlockSizes,
49 | BC: BlockModeDecClosure,
50 | {
51 | type BlockSize = BS;
52 | }
53 |
54 | impl BlockCipherDecClosure for Closure<'_, BS, BC>
55 | where
56 | BS: BlockSizes,
57 | BC: BlockModeDecClosure,
58 | {
59 | #[inline(always)]
60 | fn call>(
61 | self,
62 | cipher_backend: &B,
63 | ) {
64 | let Self { iv, f } = self;
65 | f.call(&mut Backend { iv, cipher_backend });
66 | }
67 | }
68 |
69 | let Self { cipher, iv } = self;
70 | cipher.decrypt_with_backend(Closure { iv, f })
71 | }
72 | }
73 |
74 | impl InnerUser for Decryptor
75 | where
76 | C: BlockCipherDecrypt,
77 | {
78 | type Inner = C;
79 | }
80 |
81 | impl IvSizeUser for Decryptor
82 | where
83 | C: BlockCipherDecrypt,
84 | {
85 | type IvSize = C::BlockSize;
86 | }
87 |
88 | impl InnerIvInit for Decryptor
89 | where
90 | C: BlockCipherDecrypt,
91 | {
92 | #[inline]
93 | fn inner_iv_init(cipher: C, iv: &Iv) -> Self {
94 | Self {
95 | cipher,
96 | iv: iv.clone(),
97 | }
98 | }
99 | }
100 |
101 | impl IvState for Decryptor
102 | where
103 | C: BlockCipherDecrypt,
104 | {
105 | #[inline]
106 | fn iv_state(&self) -> Iv {
107 | self.iv.clone()
108 | }
109 | }
110 |
111 | impl AlgorithmName for Decryptor
112 | where
113 | C: BlockCipherDecrypt + AlgorithmName,
114 | {
115 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
116 | f.write_str("cbc::Decryptor<")?;
117 | ::write_alg_name(f)?;
118 | f.write_str(">")
119 | }
120 | }
121 |
122 | impl fmt::Debug for Decryptor
123 | where
124 | C: BlockCipherDecrypt + AlgorithmName,
125 | {
126 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127 | f.write_str("cbc::Decryptor<")?;
128 | ::write_alg_name(f)?;
129 | f.write_str("> { ... }")
130 | }
131 | }
132 |
133 | impl Drop for Decryptor {
134 | fn drop(&mut self) {
135 | #[cfg(feature = "zeroize")]
136 | self.iv.zeroize();
137 | }
138 | }
139 |
140 | #[cfg(feature = "zeroize")]
141 | impl ZeroizeOnDrop for Decryptor {}
142 |
143 | struct Backend<'a, BS, BK>
144 | where
145 | BS: BlockSizes,
146 | BK: BlockCipherDecBackend,
147 | {
148 | iv: &'a mut Array,
149 | cipher_backend: &'a BK,
150 | }
151 |
152 | impl BlockSizeUser for Backend<'_, BS, BK>
153 | where
154 | BS: BlockSizes,
155 | BK: BlockCipherDecBackend,
156 | {
157 | type BlockSize = BS;
158 | }
159 |
160 | impl ParBlocksSizeUser for Backend<'_, BS, BK>
161 | where
162 | BS: BlockSizes,
163 | BK: BlockCipherDecBackend,
164 | {
165 | type ParBlocksSize = BK::ParBlocksSize;
166 | }
167 |
168 | impl BlockModeDecBackend for Backend<'_, BS, BK>
169 | where
170 | BS: BlockSizes,
171 | BK: BlockCipherDecBackend,
172 | {
173 | #[inline(always)]
174 | fn decrypt_block(&mut self, mut block: InOut<'_, '_, Block>) {
175 | let in_block = block.clone_in();
176 | let mut t = block.clone_in();
177 | self.cipher_backend.decrypt_block((&mut t).into());
178 | xor(&mut t, self.iv);
179 | *block.get_out() = t;
180 | *self.iv = in_block;
181 | }
182 |
183 | #[inline(always)]
184 | fn decrypt_par_blocks(&mut self, mut blocks: InOut<'_, '_, ParBlocks>) {
185 | let in_blocks = blocks.clone_in();
186 | let mut t = blocks.clone_in();
187 |
188 | self.cipher_backend.decrypt_par_blocks((&mut t).into());
189 | let n = t.len();
190 | xor(&mut t[0], self.iv);
191 | for i in 1..n {
192 | xor(&mut t[i], &in_blocks[i - 1])
193 | }
194 | *blocks.get_out() = t;
195 | *self.iv = in_blocks[n - 1].clone();
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/cbc/src/encrypt.rs:
--------------------------------------------------------------------------------
1 | use crate::xor;
2 | use cipher::{
3 | AlgorithmName, Array, Block, BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt,
4 | BlockModeEncBackend, BlockModeEncClosure, BlockModeEncrypt, BlockSizeUser, InOut, InnerIvInit,
5 | Iv, IvSizeUser, IvState, ParBlocksSizeUser,
6 | consts::U1,
7 | crypto_common::{BlockSizes, InnerUser},
8 | };
9 | use core::fmt;
10 |
11 | #[cfg(feature = "zeroize")]
12 | use cipher::zeroize::{Zeroize, ZeroizeOnDrop};
13 |
14 | /// CBC mode encryptor.
15 | #[derive(Clone)]
16 | pub struct Encryptor
17 | where
18 | C: BlockCipherEncrypt,
19 | {
20 | cipher: C,
21 | iv: Block,
22 | }
23 |
24 | impl BlockSizeUser for Encryptor
25 | where
26 | C: BlockCipherEncrypt,
27 | {
28 | type BlockSize = C::BlockSize;
29 | }
30 |
31 | impl InnerUser for Encryptor
32 | where
33 | C: BlockCipherEncrypt,
34 | {
35 | type Inner = C;
36 | }
37 |
38 | impl IvSizeUser for Encryptor
39 | where
40 | C: BlockCipherEncrypt,
41 | {
42 | type IvSize = C::BlockSize;
43 | }
44 |
45 | impl InnerIvInit for Encryptor
46 | where
47 | C: BlockCipherEncrypt,
48 | {
49 | #[inline]
50 | fn inner_iv_init(cipher: C, iv: &Iv) -> Self {
51 | Self {
52 | cipher,
53 | iv: iv.clone(),
54 | }
55 | }
56 | }
57 |
58 | impl IvState for Encryptor
59 | where
60 | C: BlockCipherEncrypt,
61 | {
62 | #[inline]
63 | fn iv_state(&self) -> Iv {
64 | self.iv.clone()
65 | }
66 | }
67 |
68 | impl BlockModeEncrypt for Encryptor
69 | where
70 | C: BlockCipherEncrypt,
71 | {
72 | fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure) {
73 | struct Closure<'a, BS, BC>
74 | where
75 | BS: BlockSizes,
76 | BC: BlockModeEncClosure,
77 | {
78 | iv: &'a mut Array,
79 | f: BC,
80 | }
81 |
82 | impl BlockSizeUser for Closure<'_, BS, BC>
83 | where
84 | BS: BlockSizes,
85 | BC: BlockModeEncClosure,
86 | {
87 | type BlockSize = BS;
88 | }
89 |
90 | impl BlockCipherEncClosure for Closure<'_, BS, BC>
91 | where
92 | BS: BlockSizes,
93 | BC: BlockModeEncClosure,
94 | {
95 | #[inline(always)]
96 | fn call>(
97 | self,
98 | cipher_backend: &B,
99 | ) {
100 | let Self { iv, f } = self;
101 | f.call(&mut Backend { iv, cipher_backend });
102 | }
103 | }
104 |
105 | let Self { cipher, iv } = self;
106 | cipher.encrypt_with_backend(Closure { iv, f })
107 | }
108 | }
109 |
110 | impl AlgorithmName for Encryptor
111 | where
112 | C: BlockCipherEncrypt + AlgorithmName,
113 | {
114 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 | f.write_str("cbc::Encryptor<")?;
116 | ::write_alg_name(f)?;
117 | f.write_str(">")
118 | }
119 | }
120 |
121 | impl fmt::Debug for Encryptor
122 | where
123 | C: BlockCipherEncrypt + AlgorithmName,
124 | {
125 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126 | f.write_str("cbc::Encryptor<")?;
127 | ::write_alg_name(f)?;
128 | f.write_str("> { ... }")
129 | }
130 | }
131 |
132 | impl Drop for Encryptor {
133 | fn drop(&mut self) {
134 | #[cfg(feature = "zeroize")]
135 | self.iv.zeroize();
136 | }
137 | }
138 |
139 | #[cfg(feature = "zeroize")]
140 | impl ZeroizeOnDrop for Encryptor {}
141 |
142 | struct Backend<'a, BS, BK>
143 | where
144 | BS: BlockSizes,
145 | BK: BlockCipherEncBackend,
146 | {
147 | iv: &'a mut Array,
148 | cipher_backend: &'a BK,
149 | }
150 |
151 | impl BlockSizeUser for Backend<'_, BS, BK>
152 | where
153 | BS: BlockSizes,
154 | BK: BlockCipherEncBackend,
155 | {
156 | type BlockSize = BS;
157 | }
158 |
159 | impl ParBlocksSizeUser for Backend<'_, BS, BK>
160 | where
161 | BS: BlockSizes,
162 | BK: BlockCipherEncBackend,
163 | {
164 | type ParBlocksSize = U1;
165 | }
166 |
167 | impl BlockModeEncBackend for Backend<'_, BS, BK>
168 | where
169 | BS: BlockSizes,
170 | BK: BlockCipherEncBackend,
171 | {
172 | #[inline(always)]
173 | fn encrypt_block(&mut self, mut block: InOut<'_, '_, Block>) {
174 | let mut t = block.clone_in();
175 | xor(&mut t, self.iv);
176 | self.cipher_backend.encrypt_block((&mut t).into());
177 | *self.iv = t.clone();
178 | *block.get_out() = t;
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/cbc/src/lib.rs:
--------------------------------------------------------------------------------
1 | //! [Cipher Block Chaining][1] (CBC) mode.
2 | //!
3 | //!
4 | //!
5 | //!
6 | //! Mode functionality is accessed using traits from re-exported [`cipher`] crate.
7 | //!
8 | //! # ⚠️ Security Warning: Hazmat!
9 | //!
10 | //! This crate does not ensure ciphertexts are authentic! Thus ciphertext integrity
11 | //! is not verified, which can lead to serious vulnerabilities!
12 | //! [AEADs][https://github.com/RustCrypto/AEADs] provide simple authenticated encryption,
13 | //! which is much less error-prone than manual integrity verification.
14 | //!
15 | //! # Example
16 | //! ```
17 | //! # #[cfg(feature = "block-padding")] {
18 | //! use aes::cipher::{block_padding::Pkcs7, BlockModeEncrypt, BlockModeDecrypt, KeyIvInit};
19 | //! use hex_literal::hex;
20 | //!
21 | //! type Aes128CbcEnc = cbc::Encryptor;
22 | //! type Aes128CbcDec = cbc::Decryptor;
23 | //!
24 | //! let key = [0x42; 16];
25 | //! let iv = [0x24; 16];
26 | //! let plaintext = *b"hello world! this is my plaintext.";
27 | //! let ciphertext = hex!(
28 | //! "c7fe247ef97b21f07cbdd26cb5d346bf"
29 | //! "d27867cb00d9486723e159978fb9a5f9"
30 | //! "14cfb228a710de4171e396e7b6cf859e"
31 | //! );
32 | //!
33 | //! // encrypt/decrypt in-place
34 | //! // buffer must be big enough for padded plaintext
35 | //! let mut buf = [0u8; 48];
36 | //! let pt_len = plaintext.len();
37 | //! buf[..pt_len].copy_from_slice(&plaintext);
38 | //! let ct = Aes128CbcEnc::new(&key.into(), &iv.into())
39 | //! .encrypt_padded::(&mut buf, pt_len)
40 | //! .unwrap();
41 | //! assert_eq!(ct, &ciphertext[..]);
42 | //!
43 | //! let pt = Aes128CbcDec::new(&key.into(), &iv.into())
44 | //! .decrypt_padded::(&mut buf)
45 | //! .unwrap();
46 | //! assert_eq!(pt, &plaintext);
47 | //!
48 | //! // encrypt/decrypt from buffer to buffer
49 | //! let mut buf = [0u8; 48];
50 | //! let ct = Aes128CbcEnc::new(&key.into(), &iv.into())
51 | //! .encrypt_padded_b2b::(&plaintext, &mut buf)
52 | //! .unwrap();
53 | //! assert_eq!(ct, &ciphertext[..]);
54 | //!
55 | //! let mut buf = [0u8; 48];
56 | //! let pt = Aes128CbcDec::new(&key.into(), &iv.into())
57 | //! .decrypt_padded_b2b::(&ct, &mut buf)
58 | //! .unwrap();
59 | //! assert_eq!(pt, &plaintext);
60 | //! # }
61 | //! ```
62 | //!
63 | //! With enabled `alloc` (or `std`) feature you also can use allocating
64 | //! convenience methods:
65 | //! ```
66 | //! # #[cfg(all(feature = "alloc", feature = "block-padding"))] {
67 | //! # use aes::cipher::{block_padding::Pkcs7, BlockModeEncrypt, BlockModeDecrypt, KeyIvInit};
68 | //! # use hex_literal::hex;
69 | //! # type Aes128CbcEnc = cbc::Encryptor;
70 | //! # type Aes128CbcDec = cbc::Decryptor;
71 | //! # let key = [0x42; 16];
72 | //! # let iv = [0x24; 16];
73 | //! # let plaintext = *b"hello world! this is my plaintext.";
74 | //! # let ciphertext = hex!(
75 | //! # "c7fe247ef97b21f07cbdd26cb5d346bf"
76 | //! # "d27867cb00d9486723e159978fb9a5f9"
77 | //! # "14cfb228a710de4171e396e7b6cf859e"
78 | //! # );
79 | //! let res = Aes128CbcEnc::new(&key.into(), &iv.into())
80 | //! .encrypt_padded_vec::(&plaintext);
81 | //! assert_eq!(res[..], ciphertext[..]);
82 | //! let res = Aes128CbcDec::new(&key.into(), &iv.into())
83 | //! .decrypt_padded_vec::(&res)
84 | //! .unwrap();
85 | //! assert_eq!(res[..], plaintext[..]);
86 | //! # }
87 | //! ```
88 | //!
89 | //! [1]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#CBC
90 |
91 | #![no_std]
92 | #![doc(
93 | html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
94 | html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
95 | )]
96 | #![forbid(unsafe_code)]
97 | #![cfg_attr(docsrs, feature(doc_auto_cfg))]
98 | #![warn(missing_debug_implementations, missing_docs, rust_2018_idioms)]
99 |
100 | mod decrypt;
101 | mod encrypt;
102 |
103 | pub use cipher;
104 | pub use decrypt::Decryptor;
105 | pub use encrypt::Encryptor;
106 |
107 | use cipher::array::{Array, ArraySize};
108 |
109 | #[inline(always)]
110 | fn xor(out: &mut Array, buf: &Array) {
111 | for (a, b) in out.iter_mut().zip(buf) {
112 | *a ^= *b;
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/cbc/tests/aes.rs:
--------------------------------------------------------------------------------
1 | use aes::*;
2 | use cbc::{Decryptor, Encryptor};
3 | use cipher::{block_mode_dec_test, block_mode_enc_test, iv_state_test};
4 |
5 | iv_state_test!(aes128_cbc_enc_iv_state, Encryptor, encrypt);
6 | iv_state_test!(aes128_cbc_dec_iv_state, Decryptor, decrypt);
7 | iv_state_test!(aes192_cbc_enc_iv_state, Encryptor, encrypt);
8 | iv_state_test!(aes192_cbc_dec_iv_state, Decryptor, decrypt);
9 | iv_state_test!(aes256_cbc_enc_iv_state, Encryptor, encrypt);
10 | iv_state_test!(aes256_cbc_dec_iv_state, Decryptor, decrypt);
11 |
12 | // Test vectors from CVAP "AES Multiblock Message Test (MMT) Sample Vectors":
13 | //
14 | block_mode_enc_test!(aes128_cbc_enc_test, "aes128", Encryptor);
15 | block_mode_dec_test!(aes128_cbc_dec_test, "aes128", Decryptor);
16 | block_mode_enc_test!(aes128enc_cbc_enc_test, "aes128", Encryptor);
17 | block_mode_dec_test!(aes128dec_cbc_dec_test, "aes128", Decryptor);
18 | block_mode_enc_test!(aes192_cbc_enc_test, "aes192", Encryptor);
19 | block_mode_dec_test!(aes192_cbc_dec_test, "aes192", Decryptor);
20 | block_mode_enc_test!(aes192enc_cbc_enc_test, "aes192", Encryptor);
21 | block_mode_dec_test!(aes192dec_cbc_dec_test, "aes192", Decryptor);
22 | block_mode_enc_test!(aes256_cbc_enc_test, "aes256", Encryptor);
23 | block_mode_dec_test!(aes256_cbc_dec_test, "aes256", Decryptor);
24 | block_mode_enc_test!(aes256enc_cbc_enc_test, "aes256", Encryptor);
25 | block_mode_dec_test!(aes256dec_cbc_dec_test, "aes256", Decryptor);
26 |
--------------------------------------------------------------------------------
/cbc/tests/data/aes128.blb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RustCrypto/block-modes/e52ed9c70aa22b8dd07285f4b15981f137960cd5/cbc/tests/data/aes128.blb
--------------------------------------------------------------------------------
/cbc/tests/data/aes192.blb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RustCrypto/block-modes/e52ed9c70aa22b8dd07285f4b15981f137960cd5/cbc/tests/data/aes192.blb
--------------------------------------------------------------------------------
/cbc/tests/data/aes256.blb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RustCrypto/block-modes/e52ed9c70aa22b8dd07285f4b15981f137960cd5/cbc/tests/data/aes256.blb
--------------------------------------------------------------------------------
/cfb-mode/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## 0.9.0 (UNRELEASED)
9 | ### Removed
10 | - `std` feature ([#76])
11 |
12 | ### Changed
13 | - Bump `cipher` from `0.4` to `0.5` ([#56])
14 | - Edition changed to 2024 and MSRV bumped to 1.85 ([#76])
15 | - Relax MSRV policy and allow MSRV bumps in patch releases
16 |
17 | [#56]: https://github.com/RustCrypto/block-modes/pull/56
18 | [#76]: https://github.com/RustCrypto/block-modes/pull/76
19 |
20 | ## 0.8.2 (2022-09-13)
21 | ### Added
22 | - `BufferEncryptor` and `BufferDecryptor` types ([#19])
23 |
24 | [#19]: https://github.com/RustCrypto/block-modes/pull/19
25 |
26 | ## 0.8.1 (2022-02-17)
27 | ### Fixed
28 | - Minimal versions build ([#9])
29 |
30 | [#9]: https://github.com/RustCrypto/block-modes/pull/9
31 |
32 | ## 0.8.0 (2022-02-10)
33 | ### Changed
34 | - Update `cipher` dependency to v0.4 and move crate
35 | to the [RustCrypto/block-modes] repository ([#2])
36 |
37 | [#2]: https://github.com/RustCrypto/block-modes/pull/2
38 | [RustCrypto/block-modes]: https://github.com/RustCrypto/block-modes
39 |
40 | ## 0.7.1 (2021-04-30)
41 | ### Changed
42 | - Removed redundant `NewBlockCipher` bound from `FromBlockCipher` implementation ([#236])
43 |
44 | [#236]: https://github.com/RustCrypto/stream-ciphers/pull/236
45 |
46 | ## 0.7.0 (2021-04-29)
47 | ### Changed
48 | - Bump `cipher` dependency to v0.3 release ([#226])
49 | - Bump `aes` dev dependency to v0.7 release ([#232])
50 |
51 | [#226]: https://github.com/RustCrypto/stream-ciphers/pull/226
52 | [#232]: https://github.com/RustCrypto/stream-ciphers/pull/232
53 |
54 | ## 0.6.0 (2020-10-16)
55 | ### Changed
56 | - Replace `block-cipher`/`stream-cipher` with `cipher` crate ([#177])
57 |
58 | [#177]: https://github.com/RustCrypto/stream-ciphers/pull/177
59 |
60 | ## 0.5.0 (2020-08-25)
61 | ### Changed
62 | - Bump `stream-cipher` dependency to v0.7, implement the `FromBlockCipher` trait ([#161], [#164])
63 |
64 | [#161]: https://github.com/RustCrypto/stream-ciphers/pull/161
65 | [#164]: https://github.com/RustCrypto/stream-ciphers/pull/164
66 |
67 | ## 0.4.0 (2020-06-08)
68 | ### Changed
69 | - Bump `stream-cipher` dependency to v0.4 ([#119])
70 | - Upgrade to Rust 2018 edition ([#119])
71 |
72 | [#119]: https://github.com/RustCrypto/stream-ciphers/pull/119
73 |
74 | ## 0.3.2 (2019-03-11)
75 |
76 | ## 0.3.1 (2018-11-01)
77 |
78 | ## 0.3.0 (2018-11-01)
79 |
80 | ## 0.2.0 (2018-10-13)
81 |
82 | ## 0.1.0 (2018-10-01)
83 |
--------------------------------------------------------------------------------
/cfb-mode/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "cfb-mode"
3 | version = "0.9.0-rc.0"
4 | description = "Cipher Feedback (CFB) block cipher mode of operation"
5 | authors = ["RustCrypto Developers"]
6 | license = "MIT OR Apache-2.0"
7 | edition = "2024"
8 | rust-version = "1.85"
9 | readme = "README.md"
10 | documentation = "https://docs.rs/cfb-mode"
11 | repository = "https://github.com/RustCrypto/block-modes"
12 | keywords = ["crypto", "block-mode", "stream-cipher", "ciphers"]
13 | categories = ["cryptography", "no-std"]
14 |
15 | [dependencies]
16 | cipher = "0.5.0-rc.0"
17 |
18 | [dev-dependencies]
19 | aes = "0.9.0-rc.0"
20 | belt-block = "0.2.0-rc.0"
21 | cipher = { version = "0.5.0-rc.0", features = ["dev"] }
22 | hex-literal = "1"
23 |
24 | [features]
25 | alloc = ["cipher/alloc"]
26 | block-padding = ["cipher/block-padding"]
27 | zeroize = ["cipher/zeroize"]
28 |
29 | [package.metadata.docs.rs]
30 | all-features = true
31 | rustdoc-args = ["--cfg", "docsrs"]
32 |
--------------------------------------------------------------------------------
/cfb-mode/LICENSE-MIT:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018-2022 RustCrypto Developers
2 | Copyright (c) 2018 Artyom Pavlov
3 |
4 | Permission is hereby granted, free of charge, to any
5 | person obtaining a copy of this software and associated
6 | documentation files (the "Software"), to deal in the
7 | Software without restriction, including without
8 | limitation the rights to use, copy, modify, merge,
9 | publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software
11 | is furnished to do so, subject to the following
12 | conditions:
13 |
14 | The above copyright notice and this permission notice
15 | shall be included in all copies or substantial portions
16 | of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
19 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
20 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
21 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
22 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
25 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 | DEALINGS IN THE SOFTWARE.
27 |
--------------------------------------------------------------------------------
/cfb-mode/README.md:
--------------------------------------------------------------------------------
1 | # RustCrypto: CFB
2 |
3 | [![crate][crate-image]][crate-link]
4 | [![Docs][docs-image]][docs-link]
5 | [![Build Status][build-image]][build-link]
6 | ![Apache2/MIT licensed][license-image]
7 | ![Rust Version][rustc-image]
8 | [![Project Chat][chat-image]][chat-link]
9 |
10 | Generic implementation of the [Cipher Feedback][CFB] (CFB) block cipher mode
11 | of operation.
12 |
13 | 
14 |
15 | See [documentation][cipher-doc] of the `cipher` crate for additional information.
16 |
17 | ## License
18 |
19 | Licensed under either of:
20 |
21 | * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
22 | * [MIT license](http://opensource.org/licenses/MIT)
23 |
24 | at your option.
25 |
26 | ### Contribution
27 |
28 | Unless you explicitly state otherwise, any contribution intentionally submitted
29 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
30 | dual licensed as above, without any additional terms or conditions.
31 |
32 | [//]: # (badges)
33 |
34 | [crate-image]: https://img.shields.io/crates/v/cfb-mode.svg?logo=rust
35 | [crate-link]: https://crates.io/crates/cfb-mode
36 | [docs-image]: https://docs.rs/cfb-mode/badge.svg
37 | [docs-link]: https://docs.rs/cfb-mode/
38 | [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
39 | [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg
40 | [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
41 | [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/308460-block-modes
42 | [build-image]: https://github.com/RustCrypto/block-modes/actions/workflows/cfb-mode.yaml/badge.svg
43 | [build-link]: https://github.com/RustCrypto/block-modes/actions/workflows/cfb-mode.yaml
44 |
45 | [//]: # (general links)
46 |
47 | [CFB]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_feedback_(CFB)
48 | [cipher-doc]: https://docs.rs/cipher/
49 |
--------------------------------------------------------------------------------
/cfb-mode/benches/aes128.rs:
--------------------------------------------------------------------------------
1 | #![feature(test)]
2 | extern crate test;
3 |
4 | use aes::Aes128;
5 |
6 | cipher::block_encryptor_bench!(
7 | KeyIv: cfb_mode::Encryptor,
8 | cfb_aes128_encrypt_block,
9 | cfb_aes128_encrypt_blocks,
10 | );
11 |
12 | cipher::block_decryptor_bench!(
13 | KeyIv: cfb_mode::Decryptor,
14 | cfb_aes128_decrypt_block,
15 | cfb_aes128_decrypt_blocks,
16 | );
17 |
--------------------------------------------------------------------------------
/cfb-mode/src/encrypt/buf.rs:
--------------------------------------------------------------------------------
1 | use super::xor_set1;
2 | use cipher::{
3 | AlgorithmName, Block, BlockCipherEncrypt, InnerIvInit, Iv, IvSizeUser,
4 | crypto_common::InnerUser, typenum::Unsigned,
5 | };
6 | use core::fmt;
7 |
8 | #[cfg(feature = "zeroize")]
9 | use cipher::zeroize::{Zeroize, ZeroizeOnDrop};
10 |
11 | /// CFB mode buffered encryptor.
12 | #[derive(Clone)]
13 | pub struct BufEncryptor
14 | where
15 | C: BlockCipherEncrypt,
16 | {
17 | cipher: C,
18 | iv: Block,
19 | pos: usize,
20 | }
21 |
22 | impl BufEncryptor
23 | where
24 | C: BlockCipherEncrypt,
25 | {
26 | /// Encrypt a buffer in multiple parts.
27 | pub fn encrypt(&mut self, mut data: &mut [u8]) {
28 | let bs = C::BlockSize::USIZE;
29 | let n = data.len();
30 |
31 | if n < bs - self.pos {
32 | xor_set1(data, &mut self.iv[self.pos..self.pos + n]);
33 | self.pos += n;
34 | return;
35 | }
36 |
37 | let (left, right) = { data }.split_at_mut(bs - self.pos);
38 | data = right;
39 | let mut iv = self.iv.clone();
40 | xor_set1(left, &mut iv[self.pos..]);
41 | self.cipher.encrypt_block(&mut iv);
42 |
43 | let mut chunks = data.chunks_exact_mut(bs);
44 | for chunk in &mut chunks {
45 | xor_set1(chunk, iv.as_mut_slice());
46 | self.cipher.encrypt_block(&mut iv);
47 | }
48 |
49 | let rem = chunks.into_remainder();
50 | xor_set1(rem, iv.as_mut_slice());
51 | self.pos = rem.len();
52 | self.iv = iv;
53 | }
54 |
55 | /// Returns the current state (block and position) of the decryptor.
56 | pub fn get_state(&self) -> (&Block, usize) {
57 | (&self.iv, self.pos)
58 | }
59 |
60 | /// Restore from the given state for resumption.
61 | pub fn from_state(cipher: C, iv: &Block, pos: usize) -> Self {
62 | Self {
63 | cipher,
64 | iv: iv.clone(),
65 | pos,
66 | }
67 | }
68 | }
69 |
70 | impl InnerUser for BufEncryptor
71 | where
72 | C: BlockCipherEncrypt,
73 | {
74 | type Inner = C;
75 | }
76 |
77 | impl IvSizeUser for BufEncryptor
78 | where
79 | C: BlockCipherEncrypt,
80 | {
81 | type IvSize = C::BlockSize;
82 | }
83 |
84 | impl InnerIvInit for BufEncryptor
85 | where
86 | C: BlockCipherEncrypt,
87 | {
88 | #[inline]
89 | fn inner_iv_init(cipher: C, iv: &Iv) -> Self {
90 | let mut iv = iv.clone();
91 | cipher.encrypt_block(&mut iv);
92 | Self { cipher, iv, pos: 0 }
93 | }
94 | }
95 |
96 | impl AlgorithmName for BufEncryptor
97 | where
98 | C: BlockCipherEncrypt + AlgorithmName,
99 | {
100 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
101 | f.write_str("cfb::BufEncryptor<")?;
102 | ::write_alg_name(f)?;
103 | f.write_str(">")
104 | }
105 | }
106 |
107 | impl fmt::Debug for BufEncryptor
108 | where
109 | C: BlockCipherEncrypt + AlgorithmName,
110 | {
111 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112 | f.write_str("cfb::BufEncryptor<")?;
113 | ::write_alg_name(f)?;
114 | f.write_str("> { ... }")
115 | }
116 | }
117 |
118 | impl Drop for BufEncryptor {
119 | fn drop(&mut self) {
120 | #[cfg(feature = "zeroize")]
121 | self.iv.zeroize();
122 | }
123 | }
124 |
125 | #[cfg(feature = "zeroize")]
126 | impl ZeroizeOnDrop for BufEncryptor {}
127 |
--------------------------------------------------------------------------------
/cfb-mode/src/lib.rs:
--------------------------------------------------------------------------------
1 | //! [Cipher feedback][1] (CFB) mode with full block feedback.
2 | //!
3 | //!
4 | //!
5 | //!
6 | //! Mode functionality is accessed using traits from re-exported [`cipher`] crate.
7 | //!
8 | //! # ⚠️ Security Warning: Hazmat!
9 | //!
10 | //! This crate does not ensure ciphertexts are authentic! Thus ciphertext integrity
11 | //! is not verified, which can lead to serious vulnerabilities!
12 | //! [AEADs][https://github.com/RustCrypto/AEADs] provide simple authenticated encryption,
13 | //! which is much less error-prone than manual integrity verification.
14 | //!
15 | //! # Example
16 | //! ```
17 | //! use aes::cipher::{AsyncStreamCipher, KeyIvInit};
18 | //! use hex_literal::hex;
19 | //!
20 | //! type Aes128CfbEnc = cfb_mode::Encryptor;
21 | //! type Aes128CfbDec = cfb_mode::Decryptor;
22 | //!
23 | //! let key = [0x42; 16];
24 | //! let iv = [0x24; 16];
25 | //! let plaintext = *b"hello world! this is my plaintext.";
26 | //! let ciphertext = hex!(
27 | //! "3357121ebb5a29468bd861467596ce3d6f99e251cc2d9f0a598032ae386d0ab995b3"
28 | //! );
29 | //!
30 | //! // encrypt/decrypt in-place
31 | //! let mut buf = plaintext.to_vec();
32 | //! Aes128CfbEnc::new(&key.into(), &iv.into()).encrypt(&mut buf);
33 | //! assert_eq!(buf[..], ciphertext[..]);
34 | //!
35 | //! Aes128CfbDec::new(&key.into(), &iv.into()).decrypt(&mut buf);
36 | //! assert_eq!(buf[..], plaintext[..]);
37 | //!
38 | //! // encrypt/decrypt from buffer to buffer
39 | //! // buffer length must be equal to input length
40 | //! let mut buf1 = [0u8; 34];
41 | //! Aes128CfbEnc::new(&key.into(), &iv.into())
42 | //! .encrypt_b2b(&plaintext, &mut buf1)
43 | //! .unwrap();
44 | //! assert_eq!(buf1[..], ciphertext[..]);
45 | //!
46 | //! let mut buf2 = [0u8; 34];
47 | //! Aes128CfbDec::new(&key.into(), &iv.into())
48 | //! .decrypt_b2b(&buf1, &mut buf2)
49 | //! .unwrap();
50 | //! assert_eq!(buf2[..], plaintext[..]);
51 | //! ```
52 | //!
53 | //! [1]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_feedback_(CFB)
54 |
55 | #![no_std]
56 | #![doc(
57 | html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
58 | html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
59 | )]
60 | #![forbid(unsafe_code)]
61 | #![cfg_attr(docsrs, feature(doc_auto_cfg))]
62 | #![warn(missing_debug_implementations, missing_docs, rust_2018_idioms)]
63 |
64 | mod decrypt;
65 | mod encrypt;
66 |
67 | pub use cipher;
68 | pub use decrypt::{BufDecryptor, Decryptor};
69 | pub use encrypt::{BufEncryptor, Encryptor};
70 |
--------------------------------------------------------------------------------
/cfb-mode/tests/aes.rs:
--------------------------------------------------------------------------------
1 | use aes::*;
2 | use cfb_mode::{BufDecryptor, BufEncryptor, Decryptor, Encryptor};
3 | use cipher::{KeyInit, block_mode_dec_test, block_mode_enc_test, iv_state_test};
4 |
5 | iv_state_test!(aes128_cfb_enc_iv_state, Encryptor, encrypt);
6 | iv_state_test!(aes128_cfb_dec_iv_state, Decryptor, decrypt);
7 | iv_state_test!(aes192_cfb_enc_iv_state, Encryptor, encrypt);
8 | iv_state_test!(aes192_cfb_dec_iv_state, Decryptor, decrypt);
9 | iv_state_test!(aes256_cfb_enc_iv_state, Encryptor, encrypt);
10 | iv_state_test!(aes256_cfb_dec_iv_state, Decryptor, decrypt);
11 |
12 | // Test vectors from CVAP "AES Multiblock Message Test (MMT) Sample Vectors":
13 | //
14 | block_mode_enc_test!(aes128_cfb_enc_test, "aes128", Encryptor);
15 | block_mode_dec_test!(aes128_cfb_dec_test, "aes128", Decryptor);
16 | block_mode_enc_test!(aes128enc_cfb_enc_test, "aes128", Encryptor);
17 | block_mode_dec_test!(aes128enc_cfb_dec_test, "aes128", Decryptor);
18 | block_mode_enc_test!(aes192_cfb_enc_test, "aes192", Encryptor);
19 | block_mode_dec_test!(aes192_cfb_dec_test, "aes192", Decryptor);
20 | block_mode_enc_test!(aes192enc_cfb_enc_test, "aes192", Encryptor);
21 | block_mode_dec_test!(aes192dec_cfb_dec_test, "aes192", Decryptor);
22 | block_mode_enc_test!(aes256_cfb_enc_test, "aes256", Encryptor);
23 | block_mode_dec_test!(aes256_cfb_dec_test, "aes256", Decryptor);
24 | block_mode_enc_test!(aes256enc_cfb_enc_test, "aes256", Encryptor);
25 | block_mode_dec_test!(aes256dec_cfb_dec_test, "aes256", Decryptor);
26 |
27 | /// Test methods from the `AsyncStreamCipher` trait.
28 | #[test]
29 | fn aes128_cfb_async_test() {
30 | use cipher::{AsyncStreamCipher, KeyIvInit};
31 |
32 | type Enc = Encryptor;
33 | type Dec = Decryptor;
34 |
35 | let key = [42; 16];
36 | let iv = [24; 16];
37 | let mut pt = [0u8; 101];
38 | for (i, b) in pt.iter_mut().enumerate() {
39 | *b = (i % 11) as u8;
40 | }
41 | let enc = Enc::new_from_slices(&key, &iv).unwrap();
42 | let mut ct = pt;
43 | enc.encrypt(&mut ct);
44 | for i in 1..100 {
45 | let enc = Enc::new_from_slices(&key, &iv).unwrap();
46 | let mut t = pt;
47 | let t = &mut t[..i];
48 | enc.encrypt(t);
49 | assert_eq!(t, &ct[..i]);
50 |
51 | let dec = Dec::new_from_slices(&key, &iv).unwrap();
52 | dec.decrypt(t);
53 | assert_eq!(t, &pt[..i]);
54 | }
55 | }
56 |
57 | #[test]
58 | fn aes128_cfb_buffered_test() {
59 | use cipher::{AsyncStreamCipher, KeyIvInit};
60 |
61 | type Enc = Encryptor;
62 |
63 | type BufEnc = BufEncryptor;
64 | type BufDec = BufDecryptor;
65 |
66 | let key = [42; 16];
67 | let iv = [24; 16];
68 | let mut pt = [0u8; 101];
69 | for (i, b) in pt.iter_mut().enumerate() {
70 | *b = (i % 11) as u8;
71 | }
72 |
73 | // unbuffered
74 | let enc = Enc::new_from_slices(&key, &iv).unwrap();
75 | let mut ct = pt;
76 | enc.encrypt(&mut ct);
77 |
78 | // buffered
79 | for i in 1..100 {
80 | let mut buf_enc = BufEnc::new_from_slices(&key, &iv).unwrap();
81 | let mut ct2 = pt;
82 | for chunk in ct2.chunks_mut(i) {
83 | buf_enc.encrypt(chunk);
84 | }
85 | assert_eq!(ct2, ct);
86 |
87 | let mut buf_dec = BufDec::new_from_slices(&key, &iv).unwrap();
88 | for chunk in ct2.chunks_mut(i) {
89 | buf_dec.decrypt(chunk);
90 | }
91 | assert_eq!(ct2, pt);
92 | }
93 |
94 | // buffered with restore
95 | for i in 1..100 {
96 | let mut buf_enc = BufEnc::new_from_slices(&key, &iv).unwrap();
97 | let mut ct2 = pt;
98 | for chunk in ct2.chunks_mut(i) {
99 | let (iv, pos) = buf_enc.get_state();
100 | let cipher = Aes128::new_from_slice(&key).unwrap();
101 | buf_enc = BufEnc::from_state(cipher, iv, pos);
102 |
103 | buf_enc.encrypt(chunk);
104 | }
105 | assert_eq!(ct2, ct);
106 |
107 | let mut buf_dec = BufDec::new_from_slices(&key, &iv).unwrap();
108 | for chunk in ct2.chunks_mut(i) {
109 | let (iv, pos) = buf_dec.get_state();
110 | let cipher = Aes128::new_from_slice(&key).unwrap();
111 | buf_dec = BufDec::from_state(cipher, iv, pos);
112 |
113 | buf_dec.decrypt(chunk);
114 | }
115 | assert_eq!(ct2, pt);
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/cfb-mode/tests/belt.rs:
--------------------------------------------------------------------------------
1 | use belt_block::BeltBlock;
2 | use cfb_mode::{Decryptor, Encryptor};
3 | use cipher::{block_mode_dec_test, block_mode_enc_test, iv_state_test};
4 |
5 | iv_state_test!(belt_cfb_enc_iv_state, Encryptor, encrypt);
6 | iv_state_test!(belt_cfb_dec_iv_state, Decryptor, decrypt);
7 |
8 | // Test vectors from STB 34.101.31-2020 (tables А.13 and А.14):
9 | //
10 | block_mode_enc_test!(belt_cfb_enc_test, "belt", Encryptor);
11 | block_mode_dec_test!(belt_cfb_dec_test, "belt", Decryptor);
12 |
--------------------------------------------------------------------------------
/cfb-mode/tests/data/aes128.blb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RustCrypto/block-modes/e52ed9c70aa22b8dd07285f4b15981f137960cd5/cfb-mode/tests/data/aes128.blb
--------------------------------------------------------------------------------
/cfb-mode/tests/data/aes192.blb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RustCrypto/block-modes/e52ed9c70aa22b8dd07285f4b15981f137960cd5/cfb-mode/tests/data/aes192.blb
--------------------------------------------------------------------------------
/cfb-mode/tests/data/aes256.blb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RustCrypto/block-modes/e52ed9c70aa22b8dd07285f4b15981f137960cd5/cfb-mode/tests/data/aes256.blb
--------------------------------------------------------------------------------
/cfb-mode/tests/data/belt.blb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RustCrypto/block-modes/e52ed9c70aa22b8dd07285f4b15981f137960cd5/cfb-mode/tests/data/belt.blb
--------------------------------------------------------------------------------
/cfb8/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## 0.9.0 (UNRELEASED)
9 | ### Removed
10 | - `std` feature ([#76])
11 |
12 | ### Changed
13 | - Bump `cipher` from `0.4` to `0.5` ([#56])
14 | - Edition changed to 2024 and MSRV bumped to 1.85 ([#76])
15 | - Relax MSRV policy and allow MSRV bumps in patch releases
16 |
17 | [#56]: https://github.com/RustCrypto/block-modes/pull/56
18 | [#75]: https://github.com/RustCrypto/block-modes/pull/76
19 |
20 | ## 0.8.1 (2022-02-17)
21 | ### Fixed
22 | - Minimal versions build ([#9])
23 |
24 | [#9]: https://github.com/RustCrypto/block-modes/pull/9
25 |
26 | ## 0.8.0 (2022-02-10)
27 | ### Changed
28 | - Update `cipher` dependency to v0.4 and move crate
29 | to the [RustCrypto/block-modes] repository ([#2])
30 |
31 | [#2]: https://github.com/RustCrypto/block-modes/pull/2
32 | [RustCrypto/block-modes]: https://github.com/RustCrypto/block-modes
33 |
34 | ## 0.7.1 (2021-04-30)
35 | ### Changed
36 | - Removed redundant `NewBlockCipher` boundfrom `FromBlockCipher` implementation ([#236])
37 |
38 | [#236]: https://github.com/RustCrypto/stream-ciphers/pull/236
39 |
40 | ## 0.7.0 (2021-04-29)
41 | ### Changed
42 | - Bump `cipher` dependency to v0.3 release ([#226])
43 | - Bump `aes` dev dependency to v0.7 release ([#232])
44 |
45 | [#226]: https://github.com/RustCrypto/stream-ciphers/pull/226
46 | [#232]: https://github.com/RustCrypto/stream-ciphers/pull/232
47 |
48 | ## 0.6.0 (2020-10-16)
49 | ### Changed
50 | - Replace `block-cipher`/`stream-cipher` with `cipher` crate ([#177])
51 |
52 | [#177]: https://github.com/RustCrypto/stream-ciphers/pull/177
53 |
54 | ## 0.5.0 (2020-08-25)
55 | ### Changed
56 | - Bump `stream-cipher` dependency to v0.7, implement the `FromBlockCipher` trait ([#161], [#164])
57 |
58 | [#161]: https://github.com/RustCrypto/stream-ciphers/pull/161
59 | [#164]: https://github.com/RustCrypto/stream-ciphers/pull/164
60 |
61 | ## 0.4.0 (2020-06-08)
62 | ### Changed
63 | - Bump `stream-cipher` dependency to v0.4 ([#120])
64 | - Upgrade to Rust 2018 edition ([#120])
65 |
66 | [#120]: https://github.com/RustCrypto/stream-ciphers/pull/120
67 |
68 | ## 0.3.2 (2019-03-11)
69 |
70 | ## 0.3.1 (2018-11-01)
71 |
72 | ## 0.3.0 (2018-11-01)
73 |
74 | ## 0.1.0 (2018-11-01)
75 |
--------------------------------------------------------------------------------
/cfb8/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "cfb8"
3 | version = "0.9.0-rc.0"
4 | description = "Cipher Feedback with eight bit feedback (CFB-8) block cipher mode of operation"
5 | authors = ["RustCrypto Developers"]
6 | license = "MIT OR Apache-2.0"
7 | edition = "2024"
8 | rust-version = "1.85"
9 | readme = "README.md"
10 | documentation = "https://docs.rs/cfb8"
11 | repository = "https://github.com/RustCrypto/block-modes"
12 | keywords = ["crypto", "block-mode", "stream-cipher", "ciphers"]
13 | categories = ["cryptography", "no-std"]
14 |
15 | [dependencies]
16 | cipher = "0.5.0-rc.0"
17 |
18 | [dev-dependencies]
19 | aes = "0.9.0-rc.0"
20 | cipher = { version = "0.5.0-rc.0", features = ["dev"] }
21 | hex-literal = "1"
22 |
23 | [features]
24 | alloc = ["cipher/alloc"]
25 | block-padding = ["cipher/block-padding"]
26 | zeroize = ["cipher/zeroize"]
27 |
28 | [package.metadata.docs.rs]
29 | all-features = true
30 | rustdoc-args = ["--cfg", "docsrs"]
31 |
--------------------------------------------------------------------------------
/cfb8/LICENSE-MIT:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018-2022 RustCrypto Developers
2 | Copyright (c) 2018 Artyom Pavlov
3 |
4 | Permission is hereby granted, free of charge, to any
5 | person obtaining a copy of this software and associated
6 | documentation files (the "Software"), to deal in the
7 | Software without restriction, including without
8 | limitation the rights to use, copy, modify, merge,
9 | publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software
11 | is furnished to do so, subject to the following
12 | conditions:
13 |
14 | The above copyright notice and this permission notice
15 | shall be included in all copies or substantial portions
16 | of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
19 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
20 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
21 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
22 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
25 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 | DEALINGS IN THE SOFTWARE.
27 |
--------------------------------------------------------------------------------
/cfb8/README.md:
--------------------------------------------------------------------------------
1 | # RustCrypto: CFB-8
2 |
3 | [![crate][crate-image]][crate-link]
4 | [![Docs][docs-image]][docs-link]
5 | [![Build Status][build-image]][build-link]
6 | ![Apache2/MIT licensed][license-image]
7 | ![Rust Version][rustc-image]
8 | [![Project Chat][chat-image]][chat-link]
9 |
10 | Generic implementation of the [Cipher Feedback][CFB-8] with eight bit
11 | feedback (CFB-8) block cipher mode of operation.
12 |
13 | 
14 |
15 | See [documentation][cipher-doc] of the `cipher` crate for additional information.
16 |
17 | ## License
18 |
19 | Licensed under either of:
20 |
21 | * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
22 | * [MIT license](http://opensource.org/licenses/MIT)
23 |
24 | at your option.
25 |
26 | ### Contribution
27 |
28 | Unless you explicitly state otherwise, any contribution intentionally submitted
29 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
30 | dual licensed as above, without any additional terms or conditions.
31 |
32 | [//]: # (badges)
33 |
34 | [crate-image]: https://img.shields.io/crates/v/cfb8.svg?logo=rust
35 | [crate-link]: https://crates.io/crates/cfb8
36 | [docs-image]: https://docs.rs/cfb8/badge.svg
37 | [docs-link]: https://docs.rs/cfb8/
38 | [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
39 | [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg
40 | [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
41 | [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/308460-block-modes
42 | [build-image]: https://github.com/RustCrypto/block-modes/actions/workflows/cfb8.yaml/badge.svg
43 | [build-link]: https://github.com/RustCrypto/block-modes/actions/workflows/cfb8.yaml
44 |
45 | [//]: # (general links)
46 |
47 | [CFB]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#CFB-1,_CFB-8,_CFB-64,_CFB-128,_etc.
48 | [cipher-doc]: https://docs.rs/cipher/
49 |
--------------------------------------------------------------------------------
/cfb8/benches/aes128.rs:
--------------------------------------------------------------------------------
1 | #![feature(test)]
2 | extern crate test;
3 |
4 | use aes::Aes128;
5 |
6 | cipher::block_encryptor_bench!(
7 | KeyIv: cfb8::Encryptor,
8 | cfb8_aes128_encrypt_block,
9 | cfb8_aes128_encrypt_blocks,
10 | );
11 |
12 | cipher::block_decryptor_bench!(
13 | KeyIv: cfb8::Decryptor,
14 | cfb8_aes128_decrypt_block,
15 | cfb8_aes128_decrypt_blocks,
16 | );
17 |
--------------------------------------------------------------------------------
/cfb8/src/decrypt.rs:
--------------------------------------------------------------------------------
1 | use cipher::{
2 | AlgorithmName, AsyncStreamCipher, Block, BlockCipherEncBackend, BlockCipherEncClosure,
3 | BlockCipherEncrypt, BlockModeDecBackend, BlockModeDecClosure, BlockModeDecrypt, BlockSizeUser,
4 | InnerIvInit, Iv, IvState, ParBlocksSizeUser,
5 | array::Array,
6 | consts::U1,
7 | crypto_common::{BlockSizes, InnerUser, IvSizeUser},
8 | inout::InOut,
9 | };
10 | use core::fmt;
11 |
12 | #[cfg(feature = "zeroize")]
13 | use cipher::zeroize::{Zeroize, ZeroizeOnDrop};
14 |
15 | /// CFB-8 mode decryptor.
16 | #[derive(Clone)]
17 | pub struct Decryptor
18 | where
19 | C: BlockCipherEncrypt,
20 | {
21 | cipher: C,
22 | iv: Block,
23 | }
24 |
25 | impl BlockSizeUser for Decryptor
26 | where
27 | C: BlockCipherEncrypt,
28 | {
29 | type BlockSize = U1;
30 | }
31 |
32 | impl BlockModeDecrypt for Decryptor
33 | where
34 | C: BlockCipherEncrypt,
35 | {
36 | fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure) {
37 | struct Closure<'a, BS, BC>
38 | where
39 | BS: BlockSizes,
40 | BC: BlockModeDecClosure,
41 | {
42 | iv: &'a mut Array,
43 | f: BC,
44 | }
45 |
46 | impl BlockSizeUser for Closure<'_, BS, BC>
47 | where
48 | BS: BlockSizes,
49 | BC: BlockModeDecClosure,
50 | {
51 | type BlockSize = BS;
52 | }
53 |
54 | impl BlockCipherEncClosure for Closure<'_, BS, BC>
55 | where
56 | BS: BlockSizes,
57 | BC: BlockModeDecClosure,
58 | {
59 | #[inline(always)]
60 | fn call>(self, backend: &B) {
61 | let Self { iv, f } = self;
62 | f.call(&mut Backend { iv, backend });
63 | }
64 | }
65 |
66 | let Self { cipher, iv } = self;
67 | cipher.encrypt_with_backend(Closure { iv, f })
68 | }
69 | }
70 |
71 | impl AsyncStreamCipher for Decryptor {}
72 |
73 | impl InnerUser for Decryptor
74 | where
75 | C: BlockCipherEncrypt,
76 | {
77 | type Inner = C;
78 | }
79 |
80 | impl IvSizeUser for Decryptor
81 | where
82 | C: BlockCipherEncrypt,
83 | {
84 | type IvSize = C::BlockSize;
85 | }
86 |
87 | impl InnerIvInit for Decryptor
88 | where
89 | C: BlockCipherEncrypt,
90 | {
91 | #[inline]
92 | fn inner_iv_init(cipher: C, iv: &Iv) -> Self {
93 | let iv = iv.clone();
94 | Self { cipher, iv }
95 | }
96 | }
97 |
98 | impl IvState for Decryptor
99 | where
100 | C: BlockCipherEncrypt,
101 | {
102 | #[inline]
103 | fn iv_state(&self) -> Iv {
104 | self.iv.clone()
105 | }
106 | }
107 |
108 | impl AlgorithmName for Decryptor
109 | where
110 | C: BlockCipherEncrypt + AlgorithmName,
111 | {
112 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 | f.write_str("cfb8::Decryptor<")?;
114 | ::write_alg_name(f)?;
115 | f.write_str(">")
116 | }
117 | }
118 |
119 | impl fmt::Debug for Decryptor
120 | where
121 | C: BlockCipherEncrypt + AlgorithmName,
122 | {
123 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124 | f.write_str("cfb8::Decryptor<")?;
125 | ::write_alg_name(f)?;
126 | f.write_str("> { ... }")
127 | }
128 | }
129 |
130 | impl Drop for Decryptor {
131 | fn drop(&mut self) {
132 | #[cfg(feature = "zeroize")]
133 | self.iv.zeroize();
134 | }
135 | }
136 |
137 | #[cfg(feature = "zeroize")]
138 | impl ZeroizeOnDrop for Decryptor {}
139 |
140 | struct Backend<'a, BS, BK>
141 | where
142 | BS: BlockSizes,
143 | BK: BlockCipherEncBackend,
144 | {
145 | iv: &'a mut Array,
146 | backend: &'a BK,
147 | }
148 |
149 | impl BlockSizeUser for Backend<'_, BS, BK>
150 | where
151 | BS: BlockSizes,
152 | BK: BlockCipherEncBackend,
153 | {
154 | type BlockSize = U1;
155 | }
156 |
157 | impl ParBlocksSizeUser for Backend<'_, BS, BK>
158 | where
159 | BS: BlockSizes,
160 | BK: BlockCipherEncBackend,
161 | {
162 | type ParBlocksSize = U1;
163 | }
164 |
165 | impl BlockModeDecBackend for Backend<'_, BS, BK>
166 | where
167 | BS: BlockSizes,
168 | BK: BlockCipherEncBackend,
169 | {
170 | #[inline(always)]
171 | fn decrypt_block(&mut self, mut block: InOut<'_, '_, Block>) {
172 | let mut t = self.iv.clone();
173 | self.backend.encrypt_block((&mut t).into());
174 | let r = block.get(0).clone_in();
175 | let k: &Array = t[..1].try_into().unwrap();
176 | block.xor_in2out(k);
177 | let n = self.iv.len();
178 | for i in 0..n - 1 {
179 | self.iv[i] = self.iv[i + 1];
180 | }
181 | self.iv[n - 1] = r;
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/cfb8/src/encrypt.rs:
--------------------------------------------------------------------------------
1 | use cipher::{
2 | AlgorithmName, AsyncStreamCipher, Block, BlockCipherEncBackend, BlockCipherEncClosure,
3 | BlockCipherEncrypt, BlockModeEncBackend, BlockModeEncClosure, BlockModeEncrypt, BlockSizeUser,
4 | InnerIvInit, Iv, IvState, ParBlocksSizeUser,
5 | array::Array,
6 | consts::U1,
7 | crypto_common::{BlockSizes, InnerUser, IvSizeUser},
8 | inout::InOut,
9 | };
10 | use core::fmt;
11 |
12 | #[cfg(feature = "zeroize")]
13 | use cipher::zeroize::{Zeroize, ZeroizeOnDrop};
14 |
15 | /// CFB-8 mode encryptor.
16 | #[derive(Clone)]
17 | pub struct Encryptor
18 | where
19 | C: BlockCipherEncrypt,
20 | {
21 | cipher: C,
22 | iv: Block,
23 | }
24 |
25 | impl BlockSizeUser for Encryptor
26 | where
27 | C: BlockCipherEncrypt,
28 | {
29 | type BlockSize = U1;
30 | }
31 |
32 | impl BlockModeEncrypt for Encryptor
33 | where
34 | C: BlockCipherEncrypt,
35 | {
36 | fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure) {
37 | struct Closure<'a, BS, BC>
38 | where
39 | BS: BlockSizes,
40 | BC: BlockModeEncClosure,
41 | {
42 | iv: &'a mut Array,
43 | f: BC,
44 | }
45 |
46 | impl BlockSizeUser for Closure<'_, BS, BC>
47 | where
48 | BS: BlockSizes,
49 | BC: BlockModeEncClosure,
50 | {
51 | type BlockSize = BS;
52 | }
53 |
54 | impl BlockCipherEncClosure for Closure<'_, BS, BC>
55 | where
56 | BS: BlockSizes,
57 | BC: BlockModeEncClosure,
58 | {
59 | #[inline(always)]
60 | fn call>(self, backend: &B) {
61 | let Self { iv, f } = self;
62 | f.call(&mut Backend { iv, backend });
63 | }
64 | }
65 |
66 | let Self { cipher, iv } = self;
67 | cipher.encrypt_with_backend(Closure { iv, f })
68 | }
69 | }
70 |
71 | impl AsyncStreamCipher for Encryptor {}
72 |
73 | impl InnerUser for Encryptor
74 | where
75 | C: BlockCipherEncrypt,
76 | {
77 | type Inner = C;
78 | }
79 |
80 | impl IvSizeUser for Encryptor
81 | where
82 | C: BlockCipherEncrypt,
83 | {
84 | type IvSize = C::BlockSize;
85 | }
86 |
87 | impl InnerIvInit for Encryptor
88 | where
89 | C: BlockCipherEncrypt,
90 | {
91 | #[inline]
92 | fn inner_iv_init(cipher: C, iv: &Iv) -> Self {
93 | let iv = iv.clone();
94 | Self { cipher, iv }
95 | }
96 | }
97 |
98 | impl IvState for Encryptor
99 | where
100 | C: BlockCipherEncrypt,
101 | {
102 | #[inline]
103 | fn iv_state(&self) -> Iv {
104 | self.iv.clone()
105 | }
106 | }
107 |
108 | impl AlgorithmName for Encryptor
109 | where
110 | C: BlockCipherEncrypt + AlgorithmName,
111 | {
112 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 | f.write_str("cfb8::Encryptor<")?;
114 | ::write_alg_name(f)?;
115 | f.write_str(">")
116 | }
117 | }
118 |
119 | impl