├── .github ├── dependabot.yml └── workflows │ ├── belt-mac.yml │ ├── cbc-mac.yml │ ├── cmac.yml │ ├── hmac.yml │ ├── pmac.yml │ ├── retail-mac.yml │ └── workspace.yml ├── .gitignore ├── .typos.toml ├── Cargo.lock ├── Cargo.toml ├── README.md ├── SECURITY.md ├── belt-mac ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── benches │ └── mod.rs ├── src │ ├── block_api.rs │ └── lib.rs └── tests │ ├── data │ └── belt-mac.blb │ └── mod.rs ├── cbc-mac ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── benches │ └── mod.rs └── src │ ├── block_api.rs │ └── lib.rs ├── cmac ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── benches │ └── mod.rs ├── src │ ├── block_api.rs │ └── lib.rs └── tests │ ├── cavp_large.rs │ ├── data │ ├── aes128.blb │ ├── aes192.blb │ ├── aes256.blb │ ├── cavp_aes128.blb │ ├── cavp_aes128_large.blb │ ├── cavp_aes192.blb │ ├── cavp_aes256.blb │ ├── cavp_tdes2.blb │ ├── cavp_tdes3.blb │ ├── kuznyechik.blb │ ├── magma.blb │ ├── wycheproof-aes128.blb │ ├── wycheproof-aes192.blb │ └── wycheproof-aes256.blb │ └── mod.rs ├── hmac ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── src │ ├── block_api.rs │ ├── lib.rs │ ├── simple.rs │ ├── simple_reset.rs │ └── utils.rs └── tests │ ├── data │ ├── md5.blb │ ├── sha224.blb │ ├── sha256.blb │ ├── sha384.blb │ ├── sha512.blb │ ├── streebog256.blb │ ├── streebog512.blb │ ├── wycheproof-sha1.blb │ ├── wycheproof-sha256.blb │ ├── wycheproof-sha384.blb │ └── wycheproof-sha512.blb │ └── mod.rs ├── pmac ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── benches │ └── mod.rs ├── src │ ├── block_api.rs │ └── lib.rs └── tests │ ├── data │ ├── aes128.blb │ ├── aes192.blb │ └── aes256.blb │ └── mod.rs └── retail-mac ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── benches └── mod.rs └── src ├── block_api.rs └── lib.rs /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | versioning-strategy: lockfile-only 5 | directory: "/" 6 | allow: 7 | - dependency-type: "all" 8 | groups: 9 | all-deps: 10 | patterns: 11 | - "*" 12 | schedule: 13 | interval: weekly 14 | open-pull-requests-limit: 10 15 | - package-ecosystem: github-actions 16 | directory: "/" 17 | schedule: 18 | interval: weekly 19 | open-pull-requests-limit: 10 20 | -------------------------------------------------------------------------------- /.github/workflows/belt-mac.yml: -------------------------------------------------------------------------------- 1 | name: belt-mac 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - ".github/workflows/belt-mac.yml" 7 | - "belt-mac/**" 8 | - "Cargo.*" 9 | push: 10 | branches: master 11 | 12 | defaults: 13 | run: 14 | working-directory: belt-mac 15 | 16 | env: 17 | CARGO_INCREMENTAL: 0 18 | RUSTFLAGS: "-Dwarnings" 19 | 20 | jobs: 21 | build: 22 | runs-on: ubuntu-latest 23 | strategy: 24 | matrix: 25 | rust: 26 | - 1.85.0 # MSRV 27 | - stable 28 | target: 29 | - thumbv7em-none-eabi 30 | - wasm32-unknown-unknown 31 | steps: 32 | - uses: actions/checkout@v4 33 | - uses: RustCrypto/actions/cargo-cache@master 34 | - uses: dtolnay/rust-toolchain@master 35 | with: 36 | toolchain: ${{ matrix.rust }} 37 | targets: ${{ matrix.target }} 38 | - run: cargo build --no-default-features --target ${{ matrix.target }} 39 | 40 | minimal-versions: 41 | # disabled until belt-block gets published 42 | if: false 43 | uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master 44 | with: 45 | working-directory: ${{ github.workflow }} 46 | 47 | test: 48 | runs-on: ubuntu-latest 49 | strategy: 50 | matrix: 51 | rust: 52 | - 1.85.0 # MSRV 53 | - stable 54 | steps: 55 | - uses: actions/checkout@v4 56 | - uses: RustCrypto/actions/cargo-cache@master 57 | - uses: dtolnay/rust-toolchain@master 58 | with: 59 | toolchain: ${{ matrix.rust }} 60 | - uses: RustCrypto/actions/cargo-hack-install@master 61 | - run: cargo hack test --feature-powerset 62 | - run: cargo test --release --all-features 63 | -------------------------------------------------------------------------------- /.github/workflows/cbc-mac.yml: -------------------------------------------------------------------------------- 1 | name: cbc-mac 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - ".github/workflows/cbc-mac.yml" 7 | - "cbc-mac/**" 8 | - "Cargo.*" 9 | push: 10 | branches: master 11 | 12 | 13 | defaults: 14 | run: 15 | working-directory: cbc-mac 16 | 17 | env: 18 | CARGO_INCREMENTAL: 0 19 | RUSTFLAGS: "-Dwarnings" 20 | 21 | jobs: 22 | build: 23 | runs-on: ubuntu-latest 24 | strategy: 25 | matrix: 26 | rust: 27 | - 1.85.0 # MSRV 28 | - stable 29 | target: 30 | - thumbv7em-none-eabi 31 | - wasm32-unknown-unknown 32 | steps: 33 | - uses: actions/checkout@v4 34 | - uses: RustCrypto/actions/cargo-cache@master 35 | - uses: dtolnay/rust-toolchain@master 36 | with: 37 | toolchain: ${{ matrix.rust }} 38 | targets: ${{ matrix.target }} 39 | - run: cargo build --no-default-features --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: dtolnay/rust-toolchain@master 59 | with: 60 | toolchain: ${{ matrix.rust }} 61 | - uses: RustCrypto/actions/cargo-hack-install@master 62 | - run: cargo hack test --feature-powerset 63 | - run: cargo test --release --all-features 64 | -------------------------------------------------------------------------------- /.github/workflows/cmac.yml: -------------------------------------------------------------------------------- 1 | name: cmac 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - ".github/workflows/cmac.yml" 7 | - "cmac/**" 8 | - "Cargo.*" 9 | push: 10 | branches: master 11 | 12 | defaults: 13 | run: 14 | working-directory: cmac 15 | 16 | env: 17 | CARGO_INCREMENTAL: 0 18 | RUSTFLAGS: "-Dwarnings" 19 | 20 | jobs: 21 | build: 22 | runs-on: ubuntu-latest 23 | strategy: 24 | matrix: 25 | rust: 26 | - 1.85.0 # MSRV 27 | - stable 28 | target: 29 | - thumbv7em-none-eabi 30 | - wasm32-unknown-unknown 31 | steps: 32 | - uses: actions/checkout@v4 33 | - uses: RustCrypto/actions/cargo-cache@master 34 | - uses: dtolnay/rust-toolchain@master 35 | with: 36 | toolchain: ${{ matrix.rust }} 37 | targets: ${{ matrix.target }} 38 | - run: cargo build --no-default-features --target ${{ matrix.target }} 39 | 40 | minimal-versions: 41 | # disabled until belt-block gets published 42 | if: false 43 | uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master 44 | with: 45 | working-directory: ${{ github.workflow }} 46 | 47 | test: 48 | runs-on: ubuntu-latest 49 | strategy: 50 | matrix: 51 | rust: 52 | - 1.85.0 # MSRV 53 | - stable 54 | steps: 55 | - uses: actions/checkout@v4 56 | - uses: RustCrypto/actions/cargo-cache@master 57 | - uses: dtolnay/rust-toolchain@master 58 | with: 59 | toolchain: ${{ matrix.rust }} 60 | - uses: RustCrypto/actions/cargo-hack-install@master 61 | - run: cargo hack test --feature-powerset 62 | - run: cargo test --release --all-features 63 | -------------------------------------------------------------------------------- /.github/workflows/hmac.yml: -------------------------------------------------------------------------------- 1 | name: hmac 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - ".github/workflows/hmac.yml" 7 | - "hmac/**" 8 | - "Cargo.*" 9 | push: 10 | branches: master 11 | 12 | 13 | defaults: 14 | run: 15 | working-directory: hmac 16 | 17 | env: 18 | CARGO_INCREMENTAL: 0 19 | RUSTFLAGS: "-Dwarnings" 20 | 21 | jobs: 22 | build: 23 | runs-on: ubuntu-latest 24 | strategy: 25 | matrix: 26 | rust: 27 | - 1.85.0 # MSRV 28 | - stable 29 | target: 30 | - thumbv7em-none-eabi 31 | - wasm32-unknown-unknown 32 | steps: 33 | - uses: actions/checkout@v4 34 | - uses: RustCrypto/actions/cargo-cache@master 35 | - uses: dtolnay/rust-toolchain@master 36 | with: 37 | toolchain: ${{ matrix.rust }} 38 | targets: ${{ matrix.target }} 39 | - run: cargo build --no-default-features --target ${{ matrix.target }} 40 | 41 | minimal-versions: 42 | if: false # TODO: temp disabled due to unpublished prerelease dependencies 43 | uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master 44 | with: 45 | working-directory: ${{ github.workflow }} 46 | 47 | test: 48 | runs-on: ubuntu-latest 49 | strategy: 50 | matrix: 51 | rust: 52 | - 1.85.0 # MSRV 53 | - stable 54 | steps: 55 | - uses: actions/checkout@v4 56 | - uses: RustCrypto/actions/cargo-cache@master 57 | - uses: dtolnay/rust-toolchain@master 58 | with: 59 | toolchain: ${{ matrix.rust }} 60 | - uses: RustCrypto/actions/cargo-hack-install@master 61 | - run: cargo hack test --feature-powerset 62 | - run: cargo test --release --all-features 63 | -------------------------------------------------------------------------------- /.github/workflows/pmac.yml: -------------------------------------------------------------------------------- 1 | name: pmac 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - ".github/workflows/pmac.yml" 7 | - "pmac/**" 8 | - "Cargo.*" 9 | push: 10 | branches: master 11 | 12 | defaults: 13 | run: 14 | working-directory: pmac 15 | 16 | env: 17 | CARGO_INCREMENTAL: 0 18 | RUSTFLAGS: "-Dwarnings" 19 | 20 | jobs: 21 | build: 22 | runs-on: ubuntu-latest 23 | strategy: 24 | matrix: 25 | rust: 26 | - 1.85.0 # MSRV 27 | - stable 28 | target: 29 | - thumbv7em-none-eabi 30 | - wasm32-unknown-unknown 31 | steps: 32 | - uses: actions/checkout@v4 33 | - uses: RustCrypto/actions/cargo-cache@master 34 | - uses: dtolnay/rust-toolchain@master 35 | with: 36 | toolchain: ${{ matrix.rust }} 37 | targets: ${{ matrix.target }} 38 | - run: cargo build --no-default-features --target ${{ matrix.target }} 39 | 40 | minimal-versions: 41 | # disabled until belt-block gets published 42 | if: false 43 | uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master 44 | with: 45 | working-directory: ${{ github.workflow }} 46 | 47 | test: 48 | runs-on: ubuntu-latest 49 | strategy: 50 | matrix: 51 | rust: 52 | - 1.85.0 # MSRV 53 | - stable 54 | steps: 55 | - uses: actions/checkout@v4 56 | - uses: RustCrypto/actions/cargo-cache@master 57 | - uses: dtolnay/rust-toolchain@master 58 | with: 59 | toolchain: ${{ matrix.rust }} 60 | - uses: RustCrypto/actions/cargo-hack-install@master 61 | - run: cargo hack test --feature-powerset 62 | - run: cargo test --release --all-features 63 | -------------------------------------------------------------------------------- /.github/workflows/retail-mac.yml: -------------------------------------------------------------------------------- 1 | name: retail-mac 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - ".github/workflows/retail-mac.yml" 7 | - "retail-mac/**" 8 | - "Cargo.*" 9 | push: 10 | branches: master 11 | 12 | defaults: 13 | run: 14 | working-directory: retail-mac 15 | 16 | env: 17 | CARGO_INCREMENTAL: 0 18 | RUSTFLAGS: "-Dwarnings" 19 | 20 | jobs: 21 | build: 22 | runs-on: ubuntu-latest 23 | strategy: 24 | matrix: 25 | rust: 26 | - 1.85.0 # MSRV 27 | - stable 28 | target: 29 | - thumbv7em-none-eabi 30 | - wasm32-unknown-unknown 31 | steps: 32 | - uses: actions/checkout@v4 33 | - uses: RustCrypto/actions/cargo-cache@master 34 | - uses: dtolnay/rust-toolchain@master 35 | with: 36 | toolchain: ${{ matrix.rust }} 37 | targets: ${{ matrix.target }} 38 | - run: cargo build --no-default-features --target ${{ matrix.target }} 39 | 40 | minimal-versions: 41 | # disabled until belt-block gets published 42 | if: false 43 | uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master 44 | with: 45 | working-directory: ${{ github.workflow }} 46 | 47 | test: 48 | runs-on: ubuntu-latest 49 | strategy: 50 | matrix: 51 | rust: 52 | - 1.85.0 # MSRV 53 | - stable 54 | steps: 55 | - uses: actions/checkout@v4 56 | - uses: RustCrypto/actions/cargo-cache@master 57 | - uses: dtolnay/rust-toolchain@master 58 | with: 59 | toolchain: ${{ matrix.rust }} 60 | - uses: RustCrypto/actions/cargo-hack-install@master 61 | - run: cargo hack test --feature-powerset 62 | - run: cargo test --release --all-features 63 | -------------------------------------------------------------------------------- /.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 -- -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 | 36 | - name: Run cargo fmt 37 | run: cargo fmt --all -- --check 38 | 39 | typos: 40 | runs-on: ubuntu-latest 41 | steps: 42 | - uses: actions/checkout@v4 43 | - uses: crate-ci/typos@v1 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | **/Cargo.lock 3 | **/target/ 4 | -------------------------------------------------------------------------------- /.typos.toml: -------------------------------------------------------------------------------- 1 | [files] 2 | extend-exclude = [ 3 | ".git/" 4 | ] 5 | 6 | [default.extend-words] 7 | "GOST" = "GOST" 8 | "DAA" = "DAA" 9 | "EDE" = "EDE" 10 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "aes" 7 | version = "0.9.0-rc.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "cd4838e4ad37bb032dea137f441d5f71c16c26c068af512e64c5bc13a88cdfc7" 10 | dependencies = [ 11 | "cfg-if", 12 | "cipher", 13 | "cpufeatures", 14 | ] 15 | 16 | [[package]] 17 | name = "belt-block" 18 | version = "0.2.0-rc.0" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "b9aa0cd4ec3b89021a53caa73cefc5a458cf33b338498e1191916153877bd794" 21 | dependencies = [ 22 | "cipher", 23 | ] 24 | 25 | [[package]] 26 | name = "belt-mac" 27 | version = "0.2.0-pre" 28 | dependencies = [ 29 | "belt-block", 30 | "cipher", 31 | "digest", 32 | "hex-literal", 33 | ] 34 | 35 | [[package]] 36 | name = "blobby" 37 | version = "0.4.0-pre.0" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "4a859067dcb257cb2ae028cb821399b55140b76fb8b2a360e052fe109019db43" 40 | 41 | [[package]] 42 | name = "block-buffer" 43 | version = "0.11.0-rc.4" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "a229bfd78e4827c91b9b95784f69492c1b77c1ab75a45a8a037b139215086f94" 46 | dependencies = [ 47 | "hybrid-array", 48 | "zeroize", 49 | ] 50 | 51 | [[package]] 52 | name = "cbc-mac" 53 | version = "0.2.0-rc.0" 54 | dependencies = [ 55 | "aes", 56 | "cipher", 57 | "des", 58 | "digest", 59 | "hex-literal", 60 | ] 61 | 62 | [[package]] 63 | name = "cfg-if" 64 | version = "1.0.0" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 67 | 68 | [[package]] 69 | name = "cipher" 70 | version = "0.5.0-rc.0" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "bd4ef774202f1749465fc7cf88d70fc30620e8cacd5429268f4bff7d003bd976" 73 | dependencies = [ 74 | "crypto-common", 75 | "inout", 76 | "zeroize", 77 | ] 78 | 79 | [[package]] 80 | name = "cmac" 81 | version = "0.8.0-rc.0" 82 | dependencies = [ 83 | "aes", 84 | "cipher", 85 | "dbl", 86 | "des", 87 | "digest", 88 | "hex-literal", 89 | "kuznyechik", 90 | "magma", 91 | ] 92 | 93 | [[package]] 94 | name = "cpufeatures" 95 | version = "0.2.17" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" 98 | dependencies = [ 99 | "libc", 100 | ] 101 | 102 | [[package]] 103 | name = "crypto-common" 104 | version = "0.2.0-rc.3" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "8a23fa214dea9efd4dacee5a5614646b30216ae0f05d4bb51bafb50e9da1c5be" 107 | dependencies = [ 108 | "hybrid-array", 109 | ] 110 | 111 | [[package]] 112 | name = "dbl" 113 | version = "0.4.0-rc.2" 114 | source = "registry+https://github.com/rust-lang/crates.io-index" 115 | checksum = "cb24c766034b76390c67f3d9c44e63019febeb4cc39e4ba40b5fc79e20c898e1" 116 | dependencies = [ 117 | "hybrid-array", 118 | ] 119 | 120 | [[package]] 121 | name = "des" 122 | version = "0.9.0-rc.0" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "8025983b9f9f242e94d459a57b81c571e92e4e1717ca57d092d8a69fc539efa1" 125 | dependencies = [ 126 | "cipher", 127 | ] 128 | 129 | [[package]] 130 | name = "digest" 131 | version = "0.11.0-rc.0" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "460dd7f37e4950526b54a5a6b1f41b6c8e763c58eb9a8fc8fc05ba5c2f44ca7b" 134 | dependencies = [ 135 | "blobby", 136 | "block-buffer", 137 | "crypto-common", 138 | "subtle", 139 | "zeroize", 140 | ] 141 | 142 | [[package]] 143 | name = "hex-literal" 144 | version = "1.0.0" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | checksum = "bcaaec4551594c969335c98c903c1397853d4198408ea609190f420500f6be71" 147 | 148 | [[package]] 149 | name = "hmac" 150 | version = "0.13.0-rc.0" 151 | dependencies = [ 152 | "digest", 153 | "hex-literal", 154 | "md-5", 155 | "sha1", 156 | "sha2", 157 | "streebog", 158 | ] 159 | 160 | [[package]] 161 | name = "hybrid-array" 162 | version = "0.3.1" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "891d15931895091dea5c47afa5b3c9a01ba634b311919fd4d41388fa0e3d76af" 165 | dependencies = [ 166 | "typenum", 167 | "zeroize", 168 | ] 169 | 170 | [[package]] 171 | name = "inout" 172 | version = "0.2.0-rc.5" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | checksum = "c774c86bce20ea04abe1c37cf0051c5690079a3a28ef5fdac2a5a0412b3d7d74" 175 | dependencies = [ 176 | "hybrid-array", 177 | ] 178 | 179 | [[package]] 180 | name = "kuznyechik" 181 | version = "0.9.0-rc.0" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "074a7089016bcddb3b8da42f663296a885f8a31ec57a7b795a92b711999ff5aa" 184 | dependencies = [ 185 | "cfg-if", 186 | "cipher", 187 | ] 188 | 189 | [[package]] 190 | name = "libc" 191 | version = "0.2.172" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" 194 | 195 | [[package]] 196 | name = "magma" 197 | version = "0.10.0-rc.0" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "9d6704a51253dc03b397da9121342836759922371190e5755ccfb21c4db9cef4" 200 | dependencies = [ 201 | "cipher", 202 | ] 203 | 204 | [[package]] 205 | name = "md-5" 206 | version = "0.11.0-rc.0" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "da1788e007bfe04177a520c827ef99f436b1ea79719d5c5f049279dfe85a7b28" 209 | dependencies = [ 210 | "cfg-if", 211 | "digest", 212 | ] 213 | 214 | [[package]] 215 | name = "pmac" 216 | version = "0.8.0-rc.0" 217 | dependencies = [ 218 | "aes", 219 | "cipher", 220 | "dbl", 221 | "digest", 222 | ] 223 | 224 | [[package]] 225 | name = "retail-mac" 226 | version = "0.1.0-pre.0" 227 | dependencies = [ 228 | "aes", 229 | "cipher", 230 | "des", 231 | "digest", 232 | "hex-literal", 233 | ] 234 | 235 | [[package]] 236 | name = "sha1" 237 | version = "0.11.0-rc.0" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "6f9318facddf9ac32a33527066936837e189b3f23ced6edc1603720ead5e2b3d" 240 | dependencies = [ 241 | "cfg-if", 242 | "cpufeatures", 243 | "digest", 244 | ] 245 | 246 | [[package]] 247 | name = "sha2" 248 | version = "0.11.0-rc.0" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "aa1d2e6b3cc4e43a8258a9a3b17aa5dfd2cc5186c7024bba8a64aa65b2c71a59" 251 | dependencies = [ 252 | "cfg-if", 253 | "cpufeatures", 254 | "digest", 255 | ] 256 | 257 | [[package]] 258 | name = "streebog" 259 | version = "0.11.0-rc.0" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "8fd1781d17a54baf1c29e23aee9d49ad89accf4551c80ed1b7edd1659a2c6dbb" 262 | dependencies = [ 263 | "digest", 264 | ] 265 | 266 | [[package]] 267 | name = "subtle" 268 | version = "2.6.1" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 271 | 272 | [[package]] 273 | name = "typenum" 274 | version = "1.18.0" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" 277 | 278 | [[package]] 279 | name = "zeroize" 280 | version = "1.8.1" 281 | source = "registry+https://github.com/rust-lang/crates.io-index" 282 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 283 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "3" 3 | members = [ 4 | "belt-mac", 5 | "cbc-mac", 6 | "cmac", 7 | "hmac", 8 | "pmac", 9 | "retail-mac", 10 | ] 11 | 12 | [profile.dev] 13 | opt-level = 2 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RustCrypto: Message Authentication Codes 2 | 3 | [![Project Chat][chat-image]][chat-link] 4 | [![dependency status][deps-image]][deps-link] 5 | ![Apache2/MIT licensed][license-image] 6 | 7 | Collection of [Message Authentication Code][1] (MAC) algorithms written in pure Rust. 8 | 9 | ## Supported Algorithms 10 | 11 | | Algorithm | Crate | Crates.io | Documentation | MSRV | 12 | |--------------|----------------|:---------:|:-------------:|:----:| 13 | | [BelT MAC] | [`belt-mac`] | [![crates.io](https://img.shields.io/crates/v/belt-mac.svg)](https://crates.io/crates/belt-mac) | [![Documentation](https://docs.rs/belt-mac/badge.svg)](https://docs.rs/belt-mac) | ![MSRV 1.85][msrv-1.85] | 14 | | [CBC-MAC] | [`cbc-mac`] | [![crates.io](https://img.shields.io/crates/v/cbc-mac.svg)](https://crates.io/crates/cbc-mac) | [![Documentation](https://docs.rs/cbc-mac/badge.svg)](https://docs.rs/cbc-mac) | ![MSRV 1.85][msrv-1.85] | 15 | | [CMAC] | [`cmac`] | [![crates.io](https://img.shields.io/crates/v/cmac.svg)](https://crates.io/crates/cmac) | [![Documentation](https://docs.rs/cmac/badge.svg)](https://docs.rs/cmac) | ![MSRV 1.85][msrv-1.85] | 16 | | [HMAC] | [`hmac`] | [![crates.io](https://img.shields.io/crates/v/hmac.svg)](https://crates.io/crates/hmac) | [![Documentation](https://docs.rs/hmac/badge.svg)](https://docs.rs/hmac) | ![MSRV 1.85][msrv-1.85] | 17 | | [PMAC] | [`pmac`] | [![crates.io](https://img.shields.io/crates/v/pmac.svg)](https://crates.io/crates/pmac) | [![Documentation](https://docs.rs/pmac/badge.svg)](https://docs.rs/pmac) | ![MSRV 1.85][msrv-1.85] | 18 | | [Retail MAC] | [`retail-mac`] | [![crates.io](https://img.shields.io/crates/v/retail-mac.svg)](https://crates.io/crates/retail-mac) | [![Documentation](https://docs.rs/retail-mac/badge.svg)](https://docs.rs/retail-mac) | ![MSRV 1.85][msrv-1.85] | 19 | 20 | ## License 21 | 22 | All crates licensed under either of 23 | 24 | * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) 25 | * [MIT license](http://opensource.org/licenses/MIT) 26 | 27 | at your option. 28 | 29 | ### Contribution 30 | 31 | Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. 32 | 33 | [//]: # (badges) 34 | 35 | [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg 36 | [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs 37 | [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg 38 | [deps-image]: https://deps.rs/repo/github/RustCrypto/MACs/status.svg 39 | [deps-link]: https://deps.rs/repo/github/RustCrypto/MACs 40 | [msrv-1.85]: https://img.shields.io/badge/rustc-1.85+-blue.svg 41 | 42 | [//]: # (crates) 43 | 44 | [`belt-mac`]: ./belt-mac 45 | [`cbc-mac`]: ./cbc-mac 46 | [`cmac`]: ./cmac 47 | [`hmac`]: ./hmac 48 | [`pmac`]: ./pmac 49 | [`retail-mac`]: ./retail-mac 50 | 51 | [//]: # (footnotes) 52 | 53 | [1]: https://en.wikipedia.org/wiki/Message_authentication_code 54 | 55 | [//]: # (algorithms) 56 | 57 | [BelT MAC]: https://apmi.bsu.by/assets/files/std/belt-spec371.pdf 58 | [CBC-MAC]: https://en.wikipedia.org/wiki/CBC-MAC 59 | [CMAC]: https://en.wikipedia.org/wiki/One-key_MAC 60 | [HMAC]: https://en.wikipedia.org/wiki/HMAC 61 | [PMAC]: https://en.wikipedia.org/wiki/PMAC_(cryptography) 62 | [Retail MAC]: https://en.wikipedia.org/wiki/ISO/IEC_9797-1#MAC_algorithm_3 63 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Security updates are applied only to the most recent release. 6 | 7 | ## Reporting a Vulnerability 8 | 9 | If you have discovered a security vulnerability in this project, please report 10 | it privately. **Do not disclose it as a public issue.** This gives us time to 11 | work with you to fix the issue before public exposure, reducing the chance that 12 | the exploit will be used before a patch is released. 13 | 14 | Please disclose it at [security advisory](https://github.com/RustCrypto/MACs/security/advisories/new). 15 | 16 | This project is maintained by a team of volunteers on a reasonable-effort basis. 17 | As such, please give us at least 90 days to work on a fix before public exposure. 18 | -------------------------------------------------------------------------------- /belt-mac/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 | ### Changed 10 | - Edition changed to 2024 and MSRV bumped to 1.85 11 | - Relax MSRV policy and allow MSRV bumps in patch releases 12 | - Update to `digest` v0.11 13 | - Update to `cipher` v0.5 14 | - Replace type aliases with newtypes ([#186]) 15 | 16 | ### Removed 17 | - `std` crate feature ([#186]) 18 | 19 | [#186]: https://github.com/RustCrypto/MACs/pull/186 20 | 21 | ## 0.1.0 (2023-04-03) 22 | Initial Release -------------------------------------------------------------------------------- /belt-mac/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belt-mac" 3 | version = "0.2.0-pre" 4 | description = "MAC 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-mac" 11 | repository = "https://github.com/RustCrypto/MACs" 12 | keywords = ["crypto", "mac", "belt-mac"] 13 | categories = ["cryptography", "no-std"] 14 | 15 | [dependencies] 16 | belt-block = "0.2.0-pre.3" 17 | cipher = "0.5.0-rc.0" 18 | digest = { version = "0.11.0-rc.0", features = ["mac"] } 19 | 20 | [dev-dependencies] 21 | digest = { version = "0.11.0-rc.0", features = ["dev"] } 22 | hex-literal = "1" 23 | 24 | [features] 25 | zeroize = ["cipher/zeroize", "digest/zeroize"] 26 | 27 | [package.metadata.docs.rs] 28 | all-features = true 29 | -------------------------------------------------------------------------------- /belt-mac/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /belt-mac/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-mac/README.md: -------------------------------------------------------------------------------- 1 | # RustCrypto: belt-mac 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 | Pure Rust implementation of [`belt-mac`][1]. 11 | 12 | # Example 13 | ```rust 14 | use belt_mac::{digest::KeyInit, BeltMac, Mac}; 15 | use hex_literal::hex; 16 | 17 | let key = [0x42; 32]; 18 | let msg = b"input message"; 19 | let expected_tag = hex!("9f5c9623b4eff8802195e81bcd841959"); 20 | 21 | // To get the authentication code: 22 | let mut mac: BeltMac = BeltMac::new_from_slice(&key).unwrap(); 23 | mac.update(msg); 24 | let tag = mac.finalize(); 25 | let tag_bytes = tag.into_bytes(); 26 | assert_eq!(&tag_bytes[..], &expected_tag[..]); 27 | 28 | // To verify the message: 29 | let mut mac: BeltMac = BeltMac::new_from_slice(&key).unwrap(); 30 | mac.update(b"input message"); 31 | mac.verify(&tag_bytes).unwrap(); 32 | ``` 33 | 34 | ## License 35 | 36 | Licensed under either of: 37 | 38 | * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) 39 | * [MIT license](http://opensource.org/licenses/MIT) 40 | 41 | at your option. 42 | 43 | ### Contribution 44 | 45 | Unless you explicitly state otherwise, any contribution intentionally submitted 46 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 47 | dual licensed as above, without any additional terms or conditions. 48 | 49 | [//]: # (badges) 50 | 51 | [crate-image]: https://img.shields.io/crates/v/belt-mac.svg?logo=rust 52 | [crate-link]: https://crates.io/crates/belt-mac 53 | [docs-image]: https://docs.rs/belt-mac/badge.svg 54 | [docs-link]: https://docs.rs/belt-mac/ 55 | [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg 56 | [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg 57 | [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg 58 | [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs 59 | [build-image]: https://github.com/RustCrypto/MACs/actions/workflows/belt-mac.yml/badge.svg 60 | [build-link]: https://github.com/RustCrypto/MACs/actions/workflows/belt-mac.yml 61 | 62 | [//]: # (general links) 63 | 64 | [1]: https://apmi.bsu.by/assets/files/std/belt-spec371.pdf 65 | -------------------------------------------------------------------------------- /belt-mac/benches/mod.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | extern crate test; 3 | 4 | use belt_mac::{BeltMac, KeyInit}; 5 | use test::Bencher; 6 | 7 | digest::bench_update!( 8 | BeltMac::new(&Default::default()); 9 | belt_mac_10 10; 10 | belt_mac_100 100; 11 | belt_mac_1000 1000; 12 | belt_mac_10000 10000; 13 | ); 14 | -------------------------------------------------------------------------------- /belt-mac/src/block_api.rs: -------------------------------------------------------------------------------- 1 | use belt_block::BeltBlock; 2 | use cipher::{BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt}; 3 | use core::fmt; 4 | use digest::{ 5 | MacMarker, Output, OutputSizeUser, Reset, 6 | array::{Array, ArraySize}, 7 | block_api::{ 8 | AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, FixedOutputCore, Lazy, 9 | UpdateCore, 10 | }, 11 | crypto_common::{BlockSizes, InnerInit, InnerUser}, 12 | }; 13 | 14 | #[cfg(feature = "zeroize")] 15 | use digest::zeroize::{Zeroize, ZeroizeOnDrop}; 16 | 17 | /// Generic core BeltMac instance, which operates over blocks. 18 | #[derive(Clone)] 19 | pub struct BeltMacCore 20 | where 21 | C: BlockCipherEncrypt + Clone, 22 | { 23 | cipher: C, 24 | state: Block, 25 | r: Block, 26 | } 27 | 28 | impl BlockSizeUser for BeltMacCore 29 | where 30 | C: BlockCipherEncrypt + Clone, 31 | { 32 | type BlockSize = C::BlockSize; 33 | } 34 | 35 | impl OutputSizeUser for BeltMacCore 36 | where 37 | C: BlockCipherEncrypt + Clone, 38 | { 39 | type OutputSize = C::BlockSize; 40 | } 41 | 42 | impl InnerUser for BeltMacCore 43 | where 44 | C: BlockCipherEncrypt + Clone, 45 | { 46 | type Inner = C; 47 | } 48 | 49 | impl MacMarker for BeltMacCore where C: BlockCipherEncrypt + Clone {} 50 | 51 | impl InnerInit for BeltMacCore 52 | where 53 | C: BlockCipherEncrypt + Clone, 54 | { 55 | #[inline] 56 | fn inner_init(cipher: C) -> Self { 57 | let state = Default::default(); 58 | let mut r = Default::default(); 59 | cipher.encrypt_block(&mut r); 60 | Self { cipher, state, r } 61 | } 62 | } 63 | 64 | impl BufferKindUser for BeltMacCore 65 | where 66 | C: BlockCipherEncrypt + Clone, 67 | { 68 | type BufferKind = Lazy; 69 | } 70 | 71 | impl UpdateCore for BeltMacCore 72 | where 73 | C: BlockCipherEncrypt + Clone, 74 | { 75 | #[inline] 76 | fn update_blocks(&mut self, blocks: &[Block]) { 77 | struct Closure<'a, N: BlockSizes> { 78 | state: &'a mut Block, 79 | blocks: &'a [Block], 80 | } 81 | 82 | impl BlockSizeUser for Closure<'_, N> { 83 | type BlockSize = N; 84 | } 85 | 86 | impl BlockCipherEncClosure for Closure<'_, N> { 87 | #[inline(always)] 88 | fn call>(self, backend: &B) { 89 | for block in self.blocks { 90 | xor(self.state, block); 91 | backend.encrypt_block((self.state).into()); 92 | } 93 | } 94 | } 95 | 96 | let Self { cipher, state, .. } = self; 97 | cipher.encrypt_with_backend(Closure { state, blocks }) 98 | } 99 | } 100 | 101 | impl Reset for BeltMacCore 102 | where 103 | C: BlockCipherEncrypt + Clone, 104 | { 105 | #[inline(always)] 106 | fn reset(&mut self) { 107 | self.state = Default::default(); 108 | } 109 | } 110 | 111 | impl FixedOutputCore for BeltMacCore 112 | where 113 | C: BlockCipherEncrypt + Clone, 114 | { 115 | #[inline] 116 | fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { 117 | let pos = buffer.get_pos(); 118 | let mut buf = buffer.pad_with_zeros(); 119 | 120 | let cipher = &mut self.cipher; 121 | let r = &self.r; 122 | let bs = r.len(); 123 | let mut new_r = Block::::default(); 124 | if pos == bs { 125 | // phi1 126 | let (h1, h2) = new_r.split_at_mut(bs - 4); 127 | h1.copy_from_slice(&r[4..]); 128 | for i in 0..4 { 129 | h2[i] = r[i] ^ r[4 + i]; 130 | } 131 | } else { 132 | buf[pos] = 0x80; 133 | // phi2 134 | let (h1, h2) = new_r.split_at_mut(4); 135 | for i in 0..4 { 136 | h1[i] = r[i] ^ r[bs - 4 + i]; 137 | } 138 | h2.copy_from_slice(&r[..bs - 4]); 139 | } 140 | 141 | let mut state = self.state.clone(); 142 | xor(&mut state, &buf); 143 | xor(&mut state, &new_r); 144 | cipher.encrypt_block_b2b(&state, out); 145 | } 146 | } 147 | 148 | impl AlgorithmName for BeltMacCore 149 | where 150 | C: BlockCipherEncrypt + Clone, 151 | { 152 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { 153 | f.write_str("BeltMac") 154 | } 155 | } 156 | 157 | impl fmt::Debug for BeltMacCore 158 | where 159 | C: BlockCipherEncrypt + Clone, 160 | { 161 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 162 | f.write_str("BeltMacCore { ... }") 163 | } 164 | } 165 | 166 | #[cfg(feature = "zeroize")] 167 | impl Drop for BeltMacCore 168 | where 169 | C: BlockCipherEncrypt + Clone, 170 | { 171 | fn drop(&mut self) { 172 | self.state.zeroize(); 173 | } 174 | } 175 | 176 | #[cfg(feature = "zeroize")] 177 | impl ZeroizeOnDrop for BeltMacCore where C: BlockCipherEncrypt + Clone + ZeroizeOnDrop {} 178 | 179 | #[inline(always)] 180 | fn xor(buf: &mut Array, data: &Array) { 181 | for i in 0..N::USIZE { 182 | buf[i] ^= data[i]; 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /belt-mac/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![doc = include_str!("../README.md")] 3 | #![doc( 4 | html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg", 5 | html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg" 6 | )] 7 | #![cfg_attr(docsrs, feature(doc_auto_cfg))] 8 | #![forbid(unsafe_code)] 9 | #![warn(missing_docs)] 10 | 11 | pub use digest::{self, KeyInit, Mac}; 12 | 13 | /// Block-level implementation. 14 | pub mod block_api; 15 | 16 | use cipher::BlockCipherEncrypt; 17 | 18 | digest::buffer_fixed!( 19 | /// BeltMac instance generic over block cipher. 20 | pub struct GenericBeltMac(block_api::BeltMacCore); 21 | impl: ResetMacTraits AlgorithmName InnerInit; 22 | ); 23 | 24 | /// BeltMac instance. 25 | pub type BeltMac = GenericBeltMac; 26 | -------------------------------------------------------------------------------- /belt-mac/tests/data/belt-mac.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/belt-mac/tests/data/belt-mac.blb -------------------------------------------------------------------------------- /belt-mac/tests/mod.rs: -------------------------------------------------------------------------------- 1 | use belt_mac::BeltMac; 2 | use digest::new_resettable_mac_test; 3 | 4 | new_resettable_mac_test!(belt_mac_stb, "belt-mac", BeltMac, "left"); 5 | -------------------------------------------------------------------------------- /cbc-mac/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 | ### Changed 10 | - Edition changed to 2024 and MSRV bumped to 1.85 11 | - Relax MSRV policy and allow MSRV bumps in patch releases 12 | - Update to `digest` v0.11 13 | - Update to `cipher` v0.5 14 | - Replace type aliases with newtypes ([#186]) 15 | 16 | ### Removed 17 | - `std` crate feature ([#186]) 18 | 19 | [#186]: https://github.com/RustCrypto/MACs/pull/186 20 | 21 | ## 0.1.1 (2022-02-17) 22 | ### Fixed 23 | - Minimal versions build ([#108]) 24 | 25 | [#108]: https://github.com/RustCrypto/MACs/pull/108 26 | 27 | ## 0.1.0 (2022-02-10) 28 | - Initial release ([#103]) 29 | 30 | [#103]: https://github.com/RustCrypto/MACs/pull/103 31 | -------------------------------------------------------------------------------- /cbc-mac/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cbc-mac" 3 | version = "0.2.0-rc.0" 4 | description = "Implementation of Cipher Block Chaining Message Authentication Code (CBC-MAC)" 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-mac" 11 | repository = "https://github.com/RustCrypto/MACs" 12 | keywords = ["crypto", "mac", "daa"] 13 | 14 | [dependencies] 15 | cipher = "0.5.0-rc.0" 16 | digest = { version = "0.11.0-rc.0", features = ["mac"] } 17 | 18 | [dev-dependencies] 19 | digest = { version = "0.11.0-rc.0", features = ["dev"] } 20 | hex-literal = "1" 21 | 22 | aes = "0.9.0-rc.0" 23 | des = "0.9.0-rc.0" 24 | 25 | [features] 26 | zeroize = ["cipher/zeroize", "digest/zeroize"] 27 | 28 | [package.metadata.docs.rs] 29 | all-features = true 30 | -------------------------------------------------------------------------------- /cbc-mac/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /cbc-mac/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Artyom Pavlov 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 | -------------------------------------------------------------------------------- /cbc-mac/README.md: -------------------------------------------------------------------------------- 1 | # RustCrypto: CBC-MAC 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 [Cipher Block Chaining Message Authentication Code (CBC-MAC)][CBC-MAC]. 11 | 12 | **WARNING!** The algorithm has known weaknesses in case of variable-length 13 | messages. See the linked Wikipedia article for more information. 14 | 15 | ## Examples 16 | 17 | ```rust 18 | use cbc_mac::{digest::KeyInit, CbcMac, Mac}; 19 | use des::Des; 20 | use hex_literal::hex; 21 | 22 | // CBC-MAC with the DES block cipher is equivalent to DAA 23 | type Daa = CbcMac; 24 | 25 | // test from FIPS 113 26 | let key = hex!("0123456789ABCDEF"); 27 | let mut mac = Daa::new_from_slice(&key).unwrap(); 28 | mac.update(b"7654321 Now is the time for "); 29 | let correct = hex!("F1D30F6849312CA4"); 30 | mac.verify_slice(&correct).unwrap(); 31 | ``` 32 | 33 | ## License 34 | 35 | Licensed under either of: 36 | 37 | * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) 38 | * [MIT license](http://opensource.org/licenses/MIT) 39 | 40 | at your option. 41 | 42 | ### Contribution 43 | 44 | Unless you explicitly state otherwise, any contribution intentionally submitted 45 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 46 | dual licensed as above, without any additional terms or conditions. 47 | 48 | [//]: # (badges) 49 | 50 | [crate-image]: https://img.shields.io/crates/v/cbc-mac.svg?logo=rust 51 | [crate-link]: https://crates.io/crates/cbc-mac 52 | [docs-image]: https://docs.rs/cbc-mac/badge.svg 53 | [docs-link]: https://docs.rs/cbc-mac/ 54 | [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg 55 | [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg 56 | [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg 57 | [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs 58 | [build-image]: https://github.com/RustCrypto/MACs/actions/workflows/cbc-mac.yml/badge.svg 59 | [build-link]: https://github.com/RustCrypto/MACs/actions/workflows/cbc-mac.yml 60 | 61 | [//]: # (general links) 62 | 63 | [CBC-MAC]: https://en.wikipedia.org/wiki/CBC-MAC 64 | -------------------------------------------------------------------------------- /cbc-mac/benches/mod.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | extern crate test; 3 | 4 | use aes::Aes128; 5 | use cbc_mac::{CbcMac, KeyInit}; 6 | use des::Des; 7 | use test::Bencher; 8 | 9 | digest::bench_update!( 10 | CbcMac::::new(&Default::default()); 11 | cbc_mac_aes128_10 10; 12 | cbc_mac_aes128_100 100; 13 | cbc_mac_aes128_1000 1000; 14 | cbc_mac_aes128_10000 10000; 15 | ); 16 | 17 | digest::bench_update!( 18 | CbcMac::::new(&Default::default()); 19 | daa_10 10; 20 | daa_100 100; 21 | daa_1000 1000; 22 | daa_10000 10000; 23 | ); 24 | -------------------------------------------------------------------------------- /cbc-mac/src/block_api.rs: -------------------------------------------------------------------------------- 1 | use cipher::{BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt}; 2 | use core::fmt; 3 | use digest::{ 4 | MacMarker, Output, OutputSizeUser, Reset, 5 | array::{Array, ArraySize}, 6 | block_api::{ 7 | AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, Eager, FixedOutputCore, 8 | UpdateCore, 9 | }, 10 | crypto_common::{BlockSizes, InnerInit, InnerUser}, 11 | }; 12 | 13 | #[cfg(feature = "zeroize")] 14 | use digest::zeroize::{Zeroize, ZeroizeOnDrop}; 15 | 16 | /// Generic core CMAC instance, which operates over blocks. 17 | #[derive(Clone)] 18 | pub struct CbcMacCore 19 | where 20 | C: BlockCipherEncrypt + Clone, 21 | { 22 | cipher: C, 23 | state: Block, 24 | } 25 | 26 | impl BlockSizeUser for CbcMacCore 27 | where 28 | C: BlockCipherEncrypt + Clone, 29 | { 30 | type BlockSize = C::BlockSize; 31 | } 32 | 33 | impl OutputSizeUser for CbcMacCore 34 | where 35 | C: BlockCipherEncrypt + Clone, 36 | { 37 | type OutputSize = C::BlockSize; 38 | } 39 | 40 | impl InnerUser for CbcMacCore 41 | where 42 | C: BlockCipherEncrypt + Clone, 43 | { 44 | type Inner = C; 45 | } 46 | 47 | impl MacMarker for CbcMacCore where C: BlockCipherEncrypt + Clone {} 48 | 49 | impl InnerInit for CbcMacCore 50 | where 51 | C: BlockCipherEncrypt + Clone, 52 | { 53 | #[inline] 54 | fn inner_init(cipher: C) -> Self { 55 | let state = Default::default(); 56 | Self { cipher, state } 57 | } 58 | } 59 | 60 | impl BufferKindUser for CbcMacCore 61 | where 62 | C: BlockCipherEncrypt + Clone, 63 | { 64 | type BufferKind = Eager; 65 | } 66 | 67 | impl UpdateCore for CbcMacCore 68 | where 69 | C: BlockCipherEncrypt + Clone, 70 | { 71 | #[inline] 72 | fn update_blocks(&mut self, blocks: &[Block]) { 73 | struct Closure<'a, N: BlockSizes> { 74 | state: &'a mut Block, 75 | blocks: &'a [Block], 76 | } 77 | 78 | impl BlockSizeUser for Closure<'_, N> { 79 | type BlockSize = N; 80 | } 81 | 82 | impl BlockCipherEncClosure for Closure<'_, N> { 83 | #[inline(always)] 84 | fn call>(self, backend: &B) { 85 | for block in self.blocks { 86 | xor(self.state, block); 87 | backend.encrypt_block((self.state).into()); 88 | } 89 | } 90 | } 91 | 92 | let Self { cipher, state } = self; 93 | cipher.encrypt_with_backend(Closure { state, blocks }) 94 | } 95 | } 96 | 97 | impl Reset for CbcMacCore 98 | where 99 | C: BlockCipherEncrypt + Clone, 100 | { 101 | #[inline(always)] 102 | fn reset(&mut self) { 103 | self.state = Default::default(); 104 | } 105 | } 106 | 107 | impl FixedOutputCore for CbcMacCore 108 | where 109 | C: BlockCipherEncrypt + Clone, 110 | { 111 | #[inline] 112 | fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { 113 | let Self { state, cipher } = self; 114 | let pos = buffer.get_pos(); 115 | if pos != 0 { 116 | xor(state, &buffer.pad_with_zeros()); 117 | cipher.encrypt_block(state); 118 | } 119 | out.copy_from_slice(state); 120 | } 121 | } 122 | 123 | impl AlgorithmName for CbcMacCore 124 | where 125 | C: BlockCipherEncrypt + Clone + AlgorithmName, 126 | { 127 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { 128 | f.write_str("CbcMac<")?; 129 | ::write_alg_name(f)?; 130 | f.write_str(">") 131 | } 132 | } 133 | 134 | impl fmt::Debug for CbcMacCore 135 | where 136 | C: BlockCipherEncrypt + Clone + AlgorithmName, 137 | { 138 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 139 | f.write_str("CbcMacCore<")?; 140 | ::write_alg_name(f)?; 141 | f.write_str("> { ... }") 142 | } 143 | } 144 | 145 | #[cfg(feature = "zeroize")] 146 | impl Drop for CbcMacCore 147 | where 148 | C: BlockCipherEncrypt + Clone, 149 | { 150 | fn drop(&mut self) { 151 | self.state.zeroize(); 152 | } 153 | } 154 | 155 | #[cfg(feature = "zeroize")] 156 | impl ZeroizeOnDrop for CbcMacCore where C: BlockCipherEncrypt + Clone + ZeroizeOnDrop {} 157 | 158 | #[inline(always)] 159 | fn xor(buf: &mut Array, data: &Array) { 160 | for i in 0..N::USIZE { 161 | buf[i] ^= data[i]; 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /cbc-mac/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![doc = include_str!("../README.md")] 3 | #![doc( 4 | html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg", 5 | html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg" 6 | )] 7 | #![cfg_attr(docsrs, feature(doc_auto_cfg))] 8 | #![forbid(unsafe_code)] 9 | #![warn(missing_docs)] 10 | 11 | pub use digest::{self, KeyInit, Mac}; 12 | 13 | mod block_api; 14 | 15 | use cipher::{AlgorithmName, BlockCipherEncrypt}; 16 | use core::fmt; 17 | use digest::block_api::CoreProxy; 18 | 19 | digest::buffer_fixed!( 20 | /// Generic CBC-MAC instance. 21 | pub struct CbcMac(block_api::CbcMacCore); 22 | impl: ResetMacTraits InnerInit; 23 | ); 24 | 25 | impl AlgorithmName for CbcMac 26 | where 27 | C: BlockCipherEncrypt + Clone + AlgorithmName, 28 | { 29 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { 30 | ::Core::write_alg_name(f) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /cmac/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.8.0 (UNRELEASED) 9 | ### Changed 10 | - Edition changed to 2024 and MSRV bumped to 1.85 11 | - Relax MSRV policy and allow MSRV bumps in patch releases 12 | - Update to `digest` v0.11 13 | - Update to `cipher` v0.5 14 | - Replace type aliases with newtypes ([#186]) 15 | 16 | ### Removed 17 | - `std` crate feature ([#186]) 18 | 19 | [#186]: https://github.com/RustCrypto/MACs/pull/186 20 | 21 | ## 0.7.2 (2022-03-14) 22 | ### Changed 23 | - Do not include large CAVP test vectors in published packages ([#128]) 24 | 25 | [#128]: https://github.com/RustCrypto/MACs/pull/128 26 | 27 | ## 0.7.1 (2022-02-17) 28 | ### Fixed 29 | - Minimal versions build ([#108]) 30 | 31 | [#108]: https://github.com/RustCrypto/MACs/pull/108 32 | 33 | ## 0.7.0 (2022-02-10) 34 | ### Changed 35 | - Migrate from `crypto-mac` dependency to `digest v0.10` ([#103]) 36 | - Bump `cipher` dependency to v0.4 ([#103]) 37 | 38 | [#103]: https://github.com/RustCrypto/MACs/pull/103 39 | 40 | ## 0.6.0 (2021-04-29) 41 | ### Changed 42 | - Bump `crypto-mac` crate dependency to v0.11 ([#73]) 43 | 44 | [#73]: https://github.com/RustCrypto/MACs/pull/73 45 | 46 | ## 0.5.1 (2020-10-16) 47 | ### Added 48 | - Zulip badge ([#64]) 49 | 50 | [#64]: https://github.com/RustCrypto/MACs/pull/64 51 | 52 | ## 0.5.0 (2020-10-16) 53 | ### Changed 54 | - Bump `crypto-mac` dependency to v0.10 ([#62]) 55 | 56 | [#62]: https://github.com/RustCrypto/MACs/pull/62 57 | 58 | ## 0.4.0 (2020-08-12) 59 | ### Changed 60 | - Bump `crypto-mac` dependency to v0.9, implement the `FromBlockCipher` trait ([#57]) 61 | 62 | [#57]: https://github.com/RustCrypto/MACs/pull/57 63 | 64 | ## 0.3.1 (2020-08-12) 65 | ### Added 66 | - Implement `From` ([#54]) 67 | - Implement `io::Write` ([#55]) 68 | 69 | [#54]: https://github.com/RustCrypto/MACs/pull/54 70 | [#55]: https://github.com/RustCrypto/MACs/pull/55 71 | 72 | ## 0.3.0 (2020-06-06) 73 | ### Changed 74 | - Bump `aes` crate dependency to v0.4 ([#40]) 75 | - Bump `dbl` crate dependency to v0.3 ([#39]) 76 | - Bump `crypto-mac` dependency to v0.8; MSRV 1.41+ ([#30]) 77 | - Rename `result` methods to `finalize` ([#38]) 78 | - Upgrade to Rust 2018 edition ([#30]) 79 | 80 | [#40]: https://github.com/RustCrypto/MACs/pull/40 81 | [#39]: https://github.com/RustCrypto/MACs/pull/39 82 | [#38]: https://github.com/RustCrypto/MACs/pull/38 83 | [#30]: https://github.com/RustCrypto/MACs/pull/30 84 | 85 | ## 0.2.0 (2018-10-03) 86 | 87 | ## 0.1.0 (2017-11-26) 88 | -------------------------------------------------------------------------------- /cmac/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cmac" 3 | version = "0.8.0-rc.0" 4 | description = "Generic implementation of Cipher-based Message Authentication Code" 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/cmac" 11 | repository = "https://github.com/RustCrypto/MACs" 12 | keywords = ["crypto", "mac", "cmac", "omac"] 13 | categories = ["cryptography", "no-std"] 14 | exclude = ["tests/cavp_large.rs", "tests/data/cavp_aes128_large.blb"] 15 | 16 | [dependencies] 17 | cipher = "0.5.0-rc.0" 18 | digest = { version = "0.11.0-rc.0", features = ["mac"] } 19 | dbl = "0.4.0-rc.0" 20 | 21 | [dev-dependencies] 22 | digest = { version = "0.11.0-rc.0", features = ["dev"] } 23 | hex-literal = "1" 24 | 25 | aes = "0.9.0-rc.0" 26 | des = "0.9.0-rc.0" 27 | kuznyechik = "0.9.0-rc.0" 28 | magma = "0.10.0-rc.0" 29 | 30 | [features] 31 | zeroize = ["cipher/zeroize", "digest/zeroize"] 32 | 33 | [package.metadata.docs.rs] 34 | all-features = true 35 | -------------------------------------------------------------------------------- /cmac/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /cmac/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Artyom Pavlov 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 | -------------------------------------------------------------------------------- /cmac/README.md: -------------------------------------------------------------------------------- 1 | # RustCrypto: CMAC 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 [Cipher-based Message Authentication Code (CMAC)][1], 11 | otherwise known as OMAC1. 12 | 13 | ## Examples 14 | We will use AES-128 block cipher from the [`aes`] crate. 15 | 16 | To get the authentication code: 17 | 18 | ```rust 19 | use aes::Aes128; 20 | use cmac::{digest::KeyInit, Cmac, Mac}; 21 | 22 | // Create `Mac` trait implementation, namely CMAC-AES128 23 | let mut mac = Cmac::::new_from_slice(b"very secret key.").unwrap(); 24 | mac.update(b"input message"); 25 | 26 | // `result` has type `Output` which is a thin wrapper around array of 27 | // bytes for providing constant time equality check 28 | let result = mac.finalize(); 29 | // To get underlying array use the `into_bytes` method, but be careful, 30 | // since incorrect use of the tag value may permit timing attacks which 31 | // defeat the security provided by the `Output` wrapper 32 | let tag_bytes = result.into_bytes(); 33 | ``` 34 | 35 | To verify the message: 36 | 37 | ```rust 38 | use aes::Aes128; 39 | use cmac::{digest::KeyInit, Cmac, Mac}; 40 | 41 | let mut mac = Cmac::::new_from_slice(b"very secret key.").unwrap(); 42 | 43 | mac.update(b"input message"); 44 | 45 | # let tag_bytes = mac.clone().finalize().into_bytes(); 46 | // `verify` will return `Ok(())` if tag is correct, `Err(MacError)` otherwise 47 | mac.verify(&tag_bytes).unwrap(); 48 | ``` 49 | 50 | ## License 51 | 52 | Licensed under either of: 53 | 54 | * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) 55 | * [MIT license](http://opensource.org/licenses/MIT) 56 | 57 | at your option. 58 | 59 | ### Contribution 60 | 61 | Unless you explicitly state otherwise, any contribution intentionally submitted 62 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 63 | dual licensed as above, without any additional terms or conditions. 64 | 65 | [//]: # (badges) 66 | 67 | [crate-image]: https://img.shields.io/crates/v/cmac.svg?logo=rust 68 | [crate-link]: https://crates.io/crates/cmac 69 | [docs-image]: https://docs.rs/cmac/badge.svg 70 | [docs-link]: https://docs.rs/cmac/ 71 | [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg 72 | [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg 73 | [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg 74 | [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs 75 | [build-image]: https://github.com/RustCrypto/MACs/actions/workflows/cmac.yml/badge.svg 76 | [build-link]: https://github.com/RustCrypto/MACs/actions/workflows/cmac.yml 77 | 78 | [//]: # (general links) 79 | 80 | [1]: https://en.wikipedia.org/wiki/One-key_MAC 81 | [`aes`]: https://docs.rs/aes 82 | -------------------------------------------------------------------------------- /cmac/benches/mod.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | extern crate test; 3 | 4 | use aes::{Aes128, Aes256}; 5 | use cmac::{Cmac, KeyInit}; 6 | use kuznyechik::Kuznyechik; 7 | use test::Bencher; 8 | 9 | digest::bench_update!( 10 | Cmac::::new(&Default::default()); 11 | cmac_aes128_10 10; 12 | cmac_aes128_100 100; 13 | cmac_aes128_1000 1000; 14 | cmac_aes128_10000 10000; 15 | ); 16 | 17 | digest::bench_update!( 18 | Cmac::::new(&Default::default()); 19 | cmac_aes256_10 10; 20 | cmac_aes256_100 100; 21 | cmac_aes256_1000 1000; 22 | cmac_aes256_10000 10000; 23 | ); 24 | 25 | digest::bench_update!( 26 | Cmac::::new(&Default::default()); 27 | cmac_kuznyechik_10 10; 28 | cmac_kuznyechik_100 100; 29 | cmac_kuznyechik_1000 1000; 30 | cmac_kuznyechik_10000 10000; 31 | ); 32 | -------------------------------------------------------------------------------- /cmac/src/block_api.rs: -------------------------------------------------------------------------------- 1 | use cipher::{BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt}; 2 | use core::fmt; 3 | use dbl::Dbl; 4 | use digest::{ 5 | MacMarker, Output, OutputSizeUser, Reset, 6 | array::{Array, ArraySize}, 7 | block_api::{ 8 | AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, FixedOutputCore, Lazy, 9 | UpdateCore, 10 | }, 11 | crypto_common::{BlockSizes, InnerInit, InnerUser}, 12 | }; 13 | 14 | #[cfg(feature = "zeroize")] 15 | use digest::zeroize::{Zeroize, ZeroizeOnDrop}; 16 | 17 | /// Generic core CMAC instance, which operates over blocks. 18 | #[derive(Clone)] 19 | pub struct CmacCore { 20 | cipher: C, 21 | state: Block, 22 | } 23 | 24 | impl BlockSizeUser for CmacCore { 25 | type BlockSize = C::BlockSize; 26 | } 27 | 28 | impl OutputSizeUser for CmacCore { 29 | type OutputSize = C::BlockSize; 30 | } 31 | 32 | impl InnerUser for CmacCore { 33 | type Inner = C; 34 | } 35 | 36 | impl MacMarker for CmacCore {} 37 | 38 | impl InnerInit for CmacCore { 39 | #[inline] 40 | fn inner_init(cipher: C) -> Self { 41 | let state = Default::default(); 42 | Self { cipher, state } 43 | } 44 | } 45 | 46 | impl BufferKindUser for CmacCore { 47 | type BufferKind = Lazy; 48 | } 49 | 50 | impl UpdateCore for CmacCore { 51 | #[inline] 52 | fn update_blocks(&mut self, blocks: &[Block]) { 53 | struct Closure<'a, N: BlockSizes> { 54 | state: &'a mut Block, 55 | blocks: &'a [Block], 56 | } 57 | 58 | impl BlockSizeUser for Closure<'_, N> { 59 | type BlockSize = N; 60 | } 61 | 62 | impl BlockCipherEncClosure for Closure<'_, N> { 63 | #[inline(always)] 64 | fn call>(self, backend: &B) { 65 | for block in self.blocks { 66 | xor(self.state, block); 67 | backend.encrypt_block((self.state).into()); 68 | } 69 | } 70 | } 71 | 72 | let Self { cipher, state } = self; 73 | cipher.encrypt_with_backend(Closure { state, blocks }) 74 | } 75 | } 76 | 77 | impl Reset for CmacCore { 78 | #[inline(always)] 79 | fn reset(&mut self) { 80 | self.state = Default::default(); 81 | } 82 | } 83 | 84 | impl FixedOutputCore for CmacCore { 85 | #[inline] 86 | fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { 87 | let Self { state, cipher } = self; 88 | let pos = buffer.get_pos(); 89 | let buf = buffer.pad_with_zeros(); 90 | 91 | let mut subkey = Default::default(); 92 | cipher.encrypt_block(&mut subkey); 93 | let key1 = C::dbl(subkey); 94 | 95 | xor(state, &buf); 96 | if pos == buf.len() { 97 | xor(state, &key1); 98 | } else { 99 | state[pos] ^= 0x80; 100 | let key2 = C::dbl(key1); 101 | xor(state, &key2); 102 | } 103 | cipher.encrypt_block(state); 104 | out.copy_from_slice(state); 105 | } 106 | } 107 | 108 | impl AlgorithmName for CmacCore { 109 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { 110 | f.write_str("Cmac<")?; 111 | ::write_alg_name(f)?; 112 | f.write_str(">") 113 | } 114 | } 115 | 116 | impl fmt::Debug for CmacCore { 117 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 118 | f.write_str("CmacCore { ... }") 119 | } 120 | } 121 | 122 | impl Drop for CmacCore { 123 | fn drop(&mut self) { 124 | #[cfg(feature = "zeroize")] 125 | { 126 | self.state.zeroize(); 127 | } 128 | } 129 | } 130 | 131 | #[cfg(feature = "zeroize")] 132 | impl ZeroizeOnDrop for CmacCore {} 133 | 134 | #[inline(always)] 135 | fn xor(buf: &mut Array, data: &Array) { 136 | for i in 0..N::USIZE { 137 | buf[i] ^= data[i]; 138 | } 139 | } 140 | 141 | /// Helper trait implemented for cipher supported by CMAC 142 | pub trait CmacCipher: BlockSizeUser + BlockCipherEncrypt + Clone { 143 | /// Double block. See the [`Dbl`] trait docs for more information. 144 | fn dbl(block: Block) -> Block; 145 | } 146 | 147 | impl CmacCipher for C 148 | where 149 | Self: BlockSizeUser + BlockCipherEncrypt + Clone, 150 | Block: Dbl, 151 | { 152 | fn dbl(block: Block) -> Block { 153 | block.dbl() 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /cmac/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![doc = include_str!("../README.md")] 3 | #![doc( 4 | html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg", 5 | html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg" 6 | )] 7 | #![cfg_attr(docsrs, feature(doc_auto_cfg))] 8 | #![forbid(unsafe_code)] 9 | #![warn(missing_docs)] 10 | 11 | pub use digest::{self, KeyInit, Mac}; 12 | 13 | /// Block-level implementation. 14 | pub mod block_api; 15 | 16 | use block_api::CmacCipher; 17 | use core::fmt; 18 | use digest::block_api::{AlgorithmName, CoreProxy}; 19 | 20 | digest::buffer_fixed!( 21 | /// Generic CMAC instance. 22 | pub struct Cmac(block_api::CmacCore); 23 | impl: ResetMacTraits InnerInit; 24 | ); 25 | 26 | impl AlgorithmName for Cmac { 27 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { 28 | ::Core::write_alg_name(f) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /cmac/tests/cavp_large.rs: -------------------------------------------------------------------------------- 1 | use aes::Aes128; 2 | use cmac::Cmac; 3 | use digest::new_resettable_mac_test; 4 | 5 | // Tests from CAVP (excluding all 64 KiB vectors for AES-128 except the first one): 6 | // https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES 7 | // 8 | // Test vectors in this file use 64 KiB of data, so they are excluded from published packages. 9 | new_resettable_mac_test!( 10 | cmac_aes128_cavp, 11 | "cavp_aes128_large", 12 | Cmac, 13 | trunc_left 14 | ); 15 | -------------------------------------------------------------------------------- /cmac/tests/data/aes128.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/cmac/tests/data/aes128.blb -------------------------------------------------------------------------------- /cmac/tests/data/aes192.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/cmac/tests/data/aes192.blb -------------------------------------------------------------------------------- /cmac/tests/data/aes256.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/cmac/tests/data/aes256.blb -------------------------------------------------------------------------------- /cmac/tests/data/cavp_aes128.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/cmac/tests/data/cavp_aes128.blb -------------------------------------------------------------------------------- /cmac/tests/data/cavp_aes128_large.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/cmac/tests/data/cavp_aes128_large.blb -------------------------------------------------------------------------------- /cmac/tests/data/cavp_aes192.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/cmac/tests/data/cavp_aes192.blb -------------------------------------------------------------------------------- /cmac/tests/data/cavp_aes256.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/cmac/tests/data/cavp_aes256.blb -------------------------------------------------------------------------------- /cmac/tests/data/cavp_tdes2.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/cmac/tests/data/cavp_tdes2.blb -------------------------------------------------------------------------------- /cmac/tests/data/cavp_tdes3.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/cmac/tests/data/cavp_tdes3.blb -------------------------------------------------------------------------------- /cmac/tests/data/kuznyechik.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/cmac/tests/data/kuznyechik.blb -------------------------------------------------------------------------------- /cmac/tests/data/magma.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/cmac/tests/data/magma.blb -------------------------------------------------------------------------------- /cmac/tests/data/wycheproof-aes128.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/cmac/tests/data/wycheproof-aes128.blb -------------------------------------------------------------------------------- /cmac/tests/data/wycheproof-aes192.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/cmac/tests/data/wycheproof-aes192.blb -------------------------------------------------------------------------------- /cmac/tests/data/wycheproof-aes256.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/cmac/tests/data/wycheproof-aes256.blb -------------------------------------------------------------------------------- /cmac/tests/mod.rs: -------------------------------------------------------------------------------- 1 | use aes::{Aes128, Aes192, Aes256}; 2 | use cmac::Cmac; 3 | use des::{TdesEde2, TdesEde3}; 4 | use digest::new_resettable_mac_test; 5 | use kuznyechik::Kuznyechik; 6 | use magma::Magma; 7 | 8 | // Tests from NIST SP 800-38B: 9 | // https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/ 10 | new_resettable_mac_test!(cmac_aes128_nist, "aes128", Cmac); 11 | new_resettable_mac_test!(cmac_aes192_nist, "aes192", Cmac); 12 | new_resettable_mac_test!(cmac_aes256_nist, "aes256", Cmac); 13 | 14 | // Tests from CAVP (excluding all 64 KiB vectors for AES-128 except the first one): 15 | // https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES 16 | new_resettable_mac_test!(cmac_aes128_cavp, "cavp_aes128", Cmac, trunc_left); 17 | new_resettable_mac_test!(cmac_aes192_cavp, "cavp_aes192", Cmac, trunc_left); 18 | new_resettable_mac_test!(cmac_aes256_cavp, "cavp_aes256", Cmac, trunc_left); 19 | new_resettable_mac_test!(cmac_tdes2_cavp, "cavp_tdes2", Cmac, trunc_left); 20 | new_resettable_mac_test!(cmac_tdes3_cavp, "cavp_tdes3", Cmac, trunc_left); 21 | 22 | // Tests from Project Wycheproof: 23 | // https://github.com/google/wycheproof 24 | new_resettable_mac_test!(cmac_aes128_wycheproof, "wycheproof-aes128", Cmac); 25 | new_resettable_mac_test!(cmac_aes192_wycheproof, "wycheproof-aes192", Cmac); 26 | new_resettable_mac_test!(cmac_aes256_wycheproof, "wycheproof-aes256", Cmac); 27 | 28 | // Test from GOST R 34.13-2015: 29 | // https://tc26.ru/standard/gost/GOST_R_3413-2015.pdf 30 | new_resettable_mac_test!(cmac_kuznyechik_gost, "kuznyechik", Cmac); 31 | new_resettable_mac_test!(cmac_magma_gost, "magma", Cmac); 32 | -------------------------------------------------------------------------------- /hmac/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.13.0 (UNRELEASED) 9 | ### Added 10 | - `HmacReset` and `SimpleHmacReset` types [#186] 11 | 12 | ### Changed 13 | - Edition changed to 2024 and MSRV bumped to 1.85 14 | - Relax MSRV policy and allow MSRV bumps in patch releases 15 | - Update to `digest` v0.11 16 | - Replace type aliases with newtypes ([#186]) 17 | 18 | ### Removed 19 | - `std` and `reset` crate features ([#186]) 20 | 21 | [#186]: https://github.com/RustCrypto/MACs/pull/186 22 | 23 | ## 0.12.1 (2022-02-17) 24 | ### Fixed 25 | - Minimal versions build ([#108]) 26 | 27 | [#108]: https://github.com/RustCrypto/MACs/pull/108 28 | 29 | ## 0.12.0 (2021-12-07) 30 | ### Changed 31 | - Bump `digest` crate dependency to v0.10 and remove `crypto-mac` ([#97]) 32 | - Use a more efficient state representation by using block-level hash API ([#97]) 33 | - Reset functionality is now optional and gated on disabled-by-default reset feature ([#97]) 34 | 35 | ### Added 36 | - `SimpleHmac` as a less constrained alternative to `Hmac` ([#97]) 37 | 38 | [#97]: https://github.com/RustCrypto/MACs/pull/97 39 | 40 | ## 0.11.0 (2021-04-29) 41 | ### Changed 42 | - Bump `crypto-mac` crate dependency to v0.11 ([#73]) 43 | 44 | [#73]: https://github.com/RustCrypto/MACs/pull/73 45 | 46 | ## 0.10.1 (2020-10-16) 47 | ### Added 48 | - Zulip badge ([#64]) 49 | 50 | [#64]: https://github.com/RustCrypto/MACs/pull/64 51 | 52 | ## 0.10.0 (2020-10-16) 53 | ### Changed 54 | - Bump `crypto-mac` dependency to v0.10 ([#62]) 55 | 56 | [#62]: https://github.com/RustCrypto/MACs/pull/62 57 | 58 | ## 0.9.0 (2020-08-12) 59 | ### Changed 60 | - Bump `crypto-mac` dependency to v0.9 ([#57]) 61 | 62 | ### Added 63 | - Implement `io::Write` ([#55]) 64 | 65 | [#55]: https://github.com/RustCrypto/MACs/pull/55 66 | [#57]: https://github.com/RustCrypto/MACs/pull/57 67 | 68 | ## 0.8.1 (2020-06-24) 69 | ### Fixed 70 | - Replace outdated `code` with `into_bytes` in documentation ([#50]) 71 | 72 | [#50]: https://github.com/RustCrypto/MACs/pull/50 73 | 74 | ## 0.8.0 (2020-06-09) 75 | ### Changed 76 | - Upgrade to `digest` v0.9 crate release; MSRV 1.41 ([#45]) 77 | - Upgrade `crypto-mac` to v0.8 ([#33]) 78 | - Rename `*result*` to `finalize` ([#38]) 79 | - Upgrade to Rust 2018 edition ([#33]) 80 | 81 | [#45]: https://github.com/RustCrypto/MACs/pull/45 82 | [#38]: https://github.com/RustCrypto/MACs/pull/38 83 | [#33]: https://github.com/RustCrypto/MACs/pull/33 84 | 85 | ## 0.7.1 (2019-07-11) 86 | 87 | ## 0.7.0 (2018-10-03) 88 | 89 | ## 0.6.3 (2018-08-15) 90 | 91 | ## 0.6.2 (2018-04-15) 92 | 93 | ## 0.6.1 (2018-04-05) 94 | 95 | ## 0.6.0 (2018-03-30) 96 | 97 | ## 0.5.0 (2017-11-15) 98 | 99 | ## 0.4.2 (2017-07-24) 100 | 101 | ## 0.4.1 (2017-07-24) 102 | 103 | ## 0.4.0 (2017-07-24) 104 | 105 | ## 0.3.1 (2017-06-12) 106 | 107 | ## 0.1.2 (2017-07-24) 108 | 109 | ## 0.1.1 (2017-05-14) 110 | 111 | ## 0.1.0 (2017-05-14) 112 | 113 | ## 0.0.1 (2016-10-21) 114 | -------------------------------------------------------------------------------- /hmac/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hmac" 3 | version = "0.13.0-rc.0" 4 | description = "Generic implementation of Hash-based Message Authentication Code (HMAC)" 5 | authors = ["RustCrypto Developers"] 6 | license = "MIT OR Apache-2.0" 7 | edition = "2024" 8 | readme = "README.md" 9 | documentation = "https://docs.rs/hmac" 10 | repository = "https://github.com/RustCrypto/MACs" 11 | keywords = ["crypto", "mac", "hmac", "digest"] 12 | categories = ["cryptography", "no-std"] 13 | rust-version = "1.85" 14 | 15 | [dependencies] 16 | digest = { version = "0.11.0-rc.0", features = ["mac"] } 17 | 18 | [dev-dependencies] 19 | digest = { version = "0.11.0-rc.0", features = ["dev"] } 20 | md-5 = { version = "0.11.0-rc.0", default-features = false } 21 | sha1 = { version = "0.11.0-rc.0", default-features = false } 22 | sha2 = { version = "0.11.0-rc.0", default-features = false } 23 | streebog = { version = "0.11.0-rc.0", default-features = false } 24 | hex-literal = "1" 25 | 26 | [features] 27 | zeroize = ["digest/zeroize"] 28 | 29 | [package.metadata.docs.rs] 30 | all-features = true 31 | -------------------------------------------------------------------------------- /hmac/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /hmac/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Artyom Pavlov 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 | -------------------------------------------------------------------------------- /hmac/README.md: -------------------------------------------------------------------------------- 1 | # RustCrypto: HMAC 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 [Hash-based Message Authentication Code (HMAC)][1]. 11 | 12 | To use it you will need a cryptographic hash function implementation which 13 | implements the [`digest`] crate traits. You can find compatible crates 14 | (e.g. [`sha2`]) in the [`RustCrypto/hashes`] repository. 15 | 16 | This crate provides four HMAC implementations: [`Hmac`], [`HmacReset`], 17 | [`SimpleHmac`], and [`SimpleHmacReset`]. 18 | 19 | The first two types are buffered wrappers around block-level 20 | [`block_api::HmacCore`] and [`block_api::HmacResetCore`] types respectively. 21 | Internally they uses efficient state representation, but work only with 22 | hash functions which expose block-level API and consume blocks eagerly 23 | (e.g. they will not work with the BLAKE2 family of hash functions). 24 | 25 | On the other hand, [`SimpleHmac`] and [`SimpleHmacReset`] are a bit less 26 | efficient, but work with all hash functions which implement 27 | the [`Digest`] trait. 28 | 29 | [`Hmac`] and [`SimpleHmac`] do not support resetting MAC state (i.e. they 30 | do not implement the [`Reset`] and [`FixedOutputReset`] traits). Use 31 | [`HmacReset`] or [`SimpleHmacReset`] if you want to reuse MAC state. 32 | 33 | ## Examples 34 | 35 | Let us demonstrate how to use HMAC using the SHA-256 hash function 36 | implemented in the [`sha2`] crate. 37 | 38 | In the following examples [`Hmac`] is interchangeable with [`SimpleHmac`]. 39 | 40 | To get authentication code: 41 | 42 | ```rust 43 | use sha2::Sha256; 44 | use hmac::{Hmac, KeyInit, Mac}; 45 | use hex_literal::hex; 46 | 47 | // Create alias for HMAC-SHA256 48 | type HmacSha256 = Hmac; 49 | 50 | let mut mac = HmacSha256::new_from_slice(b"my secret and secure key") 51 | .expect("HMAC can take key of any size"); 52 | mac.update(b"input message"); 53 | 54 | // `result` has type `CtOutput` which is a thin wrapper around array of 55 | // bytes for providing constant time equality check 56 | let result = mac.finalize(); 57 | // To get underlying array use `into_bytes`, but be careful, since 58 | // incorrect use of the code value may permit timing attacks which defeats 59 | // the security provided by the `CtOutput` 60 | let code_bytes = result.into_bytes(); 61 | let expected = hex!(" 62 | 97d2a569059bbcd8ead4444ff99071f4 63 | c01d005bcefe0d3567e1be628e5fdcd9 64 | "); 65 | assert_eq!(code_bytes[..], expected[..]); 66 | ``` 67 | 68 | To verify the message: 69 | 70 | ```rust 71 | use sha2::Sha256; 72 | use hmac::{Hmac, KeyInit, Mac}; 73 | use hex_literal::hex; 74 | 75 | type HmacSha256 = Hmac; 76 | 77 | let mut mac = HmacSha256::new_from_slice(b"my secret and secure key") 78 | .expect("HMAC can take key of any size"); 79 | 80 | mac.update(b"input message"); 81 | 82 | let code_bytes = hex!(" 83 | 97d2a569059bbcd8ead4444ff99071f4 84 | c01d005bcefe0d3567e1be628e5fdcd9 85 | "); 86 | // `verify_slice` will return `Ok(())` if code is correct, `Err(MacError)` otherwise 87 | mac.verify_slice(&code_bytes[..]).unwrap(); 88 | ``` 89 | 90 | ## Block and input sizes 91 | 92 | Usually it is assumed that block size is larger than output size. Due to the 93 | generic nature of the implementation, we must handle cases when this assumption 94 | does not hold. This is done by truncating hash output to the hash 95 | block size if needed. 96 | 97 | ## License 98 | 99 | Licensed under either of: 100 | 101 | * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) 102 | * [MIT license](http://opensource.org/licenses/MIT) 103 | 104 | at your option. 105 | 106 | ### Contribution 107 | 108 | Unless you explicitly state otherwise, any contribution intentionally submitted 109 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 110 | dual licensed as above, without any additional terms or conditions. 111 | 112 | [//]: # (badges) 113 | 114 | [crate-image]: https://img.shields.io/crates/v/hmac.svg?logo=rust 115 | [crate-link]: https://crates.io/crates/hmac 116 | [docs-image]: https://docs.rs/hmac/badge.svg 117 | [docs-link]: https://docs.rs/hmac/ 118 | [build-image]: https://github.com/RustCrypto/MACs/actions/workflows/hmac.yml/badge.svg 119 | [build-link]: https://github.com/RustCrypto/MACs/actions/workflows/hmac.yml 120 | [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg 121 | [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg 122 | [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg 123 | [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs 124 | 125 | [//]: # (general links) 126 | 127 | [1]: https://en.wikipedia.org/wiki/HMAC 128 | [`digest`]: https://docs.rs/digest 129 | [`sha2`]: https://docs.rs/sha2 130 | [`RustCrypto/hashes`]: https://github.com/RustCrypto/hashes 131 | 132 | [//]: # (intra-crate links) 133 | [`Reset`]: https://docs.rs/digest/latest/digest/trait.Reset.html 134 | [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html 135 | [`FixedOutputReset`]: https://docs.rs/digest/latest/digest/trait.FixedOutputReset.html 136 | [`Hmac`]: https://docs.rs/hmac/latest/hmac/struct.Hmac.html 137 | [`HmacReset`]: https://docs.rs/hmac/latest/hmac/struct.HmacReset.html 138 | [`SimpleHmac`]: https://docs.rs/hmac/latest/hmac/struct.SimpleHmac.html 139 | [`SimpleHmacReset`]: https://docs.rs/hmac/latest/hmac/struct.SimpleHmacReset.html 140 | [`block_api::HmacCore`]: https://docs.rs/hmac/latest/hmac/block_api/struct.HmacCore.html 141 | [`block_api::HmacResetCore`]: https://docs.rs/hmac/latest/hmac/block_api/struct.HmacResetCore.html 142 | -------------------------------------------------------------------------------- /hmac/src/block_api.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::{EagerHash, IPAD, OPAD, get_der_key}; 2 | use core::{fmt, slice}; 3 | use digest::{ 4 | InvalidLength, KeyInit, MacMarker, Output, Reset, 5 | block_api::{ 6 | AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, FixedOutputCore, 7 | OutputSizeUser, UpdateCore, 8 | }, 9 | block_buffer::Eager, 10 | crypto_common::{Key, KeySizeUser}, 11 | }; 12 | 13 | /// Generic core HMAC instance, which operates over blocks. 14 | pub struct HmacCore { 15 | digest: D::Core, 16 | opad_digest: D::Core, 17 | } 18 | 19 | impl Clone for HmacCore { 20 | fn clone(&self) -> Self { 21 | Self { 22 | digest: self.digest.clone(), 23 | opad_digest: self.opad_digest.clone(), 24 | } 25 | } 26 | } 27 | 28 | impl MacMarker for HmacCore {} 29 | 30 | impl BufferKindUser for HmacCore { 31 | type BufferKind = Eager; 32 | } 33 | 34 | impl KeySizeUser for HmacCore { 35 | type KeySize = <::Core as BlockSizeUser>::BlockSize; 36 | } 37 | 38 | impl BlockSizeUser for HmacCore { 39 | type BlockSize = <::Core as BlockSizeUser>::BlockSize; 40 | } 41 | 42 | impl OutputSizeUser for HmacCore { 43 | type OutputSize = <::Core as OutputSizeUser>::OutputSize; 44 | } 45 | 46 | impl KeyInit for HmacCore { 47 | #[inline(always)] 48 | fn new(key: &Key) -> Self { 49 | Self::new_from_slice(key.as_slice()).unwrap() 50 | } 51 | 52 | #[inline(always)] 53 | fn new_from_slice(key: &[u8]) -> Result { 54 | let mut buf = get_der_key::(key); 55 | buf.iter_mut().for_each(|b: &mut u8| *b ^= IPAD); 56 | 57 | let mut digest = D::Core::default(); 58 | digest.update_blocks(slice::from_ref(&buf)); 59 | 60 | buf.iter_mut().for_each(|b: &mut u8| *b ^= IPAD ^ OPAD); 61 | 62 | let mut opad_digest = D::Core::default(); 63 | opad_digest.update_blocks(slice::from_ref(&buf)); 64 | 65 | Ok(Self { 66 | opad_digest, 67 | digest, 68 | }) 69 | } 70 | } 71 | 72 | impl UpdateCore for HmacCore { 73 | #[inline(always)] 74 | fn update_blocks(&mut self, blocks: &[Block]) { 75 | self.digest.update_blocks(blocks); 76 | } 77 | } 78 | 79 | impl FixedOutputCore for HmacCore { 80 | #[inline(always)] 81 | fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { 82 | let mut hash = Output::::default(); 83 | self.digest.finalize_fixed_core(buffer, &mut hash); 84 | // finalize_fixed_core should reset the buffer as well, but 85 | // to be extra safe we reset it explicitly again. 86 | buffer.reset(); 87 | let h = &mut self.opad_digest; 88 | buffer.digest_blocks(&hash, |b| h.update_blocks(b)); 89 | h.finalize_fixed_core(buffer, out); 90 | } 91 | } 92 | 93 | impl AlgorithmName for HmacCore { 94 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { 95 | f.write_str("Hmac<")?; 96 | ::write_alg_name(f)?; 97 | f.write_str(">") 98 | } 99 | } 100 | 101 | impl fmt::Debug for HmacCore 102 | where 103 | D::Core: AlgorithmName, 104 | { 105 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 106 | f.write_str("HmacCore { ... }") 107 | } 108 | } 109 | 110 | /// Generic core HMAC instance, which operates over blocks. 111 | pub struct HmacResetCore { 112 | digest: D::Core, 113 | opad_digest: D::Core, 114 | ipad_digest: D::Core, 115 | } 116 | 117 | impl Clone for HmacResetCore { 118 | fn clone(&self) -> Self { 119 | Self { 120 | digest: self.digest.clone(), 121 | opad_digest: self.opad_digest.clone(), 122 | ipad_digest: self.ipad_digest.clone(), 123 | } 124 | } 125 | } 126 | 127 | impl MacMarker for HmacResetCore {} 128 | 129 | impl BufferKindUser for HmacResetCore { 130 | type BufferKind = Eager; 131 | } 132 | 133 | impl KeySizeUser for HmacResetCore { 134 | type KeySize = <::Core as BlockSizeUser>::BlockSize; 135 | } 136 | 137 | impl BlockSizeUser for HmacResetCore { 138 | type BlockSize = <::Core as BlockSizeUser>::BlockSize; 139 | } 140 | 141 | impl OutputSizeUser for HmacResetCore { 142 | type OutputSize = <::Core as OutputSizeUser>::OutputSize; 143 | } 144 | 145 | impl KeyInit for HmacResetCore { 146 | #[inline(always)] 147 | fn new(key: &Key) -> Self { 148 | Self::new_from_slice(key.as_slice()).unwrap() 149 | } 150 | 151 | #[inline(always)] 152 | fn new_from_slice(key: &[u8]) -> Result { 153 | let mut buf = get_der_key::(key); 154 | buf.iter_mut().for_each(|b: &mut u8| *b ^= IPAD); 155 | 156 | let mut digest = D::Core::default(); 157 | digest.update_blocks(slice::from_ref(&buf)); 158 | 159 | buf.iter_mut().for_each(|b: &mut u8| *b ^= IPAD ^ OPAD); 160 | 161 | let mut opad_digest = D::Core::default(); 162 | opad_digest.update_blocks(slice::from_ref(&buf)); 163 | 164 | Ok(Self { 165 | ipad_digest: digest.clone(), 166 | opad_digest, 167 | digest, 168 | }) 169 | } 170 | } 171 | 172 | impl UpdateCore for HmacResetCore { 173 | #[inline(always)] 174 | fn update_blocks(&mut self, blocks: &[Block]) { 175 | self.digest.update_blocks(blocks); 176 | } 177 | } 178 | 179 | impl FixedOutputCore for HmacResetCore { 180 | #[inline(always)] 181 | fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { 182 | let mut hash = Output::::default(); 183 | self.digest.finalize_fixed_core(buffer, &mut hash); 184 | // finalize_fixed_core should reset the buffer as well, but 185 | // to be extra safe we reset it explicitly again. 186 | buffer.reset(); 187 | let mut h = self.opad_digest.clone(); 188 | buffer.digest_blocks(&hash, |b| h.update_blocks(b)); 189 | h.finalize_fixed_core(buffer, out); 190 | } 191 | } 192 | 193 | impl Reset for HmacResetCore { 194 | #[inline(always)] 195 | fn reset(&mut self) { 196 | self.digest = self.ipad_digest.clone(); 197 | } 198 | } 199 | 200 | impl AlgorithmName for HmacResetCore { 201 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { 202 | f.write_str("Hmac<")?; 203 | ::write_alg_name(f)?; 204 | f.write_str(">") 205 | } 206 | } 207 | 208 | impl fmt::Debug for HmacResetCore 209 | where 210 | D::Core: AlgorithmName, 211 | { 212 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 213 | f.write_str("HmacResetCore { ... }") 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /hmac/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Overwrite intra-crate links 2 | //! [`Reset`]: digest::Reset 3 | //! [`Digest`]: digest::Digest 4 | //! [`FixedOutputReset`]: digest::FixedOutputReset 5 | //! [`Hmac`]: Hmac 6 | //! [`HmacReset`]: HmacReset 7 | //! [`SimpleHmac`]: SimpleHmac 8 | //! [`SimpleHmacReset`]: SimpleHmacReset 9 | //! [`block_api::HmacCore`]: block_api::HmacCore 10 | //! [`block_api::HmacResetCore`]: block_api::HmacResetCore 11 | 12 | #![no_std] 13 | #![doc = include_str!("../README.md")] 14 | #![doc( 15 | html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg", 16 | html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg" 17 | )] 18 | #![cfg_attr(docsrs, feature(doc_auto_cfg))] 19 | #![forbid(unsafe_code)] 20 | #![warn(missing_docs)] 21 | 22 | pub use digest::{self, KeyInit, Mac}; 23 | 24 | /// Block-level implementation. 25 | pub mod block_api; 26 | mod simple; 27 | mod simple_reset; 28 | mod utils; 29 | 30 | pub use simple::SimpleHmac; 31 | pub use simple_reset::SimpleHmacReset; 32 | pub use utils::EagerHash; 33 | 34 | use core::fmt; 35 | use digest::block_api::{AlgorithmName, CoreProxy}; 36 | 37 | digest::buffer_fixed!( 38 | /// Generic HMAC instance. 39 | pub struct Hmac(block_api::HmacCore); 40 | impl: MacTraits KeyInit; 41 | ); 42 | 43 | impl AlgorithmName for Hmac { 44 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { 45 | ::Core::write_alg_name(f) 46 | } 47 | } 48 | 49 | digest::buffer_fixed!( 50 | /// Generic HMAC instance with reset support. 51 | pub struct HmacReset(block_api::HmacResetCore); 52 | impl: ResetMacTraits KeyInit; 53 | ); 54 | 55 | impl AlgorithmName for HmacReset { 56 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { 57 | ::Core::write_alg_name(f) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /hmac/src/simple.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::{IPAD, OPAD, get_der_key}; 2 | use core::fmt; 3 | use digest::{ 4 | Digest, FixedOutput, KeyInit, MacMarker, Output, OutputSizeUser, Update, 5 | crypto_common::{Block, BlockSizeUser, InvalidLength, Key, KeySizeUser}, 6 | }; 7 | 8 | /// Simplified HMAC instance able to operate over hash functions 9 | /// which do not expose block-level API and hash functions which 10 | /// process blocks lazily (e.g. BLAKE2). 11 | #[derive(Clone)] 12 | pub struct SimpleHmac { 13 | digest: D, 14 | opad_key: Block, 15 | } 16 | 17 | impl KeySizeUser for SimpleHmac { 18 | type KeySize = D::BlockSize; 19 | } 20 | 21 | impl MacMarker for SimpleHmac {} 22 | 23 | impl KeyInit for SimpleHmac { 24 | fn new(key: &Key) -> Self { 25 | Self::new_from_slice(key.as_slice()).unwrap() 26 | } 27 | 28 | #[inline] 29 | fn new_from_slice(key: &[u8]) -> Result { 30 | let mut buf = get_der_key::(key); 31 | buf.iter_mut().for_each(|b: &mut u8| *b ^= IPAD); 32 | 33 | let mut digest = D::new(); 34 | digest.update(&buf); 35 | 36 | buf.iter_mut().for_each(|b: &mut u8| *b ^= OPAD ^ IPAD); 37 | 38 | Ok(Self { 39 | digest, 40 | opad_key: buf, 41 | }) 42 | } 43 | } 44 | 45 | impl Update for SimpleHmac { 46 | #[inline(always)] 47 | fn update(&mut self, data: &[u8]) { 48 | self.digest.update(data); 49 | } 50 | } 51 | 52 | impl OutputSizeUser for SimpleHmac { 53 | type OutputSize = D::OutputSize; 54 | } 55 | 56 | impl FixedOutput for SimpleHmac { 57 | fn finalize_into(self, out: &mut Output) { 58 | let mut h = D::new(); 59 | h.update(&self.opad_key); 60 | h.update(self.digest.finalize()); 61 | h.finalize_into(out); 62 | } 63 | } 64 | 65 | impl fmt::Debug for SimpleHmac { 66 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 67 | f.write_str("SimpleHmac { ... }") 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /hmac/src/simple_reset.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::{IPAD, OPAD, get_der_key}; 2 | use core::fmt; 3 | use digest::{ 4 | Digest, FixedOutput, KeyInit, MacMarker, Output, OutputSizeUser, Update, 5 | crypto_common::{Block, BlockSizeUser, InvalidLength, Key, KeySizeUser}, 6 | }; 7 | use digest::{FixedOutputReset, Reset}; 8 | 9 | /// Simplified HMAC instance with reset support able to operate 10 | /// over hash functions which do not expose block-level API and 11 | /// hash functions which process blocks lazily (e.g. BLAKE2). 12 | #[derive(Clone)] 13 | pub struct SimpleHmacReset { 14 | digest: D, 15 | opad_key: Block, 16 | ipad_key: Block, 17 | } 18 | 19 | impl KeySizeUser for SimpleHmacReset { 20 | type KeySize = D::BlockSize; 21 | } 22 | 23 | impl MacMarker for SimpleHmacReset {} 24 | 25 | impl KeyInit for SimpleHmacReset { 26 | fn new(key: &Key) -> Self { 27 | Self::new_from_slice(key.as_slice()).unwrap() 28 | } 29 | 30 | #[inline] 31 | fn new_from_slice(key: &[u8]) -> Result { 32 | let der_key = get_der_key::(key); 33 | 34 | let mut ipad_key = der_key.clone(); 35 | ipad_key.iter_mut().for_each(|b: &mut u8| *b ^= IPAD); 36 | 37 | let mut digest = D::new(); 38 | digest.update(&ipad_key); 39 | 40 | let mut opad_key = der_key; 41 | opad_key.iter_mut().for_each(|b: &mut u8| *b ^= OPAD); 42 | 43 | Ok(Self { 44 | digest, 45 | opad_key, 46 | ipad_key, 47 | }) 48 | } 49 | } 50 | 51 | impl Update for SimpleHmacReset { 52 | #[inline(always)] 53 | fn update(&mut self, data: &[u8]) { 54 | self.digest.update(data); 55 | } 56 | } 57 | 58 | impl OutputSizeUser for SimpleHmacReset { 59 | type OutputSize = D::OutputSize; 60 | } 61 | 62 | impl FixedOutput for SimpleHmacReset { 63 | fn finalize_into(self, out: &mut Output) { 64 | let mut h = D::new(); 65 | h.update(&self.opad_key); 66 | h.update(self.digest.finalize()); 67 | h.finalize_into(out); 68 | } 69 | } 70 | 71 | impl fmt::Debug for SimpleHmacReset { 72 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 73 | f.write_str("SimpleResetHmac") 74 | } 75 | } 76 | 77 | impl Reset for SimpleHmacReset { 78 | fn reset(&mut self) { 79 | Reset::reset(&mut self.digest); 80 | self.digest.update(&self.ipad_key); 81 | } 82 | } 83 | 84 | impl FixedOutputReset for SimpleHmacReset { 85 | fn finalize_into_reset(&mut self, out: &mut Output) { 86 | let mut h = D::new(); 87 | Update::update(&mut h, &self.opad_key); 88 | Update::update(&mut h, &self.digest.finalize_reset()); 89 | Update::update(&mut self.digest, &self.ipad_key); 90 | Digest::finalize_into(h, out); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /hmac/src/utils.rs: -------------------------------------------------------------------------------- 1 | use digest::{ 2 | Digest, HashMarker, 3 | block_api::{ 4 | Block, BlockSizeUser, BufferKindUser, CoreProxy, Eager, FixedOutputCore, UpdateCore, 5 | }, 6 | }; 7 | 8 | pub(crate) const IPAD: u8 = 0x36; 9 | pub(crate) const OPAD: u8 = 0x5C; 10 | 11 | pub(crate) fn get_der_key(key: &[u8]) -> Block { 12 | let mut der_key = Block::::default(); 13 | // The key that HMAC processes must be the same as the block size of the 14 | // underlying hash function. If the provided key is smaller than that, 15 | // we just pad it with zeros. If its larger, we hash it and then pad it 16 | // with zeros. 17 | if key.len() <= der_key.len() { 18 | der_key[..key.len()].copy_from_slice(key); 19 | } else { 20 | let hash = D::digest(key); 21 | // All commonly used hash functions have block size bigger 22 | // than output hash size, but to be extra rigorous we 23 | // handle the potential uncommon cases as well. 24 | // The condition is calculated at compile time, so this 25 | // branch gets removed from the final binary. 26 | if hash.len() <= der_key.len() { 27 | der_key[..hash.len()].copy_from_slice(&hash); 28 | } else { 29 | let n = der_key.len(); 30 | der_key.copy_from_slice(&hash[..n]); 31 | } 32 | } 33 | der_key 34 | } 35 | 36 | /// Trait implemented by eager hashes which expose their block-level core. 37 | pub trait EagerHash: BlockSizeUser + Digest { 38 | /// Block-level core type of the hash. 39 | type Core: HashMarker 40 | + UpdateCore 41 | + FixedOutputCore 42 | + BlockSizeUser::BlockSize> 43 | + BufferKindUser 44 | + Default 45 | + Clone; 46 | } 47 | 48 | impl EagerHash for T 49 | where 50 | T: CoreProxy + BlockSizeUser + Digest, 51 | ::Core: HashMarker 52 | + UpdateCore 53 | + FixedOutputCore 54 | + BlockSizeUser::BlockSize> 55 | + BufferKindUser 56 | + Default 57 | + Clone, 58 | { 59 | type Core = T::Core; 60 | } 61 | -------------------------------------------------------------------------------- /hmac/tests/data/md5.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/hmac/tests/data/md5.blb -------------------------------------------------------------------------------- /hmac/tests/data/sha224.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/hmac/tests/data/sha224.blb -------------------------------------------------------------------------------- /hmac/tests/data/sha256.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/hmac/tests/data/sha256.blb -------------------------------------------------------------------------------- /hmac/tests/data/sha384.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/hmac/tests/data/sha384.blb -------------------------------------------------------------------------------- /hmac/tests/data/sha512.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/hmac/tests/data/sha512.blb -------------------------------------------------------------------------------- /hmac/tests/data/streebog256.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/hmac/tests/data/streebog256.blb -------------------------------------------------------------------------------- /hmac/tests/data/streebog512.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/hmac/tests/data/streebog512.blb -------------------------------------------------------------------------------- /hmac/tests/data/wycheproof-sha1.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/hmac/tests/data/wycheproof-sha1.blb -------------------------------------------------------------------------------- /hmac/tests/data/wycheproof-sha256.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/hmac/tests/data/wycheproof-sha256.blb -------------------------------------------------------------------------------- /hmac/tests/data/wycheproof-sha384.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/hmac/tests/data/wycheproof-sha384.blb -------------------------------------------------------------------------------- /hmac/tests/data/wycheproof-sha512.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/hmac/tests/data/wycheproof-sha512.blb -------------------------------------------------------------------------------- /hmac/tests/mod.rs: -------------------------------------------------------------------------------- 1 | macro_rules! test { 2 | ($mod_name:ident, $test_name:expr, $hash:ty $(, $t:ident)?) => { 3 | mod $mod_name { 4 | digest::new_mac_test!(hmac, $test_name, hmac::Hmac<$hash> $(, $t)?); 5 | digest::new_mac_test!(simple_hmac, $test_name, hmac::SimpleHmac<$hash> $(, $t)?); 6 | digest::new_resettable_mac_test!( 7 | hmac_reset, 8 | $test_name, 9 | hmac::HmacReset<$hash> 10 | $(, $t)? 11 | ); 12 | digest::new_resettable_mac_test!( 13 | simple_reset_hmac, 14 | $test_name, 15 | hmac::SimpleHmacReset<$hash> 16 | $(, $t)? 17 | ); 18 | } 19 | }; 20 | } 21 | 22 | // Test vectors from RFC 2104, plus wiki test 23 | test!(md5_rfc2104, "md5", md5::Md5); 24 | 25 | // Test vectors from RFC 4231 26 | test!(sha224_rfc4231, "sha224", sha2::Sha224); 27 | test!(sha256_rfc4231, "sha256", sha2::Sha256); 28 | test!(sha384_rfc4231, "sha384", sha2::Sha384); 29 | test!(sha512_rfc4231, "sha512", sha2::Sha512); 30 | 31 | // Test vectors from R 50.1.113-2016: 32 | // https://tc26.ru/standard/rs/Р%2050.1.113-2016.pdf 33 | test!(treebog256, "streebog256", streebog::Streebog256); 34 | test!(streebog512, "streebog512", streebog::Streebog512); 35 | 36 | // Tests from Project Wycheproof: 37 | // https://github.com/google/wycheproof 38 | test!(sha1_wycheproof, "wycheproof-sha1", sha1::Sha1, trunc_left); 39 | test!( 40 | sha256_wycheproof, 41 | "wycheproof-sha256", 42 | sha2::Sha256, 43 | trunc_left 44 | ); 45 | test!( 46 | sha384_wycheproof, 47 | "wycheproof-sha384", 48 | sha2::Sha384, 49 | trunc_left 50 | ); 51 | test!( 52 | sha512_wycheproof, 53 | "wycheproof-sha512", 54 | sha2::Sha512, 55 | trunc_left 56 | ); 57 | -------------------------------------------------------------------------------- /pmac/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.8.0 (UNRELEASED) 9 | ### Changed 10 | - Edition changed to 2024 and MSRV bumped to 1.85 11 | - Relax MSRV policy and allow MSRV bumps in patch releases 12 | - Update to `digest` v0.11 13 | - Update to `cipher` v0.5 14 | - Replace type aliases with newtypes ([#186]) 15 | 16 | ### Removed 17 | - `std` crate feature ([#186]) 18 | 19 | [#186]: https://github.com/RustCrypto/MACs/pull/186 20 | 21 | ## 0.7.1 (2022-02-17) 22 | ### Fixed 23 | - Minimal versions build ([#108]) 24 | 25 | [#108]: https://github.com/RustCrypto/MACs/pull/108 26 | 27 | ## 0.7.0 (2022-02-10) 28 | ### Changed 29 | - Migrate from `crypto-mac` dependency to `digest v0.10` ([#103]) 30 | - Bump `cipher` dependency to v0.4 ([#103]) 31 | 32 | [#103]: https://github.com/RustCrypto/MACs/pull/103 33 | 34 | ## 0.6.0 (2021-04-29) 35 | ### Changed 36 | - Bump `crypto-mac` crate dependency to v0.11 ([#73]) 37 | 38 | [#73]: https://github.com/RustCrypto/MACs/pull/73 39 | 40 | ## 0.5.1 (2020-10-16) 41 | ### Added 42 | - Zulip badge ([#64]) 43 | 44 | [#64]: https://github.com/RustCrypto/MACs/pull/64 45 | 46 | ## 0.5.0 (2020-10-16) 47 | ### Changed 48 | - Bump `crypto-mac` dependency to v0.10 ([#62]) 49 | 50 | [#62]: https://github.com/RustCrypto/MACs/pull/62 51 | 52 | ## 0.4.0 (2020-08-12) 53 | ### Changed 54 | - Bump `crypto-mac` dependency to v0.9, implement the `FromBlockCipher` trait ([#57]) 55 | 56 | ### Added 57 | - `io::Write` impl ([#55]) 58 | 59 | [#55]: https://github.com/RustCrypto/MACs/pull/55 60 | [#57]: https://github.com/RustCrypto/MACs/pull/57 61 | 62 | ## 0.3.0 (2020-06-06) 63 | ### Changed 64 | - Bump `aes` crate dependency to v0.4 ([#40]) 65 | - Bump `dbl` crate dependency to v0.3 ([#39]) 66 | - Bump `crypto-mac` dependency to v0.8; MSRV 1.41+ ([#34]) 67 | - Rename `result` methods to `finalize` ([#38]) 68 | - Upgrade to Rust 2018 edition ([#34]) 69 | 70 | [#40]: https://github.com/RustCrypto/MACs/pull/40 71 | [#39]: https://github.com/RustCrypto/MACs/pull/39 72 | [#38]: https://github.com/RustCrypto/MACs/pull/38 73 | [#34]: https://github.com/RustCrypto/MACs/pull/34 74 | 75 | ## 0.2.0 (2018-10-03) 76 | 77 | ## 0.1.0 (2017-11-26) 78 | -------------------------------------------------------------------------------- /pmac/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pmac" 3 | version = "0.8.0-rc.0" 4 | description = "Generic implementation of Parallelizable Message Authentication Code" 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/pmac" 11 | repository = "https://github.com/RustCrypto/MACs" 12 | keywords = ["crypto", "mac", "pmac"] 13 | categories = ["cryptography", "no-std"] 14 | 15 | [dependencies] 16 | cipher = "0.5.0-rc.0" 17 | digest = { version = "0.11.0-rc.0", features = ["mac"] } 18 | dbl = "0.4.0-rc.0" 19 | 20 | [dev-dependencies] 21 | aes = "0.9.0-rc.0" 22 | digest = { version = "0.11.0-rc.0", features = ["dev"] } 23 | 24 | [features] 25 | zeroize = ["cipher/zeroize", "digest/zeroize"] 26 | 27 | [package.metadata.docs.rs] 28 | all-features = true 29 | -------------------------------------------------------------------------------- /pmac/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /pmac/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Artyom Pavlov 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 | -------------------------------------------------------------------------------- /pmac/README.md: -------------------------------------------------------------------------------- 1 | # RustCrypto: PMAC 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 [Parallelizable Message Authentication Code (PMAC)][1]. 11 | 12 | ## Examples 13 | We will use AES-128 block cipher from the [`aes`] crate. 14 | 15 | To get authentication code: 16 | 17 | ```rust 18 | use aes::Aes128; 19 | use pmac::{digest::KeyInit, Pmac, Mac}; 20 | 21 | // Create `Mac` trait implementation, namely PMAC-AES128 22 | let mut mac = Pmac::::new_from_slice(b"very secret key.").unwrap(); 23 | mac.update(b"input message"); 24 | 25 | // `result` has type `Output` which is a thin wrapper around array of 26 | // bytes for providing constant time equality check 27 | let result = mac.finalize(); 28 | // To get underlying array use `into_bytes` method, but be careful, since 29 | // incorrect use of the tag value may permit timing attacks which defeat 30 | // the security provided by the `Output` wrapper 31 | let tag_bytes = result.into_bytes(); 32 | ``` 33 | 34 | To verify the message: 35 | 36 | ```rust 37 | # use aes::Aes128; 38 | # use pmac::{digest::KeyInit, Pmac, Mac}; 39 | let mut mac = Pmac::::new_from_slice(b"very secret key.").unwrap(); 40 | 41 | mac.update(b"input message"); 42 | 43 | # let tag_bytes = mac.clone().finalize().into_bytes(); 44 | // `verify` will return `Ok(())` if tag is correct, `Err(MacError)` otherwise 45 | mac.verify(&tag_bytes).unwrap(); 46 | ``` 47 | 48 | ## License 49 | 50 | Licensed under either of: 51 | 52 | * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) 53 | * [MIT license](http://opensource.org/licenses/MIT) 54 | 55 | at your option. 56 | 57 | ### Contribution 58 | 59 | Unless you explicitly state otherwise, any contribution intentionally submitted 60 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 61 | dual licensed as above, without any additional terms or conditions. 62 | 63 | [//]: # (badges) 64 | 65 | [crate-image]: https://img.shields.io/crates/v/pmac.svg?logo=rust 66 | [crate-link]: https://crates.io/crates/pmac 67 | [docs-image]: https://docs.rs/pmac/badge.svg 68 | [docs-link]: https://docs.rs/pmac/ 69 | [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg 70 | [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg 71 | [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg 72 | [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs 73 | [build-image]: https://github.com/RustCrypto/MACs/actions/workflows/pmac.yml/badge.svg 74 | [build-link]: https://github.com/RustCrypto/MACs/actions/workflows/pmac.yml 75 | 76 | [//]: # (general links) 77 | 78 | [1]: https://en.wikipedia.org/wiki/PMAC_(cryptography) 79 | [`aes`]: https://docs.rs/aes 80 | -------------------------------------------------------------------------------- /pmac/benches/mod.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | extern crate test; 3 | 4 | use aes::{Aes128, Aes256}; 5 | use pmac::{KeyInit, Pmac}; 6 | use test::Bencher; 7 | 8 | digest::bench_update!( 9 | Pmac::::new(&Default::default()); 10 | pmac_aes128_10 10; 11 | pmac_aes128_100 100; 12 | pmac_aes128_1000 1000; 13 | pmac_aes128_10000 10000; 14 | ); 15 | 16 | digest::bench_update!( 17 | Pmac::::new(&Default::default()); 18 | pmac_aes256_10 10; 19 | pmac_aes256_100 100; 20 | pmac_aes256_1000 1000; 21 | pmac_aes256_10000 10000; 22 | ); 23 | -------------------------------------------------------------------------------- /pmac/src/block_api.rs: -------------------------------------------------------------------------------- 1 | use cipher::{BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, ParBlocks}; 2 | use core::fmt; 3 | use dbl::Dbl; 4 | use digest::{ 5 | MacMarker, Output, OutputSizeUser, Reset, 6 | array::{Array, ArraySize}, 7 | block_api::{ 8 | AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, FixedOutputCore, Lazy, 9 | UpdateCore, 10 | }, 11 | crypto_common::{InnerInit, InnerUser}, 12 | typenum::Unsigned, 13 | }; 14 | 15 | #[cfg(feature = "zeroize")] 16 | use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; 17 | 18 | /// Generic PMAC instance 19 | /// 20 | /// `LC_SIZE` regulates size of pre-computed table used in PMAC computation. 21 | /// With `LC_SIZE = 20` and for 128-bit block cipher the table is sufficient 22 | /// for 16*2^20 = 16 MiB of input data. For longer messages the `l` value will 23 | /// be computed on the fly from the last table value, which will be a bit less 24 | /// efficient. 25 | #[derive(Clone)] 26 | pub struct PmacCore { 27 | state: PmacState, 28 | cipher: C, 29 | } 30 | 31 | #[derive(Clone)] 32 | struct PmacState { 33 | counter: usize, 34 | l_inv: Block, 35 | l_cache: [Block; LC_SIZE], 36 | tag: Block, 37 | offset: Block, 38 | } 39 | 40 | impl PmacState { 41 | #[inline(always)] 42 | fn next_offset(&mut self) -> &Block { 43 | let ntz = self.counter.trailing_zeros() as usize; 44 | self.counter += 1; 45 | let l = if ntz < LC_SIZE { 46 | self.l_cache[ntz].clone() 47 | } else { 48 | let mut block = self.l_cache[LC_SIZE - 1].clone(); 49 | for _ in LC_SIZE - 1..ntz { 50 | block = C::dbl(block); 51 | } 52 | block 53 | }; 54 | xor(&mut self.offset, &l); 55 | &self.offset 56 | } 57 | } 58 | 59 | impl Drop for PmacState { 60 | fn drop(&mut self) { 61 | #[cfg(feature = "zeroize")] 62 | { 63 | self.counter.zeroize(); 64 | self.l_inv.zeroize(); 65 | self.l_cache.iter_mut().for_each(|c| c.zeroize()); 66 | self.tag.zeroize(); 67 | self.offset.zeroize(); 68 | } 69 | } 70 | } 71 | 72 | impl BlockSizeUser for PmacCore { 73 | type BlockSize = C::BlockSize; 74 | } 75 | 76 | impl OutputSizeUser for PmacCore { 77 | type OutputSize = C::BlockSize; 78 | } 79 | 80 | impl InnerUser for PmacCore { 81 | type Inner = C; 82 | } 83 | 84 | impl MacMarker for PmacCore {} 85 | 86 | impl Reset for PmacCore { 87 | #[inline(always)] 88 | fn reset(&mut self) { 89 | self.state.tag = Default::default(); 90 | self.state.offset = Default::default(); 91 | self.state.counter = 1; 92 | } 93 | } 94 | 95 | impl BufferKindUser for PmacCore { 96 | type BufferKind = Lazy; 97 | } 98 | 99 | impl AlgorithmName for PmacCore { 100 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { 101 | f.write_str("Pmac<")?; 102 | ::write_alg_name(f)?; 103 | f.write_str(">") 104 | } 105 | } 106 | 107 | impl fmt::Debug for PmacCore { 108 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 109 | f.write_str("PmacCore { ... }") 110 | } 111 | } 112 | 113 | impl InnerInit for PmacCore { 114 | #[inline] 115 | fn inner_init(cipher: C) -> Self { 116 | let mut l = Default::default(); 117 | cipher.encrypt_block(&mut l); 118 | let l_inv = C::inv_dbl(l.clone()); 119 | 120 | let l_cache = [(); LC_SIZE].map(|_| { 121 | let next_l = C::dbl(l.clone()); 122 | core::mem::replace(&mut l, next_l) 123 | }); 124 | 125 | let state = PmacState { 126 | l_cache, 127 | l_inv, 128 | tag: Default::default(), 129 | offset: Default::default(), 130 | counter: 1, 131 | }; 132 | Self { cipher, state } 133 | } 134 | } 135 | 136 | impl UpdateCore for PmacCore { 137 | #[inline] 138 | fn update_blocks(&mut self, blocks: &[Block]) { 139 | struct Closure<'a, C: PmacCipher, const LC_SIZE: usize> { 140 | state: &'a mut PmacState, 141 | blocks: &'a [Block], 142 | } 143 | 144 | impl BlockSizeUser for Closure<'_, C, LC_SIZE> { 145 | type BlockSize = C::BlockSize; 146 | } 147 | 148 | impl BlockCipherEncClosure for Closure<'_, C, LC_SIZE> { 149 | #[inline(always)] 150 | fn call>(self, backend: &B) { 151 | let Self { mut blocks, state } = self; 152 | if B::ParBlocksSize::USIZE > 1 { 153 | // TODO: replace with `slice::as_chunks` on stabilization 154 | // and migration to const generics 155 | let mut iter = blocks.chunks_exact(B::ParBlocksSize::USIZE); 156 | for chunk in &mut iter { 157 | let mut tmp = ParBlocks::::try_from(chunk).expect("size mismatch"); 158 | 159 | for block in tmp.iter_mut() { 160 | xor(block, state.next_offset()); 161 | } 162 | 163 | backend.encrypt_par_blocks((&mut tmp).into()); 164 | 165 | for t in tmp.iter() { 166 | xor(&mut state.tag, t); 167 | } 168 | } 169 | blocks = iter.remainder(); 170 | } 171 | 172 | for block in blocks { 173 | let mut block = block.clone(); 174 | xor(&mut block, state.next_offset()); 175 | backend.encrypt_block((&mut block).into()); 176 | xor(&mut state.tag, &block); 177 | } 178 | } 179 | } 180 | 181 | let Self { cipher, state } = self; 182 | cipher.encrypt_with_backend(Closure { blocks, state }) 183 | } 184 | } 185 | 186 | impl FixedOutputCore for PmacCore { 187 | #[inline] 188 | fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { 189 | let Self { 190 | cipher, 191 | state: PmacState { tag, l_inv, .. }, 192 | } = self; 193 | let pos = buffer.get_pos(); 194 | let buf = buffer.pad_with_zeros(); 195 | if pos == buf.len() { 196 | xor(tag, &buf); 197 | xor(tag, l_inv); 198 | } else { 199 | tag[pos] ^= 0x80; 200 | xor(tag, &buf); 201 | } 202 | cipher.encrypt_block_b2b(tag, out); 203 | } 204 | } 205 | 206 | #[cfg(feature = "zeroize")] 207 | impl ZeroizeOnDrop for PmacCore {} 208 | 209 | #[inline(always)] 210 | fn xor(buf: &mut Array, data: &Array) { 211 | for i in 0..N::USIZE { 212 | buf[i] ^= data[i]; 213 | } 214 | } 215 | 216 | /// Helper trait implemented for cipher supported by CMAC 217 | pub trait PmacCipher: BlockSizeUser + BlockCipherEncrypt + Clone { 218 | /// Double block. See the [`Dbl`] trait docs for more information. 219 | fn dbl(block: Block) -> Block; 220 | /// Reverse double block.. See the [`Dbl`] trait docs for more information. 221 | fn inv_dbl(block: Block) -> Block; 222 | } 223 | 224 | impl PmacCipher for C 225 | where 226 | Self: BlockSizeUser + BlockCipherEncrypt + Clone, 227 | Block: Dbl, 228 | { 229 | fn dbl(block: Block) -> Block { 230 | block.dbl() 231 | } 232 | 233 | fn inv_dbl(block: Block) -> Block { 234 | block.inv_dbl() 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /pmac/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![doc = include_str!("../README.md")] 3 | #![doc( 4 | html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg", 5 | html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg" 6 | )] 7 | #![cfg_attr(docsrs, feature(doc_auto_cfg))] 8 | #![forbid(unsafe_code)] 9 | #![warn(missing_docs)] 10 | 11 | pub use digest::{self, KeyInit, Mac}; 12 | 13 | /// Block-level implementation. 14 | pub mod block_api; 15 | 16 | use block_api::PmacCipher; 17 | use core::fmt; 18 | use digest::block_api::{AlgorithmName, CoreProxy}; 19 | 20 | digest::buffer_fixed!( 21 | /// Generic PMAC instance with `LC_SIZE` = 20. 22 | pub struct Pmac(block_api::PmacCore); 23 | impl: ResetMacTraits InnerInit; 24 | ); 25 | 26 | impl AlgorithmName for Pmac { 27 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { 28 | ::Core::write_alg_name(f) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /pmac/tests/data/aes128.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/pmac/tests/data/aes128.blb -------------------------------------------------------------------------------- /pmac/tests/data/aes192.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/pmac/tests/data/aes192.blb -------------------------------------------------------------------------------- /pmac/tests/data/aes256.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/MACs/9867dc58ebb676f8a473e611889dd23cb2c6190e/pmac/tests/data/aes256.blb -------------------------------------------------------------------------------- /pmac/tests/mod.rs: -------------------------------------------------------------------------------- 1 | use aes::{Aes128, Aes192, Aes256}; 2 | use digest::new_resettable_mac_test; 3 | use pmac::Pmac; 4 | 5 | // Test vectors from: http://web.cs.ucdavis.edu/~rogaway/ocb/pmac-test.htm 6 | new_resettable_mac_test!(pmac_aes128, "aes128", Pmac); 7 | new_resettable_mac_test!(pmac_aes192, "aes192", Pmac); 8 | new_resettable_mac_test!(pmac_aes256, "aes256", Pmac); 9 | -------------------------------------------------------------------------------- /retail-mac/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 (UNRELEASED) 9 | - Initial release 10 | -------------------------------------------------------------------------------- /retail-mac/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "retail-mac" 3 | version = "0.1.0-pre.0" 4 | description = "Implementation of Retail Message Authentication Code (Retail MAC)" 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/retail-mac" 11 | repository = "https://github.com/RustCrypto/MACs" 12 | keywords = ["crypto", "mac"] 13 | 14 | [dependencies] 15 | cipher = "0.5.0-rc.0" 16 | digest = { version = "0.11.0-rc.0", features = ["mac"] } 17 | 18 | [dev-dependencies] 19 | digest = { version = "0.11.0-rc.0", features = ["dev"] } 20 | hex-literal = "1" 21 | 22 | aes = "0.9.0-rc.0" 23 | des = "0.9.0-rc.0" 24 | 25 | [features] 26 | zeroize = ["cipher/zeroize", "digest/zeroize"] 27 | 28 | [package.metadata.docs.rs] 29 | all-features = true 30 | -------------------------------------------------------------------------------- /retail-mac/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /retail-mac/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Artyom Pavlov 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 | -------------------------------------------------------------------------------- /retail-mac/README.md: -------------------------------------------------------------------------------- 1 | # RustCrypto: Retail MAC 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 | Pure Rust implementation of the [Retail Message Authentication Code][Retail MAC], 11 | also known as ISO/IEC 9797-1 MAC algorithm 3. 12 | 13 | **WARNING!** The algorithm has known weaknesses in case of variable-length 14 | messages. See the Wikipedia article for [CBC-MAC] for more information. 15 | 16 | ## Examples 17 | 18 | ```rust 19 | use retail_mac::{digest::KeyInit, RetailMac, Mac}; 20 | use des::Des; 21 | use hex_literal::hex; 22 | 23 | type RetailMacDes = RetailMac; 24 | 25 | // test from ISO/IEC 9797-1:2011 section B.4 26 | // K and K' are concatenated: 27 | let key = hex!("0123456789ABCDEFFEDCBA9876543210"); 28 | 29 | let mut mac = RetailMacDes::new_from_slice(&key).unwrap(); 30 | mac.update(b"Now is the time for all "); 31 | let correct = hex!("A1C72E74EA3FA9B6"); 32 | mac.verify_slice(&correct).unwrap(); 33 | 34 | let mut mac2 = RetailMacDes::new_from_slice(&key).unwrap(); 35 | mac2.update(b"Now is the time for it"); 36 | let correct2 = hex!("2E2B1428CC78254F"); 37 | mac2.verify_slice(&correct2).unwrap(); 38 | ``` 39 | 40 | ## License 41 | 42 | Licensed under either of: 43 | 44 | * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) 45 | * [MIT license](http://opensource.org/licenses/MIT) 46 | 47 | at your option. 48 | 49 | ### Contribution 50 | 51 | Unless you explicitly state otherwise, any contribution intentionally submitted 52 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 53 | dual licensed as above, without any additional terms or conditions. 54 | 55 | [//]: # (badges) 56 | 57 | [crate-image]: https://img.shields.io/crates/v/retail-mac.svg?logo=rust 58 | [crate-link]: https://crates.io/crates/retail-mac 59 | [docs-image]: https://docs.rs/retail-mac/badge.svg 60 | [docs-link]: https://docs.rs/retail-mac/ 61 | [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg 62 | [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg 63 | [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg 64 | [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs 65 | [build-image]: https://github.com/RustCrypto/MACs/actions/workflows/retail-mac.yml/badge.svg 66 | [build-link]: https://github.com/RustCrypto/MACs/actions/workflows/retail-mac.yml 67 | 68 | [//]: # (general links) 69 | 70 | [Retail MAC]: https://en.wikipedia.org/wiki/ISO/IEC_9797-1#MAC_algorithm_3 71 | [CBC-MAC]: https://en.wikipedia.org/wiki/CBC-MAC#Security_with_fixed_and_variable-length_messages 72 | -------------------------------------------------------------------------------- /retail-mac/benches/mod.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | extern crate test; 3 | 4 | use aes::Aes128; 5 | use des::Des; 6 | use retail_mac::{KeyInit, RetailMac}; 7 | use test::Bencher; 8 | 9 | digest::bench_update!( 10 | RetailMac::::new(&Default::default()); 11 | retail_mac_aes128_10 10; 12 | retail_mac_aes128_100 100; 13 | retail_mac_aes128_1000 1000; 14 | retail_mac_aes128_10000 10000; 15 | ); 16 | 17 | digest::bench_update!( 18 | RetailMac::::new(&Default::default()); 19 | retail_mac_des_10 10; 20 | retail_mac_des_100 100; 21 | retail_mac_des_1000 1000; 22 | retail_mac_des_10000 10000; 23 | ); 24 | -------------------------------------------------------------------------------- /retail-mac/src/block_api.rs: -------------------------------------------------------------------------------- 1 | use cipher::{ 2 | BlockCipherDecrypt, BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, 3 | InvalidLength, KeySizeUser, 4 | }; 5 | use core::{fmt, ops::Mul}; 6 | use digest::{ 7 | Key, KeyInit, MacMarker, Output, OutputSizeUser, Reset, 8 | array::{Array, ArraySize}, 9 | block_api::{ 10 | AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, Eager, FixedOutputCore, 11 | UpdateCore, 12 | }, 13 | crypto_common::BlockSizes, 14 | typenum::{Prod, U2}, 15 | }; 16 | 17 | #[cfg(feature = "zeroize")] 18 | use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; 19 | 20 | /// Generic core Retail MAC instance, which operates over blocks. 21 | #[derive(Clone)] 22 | pub struct RetailMacCore 23 | where 24 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone, 25 | { 26 | cipher: C, 27 | cipher_prime: C, 28 | state: Block, 29 | } 30 | 31 | impl BlockSizeUser for RetailMacCore 32 | where 33 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone, 34 | { 35 | type BlockSize = C::BlockSize; 36 | } 37 | 38 | impl OutputSizeUser for RetailMacCore 39 | where 40 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone, 41 | { 42 | type OutputSize = C::BlockSize; 43 | } 44 | 45 | impl KeySizeUser for RetailMacCore 46 | where 47 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone, 48 | ::BlockSize: Mul, 49 | Prod<::BlockSize, U2>: ArraySize, 50 | { 51 | type KeySize = Prod<::BlockSize, U2>; 52 | } 53 | 54 | impl MacMarker for RetailMacCore where C: BlockCipherEncrypt + BlockCipherDecrypt + Clone {} 55 | 56 | impl BufferKindUser for RetailMacCore 57 | where 58 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone, 59 | { 60 | type BufferKind = Eager; 61 | } 62 | 63 | impl KeyInit for RetailMacCore 64 | where 65 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone + KeyInit, 66 | ::BlockSize: Mul, 67 | Prod<::BlockSize, U2>: ArraySize, 68 | { 69 | #[inline(always)] 70 | fn new(key: &Key) -> Self { 71 | Self::new_from_slice(key.as_slice()).unwrap() 72 | } 73 | 74 | #[inline(always)] 75 | fn new_from_slice(key: &[u8]) -> Result { 76 | let cipher = C::new_from_slice(&key[..key.len() / 2])?; 77 | let cipher_prime = C::new_from_slice(&key[key.len() / 2..])?; 78 | Ok(Self { 79 | cipher, 80 | cipher_prime, 81 | state: Block::::default(), 82 | }) 83 | } 84 | } 85 | 86 | impl UpdateCore for RetailMacCore 87 | where 88 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone, 89 | { 90 | #[inline] 91 | fn update_blocks(&mut self, blocks: &[Block]) { 92 | struct Closure<'a, N: BlockSizes> { 93 | state: &'a mut Block, 94 | blocks: &'a [Block], 95 | } 96 | 97 | impl BlockSizeUser for Closure<'_, N> { 98 | type BlockSize = N; 99 | } 100 | 101 | impl BlockCipherEncClosure for Closure<'_, N> { 102 | #[inline(always)] 103 | fn call>(self, backend: &B) { 104 | for block in self.blocks { 105 | xor(self.state, block); 106 | backend.encrypt_block((self.state).into()); 107 | } 108 | } 109 | } 110 | 111 | let Self { cipher, state, .. } = self; 112 | cipher.encrypt_with_backend(Closure { state, blocks }) 113 | } 114 | } 115 | 116 | impl Reset for RetailMacCore 117 | where 118 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone, 119 | { 120 | #[inline(always)] 121 | fn reset(&mut self) { 122 | self.state = Default::default(); 123 | } 124 | } 125 | 126 | impl FixedOutputCore for RetailMacCore 127 | where 128 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone, 129 | { 130 | #[inline] 131 | fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { 132 | let Self { 133 | state, 134 | cipher, 135 | cipher_prime, 136 | } = self; 137 | let pos = buffer.get_pos(); 138 | if pos != 0 { 139 | xor(state, &buffer.pad_with_zeros()); 140 | cipher.encrypt_block(state); 141 | } 142 | cipher_prime.decrypt_block(state); 143 | cipher.encrypt_block(state); 144 | out.copy_from_slice(state); 145 | } 146 | } 147 | 148 | impl AlgorithmName for RetailMacCore 149 | where 150 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone + AlgorithmName, 151 | { 152 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { 153 | f.write_str("RetailMac<")?; 154 | ::write_alg_name(f)?; 155 | f.write_str(">") 156 | } 157 | } 158 | 159 | impl fmt::Debug for RetailMacCore 160 | where 161 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone + AlgorithmName, 162 | { 163 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 164 | f.write_str("RetailMacCore<")?; 165 | ::write_alg_name(f)?; 166 | f.write_str("> { ... }") 167 | } 168 | } 169 | 170 | #[cfg(feature = "zeroize")] 171 | impl Drop for RetailMacCore 172 | where 173 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone, 174 | { 175 | fn drop(&mut self) { 176 | self.state.zeroize(); 177 | } 178 | } 179 | 180 | #[cfg(feature = "zeroize")] 181 | impl ZeroizeOnDrop for RetailMacCore where 182 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone + ZeroizeOnDrop 183 | { 184 | } 185 | 186 | #[inline(always)] 187 | fn xor(buf: &mut Array, data: &Array) { 188 | for i in 0..N::USIZE { 189 | buf[i] ^= data[i]; 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /retail-mac/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![doc = include_str!("../README.md")] 3 | #![doc( 4 | html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg", 5 | html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg" 6 | )] 7 | #![cfg_attr(docsrs, feature(doc_auto_cfg))] 8 | #![forbid(unsafe_code)] 9 | #![warn(missing_docs)] 10 | 11 | pub use digest::{self, Key, KeyInit, Mac}; 12 | 13 | /// Block-level implementation. 14 | pub mod block_api; 15 | 16 | use block_api::RetailMacCore; 17 | use cipher::{AlgorithmName, BlockCipherDecrypt, BlockCipherEncrypt, BlockSizeUser, KeySizeUser}; 18 | use core::{fmt, ops::Mul}; 19 | use digest::{ 20 | InvalidLength, 21 | array::ArraySize, 22 | block_api::CoreProxy, 23 | typenum::{Prod, U2}, 24 | }; 25 | 26 | digest::buffer_fixed!( 27 | /// Generic Retail MAC instance. 28 | pub struct RetailMac(RetailMacCore); 29 | impl: ResetMacTraits; 30 | ); 31 | 32 | impl KeySizeUser for RetailMac 33 | where 34 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone, 35 | ::BlockSize: Mul, 36 | Prod<::BlockSize, U2>: ArraySize, 37 | { 38 | type KeySize = Prod<::BlockSize, U2>; 39 | } 40 | 41 | impl KeyInit for RetailMac 42 | where 43 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone + KeyInit, 44 | ::BlockSize: Mul, 45 | Prod<::BlockSize, U2>: ArraySize, 46 | { 47 | #[inline(always)] 48 | fn new(key: &Key) -> Self { 49 | Self { 50 | core: KeyInit::new(key), 51 | buffer: Default::default(), 52 | } 53 | } 54 | 55 | #[inline(always)] 56 | fn new_from_slice(key: &[u8]) -> Result { 57 | KeyInit::new_from_slice(key).map(|core| Self { 58 | core, 59 | buffer: Default::default(), 60 | }) 61 | } 62 | } 63 | 64 | impl AlgorithmName for RetailMac 65 | where 66 | C: BlockCipherEncrypt + BlockCipherDecrypt + Clone + AlgorithmName, 67 | { 68 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { 69 | ::Core::write_alg_name(f) 70 | } 71 | } 72 | --------------------------------------------------------------------------------