From f91d2fd3dbe7d97794702ff274b1f44a49ca6cd1 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Tue, 28 Jan 2020 15:09:10 +0100 Subject: [PATCH] Initial commit --- .cargo/config | 7 + .github/ISSUE_TEMPLATE.md | 16 + .github/PULL_REQUEST_TEMPLATE.md | 6 + .gitignore | 7 + .gitmodules | 6 + .markdownlint.json | 35 + .travis.yml | 45 + .vscode/extensions.json | 6 + .vscode/settings.json | 7 + Cargo.toml | 35 + LICENSE | 202 + README.md | 116 + deploy.sh | 321 ++ docs/contributing.md | 28 + docs/img/OpenSK.svg | 1 + docs/img/devkit_annotated.jpg | Bin 0 -> 544396 bytes docs/img/dongle_clip.jpg | Bin 0 -> 176028 bytes docs/img/dongle_front.jpg | Bin 0 -> 409378 bytes docs/img/dongle_pads.jpg | Bin 0 -> 130232 bytes docs/install.md | 262 + examples/crypto_bench.rs | 180 + layout.ld | 170 + libraries/cbor/Cargo.toml | 15 + libraries/cbor/src/lib.rs | 29 + libraries/cbor/src/macros.rs | 500 ++ libraries/cbor/src/reader.rs | 811 +++ libraries/cbor/src/values.rs | 268 + libraries/cbor/src/writer.rs | 429 ++ libraries/crypto/Cargo.toml | 29 + libraries/crypto/src/aes256.rs | 541 ++ libraries/crypto/src/cbc.rs | 258 + libraries/crypto/src/ec/exponent256.rs | 346 ++ libraries/crypto/src/ec/gfp256.rs | 260 + libraries/crypto/src/ec/int256.rs | 1181 +++++ libraries/crypto/src/ec/mod.rs | 20 + libraries/crypto/src/ec/montgomery.rs | 1109 ++++ libraries/crypto/src/ec/point.rs | 1034 ++++ libraries/crypto/src/ec/precomputed.rs | 324 ++ libraries/crypto/src/ecdh.rs | 154 + libraries/crypto/src/ecdsa.rs | 643 +++ libraries/crypto/src/hmac.rs | 281 + libraries/crypto/src/lib.rs | 67 + libraries/crypto/src/rng256.rs | 91 + libraries/crypto/src/sha256.rs | 423 ++ libraries/crypto/src/util.rs | 41 + libraries/crypto/tests/aesavs.rs | 103 + libraries/crypto/tests/asn1.rs | 232 + libraries/crypto/tests/data/ECBVarKey256.rsp | 2571 +++++++++ libraries/crypto/tests/data/ECBVarTxt256.rsp | 1291 +++++ .../data/ecdsa_secp256r1_sha256_test.json | 4578 +++++++++++++++++ libraries/crypto/tests/wycheproof.rs | 217 + nrf52840dk_layout.ld | 19 + patches/libtock-rs/01-panic_console.patch | 81 + patches/libtock-rs/02-timer.patch | 72 + patches/libtock-rs/03-public_syscalls.patch | 13 + patches/libtock-rs/04-bigger_heap.patch | 13 + patches/tock/01-persistent-storage.patch | 323 ++ patches/tock/02-usb.patch | 1009 ++++ patches/tock/03-app-memory.patch | 13 + patches/tock/04-rtt.patch | 522 ++ reset.sh | 51 + rules.d/55-opensk.rules | 1 + run_desktop_tests.sh | 72 + rust-toolchain | 1 + rustfmt.toml | 3 + setup.sh | 49 + src/ctap/command.rs | 483 ++ src/ctap/ctap1.rs | 675 +++ src/ctap/data_formats.rs | 1020 ++++ src/ctap/hid/mod.rs | 596 +++ src/ctap/hid/receive.rs | 590 +++ src/ctap/hid/send.rs | 296 ++ src/ctap/mod.rs | 1297 +++++ src/ctap/response.rs | 267 + src/ctap/status_code.rs | 71 + src/ctap/storage.rs | 682 +++ src/ctap/timed_permission.rs | 188 + src/embedded_flash/buffer.rs | 455 ++ src/embedded_flash/mod.rs | 25 + src/embedded_flash/storage.rs | 107 + src/embedded_flash/store/bitfield.rs | 172 + src/embedded_flash/store/format.rs | 514 ++ src/embedded_flash/store/mod.rs | 1028 ++++ src/embedded_flash/syscall.rs | 195 + src/lib.rs | 21 + src/main.rs | 388 ++ src/usb_ctap_hid.rs | 344 ++ third_party/libtock-rs | 1 + third_party/tock | 1 + tools/gen_key_materials.sh | 169 + 90 files changed, 31123 insertions(+) create mode 100644 .cargo/config create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 .markdownlint.json create mode 100644 .travis.yml create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 Cargo.toml create mode 100644 LICENSE create mode 100644 README.md create mode 100755 deploy.sh create mode 100644 docs/contributing.md create mode 100644 docs/img/OpenSK.svg create mode 100644 docs/img/devkit_annotated.jpg create mode 100644 docs/img/dongle_clip.jpg create mode 100644 docs/img/dongle_front.jpg create mode 100644 docs/img/dongle_pads.jpg create mode 100644 docs/install.md create mode 100644 examples/crypto_bench.rs create mode 100644 layout.ld create mode 100644 libraries/cbor/Cargo.toml create mode 100644 libraries/cbor/src/lib.rs create mode 100644 libraries/cbor/src/macros.rs create mode 100644 libraries/cbor/src/reader.rs create mode 100644 libraries/cbor/src/values.rs create mode 100644 libraries/cbor/src/writer.rs create mode 100644 libraries/crypto/Cargo.toml create mode 100644 libraries/crypto/src/aes256.rs create mode 100644 libraries/crypto/src/cbc.rs create mode 100644 libraries/crypto/src/ec/exponent256.rs create mode 100644 libraries/crypto/src/ec/gfp256.rs create mode 100644 libraries/crypto/src/ec/int256.rs create mode 100644 libraries/crypto/src/ec/mod.rs create mode 100644 libraries/crypto/src/ec/montgomery.rs create mode 100644 libraries/crypto/src/ec/point.rs create mode 100644 libraries/crypto/src/ec/precomputed.rs create mode 100644 libraries/crypto/src/ecdh.rs create mode 100644 libraries/crypto/src/ecdsa.rs create mode 100644 libraries/crypto/src/hmac.rs create mode 100644 libraries/crypto/src/lib.rs create mode 100644 libraries/crypto/src/rng256.rs create mode 100644 libraries/crypto/src/sha256.rs create mode 100644 libraries/crypto/src/util.rs create mode 100644 libraries/crypto/tests/aesavs.rs create mode 100644 libraries/crypto/tests/asn1.rs create mode 100644 libraries/crypto/tests/data/ECBVarKey256.rsp create mode 100644 libraries/crypto/tests/data/ECBVarTxt256.rsp create mode 100644 libraries/crypto/tests/data/ecdsa_secp256r1_sha256_test.json create mode 100644 libraries/crypto/tests/wycheproof.rs create mode 100644 nrf52840dk_layout.ld create mode 100644 patches/libtock-rs/01-panic_console.patch create mode 100644 patches/libtock-rs/02-timer.patch create mode 100644 patches/libtock-rs/03-public_syscalls.patch create mode 100644 patches/libtock-rs/04-bigger_heap.patch create mode 100644 patches/tock/01-persistent-storage.patch create mode 100644 patches/tock/02-usb.patch create mode 100644 patches/tock/03-app-memory.patch create mode 100644 patches/tock/04-rtt.patch create mode 100755 reset.sh create mode 100644 rules.d/55-opensk.rules create mode 100755 run_desktop_tests.sh create mode 100644 rust-toolchain create mode 100644 rustfmt.toml create mode 100755 setup.sh create mode 100644 src/ctap/command.rs create mode 100644 src/ctap/ctap1.rs create mode 100644 src/ctap/data_formats.rs create mode 100644 src/ctap/hid/mod.rs create mode 100644 src/ctap/hid/receive.rs create mode 100644 src/ctap/hid/send.rs create mode 100644 src/ctap/mod.rs create mode 100644 src/ctap/response.rs create mode 100644 src/ctap/status_code.rs create mode 100644 src/ctap/storage.rs create mode 100644 src/ctap/timed_permission.rs create mode 100644 src/embedded_flash/buffer.rs create mode 100644 src/embedded_flash/mod.rs create mode 100644 src/embedded_flash/storage.rs create mode 100644 src/embedded_flash/store/bitfield.rs create mode 100644 src/embedded_flash/store/format.rs create mode 100644 src/embedded_flash/store/mod.rs create mode 100644 src/embedded_flash/syscall.rs create mode 100644 src/lib.rs create mode 100644 src/main.rs create mode 100644 src/usb_ctap_hid.rs create mode 160000 third_party/libtock-rs create mode 160000 third_party/tock create mode 100644 tools/gen_key_materials.sh diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 0000000..92823f7 --- /dev/null +++ b/.cargo/config @@ -0,0 +1,7 @@ +# Target configuration for the CTAP2 app on the nRF52840 chip +[target.thumbv7em-none-eabi] +rustflags = [ + "-C", "link-arg=-Tnrf52840dk_layout.ld", + "-C", "relocation-model=static", + "-D", "warnings", +] diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..3c52212 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,16 @@ +## Expected Behavior + + +## Actual Behavior + + +## Steps to Reproduce the Problem + +1. +1. +1. + +## Specifications + +- Version: +- Platform: \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..0787bd9 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,6 @@ +Fixes # + +> It's a good idea to open an issue first for discussion. + +- [ ] Tests pass +- [ ] Appropriate changes to README are included in PR \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..625fa19 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +target/ +Cargo.lock + +# Prevent people from commiting sensitive files. +crypto_data/ +src/ctap/key_material.rs + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b70a516 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "third_party/libtock-rs"] + path = third_party/libtock-rs + url = https://github.com/tock/libtock-rs +[submodule "third_party/tock"] + path = third_party/tock + url = https://github.com/tock/tock diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000..e1d84fb --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,35 @@ +{ + "default": true, + "heading-style": { + "style": "atx" + }, + "no-trailing-spaces": { + "br_spaces": 0, + "strict": true + }, + "ul-indent": { + "indent": 4 + }, + "line-length": { + "line_length": 80, + "code_blocks": false + }, + "list-marker-space": { + "ol_single": 2, + "ol_multi": 2, + "ul_single": 3, + "ul_multi": 3 + }, + "no-inline-html": { + "allowed_elements": [ + "img" + ] + }, + "fenced-code-language": true, + "code-block-style": { + "style": "fenced" + }, + "code-fence-style": { + "style": "backtick" + } +} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..3cb7c35 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,45 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +language: rust +rust: + - nightly-2020-01-16 + +os: + - linux + +dist: "trusty" # we need python3-pip + +addons: + apt: + packages: + - "python3" + - "python3-pip" + +cache: + - rust + - cargo + +before-install: + - openssl version + +install: + - rustup target add thumbv7em-none-eabi + - rustup component add rustfmt + - cargo install cargo-audit + +script: + - ./setup.sh + - cargo audit + - ./run_desktop_tests.sh diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..755027f --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "davidanson.vscode-markdownlint", + "rust-lang.rust" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f502ab1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "editor.formatOnSave": true, + "rust-client.channel": "nightly", + // The toolchain is updated from time to time so let's make sure that RLS is updated too + "rust-client.updateOnStartup": true, + "rust.clippy_preference": "on" +} diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..624c37a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "ctap2" +version = "0.1.0" +authors = [ + "Fabian Kaczmarczyck ", + "Guillaume Endignoux ", + "Jean-Michel Picod ", +] +license = "Apache-2.0" +edition = "2018" + +[dependencies] +libtock = { path = "third_party/libtock-rs" } +cbor = { path = "libraries/cbor" } +crypto = { path = "libraries/crypto" } +byteorder = { version = "1", default-features = false } +arrayref = "0.3.6" +subtle = { version = "2.2", default-features = false, features = ["nightly"] } + +[features] +std = ["cbor/std", "crypto/std", "crypto/derive_debug"] +debug_ctap = ["crypto/derive_debug"] +with_ctap1 = ["crypto/with_ctap1"] +panic_console = ["libtock/panic_console"] + +[dev-dependencies] +elf2tab = "0.4.0" + +[profile.dev] +panic = "abort" +lto = true # Link Time Optimization usually reduces size of binaries and static libraries + +[profile.release] +panic = "abort" +lto = true # Link Time Optimization usually reduces size of binaries and static libraries diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ade3a63 --- /dev/null +++ b/README.md @@ -0,0 +1,116 @@ +# OpenSK logo + +[![Build Status](https://travis-ci.org/google/OpenSK.svg?branch=master)](https://travis-ci.org/google/OpenSK) + +## OpenSK + +This repository contains a Rust implementation of a +[FIDO2](https://fidoalliance.org/fido2/) authenticator. + +We developed this as a [Tock OS](https://tockos.org) application and it has been +successfully tested on the following boards: + +* [Nordic nRF52840-DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) +* [Nordic nRF52840-dongle](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle) + +## Disclaimer + +This project is proof-of-concept and a research platform. It's still under +development and as such comes with a few limitations: + +### FIDO2 + +Although we tested and implemented our firmware based on the published +[CTAP2.0 specifications](https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html), +our implementation was not reviewed nor officially tested and doesn't claim to +be FIDO Certified. + +### Cryptography + +We're currently still in the process on making the +[ARM® CryptoCell-310](https://developer.arm.com/ip-products/security-ip/cryptocell-300-family) +embedded in the +[Nordic nRF52840 chip](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf52840%2Fcryptocell.html) +work to get hardware-accelerated cryptography. In the meantime we implemented +the required cryptography algorithms (ECDSA, ECC secp256r1, HMAC-SHA256 and +AES256) in Rust as a placeholder. Those implementations are research-quality +code and haven't been reviewed. They don't provide constant-time guarantees and +are not designed to be resistant against side-channel attacks. + +## Installation + +For a more detailed guide, please refer to our +[installation guide](docs/install.md). + +1. If you just cloned this repository, run the following script (**Note**: you + only need to do this once): + + ```shell + ./setup.sh + ``` + +2. If you have a Nordic development board that doesn't already have Tock OS + installed, you can install both TockOS and the OpenSK application by running + the following command, depending on the board you have: + + ```shell + # Nordic nRF52840-DK board + board=nrf52840dk ./deploy.sh os app + # Nordic nRF52840-Dongle + board=nrf52840_dongle ./deploy.sh os app + ``` + +3. If Tock OS is already installed and you want to install/update the OpenSK + application on your board (**Warning**: it will erase the locally stored + credentials), run: + + ```shell + ./deploy.sh app + ``` + +4. On Linux, you may want to avoid the need for `root` privileges to interact + with the key. For that purpose we provide a udev rule file that can be + installed with the following command: + + ```shell + sudo cp rules.d/55-opensk.rules /etc/udev/rules.d/ && + sudo udevadm control --reload + ``` + +### Customization + +If you build your own security key, depending on the hardware you use, there are +a few things you can personalize: + +1. If you have multiple buttons, choose the buttons responsible for user + presence in main.rs. +2. Decide whether you want to use batch attestation. There is a boolean flag in + `ctap/mod.rs`. It is mandatory for U2F, and you can create your own + self-signed certificate. The flag is used for FIDO2 and has some privacy + implications. Please check + [WebAuthn](https://www.w3.org/TR/webauthn/#attestation) for more + information. +3. Decide whether you want to use signature counters. Currently, only global + signature counters are implemented, as they are the default option for U2F. + The flag in `ctap/mod.rs` only turns them off for FIDO2. The most privacy + preserving solution is individual or no signature counters. Again, please + check [WebAuthn](https://www.w3.org/TR/webauthn/#signature-counter) for + documentation. +4. Depending on your available flash storage, choose an appropriate maximum + number of supported residential keys and number of pages in + `ctap/storage.rs`. + +### 3D printed enclosure + +To protect and carry your key, we partnered with a professional designer and we +are providing a custom enclosure that can be printed on both professional 3D +printers and hobbyist models. + +All the required files can be downloaded from +[Thingiverse](https://www.thingiverse.com/thing:4132768) including the STEP +file, allowing you to easily make the modifications you need to further +customize it. + +## Contributing + +See [Contributing.md](docs/contributing.md). diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..974888d --- /dev/null +++ b/deploy.sh @@ -0,0 +1,321 @@ +#!/usr/bin/env bash +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +set -e + +if [ "x$VERBOSE" != "x" ] +then + set -x +fi + +info_text="$(tput bold)info:$(tput sgr0)" +error_text="$(tput bold)error:$(tput sgr0)" + +tab_folder="target/tab" +# elf2tab requires a file named "cortex-m4", so this path is used for all +# target applications. +elf_file_name="${tab_folder}/cortex-m4.elf" + +# elf2tab 0.4.0 and below uses "-n" flag but 0.5.0-dev changes that "-p" or +# "--package-name" +# We try to be compatible with both versions. +elf2tab_package_param="-n" +if which elf2tab > /dev/null 2>&1 +then + if [ "$(elf2tab --version | cut -d' ' -f2)" = "0.5.0-dev" ] + then + # Short parameter is "-p" but long parameter names should be prefered + # when they are used in scripts. + elf2tab_package_param="--package-name" + fi +else + echo "" + echo "Command elf2tab not found. Have you run the setup.sh script?" + exit 2 +fi + +# We need to specify the board explicitly to be able to flash after 0x80000. +tockloader_flags=( + --jlink + --board="${board:-nrf52840}" + --arch=cortex-m4 + --jlink-device=nrf52840_xxaa + --page-size=4096 +) + +declare -A supported_boards +supported_boards["nrf52840dk"]="Y" +supported_boards["nrf52840_dongle"]="Y" + +declare -A enabled_features=( [with_ctap1]=Y ) + +print_usage () { + cat < + +Example: + In order to install TockOS and a debug version of OpenSK on a Nordic nRF52840-DK + board, you need to run the following command: + board=nrf52840dk $0 --panic-console os app_debug + +Actions: + os + Compiles and installs Tock OS on the selected board. + The target board must be indicated by setting the environment + variable \$board + + app + Compiles and installs OpenSK application. + + app_debug + Compiles and installs OpenSK application in debug mode (i.e. more debug messages + will be sent over the console port such as hexdumps of packets) + + crypto_bench + Compiles and installs the crypto_bench example that tests the performance + of the cryptographic algorithms on the board. + +Options: + --dont-clear-apps + When installing an application, previously installed applications won't + be erased from the board. + + --no-u2f + Compiles OpenSK application without backward compatible support for + U2F/CTAP1 protocol. + + + --regen-keys + Forces the generation of src/ctap/key_materials.rs file. + This won't force re-generate OpenSSL files under crypto_data/ directory. + If the OpenSSL files needs to be re-generated, simply delete them (or + the whole directory). + + --panic-console + In case of application panic, the console will be used to output messages + before starting blinking the LEDs on the board. + +EOH +} + +display_supported_boards () { + echo "$info_text Currently supported boards are:" + for b in ${!supported_boards[@]} + do + if [ -d "third_party/tock/boards/nordic/$b" -a \ + -e "third_party/tock/boards/nordic/$b/Cargo.toml" ] + then + echo " - $b" + fi + done +} + +# Import generate_crypto_materials function +source tools/gen_key_materials.sh + +build_app_padding () { + # On nRF52840, the MMU can have 8 sub-regions and the flash size is 0x1000000. + # By default, applications are flashed at 0x30000 which means the maximum size + # for an application is 0x40000 (an application of size 0x80000 would need 16 + # sub-regions of size 0x10000; sub-regions need to be aligned on their size). + # This padding permits to have the application start at 0x40000 and increase + # the maximum application size to 0x80000 (with 4 sub-regions of size + # 0x40000). + ( + # Version: 2 + echo -n "0200" + # Header size: 0x10 + echo -n "1000" + # Total size: 0x10000 + echo -n "00000100" + # Flags: 0 + echo -n "00000000" + # Checksum + echo -n "02001100" + ) | xxd -p -r > "${tab_folder}/padding.bin" +} + +build_app () { + # Flatten the array + # This is equivalent to the following python snippet: ' '.join(arr).replace(' ', ',') + local feature_list=$(IFS=$'\n'; echo "$@") + if [ "X${feature_list}" != "X" ] + then + feature_list="${feature_list// /,}" + fi + + cargo build \ + --release \ + --target=thumbv7em-none-eabi \ + --features="${feature_list}" + + mkdir -p "target/tab" + cp "target/thumbv7em-none-eabi/release/ctap2" "$elf_file_name" + + elf2tab \ + "${elf2tab_package_param}" "ctap2" \ + -o "${tab_folder}/ctap2.tab" \ + "$elf_file_name" \ + --stack 16384 \ + --app-heap 90000 \ + --kernel-heap 1024 \ + --protected-region-size=64 +} + +build_crypto_bench () { + cargo build \ + --release \ + --target=thumbv7em-none-eabi \ + --example crypto_bench + + mkdir -p "target/tab" + cp "target/thumbv7em-none-eabi/release/examples/crypto_bench" "$elf_file_name" + + elf2tab \ + "${elf2tab_package_param}" "crypto_bench" \ + -o "${tab_folder}/crypto_bench.tab" \ + "$elf_file_name" \ + --stack 16384 \ + --app-heap 90000 \ + --kernel-heap 1024 \ + --protected-region-size=64 +} + +deploy_tock () { + if [ "x$board" = "x" ]; + then + echo "$error_text You must set the board in order to install Tock OS (example: \`board=nrf52840dk $0 os\`)" + display_supported_boards + return 1 + fi + if [ "${supported_boards[$board]+x}" = "x" -a -d "third_party/tock/boards/nordic/$board" ] + then + make -C third_party/tock/boards/nordic/$board flash + else + echo "$error_text The board '$board' doesn't seem to be supported" + display_supported_boards + return 1 + fi +} + +clear_apps=Y +install_os=N +install_app=none + +force_generate=N +has_errors=N + +if [ "$#" -eq "0" ] +then + print_usage + exit 1 +fi + +while [ "$#" -ge "1" ] +do + case "$1" in + --dont-clear-apps) + clear_apps=N + ;; + + --no-u2f) + unset enabled_features["with_ctap1"] + ;; + + --regen-keys) + force_generate=Y + ;; + + --panic-console) + enabled_features["panic_console"]="Y" + ;; + + os) + install_os=Y + ;; + + app) + install_app=ctap2 + ;; + + app_debug) + install_app=ctap2 + enabled_features["debug_ctap"]="Y" + ;; + + crypto_bench) + install_app=crypto_bench + ;; + + *) + echo "$error_text Unsupported option: '"$1"'" + has_errors=Y + ;; + esac + shift 1 +done + +if [ "$has_errors" = "Y" ] +then + echo "" + print_usage + exit 1 +fi + +# Test if we need to update Rust toolchain +# rustc --version outputs a version line such as: +# rustc 1.40.0-nightly (0e8a4b441 2019-10-16) +# The sed regexp turns it into: +# nightly-2019-10-16 +current_toolchain=$(rustc --version | sed -e 's/^rustc [0-9]*\.[0-9]*\.[0-9]*-\(nightly\) ([0-9a-f]* \([0-9]*-[0-9]*-[0-9]*\))$/\1-\2/') +target_toolchain=$(head -n 1 rust-toolchain) + +if [ "x${current_toolchain}" != "x${target_toolchain}" ] +then + rustup install "${target_toolchain}" + rustup target add thumbv7em-none-eabi +fi + +if [ "$install_os" = "Y" ] +then + deploy_tock +fi + +# Don't try to uninstall app if we don't plan to install after. +if [ "$install_app" != "none" -a "$clear_apps" = "Y" ] +then + # Uninstall can fail if there's no app already installed. + # This is fine and we don't want that to stop the script + tockloader uninstall "${tockloader_flags[@]}" -a 0x40000 || true +fi + +if [ "$install_app" = "ctap2" ] +then + generate_crypto_materials "${force_generate}" + build_app "${!enabled_features[@]}" +fi + +if [ "$install_app" = "crypto_bench" ] +then + build_crypto_bench +fi + +if [ "$install_app" != "none" ] +then + build_app_padding + tockloader flash "${tockloader_flags[@]}" -a 0x30000 "${tab_folder}/padding.bin" + tockloader install "${tockloader_flags[@]}" -a 0x40000 "${tab_folder}/${install_app}.tab" +fi diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 0000000..654a071 --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,28 @@ +# How to Contribute + +We'd love to accept your patches and contributions to this project. There are +just a few small guidelines you need to follow. + +## Contributor License Agreement + +Contributions to this project must be accompanied by a Contributor License +Agreement. You (or your employer) retain the copyright to your contribution; +this simply gives us permission to use and redistribute your contributions as +part of the project. Head over to to see +your current agreements on file or to sign a new one. + +You generally only need to submit a CLA once, so if you've already submitted one +(even if it was for a different project), you probably don't need to do it +again. + +## Code reviews + +All submissions, including submissions by project members, require review. We +use GitHub pull requests for this purpose. Consult +[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more +information on using pull requests. + +## Community Guidelines + +This project follows [Google's Open Source Community +Guidelines](https://opensource.google/conduct/). diff --git a/docs/img/OpenSK.svg b/docs/img/OpenSK.svg new file mode 100644 index 0000000..df1692d --- /dev/null +++ b/docs/img/OpenSK.svg @@ -0,0 +1 @@ +Mono \ No newline at end of file diff --git a/docs/img/devkit_annotated.jpg b/docs/img/devkit_annotated.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1fff7d32a7ed967842848ac3475bdb45ab22ca9b GIT binary patch literal 544396 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 z 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%0D@n!eMyZPqA*@fnA#~o;Y@! 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�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�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 *CQ#bu(l-OMIZ9@*z&lPH)%d5nFxXdH(DHUJp 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%0Dqh;kh{r7L5Zfjy-a(VLR%guj$iY!ivYa6?k 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

T-+V$rc>)O7B@YO_<$ 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 literal 0 HcmV?d00001 diff --git a/docs/img/dongle_clip.jpg b/docs/img/dongle_clip.jpg new file mode 100644 index 0000000000000000000000000000000000000000..636e1a5dc9c915f2f8cac179e592ae5064c68626 GIT binary patch literal 176028 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
xZj`;|xO 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

lETdj_Vt-=_w^ono%Edha@H+QpMVQ)$2Ff> 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�p57_R7xJ*Y-TF7~gm+eejd9zIw~@6AUw;4G z)h*@_S2b1*jZ2+Qu|J!e$h&Fr$LY#@-EJO|4*k%WcuwGKdrDI0GU;Gd z&#N{jW{+R|TAZr2E>Ju7tT(slpGcMYrZJmaL!TEW-P67AC&9qrJ z58PH)uzr-a*6zyU*5w?E>Ua5Pme0|%x|VXkcW-!Sq>DB~)(Np4Op?odZMbfnsZL6Y zcz5OUS;4xbTeX`y)o(99XKt-^!@GCYgYSn;Jy*5`d<=Z6B3pUven{G!>1mOVJGTnu zR37HtB>QH8bMBoiXZt!Ufire0K*s@fEk(1eu>B61G@0cV!?IaIQojpDF*~Ekrvu}WZ;>q#aU_30^K8=&XtKZTyokdqJBkjTgbYLRbKlY02aJ-v(iqgI^qHEWw2;QKaDU{}kN zLj^XErr0Ef`TDQ6Roph=kbxS%24|0r0>@#AWS+zZ1vOm;e%%Eeh8bI;bf0Xu*di$P zlYc_Thwh^0Iq72Eu6yRx7d#gI6@4gW*Zo<09-P`YHR4d}{gw?ME(u-!lU(#gb-6C% za^-?Is>>6M9-b1``EW_>a&yG3nXcAK)9sS>{&dyz{eEIs5@l?&?$6OQGD^48#y*qk&3Rlpb)_V0!-{1m?0zo`WO`b+V&YOmwb}D~iaYJy75NMKV0uX1*((tgzM3?8B*-+gBXf zYkBgSvV*{Z-=RDlPp1I^*nwa*6;VJ(qrQAignj9K<=o8GGpA;Hp6A+8-Z6FYnPr(Otl1|%esO8lU1{m)Yxv=2nQXmG7`wTsC=1=!)}Pvu{L)WvN6+M;ujZSswcF zyO&T6XN#GXL++A?9<7_EPlzgsRa4(q>NzLUJ4<196JzhpiA7PfBuhkY%q`uLE7J9B zrJu=#U7Jp1uhD8ZGszAAVCc8ZT+O^oyx{Xg7M-JMGt`${VX7{Bxbj`6?!1}8yz5IA zrZT_nJz#b0QlMIzmg^ITNBS zf(MCnr>|J}#bR1-qrh3yaEXP>CY&-@rsKmS6)XvpU(Mgl*bHpy#9L#5Al|0~7alm1Ji2}>deXh%%pOsq?#n^k} zDQEsJhHXhqXE(QMOgYq&Afupg?+}y00h@sio=ZLF1 z=q@N>dC0YOp=2gwmcXVE<5m?3-H$DcC$x0<*$GT=+nC7Uy1(SI#^wJEOy*6qj|nJS z9G1vk6Q$!qeoL+W9ue^VCg;USp@`7F;%>j$Q3gPNG_M&acG5y z5|hU@jy-wjH4e^UImXDh?8PCYeF1_Kd=fS^H6AnI;851MJNuZlqff%V4FPOTOqK^e zH1s^?5s8n`=)J=t!MR~$%VL{_$~KSg1>gPM_^I4=Kl9-aC;l_6c`7E@W-wz*bW38B z(gg>>j4gr{nuZP85=Bkju8S_Vak;R#@d*g!W*n5LJi1mQnI}QKL02MSiK9z`vc=)K zM-qDs6Au}DFbI_1?Z$C%=%t{noVNeuIt6RLB;ffDBXfazCw4U?lFUp-EQ^m`3Lq-*06It|DS>3!cYHq*FKdW-SqeLE`y_cX3bFgm|>W& z`)5u>-?i_M{h6{UrIJQLV>$Tl)zb}4DcTW7t z<&*pWvHw59kSM^w#K^?L!pzFd&c?yP!^F+V#LObdz$&CDtYqlOCK9M@lvvm(>NHV6 z#W*Nw;YKm%qDcoYvMZ>Xm^MB9pk@|aJbBTjj|MKTA;~Ev%~LmRKI9M(nmVO)@!^)% zC0j24zs118$jHEE&-9<+)8v14_kVELKYagB;Xi|L{vWgd3_o=LGw2`w&%pfg&*D!p z|9tnWpO-DD{~-3C;o$rK3{TkqGaSzS&(N~Z%wqdL>AW5HKfV8HmH*T1&%FJQ^KZ-Z z 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

*rj@kDhp8!E(!P!&_A^bop{{GkN#V3tci~~ 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%0ABU1__@&obX{ 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⋘FJ>(JmbN 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 baH^|miXu<**MGaRW*khi7nQ$W|NkZcUy%?V literal 0 HcmV?d00001 diff --git a/docs/img/dongle_pads.jpg b/docs/img/dongle_pads.jpg new file mode 100644 index 0000000000000000000000000000000000000000..32348a78767552b05b2acd41cf14d3ba4caa3a18 GIT binary patch literal 130232 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 z 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 PY`fhW_MMII`F|4t9(QO> literal 0 HcmV?d00001 diff --git a/docs/install.md b/docs/install.md new file mode 100644 index 0000000..502cf02 --- /dev/null +++ b/docs/install.md @@ -0,0 +1,262 @@ +OpenSK logo + +# Installation guide + +This document describes in details how to turn a Nordic nRF52840 board into a +working FIDO2 security key. + +## Pre-requisite + +### Hardware + +You will need one the following supported boards: + +* [Nordic nRF52840-DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) + development kit. This board is more convenient for development and debug + scenarios as the JTAG probe is already on the board. +* [Nordic nRF52840 Dongle](https://www.nordicsemi.com/Software-and-tools/Development-Kits/nRF52840-Dongle) + to have a more practical form factor. + +In the case of the Nordic USB dongle, you will also need the following extra +hardware: + +* a [Segger J-Link](https://www.segger.com/products/debug-probes/j-link/) JTAG + probe. +* a + [TC2050 Tag-Connect programming cable](http://www.tag-connect.com/TC2050-IDC-NL-050-ALL). +* a [Tag-Connect TC2050 ARM2010](http://www.tag-connect.com/TC2050-ARM2010) + adaptor +* optionally a + [Tag-Connect TC2050 retainer clip](http://www.tag-connect.com/TC2050-CLIP) + to keep the spring loaded connector pressed to the PCB. + +Although [OpenOCD](http://openocd.org/) should be supported we encountered some +issues while trying to flash a firmware with it. Therefore we suggest at the +moment to use a +[Segger J-Link](https://www.segger.com/products/debug-probes/j-link/) probe +instead. + +This guide **does not** cover how to setup the JTAG probe on your system. + +### Software + +In order to compile and flash a working OpenSK firmware, you will need the +following: + +* a working [Rust](https://rustup.rs/) toolchain installed on your system +* python3 and pip +* the OpenSSL command line tool + +The scripts provided in this project have been tested under Linux and OS X. We +haven't tested them on Windows and other platforms. + +## Compiling the firmware + +### Initial setup + +If you just cloned this repository, you need to run the following script +(_output may differ_): + +```shell +$ ./setup.sh +[-] Applying patch "01-persistent-storage.patch"... DONE. +[-] Applying patch "02-usb.patch"... DONE. +[-] Applying patch "03-app-memory.patch"... DONE. +[-] Applying patch "04-rtt.patch"... DONE. +[-] Applying patch "01-panic_console.patch"... DONE. +[-] Applying patch "02-timer.patch"... DONE. +[-] Applying patch "03-public_syscalls.patch"... DONE. +[-] Applying patch "04-bigger_heap.patch"... DONE. +Signature ok +subject=CN = Google OpenSK CA +Getting Private key +Signature ok +subject=CN = Google OpenSK Hacker Edition +Getting CA Private Key +info: syncing channel updates for 'nightly-2020-01-16-x86_64-unknown-linux-gnu' + + nightly-2020-01-16-x86_64-unknown-linux-gnu unchanged - rustc 1.42.0-nightly (3291ae339 2020-01-15) + +Requirement already up-to-date: tockloader in /usr/lib/python3/dist-packages/tockloader-1.4.0.dev0-py3.7.egg (1.4.0.dev0) +Requirement already satisfied, skipping upgrade: argcomplete>=1.8.2 in /usr/lib/python3/dist-packages (from tockloader) (1.10.0) +Requirement already satisfied, skipping upgrade: colorama>=0.3.7 in /usr/lib/python3/dist-packages (from tockloader) (0.3.7) +Requirement already satisfied, skipping upgrade: crcmod>=1.7 in /usr/lib/python3/dist-packages (from tockloader) (1.7) +Requirement already satisfied, skipping upgrade: pyserial>=3.0.1 in /usr/lib/python3/dist-packages (from tockloader) (3.4) +Requirement already satisfied, skipping upgrade: pytoml>=0.1.11 in /usr/lib/python3/dist-packages (from tockloader) (0.1.21) +info: component 'rust-std' for target 'thumbv7em-none-eabi' is up to date + Updating crates.io index + Ignored package `elf2tab v0.4.0` is already installed, use --force to override +``` + +The script performs the following steps: + +1. Make sure that the git submodules are checked out + +1. Apply our patches that haven't yet been merged upstream to both + [Tock](https://github.com/tock/tock) and + [libtock-rs](https://github.com/tock/libtock-rs) + +1. Generate a self-signed certificate authority as well as a private key and a + corresponding certificate for your OpenSK key signed by this CA. You will be + able to replace them with your own certificate and private key. + +1. Ensure that your Rust toolchain is using the same version that we tested + OpenSK with. + +1. Install [tockloader](https://github.com/tock/tockloader). + +1. Ensure that the Rust toolchain can compile code for ARM devices. + +### Replacing the certificates + +All the generated certificates and private keys are stored in the directory +`crypto_data/`. + +This is the expected content after running our `setup.sh` script: + +File | Purpose +----------------- | -------------------------------------------------------- +`opensk_ca.csr` | Certificate sign request for the Root CA +`opensk_ca.key` | ECC secp256r1 private key used for the Root CA +`opensk_ca.pem` | PEM encoded certificate of the Root CA +`opensk_ca.srl` | File generated by OpenSSL +`opensk_cert.csr` | Certificate sign request for the attestation certificate +`opensk_cert.pem` | PEM encoded certificate used for the authenticator +`opensk.key` | ECC secp256r1 private key used for the autenticator + +If you want to use your own attestation certificate and private key, simply +replace `opensk_cert.pem` and `opensk.key` files. + +Our build script is responsible for converting `opensk_cert.pem` and +`opensk.key` files into the following Rust file: `src/ctap/key_material.rs`. + +### Flashing a firmware + +#### Nordic nRF52840-DK board + +![Nordic development kit](img/devkit_annotated.jpg) + +1. Connect a micro USB cable to the JTAG USB port. + +1. Run our script for compiling/flashing your device (_output may differ_): + + ```shell + $ board=nrf52840dk ./deploy.sh app os + make: Entering directory './third_party/tock/boards/nordic/nrf52840dk' + Compiling kernel v0.1.0 (./third_party/tock/kernel) + Compiling cortexm v0.1.0 (./third_party/tock/arch/cortex-m) + Compiling nrf5x v0.1.0 (./third_party/tock/chips/nrf5x) + Compiling capsules v0.1.0 (./third_party/tock/capsules) + Compiling cortexm4 v0.1.0 (./third_party/tock/arch/cortex-m4) + Compiling nrf52 v0.1.0 (./third_party/tock/chips/nrf52) + Compiling nrf52840 v0.1.0 (./third_party/tock/chips/nrf52840) + Compiling components v0.1.0 (./third_party/tock/boards/components) + Compiling nrf52dk_base v0.1.0 (./third_party/tock/boards/nordic/nrf52dk_base) + Compiling nrf52840dk v0.1.0 (./third_party/tock/boards/nordic/nrf52840dk) + Finished release [optimized + debuginfo] target(s) in 11.28s + text data bss dec hex filename + 114688 1760 260384 376832 5c000 target/thumbv7em-none-eabi/release/nrf52840dk + tockloader flash --address 0x00000 --jlink --board nrf52dk target/thumbv7em-none-eabi/release/nrf52840dk.bin + [STATUS ] Flashing binar(y|ies) to board... + [INFO ] Using known arch and jtag-device for known board nrf52dk + [INFO ] Finished in 0.324 seconds + + make: Leaving directory './third_party/tock/boards/nordic/nrf52840dk' + [STATUS ] Preparing to uninstall apps... + [INFO ] Using known arch and jtag-device for known board nrf52dk + [ERROR ] No apps are installed on the board + + Compiling libtock v0.1.0 (./third_party/libtock-rs) + Compiling crypto v0.1.0 (./libraries/crypto) + Compiling ctap2 v0.1.0 (.) + Finished release [optimized] target(s) in 7.60s + [STATUS ] Flashing binar(y|ies) to board... + [INFO ] Using known arch and jtag-device for known board nrf52dk + [INFO ] Finished in 0.305 seconds + + [STATUS ] Installing app on the board... + [INFO ] Using known arch and jtag-device for known board nrf52dk + [INFO ] Finished in 0.975 seconds + ``` + +1. Connect a micro USB cable to the device USB port. + +**Note**: Due to current limitations of our implementation and Tock, you may +have to press the `BOOT/RESET` button, located next to the device USB port on +the board in order to see your OpenSK device on your system. + +#### Nordic nRF52840 Dongle + +![Nordic dongle](img/dongle_front.jpg) + +1. The JTAG probe used for programming won't provide power to the board. + Therefore you will need to use a USB-A extension cable to power the dongle + through its USB port. + +1. Connect the TC2050 cable to the pads below the PCB: + + ![Nordic dongle pads](img/dongle_pads.jpg) + +1. You can use the retainer clip if you have one to avoid maintaining pressure + between the board and the cable: + + ![Nordic dongle retainer clip](img/dongle_clip.jpg) + +1. Run our script for compiling/flashing your device (_output may differ_): + + ```shell + $ board=nrf52840_dongle ./deploy.sh app os + make: Entering directory './third_party/tock/boards/nordic/nrf52840_dongle' + Compiling kernel v0.1.0 (./third_party/tock/kernel) + Compiling cortexm v0.1.0 (./third_party/tock/arch/cortex-m) + Compiling nrf5x v0.1.0 (./third_party/tock/chips/nrf5x) + Compiling capsules v0.1.0 (./third_party/tock/capsules) + Compiling cortexm4 v0.1.0 (./third_party/tock/arch/cortex-m4) + Compiling nrf52 v0.1.0 (./third_party/tock/chips/nrf52) + Compiling nrf52840 v0.1.0 (./third_party/tock/chips/nrf52840) + Compiling components v0.1.0 (./third_party/tock/boards/components) + Compiling nrf52dk_base v0.1.0 (./third_party/tock/boards/nordic/nrf52dk_base) + Compiling nrf52840_dongle v0.1.0 (./third_party/tock/boards/nordic/nrf52840_dongle) + Finished release [optimized + debuginfo] target(s) in 10.47s + text data bss dec hex filename + 110592 1688 252264 364544 59000 target/thumbv7em-none-eabi/release/nrf52840_dongle + tockloader flash --address 0x00000 --jlink --board nrf52dk target/thumbv7em-none-eabi/release/nrf52840_dongle.bin + [STATUS ] Flashing binar(y|ies) to board... + [INFO ] Using known arch and jtag-device for known board nrf52dk + [INFO ] Finished in 0.296 seconds + + make: Leaving directory './third_party/tock/boards/nordic/nrf52840_dongle' + [STATUS ] Preparing to uninstall apps... + [INFO ] Using known arch and jtag-device for known board nrf52dk + [ERROR ] No apps are installed on the board + + Compiling libtock v0.1.0 (./third_party/libtock-rs) + Compiling crypto v0.1.0 (./libraries/crypto) + Compiling ctap2 v0.1.0 (.) + Finished release [optimized] target(s) in 7.60s + [STATUS ] Flashing binar(y|ies) to board... + [INFO ] Using known arch and jtag-device for known board nrf52dk + [INFO ] Finished in 0.317 seconds + + [STATUS ] Installing app on the board... + [INFO ] Using known arch and jtag-device for known board nrf52dk + [INFO ] Finished in 0.902 seconds + ``` + +1. Remove the programming cable and the USB-A extension cable. + +### Installing the udev rule (Linux only) + +By default on Linux, a USB device will require root privilege in order interact +with it. As it is not recommended to run your web browser with such a high +privileged account, we made a `udev` rule file to allow regular users to +interact with OpenSK authenticators. + +To install it, you need to execute the following commands: + +```shell +sudo cp rules.d/55-opensk.rules /etc/udev/rules.d/ +sudo udevadm control --reload +``` + +Then, you will need to unplug and replug the key for the rule to trigger. diff --git a/examples/crypto_bench.rs b/examples/crypto_bench.rs new file mode 100644 index 0000000..95a82d2 --- /dev/null +++ b/examples/crypto_bench.rs @@ -0,0 +1,180 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![no_std] + +#[macro_use] +extern crate alloc; +extern crate crypto; +extern crate libtock; + +use alloc::vec::Vec; +use core::fmt::Write; +use crypto::{ + aes256, cbc, ecdsa, rng256, sha256, Decrypt16BytesBlock, Encrypt16BytesBlock, Hash256, +}; +use libtock::console::Console; +use libtock::timer; +use libtock::timer::Timer; +use libtock::timer::Timestamp; + +fn main() { + let mut console = Console::new(); + // Setup the timer with a dummy callback (we only care about reading the current time, but the + // API forces us to set an alarm callback too). + let mut with_callback = timer::with_callback(|_, _| {}); + let timer = with_callback.init().unwrap(); + + let mut rng = rng256::TockRng256 {}; + + writeln!(console, "****************************************").unwrap(); + writeln!( + console, + "Clock frequency: {} Hz", + timer.clock_frequency().hz() + ) + .unwrap(); + + // AES + bench(&mut console, &timer, "aes256::EncryptionKey::new", || { + aes256::EncryptionKey::new(&[0; 32]); + }); + let ek = aes256::EncryptionKey::new(&[0; 32]); + bench(&mut console, &timer, "aes256::DecryptionKey::new", || { + aes256::DecryptionKey::new(&ek); + }); + let dk = aes256::DecryptionKey::new(&ek); + + bench( + &mut console, + &timer, + "aes256::EncryptionKey::encrypt_block", + || { + ek.encrypt_block(&mut [0; 16]); + }, + ); + bench( + &mut console, + &timer, + "aes256::DecryptionKey::decrypt_block", + || { + dk.decrypt_block(&mut [0; 16]); + }, + ); + + // CBC + let mut blocks = Vec::new(); + for i in 0..8 { + blocks.resize(1 << i, [0; 16]); + bench( + &mut console, + &timer, + &format!("cbc::cbc_encrypt({} bytes)", blocks.len() * 16), + || { + cbc::cbc_encrypt(&ek, [0; 16], &mut blocks); + }, + ); + } + drop(blocks); + + let mut blocks = Vec::new(); + for i in 0..8 { + blocks.resize(1 << i, [0; 16]); + bench( + &mut console, + &timer, + &format!("cbc::cbc_decrypt({} bytes)", blocks.len() * 16), + || { + cbc::cbc_decrypt(&dk, [0; 16], &mut blocks); + }, + ); + } + drop(blocks); + + // SHA-256 + let mut contents = Vec::new(); + for i in 0..8 { + contents.resize(16 << i, 0); + bench( + &mut console, + &timer, + &format!("sha256::Sha256::update({} bytes)", contents.len()), + || { + let mut sha = sha256::Sha256::new(); + sha.update(&contents); + sha.finalize(); + }, + ); + } + drop(contents); + + // ECDSA + bench(&mut console, &timer, "ecdsa::SecKey::gensk", || { + ecdsa::SecKey::gensk(&mut rng); + }); + let k = ecdsa::SecKey::gensk(&mut rng); + bench(&mut console, &timer, "ecdsa::SecKey::genpk", || { + k.genpk(); + }); + bench( + &mut console, + &timer, + "ecdsa::SecKey::sign_rng::", + || { + k.sign_rng::(&[], &mut rng); + }, + ); + bench( + &mut console, + &timer, + "ecdsa::SecKey::sign_rfc6979::", + || { + k.sign_rfc6979::(&[]); + }, + ); + + writeln!(console, "****************************************").unwrap(); + writeln!(console, "All the benchmarks are done.\nHave a nice day!").unwrap(); + writeln!(console, "****************************************").unwrap(); +} + +fn bench(console: &mut Console, timer: &Timer, title: &str, mut f: F) +where + F: FnMut() -> (), +{ + writeln!(console, "****************************************").unwrap(); + writeln!(console, "Benchmarking: {}", title).unwrap(); + writeln!(console, "----------------------------------------").unwrap(); + let mut count = 1; + for _ in 0..30 { + let start = Timestamp::::from_clock_value(timer.get_current_clock()); + for _ in 0..count { + f(); + } + let end = Timestamp::::from_clock_value(timer.get_current_clock()); + let elapsed = (end - start).ms(); + writeln!( + console, + "{} ms elapsed for {} iterations ({} ms/iter)", + elapsed, + count, + elapsed / (count as f64) + ) + .unwrap(); + if elapsed > 1000.0 { + break; + } + count <<= 1; + } +} diff --git a/layout.ld b/layout.ld new file mode 100644 index 0000000..5bc9d0c --- /dev/null +++ b/layout.ld @@ -0,0 +1,170 @@ +/* Userland Generic Layout + * + * Currently, due to incomplete ROPI-RWPI support in rustc (see + * https://github.com/tock/libtock-rs/issues/28), this layout implements static + * linking. An application init script must define the FLASH and SRAM address + * ranges as well as MPU_MIN_ALIGN before including this layout file. + * + * Here is a an example application linker script to get started: + * MEMORY { + * /* FLASH memory region must start immediately *after* the Tock + * * Binary Format headers, which means you need to offset the + * * beginning of FLASH memory region relative to where the + * * application is loaded. + * FLASH (rx) : ORIGIN = 0x10030, LENGTH = 0x0FFD0 + * SRAM (RWX) : ORIGIN = 0x20000, LENGTH = 0x10000 + * } + * STACK_SIZE = 2048; + * MPU_MIN_ALIGN = 8K; + * INCLUDE ../libtock-rs/layout.ld + */ + +ENTRY(_start) + +SECTIONS { + /* Section for just the app crt0 header. + * This must be first so that the app can find it. + */ + .crt0_header : + { + _beginning = .; /* Start of the app in flash. */ + /** + * Populate the header expected by `crt0`: + * + * struct hdr { + * uint32_t got_sym_start; + * uint32_t got_start; + * uint32_t got_size; + * uint32_t data_sym_start; + * uint32_t data_start; + * uint32_t data_size; + * uint32_t bss_start; + * uint32_t bss_size; + * uint32_t reldata_start; + * uint32_t stack_size; + * }; + */ + /* Offset of GOT symbols in flash */ + LONG(LOADADDR(.got) - _beginning); + /* Offset of GOT section in memory */ + LONG(_got); + /* Size of GOT section */ + LONG(SIZEOF(.got)); + /* Offset of data symbols in flash */ + LONG(LOADADDR(.data) - _beginning); + /* Offset of data section in memory */ + LONG(_data); + /* Size of data section */ + LONG(SIZEOF(.data)); + /* Offset of BSS section in memory */ + LONG(_bss); + /* Size of BSS section */ + LONG(SIZEOF(.bss)); + /* First address offset after program flash, where elf2tab places + * .rel.data section */ + LONG(LOADADDR(.endflash) - _beginning); + /* The size of the stack requested by this application */ + LONG(STACK_SIZE); + /* Pad the header out to a multiple of 32 bytes so there is not a gap + * between the header and subsequent .data section. It's unclear why, + * but LLD is aligning sections to a multiple of 32 bytes. */ + . = ALIGN(32); + } > FLASH =0xFF + + /* App state section. Used for persistent app data. + * We put this first because this is what libtock-c does. They provide the + * following explanation: if the app code changes but the persistent data + * doesn't, the app_state can be preserved. + */ + .wfr.app_state : + { + . = ALIGN(4K); + KEEP (*(.app_state)) + . = ALIGN(4K); + } > FLASH =0xFFFFFFFF + + /* Text section, Code! */ + .text : + { + . = ALIGN(4); + _text = .; + KEEP (*(.start)) + *(.text*) + *(.rodata*) + KEEP (*(.syscalls)) + *(.ARM.extab*) + . = ALIGN(4); /* Make sure we're word-aligned here */ + _etext = .; + } > FLASH =0xFF + + /* Application stack */ + .stack : + { + . = . + STACK_SIZE; + + _stack_top_unaligned = .; + . = ALIGN(8); + _stack_top_aligned = .; + } > SRAM + + /* Data section, static initialized variables + * Note: This is placed in Flash after the text section, but needs to be + * moved to SRAM at runtime + */ + .data : AT (_etext) + { + . = ALIGN(4); /* Make sure we're word-aligned here */ + _data = .; + KEEP(*(.data*)) + . = ALIGN(4); /* Make sure we're word-aligned at the end of flash */ + } > SRAM + + /* Global Offset Table */ + .got : + { + . = ALIGN(4); /* Make sure we're word-aligned here */ + _got = .; + *(.got*) + *(.got.plt*) + . = ALIGN(4); + } > SRAM + + /* BSS section, static uninitialized variables */ + .bss : + { + . = ALIGN(4); /* Make sure we're word-aligned here */ + _bss = .; + KEEP(*(.bss*)) + *(COMMON) + . = ALIGN(4); + } > SRAM + + /* End of flash. */ + .endflash : + { + } > FLASH + + /* ARM Exception support + * + * This contains compiler-generated support for unwinding the stack, + * consisting of key-value pairs of function addresses and information on + * how to unwind stack frames. + * https://wiki.linaro.org/KenWerner/Sandbox/libunwind?action=AttachFile&do=get&target=libunwind-LDS.pdf + * + * .ARM.exidx is sorted, so has to go in its own output section. + * + * __NOTE__: It's at the end because we currently don't actually serialize + * it to the binary in elf2tbf. If it was before the RAM sections, it would + * through off our calculations of the header. + */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + /* (C++) Index entries for section unwinding */ + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + PROVIDE_HIDDEN (__exidx_end = .); +} + +ASSERT((_stack_top_aligned - _stack_top_unaligned) == 0, " +STACK_SIZE must be 8 byte multiple") diff --git a/libraries/cbor/Cargo.toml b/libraries/cbor/Cargo.toml new file mode 100644 index 0000000..bcae013 --- /dev/null +++ b/libraries/cbor/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "cbor" +version = "0.1.0" +authors = [ + "Fabian Kaczmarczyck ", + "Guillaume Endignoux ", + "Jean-Michel Picod ", +] +license = "Apache-2.0" +edition = "2018" + +[dependencies] + +[features] +std = [] diff --git a/libraries/cbor/src/lib.rs b/libraries/cbor/src/lib.rs new file mode 100644 index 0000000..00a9c55 --- /dev/null +++ b/libraries/cbor/src/lib.rs @@ -0,0 +1,29 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; +#[cfg(feature = "std")] +extern crate core; + +#[macro_use] +pub mod macros; +pub mod reader; +pub mod values; +pub mod writer; + +pub use self::reader::read; +pub use self::values::{KeyType, SimpleValue, Value}; +pub use self::writer::write; diff --git a/libraries/cbor/src/macros.rs b/libraries/cbor/src/macros.rs new file mode 100644 index 0000000..5a3d8f5 --- /dev/null +++ b/libraries/cbor/src/macros.rs @@ -0,0 +1,500 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#[macro_export] +macro_rules! cbor_map { + // trailing comma case + ( $( $key:expr => $value:expr, )+ ) => { + cbor_map! ( $($key => $value),+ ) + }; + + ( $( $key:expr => $value:expr ),* ) => { + { + // The import is unused if the list is empty. + #[allow(unused_imports)] + use $crate::values::{IntoCborKey, IntoCborValue}; + let mut _map = ::alloc::collections::BTreeMap::new(); + $( + _map.insert($key.into_cbor_key(), $value.into_cbor_value()); + )* + $crate::values::Value::Map(_map) + } + }; +} + +#[macro_export] +macro_rules! cbor_map_options { + // trailing comma case + ( $( $key:expr => $value:expr, )+ ) => { + cbor_map_options! ( $($key => $value),+ ) + }; + + ( $( $key:expr => $value:expr ),* ) => { + { + // The import is unused if the list is empty. + #[allow(unused_imports)] + use $crate::values::{IntoCborKey, IntoCborValueOption}; + let mut _map = ::alloc::collections::BTreeMap::<_, $crate::values::Value>::new(); + $( + { + let opt: Option<$crate::values::Value> = $value.into_cbor_value_option(); + if let Some(val) = opt { + _map.insert($key.into_cbor_key(), val); + } + } + )* + $crate::values::Value::Map(_map) + } + }; +} + +#[macro_export] +macro_rules! cbor_map_btree { + ( $tree:expr ) => { + $crate::values::Value::Map($tree) + }; +} + +#[macro_export] +macro_rules! cbor_array { + // trailing comma case + ( $( $value:expr, )+ ) => { + cbor_array! ( $($value),+ ) + }; + + ( $( $value:expr ),* ) => { + { + // The import is unused if the list is empty. + #[allow(unused_imports)] + use $crate::values::IntoCborValue; + $crate::values::Value::Array(vec![ $( $value.into_cbor_value(), )* ]) + } + }; +} + +#[macro_export] +macro_rules! cbor_array_vec { + ( $vec:expr ) => {{ + use $crate::values::IntoCborValue; + $crate::values::Value::Array($vec.into_iter().map(|x| x.into_cbor_value()).collect()) + }}; +} + +#[cfg(test)] +macro_rules! cbor_true { + ( ) => { + $crate::values::Value::Simple($crate::values::SimpleValue::TrueValue) + }; +} + +#[macro_export] +macro_rules! cbor_false { + ( ) => { + $crate::values::Value::Simple($crate::values::SimpleValue::FalseValue) + }; +} + +#[macro_export] +macro_rules! cbor_null { + ( ) => { + $crate::values::Value::Simple($crate::values::SimpleValue::NullValue) + }; +} + +#[cfg(test)] +macro_rules! cbor_undefined { + ( ) => { + $crate::values::Value::Simple($crate::values::SimpleValue::Undefined) + }; +} + +#[macro_export] +macro_rules! cbor_bool { + ( $x:expr ) => { + $crate::values::Value::bool_value($x) + }; +} + +// For key types, we construct a KeyType and call .into(), which will automatically convert it to a +// KeyType or a Value depending on the context. +#[macro_export] +macro_rules! cbor_unsigned { + ( $x:expr ) => { + cbor_key_unsigned!($x).into() + }; +} + +#[macro_export] +macro_rules! cbor_int { + ( $x:expr ) => { + cbor_key_int!($x).into() + }; +} + +#[macro_export] +macro_rules! cbor_text { + ( $x:expr ) => { + cbor_key_text!($x).into() + }; +} + +#[macro_export] +macro_rules! cbor_bytes { + ( $x:expr ) => { + cbor_key_bytes!($x).into() + }; +} + +// Macro to use with a literal, e.g. cbor_bytes_lit!(b"foo") +#[macro_export] +macro_rules! cbor_bytes_lit { + ( $x:expr ) => { + cbor_bytes!(($x as &[u8]).to_vec()) + }; +} + +// Some explicit macros are also available for contexts where the type is not explicit. +#[macro_export] +macro_rules! cbor_key_unsigned { + ( $x:expr ) => { + $crate::values::KeyType::Unsigned($x) + }; +} + +#[macro_export] +macro_rules! cbor_key_int { + ( $x:expr ) => { + $crate::values::KeyType::integer($x) + }; +} + +#[macro_export] +macro_rules! cbor_key_text { + ( $x:expr ) => { + $crate::values::KeyType::TextString($x.into()) + }; +} + +#[macro_export] +macro_rules! cbor_key_bytes { + ( $x:expr ) => { + $crate::values::KeyType::ByteString($x) + }; +} + +#[cfg(test)] +mod test { + use super::super::values::{KeyType, SimpleValue, Value}; + use alloc::collections::BTreeMap; + + #[test] + fn test_cbor_simple_values() { + assert_eq!(cbor_true!(), Value::Simple(SimpleValue::TrueValue)); + assert_eq!(cbor_false!(), Value::Simple(SimpleValue::FalseValue)); + assert_eq!(cbor_null!(), Value::Simple(SimpleValue::NullValue)); + assert_eq!(cbor_undefined!(), Value::Simple(SimpleValue::Undefined)); + } + + #[test] + fn test_cbor_bool() { + assert_eq!(cbor_bool!(true), Value::Simple(SimpleValue::TrueValue)); + assert_eq!(cbor_bool!(false), Value::Simple(SimpleValue::FalseValue)); + } + + #[test] + fn test_cbor_int_unsigned() { + assert_eq!(cbor_key_int!(0), KeyType::Unsigned(0)); + assert_eq!(cbor_key_int!(1), KeyType::Unsigned(1)); + assert_eq!(cbor_key_int!(123456), KeyType::Unsigned(123456)); + assert_eq!( + cbor_key_int!(std::i64::MAX), + KeyType::Unsigned(std::i64::MAX as u64) + ); + } + + #[test] + fn test_cbor_int_negative() { + assert_eq!(cbor_key_int!(-1), KeyType::Negative(-1)); + assert_eq!(cbor_key_int!(-123456), KeyType::Negative(-123456)); + assert_eq!( + cbor_key_int!(std::i64::MIN), + KeyType::Negative(std::i64::MIN) + ); + } + + #[test] + fn test_cbor_int_literals() { + let a = cbor_array![ + std::i64::MIN, + std::i32::MIN, + -123456, + -1, + 0, + 1, + 123456, + std::i32::MAX, + std::i64::MAX, + std::u64::MAX, + ]; + let b = Value::Array(vec![ + Value::KeyValue(KeyType::Negative(std::i64::MIN)), + Value::KeyValue(KeyType::Negative(std::i32::MIN as i64)), + Value::KeyValue(KeyType::Negative(-123456)), + Value::KeyValue(KeyType::Negative(-1)), + Value::KeyValue(KeyType::Unsigned(0)), + Value::KeyValue(KeyType::Unsigned(1)), + Value::KeyValue(KeyType::Unsigned(123456)), + Value::KeyValue(KeyType::Unsigned(std::i32::MAX as u64)), + Value::KeyValue(KeyType::Unsigned(std::i64::MAX as u64)), + Value::KeyValue(KeyType::Unsigned(std::u64::MAX)), + ]); + assert_eq!(a, b); + } + + #[test] + fn test_cbor_array() { + let a = cbor_array![ + -123, + 456, + true, + cbor_null!(), + "foo", + b"bar", + cbor_array![], + cbor_array![0, 1], + cbor_map! {}, + cbor_map! {2 => 3}, + ]; + let b = Value::Array(vec![ + Value::KeyValue(KeyType::Negative(-123)), + Value::KeyValue(KeyType::Unsigned(456)), + Value::Simple(SimpleValue::TrueValue), + Value::Simple(SimpleValue::NullValue), + Value::KeyValue(KeyType::TextString(String::from("foo"))), + Value::KeyValue(KeyType::ByteString(b"bar".to_vec())), + Value::Array(Vec::new()), + Value::Array(vec![ + Value::KeyValue(KeyType::Unsigned(0)), + Value::KeyValue(KeyType::Unsigned(1)), + ]), + Value::Map(BTreeMap::new()), + Value::Map( + [(KeyType::Unsigned(2), Value::KeyValue(KeyType::Unsigned(3)))] + .iter() + .cloned() + .collect(), + ), + ]); + assert_eq!(a, b); + } + + #[test] + fn test_cbor_array_vec_empty() { + let a = cbor_array_vec!(Vec::::new()); + let b = Value::Array(Vec::new()); + assert_eq!(a, b); + } + + #[test] + fn test_cbor_array_vec_int() { + let a = cbor_array_vec!(vec![1, 2, 3, 4]); + let b = Value::Array(vec![ + Value::KeyValue(KeyType::Unsigned(1)), + Value::KeyValue(KeyType::Unsigned(2)), + Value::KeyValue(KeyType::Unsigned(3)), + Value::KeyValue(KeyType::Unsigned(4)), + ]); + assert_eq!(a, b); + } + + #[test] + fn test_cbor_array_vec_text() { + let a = cbor_array_vec!(vec!["a", "b", "c"]); + let b = Value::Array(vec![ + Value::KeyValue(KeyType::TextString(String::from("a"))), + Value::KeyValue(KeyType::TextString(String::from("b"))), + Value::KeyValue(KeyType::TextString(String::from("c"))), + ]); + assert_eq!(a, b); + } + + #[test] + fn test_cbor_array_vec_bytes() { + let a = cbor_array_vec!(vec![b"a", b"b", b"c"]); + let b = Value::Array(vec![ + Value::KeyValue(KeyType::ByteString(b"a".to_vec())), + Value::KeyValue(KeyType::ByteString(b"b".to_vec())), + Value::KeyValue(KeyType::ByteString(b"c".to_vec())), + ]); + assert_eq!(a, b); + } + + #[test] + fn test_cbor_map() { + let a = cbor_map! { + -1 => -23, + 4 => 56, + "foo" => true, + b"bar" => cbor_null!(), + 5 => "foo", + 6 => b"bar", + 7 => cbor_array![], + 8 => cbor_array![0, 1], + 9 => cbor_map!{}, + 10 => cbor_map!{2 => 3}, + }; + let b = Value::Map( + [ + ( + KeyType::Negative(-1), + Value::KeyValue(KeyType::Negative(-23)), + ), + (KeyType::Unsigned(4), Value::KeyValue(KeyType::Unsigned(56))), + ( + KeyType::TextString(String::from("foo")), + Value::Simple(SimpleValue::TrueValue), + ), + ( + KeyType::ByteString(b"bar".to_vec()), + Value::Simple(SimpleValue::NullValue), + ), + ( + KeyType::Unsigned(5), + Value::KeyValue(KeyType::TextString(String::from("foo"))), + ), + ( + KeyType::Unsigned(6), + Value::KeyValue(KeyType::ByteString(b"bar".to_vec())), + ), + (KeyType::Unsigned(7), Value::Array(Vec::new())), + ( + KeyType::Unsigned(8), + Value::Array(vec![ + Value::KeyValue(KeyType::Unsigned(0)), + Value::KeyValue(KeyType::Unsigned(1)), + ]), + ), + (KeyType::Unsigned(9), Value::Map(BTreeMap::new())), + ( + KeyType::Unsigned(10), + Value::Map( + [(KeyType::Unsigned(2), Value::KeyValue(KeyType::Unsigned(3)))] + .iter() + .cloned() + .collect(), + ), + ), + ] + .iter() + .cloned() + .collect(), + ); + assert_eq!(a, b); + } + + #[test] + fn test_cbor_map_options() { + let a = cbor_map_options! { + -1 => -23, + 4 => Some(56), + 11 => None::, + "foo" => true, + 12 => None::<&str>, + b"bar" => Some(cbor_null!()), + 13 => None::>, + 5 => "foo", + 14 => None::<&[u8]>, + 6 => Some(b"bar" as &[u8]), + 15 => None::, + 7 => cbor_array![], + 16 => None::, + 8 => Some(cbor_array![0, 1]), + 17 => None::, + 9 => cbor_map!{}, + 18 => None::, + 10 => Some(cbor_map!{2 => 3}), + }; + let b = Value::Map( + [ + ( + KeyType::Negative(-1), + Value::KeyValue(KeyType::Negative(-23)), + ), + (KeyType::Unsigned(4), Value::KeyValue(KeyType::Unsigned(56))), + ( + KeyType::TextString(String::from("foo")), + Value::Simple(SimpleValue::TrueValue), + ), + ( + KeyType::ByteString(b"bar".to_vec()), + Value::Simple(SimpleValue::NullValue), + ), + ( + KeyType::Unsigned(5), + Value::KeyValue(KeyType::TextString(String::from("foo"))), + ), + ( + KeyType::Unsigned(6), + Value::KeyValue(KeyType::ByteString(b"bar".to_vec())), + ), + (KeyType::Unsigned(7), Value::Array(Vec::new())), + ( + KeyType::Unsigned(8), + Value::Array(vec![ + Value::KeyValue(KeyType::Unsigned(0)), + Value::KeyValue(KeyType::Unsigned(1)), + ]), + ), + (KeyType::Unsigned(9), Value::Map(BTreeMap::new())), + ( + KeyType::Unsigned(10), + Value::Map( + [(KeyType::Unsigned(2), Value::KeyValue(KeyType::Unsigned(3)))] + .iter() + .cloned() + .collect(), + ), + ), + ] + .iter() + .cloned() + .collect(), + ); + assert_eq!(a, b); + } + + #[test] + fn test_cbor_map_btree_empty() { + let a = cbor_map_btree!(BTreeMap::new()); + let b = Value::Map(BTreeMap::new()); + assert_eq!(a, b); + } + + #[test] + fn test_cbor_map_btree_foo() { + let a = cbor_map_btree!( + [(KeyType::Unsigned(2), Value::KeyValue(KeyType::Unsigned(3)))] + .iter() + .cloned() + .collect() + ); + let b = Value::Map( + [(KeyType::Unsigned(2), Value::KeyValue(KeyType::Unsigned(3)))] + .iter() + .cloned() + .collect(), + ); + assert_eq!(a, b); + } +} diff --git a/libraries/cbor/src/reader.rs b/libraries/cbor/src/reader.rs new file mode 100644 index 0000000..0ba6a6c --- /dev/null +++ b/libraries/cbor/src/reader.rs @@ -0,0 +1,811 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::values::{Constants, KeyType, SimpleValue, Value}; +use alloc::collections::BTreeMap; +use alloc::str; +use alloc::vec::Vec; + +#[derive(Debug, PartialEq)] +pub enum DecoderError { + UnsupportedMajorType, + UnknownAdditionalInfo, + IncompleteCborData, + IncorrectMapKeyType, + TooMuchNesting, + InvalidUtf8, + ExtranousData, + OutOfOrderKey, + NonMinimalCborEncoding, + UnsupportedSimpleValue, + UnsupportedFloatingPointValue, + OutOfRangeIntegerValue, +} + +pub fn read(encoded_cbor: &[u8]) -> Result { + let mut reader = Reader::new(encoded_cbor); + let value = reader.decode_complete_data_item(Reader::MAX_NESTING_DEPTH)?; + if !reader.remaining_cbor.is_empty() { + return Err(DecoderError::ExtranousData); + } + Ok(value) +} + +struct Reader<'a> { + remaining_cbor: &'a [u8], +} + +impl<'a> Reader<'a> { + const MAX_NESTING_DEPTH: i8 = 4; + + pub fn new(cbor: &'a [u8]) -> Reader<'a> { + Reader { + remaining_cbor: cbor, + } + } + + pub fn decode_complete_data_item( + &mut self, + remaining_depth: i8, + ) -> Result { + if remaining_depth < 0 { + return Err(DecoderError::TooMuchNesting); + } + + match self.read_bytes(1) { + Some([first_byte]) => { + // Unsigned byte means logical shift, so only zeros get shifted in. + let major_type_value = first_byte >> Constants::MAJOR_TYPE_BIT_SHIFT; + let additional_info = first_byte & Constants::ADDITIONAL_INFORMATION_MASK; + let size_result = self.read_variadic_length_integer(additional_info); + match size_result { + Ok(size_value) => match major_type_value { + 0 => self.decode_value_to_unsigned(size_value), + 1 => self.decode_value_to_negative(size_value), + 2 => self.read_byte_string_content(size_value), + 3 => self.read_text_string_content(size_value), + 4 => self.read_array_content(size_value, remaining_depth), + 5 => self.read_map_content(size_value, remaining_depth), + 7 => self.decode_to_simple_value(size_value, additional_info), + _ => Err(DecoderError::UnsupportedMajorType), + }, + Err(decode_error) => Err(decode_error), + } + } + _ => Err(DecoderError::IncompleteCborData), + } + } + + fn read_bytes(&mut self, num_bytes: usize) -> Option<&[u8]> { + if num_bytes > self.remaining_cbor.len() { + None + } else { + let (left, right) = self.remaining_cbor.split_at(num_bytes); + self.remaining_cbor = right; + Some(left) + } + } + + fn read_variadic_length_integer(&mut self, additional_info: u8) -> Result { + let additional_bytes_num = match additional_info { + 0..=Constants::ADDITIONAL_INFORMATION_MAX_INT => return Ok(additional_info as u64), + Constants::ADDITIONAL_INFORMATION_1_BYTE => 1, + Constants::ADDITIONAL_INFORMATION_2_BYTES => 2, + Constants::ADDITIONAL_INFORMATION_4_BYTES => 4, + Constants::ADDITIONAL_INFORMATION_8_BYTES => 8, + _ => return Err(DecoderError::UnknownAdditionalInfo), + }; + match self.read_bytes(additional_bytes_num) { + Some(bytes) => { + let mut size_value = 0u64; + for byte in bytes { + size_value <<= 8; + size_value += *byte as u64; + } + if (additional_bytes_num == 1 && size_value < 24) + || size_value < (1u64 << (8 * (additional_bytes_num >> 1))) + { + Err(DecoderError::NonMinimalCborEncoding) + } else { + Ok(size_value) + } + } + None => Err(DecoderError::IncompleteCborData), + } + } + + fn decode_value_to_unsigned(&self, size_value: u64) -> Result { + Ok(cbor_unsigned!(size_value)) + } + + fn decode_value_to_negative(&self, size_value: u64) -> Result { + let signed_size = size_value as i64; + if signed_size < 0 { + Err(DecoderError::OutOfRangeIntegerValue) + } else { + Ok(Value::KeyValue(KeyType::Negative(-(size_value as i64) - 1))) + } + } + + fn read_byte_string_content(&mut self, size_value: u64) -> Result { + match self.read_bytes(size_value as usize) { + Some(bytes) => Ok(cbor_bytes_lit!(bytes)), + None => Err(DecoderError::IncompleteCborData), + } + } + + fn read_text_string_content(&mut self, size_value: u64) -> Result { + match self.read_bytes(size_value as usize) { + Some(bytes) => match str::from_utf8(bytes) { + Ok(s) => Ok(cbor_text!(s)), + Err(_) => Err(DecoderError::InvalidUtf8), + }, + None => Err(DecoderError::IncompleteCborData), + } + } + + fn read_array_content( + &mut self, + size_value: u64, + remaining_depth: i8, + ) -> Result { + // Don't set the capacity already, it is an unsanitized input. + let mut value_array = Vec::new(); + for _ in 0..size_value { + value_array.push(self.decode_complete_data_item(remaining_depth - 1)?); + } + Ok(cbor_array_vec!(value_array)) + } + + fn read_map_content( + &mut self, + size_value: u64, + remaining_depth: i8, + ) -> Result { + let mut value_map = BTreeMap::new(); + let mut last_key_option = None; + for _ in 0..size_value { + let key_value = self.decode_complete_data_item(remaining_depth - 1)?; + if let Value::KeyValue(key) = key_value { + if let Some(last_key) = last_key_option { + if last_key >= key { + return Err(DecoderError::OutOfOrderKey); + } + } + last_key_option = Some(key.clone()); + value_map.insert(key, self.decode_complete_data_item(remaining_depth - 1)?); + } else { + return Err(DecoderError::IncorrectMapKeyType); + } + } + Ok(cbor_map_btree!(value_map)) + } + + fn decode_to_simple_value( + &self, + size_value: u64, + additional_info: u8, + ) -> Result { + if additional_info > Constants::ADDITIONAL_INFORMATION_MAX_INT + && additional_info != Constants::ADDITIONAL_INFORMATION_1_BYTE + { + // TODO(kaczmarczyck) the chromium C++ reference allows equality to 24 here, why? + // Also, why not just disallow ANY additional_info != size_value? + return Err(DecoderError::UnsupportedFloatingPointValue); + } + match SimpleValue::from_integer(size_value) { + Some(simple_value) => Ok(Value::Simple(simple_value)), + None => Err(DecoderError::UnsupportedSimpleValue), + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_read_unsigned() { + let cases = vec![ + (0, vec![0x00]), + (1, vec![0x01]), + (10, vec![0x0A]), + (23, vec![0x17]), + (24, vec![0x18, 0x18]), + (255, vec![0x18, 0xFF]), + (256, vec![0x19, 0x01, 0x00]), + (65535, vec![0x19, 0xFF, 0xFF]), + (65536, vec![0x1A, 0x00, 0x01, 0x00, 0x00]), + (0xFFFFFFFF, vec![0x1A, 0xFF, 0xFF, 0xFF, 0xFF]), + ( + 0x100000000, + vec![0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00], + ), + ( + std::i64::MAX, + vec![0x1B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], + ), + ]; + for (unsigned, mut cbor) in cases { + assert_eq!(read(&cbor), Ok(cbor_int!(unsigned))); + cbor.push(0x01); + assert_eq!(read(&cbor), Err(DecoderError::ExtranousData)); + } + } + + #[test] + fn test_read_unsigned_non_minimum_byte_length() { + let encodings = vec![ + // Uint 23 encoded with 1 byte. + vec![0x18, 0x17], + // Uint 255 encoded with 2 bytes. + vec![0x19, 0x00, 0xff], + // Uint 65535 encoded with 4 bytes. + vec![0x1a, 0x00, 0x00, 0xff, 0xff], + // Uint 4294967295 encoded with 8 bytes. + vec![0x1b, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff], + // When decoding byte has more than one syntax error, the first syntax + // error encountered during deserialization is returned as the error code. + vec![ + 0xa2, // map with non-minimally encoded key + 0x17, // key 24 + 0x61, 0x42, // value :"B" + 0x18, 0x17, // key 23 encoded with extra byte + 0x61, 0x45, // value "E" + ], + vec![ + 0xa2, // map with out of order and non-minimally encoded key + 0x18, 0x17, // key 23 encoded with extra byte + 0x61, 0x45, // value "E" + 0x17, // key 23 + 0x61, 0x42, // value :"B" + ], + vec![ + 0xa2, // map with duplicate non-minimally encoded key + 0x18, 0x17, // key 23 encoded with extra byte + 0x61, 0x45, // value "E" + 0x18, 0x17, // key 23 encoded with extra byte + 0x61, 0x42, // value :"B" + ], + ]; + for encoding in encodings { + assert_eq!(read(&encoding), Err(DecoderError::NonMinimalCborEncoding)); + } + } + + #[test] + fn test_read_negative() { + let cases = vec![ + (-1, vec![0x20]), + (-24, vec![0x37]), + (-25, vec![0x38, 0x18]), + (-256, vec![0x38, 0xFF]), + (-1000, vec![0x39, 0x03, 0xE7]), + (-1000000, vec![0x3A, 0x00, 0x0F, 0x42, 0x3F]), + (-4294967296, vec![0x3A, 0xFF, 0xFF, 0xFF, 0xFF]), + ( + std::i64::MIN, + vec![0x3B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], + ), + ]; + for (negative, mut cbor) in cases { + assert_eq!(read(&cbor), Ok(cbor_int!(negative))); + cbor.push(0x01); + assert_eq!(read(&cbor), Err(DecoderError::ExtranousData)); + } + } + + #[test] + fn test_read_byte_string() { + let cases = vec![ + (Vec::new(), vec![0x40]), + ( + vec![0x01, 0x02, 0x03, 0x04], + vec![0x44, 0x01, 0x02, 0x03, 0x04], + ), + ]; + for (byte_string, mut cbor) in cases { + assert_eq!(read(&cbor), Ok(cbor_bytes!(byte_string))); + cbor.push(0x01); + assert_eq!(read(&cbor), Err(DecoderError::ExtranousData)); + } + } + + #[test] + fn test_read_text_string() { + let unicode_3byte = vec![0xE6, 0xB0, 0xB4]; + let cases = vec![ + ("", vec![0x60]), + ("a", vec![0x61, 0x61]), + ("IETF", vec![0x64, 0x49, 0x45, 0x54, 0x46]), + ("\"\\", vec![0x62, 0x22, 0x5C]), + ("ü", vec![0x62, 0xC3, 0xBC]), + ( + std::str::from_utf8(&unicode_3byte).unwrap(), + vec![0x63, 0xE6, 0xB0, 0xB4], + ), + ("𐅑", vec![0x64, 0xF0, 0x90, 0x85, 0x91]), + ]; + for (text_string, mut cbor) in cases { + assert_eq!(read(&cbor), Ok(cbor_text!(text_string))); + cbor.push(0x01); + assert_eq!(read(&cbor), Err(DecoderError::ExtranousData)); + } + } + + #[test] + fn test_read_text_string_with_nul() { + let cases = vec![ + ( + "string_without_nul", + vec![ + 0x72, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x5F, 0x77, 0x69, 0x74, 0x68, 0x6F, + 0x75, 0x74, 0x5F, 0x6E, 0x75, 0x6C, + ], + ), + ( + "nul_terminated_string\0", + vec![ + 0x76, 0x6E, 0x75, 0x6C, 0x5F, 0x74, 0x65, 0x72, 0x6D, 0x69, 0x6E, 0x61, 0x74, + 0x65, 0x64, 0x5F, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x00, + ], + ), + ( + "embedded\0nul", + vec![ + 0x6C, 0x65, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x00, 0x6E, 0x75, 0x6C, + ], + ), + ( + "trailing_nuls\0\0", + vec![ + 0x6F, 0x74, 0x72, 0x61, 0x69, 0x6C, 0x69, 0x6E, 0x67, 0x5F, 0x6E, 0x75, 0x6C, + 0x73, 0x00, 0x00, + ], + ), + ]; + for (text_string, mut cbor) in cases { + assert_eq!(read(&cbor), Ok(cbor_text!(text_string))); + cbor.push(0x01); + assert_eq!(read(&cbor), Err(DecoderError::ExtranousData)); + } + } + + #[test] + fn test_read_text_string_with_invalid_byte_sequence_after_nul() { + assert_eq!( + read(&vec![0x63, 0x00, 0x00, 0xA6]), + Err(DecoderError::InvalidUtf8) + ); + } + + #[test] + fn test_read_array() { + let value_vec: Vec<_> = (1..26).collect(); + let mut test_cbor = vec![ + 0x98, 0x19, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, + 0x19, + ]; + assert_eq!(read(&test_cbor.clone()), Ok(cbor_array_vec!(value_vec))); + test_cbor.push(0x01); + assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData)); + } + + #[test] + fn test_read_map() { + let value_map = cbor_map! { + 24 => "abc", + "" => ".", + "b" => "B", + "aa" => "AA", + }; + let mut test_cbor = vec![ + 0xa4, // map with 4 key value pairs: + 0x18, 0x18, // 24 + 0x63, 0x61, 0x62, 0x63, // "abc" + 0x60, // "" + 0x61, 0x2e, // "." + 0x61, 0x62, // "b" + 0x61, 0x42, // "B" + 0x62, 0x61, 0x61, // "aa" + 0x62, 0x41, 0x41, // "AA" + ]; + assert_eq!(read(&test_cbor), Ok(value_map)); + test_cbor.push(0x01); + assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData)); + } + + #[test] + fn test_read_map_with_unsigned_keys() { + let value_map = cbor_map! { + 1 => "a", + 9 => "b", + 999 => "c", + 1111 => "d", + }; + let mut test_cbor = vec![ + 0xa4, // map with 4 key value pairs: + 0x01, // key : 1 + 0x61, 0x61, // value : "a" + 0x09, // key : 9 + 0x61, 0x62, // value : "b" + 0x19, 0x03, 0xE7, // key : 999 + 0x61, 0x63, // value "c" + 0x19, 0x04, 0x57, // key : 1111 + 0x61, 0x64, // value : "d" + ]; + assert_eq!(read(&test_cbor), Ok(value_map)); + test_cbor.push(0x01); + assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData)); + } + + #[test] + fn test_read_map_with_negative_keys() { + let value_map = cbor_map! { + -1 => 1, + -2 => 2, + -100 => 3, + }; + let mut test_cbor = vec![ + 0xA3, // map with 3 key value pairs + 0x20, // key : -1 + 0x01, // value : 1 + 0x21, // key : -2 + 0x02, // value : 2 + 0x38, 0x63, // key : -100 + 0x03, // value : 3 + ]; + assert_eq!(read(&test_cbor), Ok(value_map)); + test_cbor.push(0x01); + assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData)); + } + + #[test] + fn test_read_map_with_array() { + let value_map = cbor_map! { + "a" => 1, + "b" => cbor_array![2, 3], + }; + let mut test_cbor = vec![ + 0xa2, // map of 2 pairs + 0x61, 0x61, // "a" + 0x01, 0x61, 0x62, // "b" + 0x82, // array with 2 elements + 0x02, 0x03, + ]; + assert_eq!(read(&test_cbor), Ok(value_map)); + test_cbor.push(0x01); + assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData)); + } + + #[test] + fn test_read_map_with_text_string_keys() { + let value_map = cbor_map! { + "k" => "v", + "foo" => "bar", + }; + let mut test_cbor = vec![ + 0xa2, // map of 2 pairs + 0x61, b'k', // text string "k" + 0x61, b'v', 0x63, b'f', b'o', b'o', // text string "foo" + 0x63, b'b', b'a', b'r', + ]; + assert_eq!(read(&test_cbor), Ok(value_map)); + test_cbor.push(0x01); + assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData)); + } + + #[test] + fn test_read_map_with_byte_string_keys() { + let value_map = cbor_map! { + b"k" => b"v", + b"foo" => b"bar", + }; + let mut test_cbor = vec![ + 0xa2, // map of 2 pairs + 0x41, b'k', // text string "k" + 0x41, b'v', 0x43, b'f', b'o', b'o', // text string "foo" + 0x43, b'b', b'a', b'r', + ]; + assert_eq!(read(&test_cbor), Ok(value_map)); + test_cbor.push(0x01); + assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData)); + } + + #[test] + fn test_read_nested_map() { + let value_map = cbor_map! { + "a" => 1, + "b" => cbor_map! { + "c" => 2, + "d" => 3, + }, + }; + let mut test_cbor = vec![ + 0xa2, // map of 2 pairs + 0x61, 0x61, 0x01, // "a" + 0x61, 0x62, // "b" + 0xa2, // map of 2 pairs + 0x61, 0x63, 0x02, // "c" + 0x61, 0x64, 0x03, // "d" + ]; + assert_eq!(read(&test_cbor), Ok(value_map)); + test_cbor.push(0x01); + assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData)); + } + + #[test] + fn test_read_integer_out_of_range() { + let cases = vec![ + // The positive case is impossible since we support u64. + // vec![0x1B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + vec![0x3B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + ]; + for cbor in cases { + assert_eq!(read(&cbor), Err(DecoderError::OutOfRangeIntegerValue)); + } + } + + #[test] + fn test_read_simple_value() { + let cases = vec![ + (cbor_false!(), vec![0xF4]), + (cbor_true!(), vec![0xF5]), + (cbor_null!(), vec![0xF6]), + (cbor_undefined!(), vec![0xF7]), + ]; + for (simple, mut cbor) in cases { + assert_eq!(read(&cbor.clone()), Ok(simple)); + cbor.push(0x01); + assert_eq!(read(&cbor), Err(DecoderError::ExtranousData)); + } + } + + #[test] + fn test_read_unsupported_floating_point_numbers() { + let cases = vec![ + vec![0xF9, 0x10, 0x00], + vec![0xFA, 0x10, 0x00, 0x00, 0x00], + vec![0xFB, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + ]; + for cbor in cases { + assert_eq!( + read(&cbor), + Err(DecoderError::UnsupportedFloatingPointValue) + ); + } + } + + #[test] + fn test_read_incomplete_cbor_data_error() { + let cases = vec![ + vec![0x19, 0x03], + vec![0x44, 0x01, 0x02, 0x03], + vec![0x65, 0x49, 0x45, 0x54, 0x46], + vec![0x82, 0x02], + vec![0xA2, 0x61, 0x61, 0x01], + vec![0x18], + vec![0x99], + vec![0xBA], + vec![0x5B], + vec![0x3B], + vec![0x99, 0x01], + vec![0xBA, 0x01, 0x02, 0x03], + vec![0x3B, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], + ]; + for cbor in cases { + assert_eq!(read(&cbor), Err(DecoderError::IncompleteCborData)); + } + } + + #[test] + fn test_read_unsupported_map_key_format_error() { + // While CBOR can handle all types as map keys, we only support a subset. + let bad_map_cbor = vec![ + 0xa2, // map of 2 pairs + 0x82, 0x01, 0x02, // invalid key : [1, 2] + 0x02, // value : 2 + 0x61, 0x64, // key : "d" + 0x03, // value : 3 + ]; + assert_eq!(read(&bad_map_cbor), Err(DecoderError::IncorrectMapKeyType)); + } + + #[test] + fn test_read_unknown_additional_info_error() { + let cases = vec![ + vec![0x7C, 0x49, 0x45, 0x54, 0x46], + vec![0x7D, 0x22, 0x5C], + vec![0x7E, 0xC3, 0xBC], + vec![0x7F, 0xE6, 0xB0, 0xB4], + vec![0xFC], + vec![0xFD], + vec![0xFE], + vec![0xFF], + ]; + for cbor in cases { + assert_eq!(read(&cbor), Err(DecoderError::UnknownAdditionalInfo)); + } + } + + #[test] + fn test_read_too_much_nesting_error() { + let cases = vec![ + vec![0x18, 0x64], + vec![0x44, 0x01, 0x02, 0x03, 0x04], + vec![0x64, 0x49, 0x45, 0x54, 0x46], + vec![0x80], + vec![0xA0], + ]; + for cbor in cases { + let mut reader = Reader::new(&cbor); + assert!(reader.decode_complete_data_item(0).is_ok()); + } + let map_cbor = vec![ + 0xa2, // map of 2 pairs + 0x61, 0x61, // "a" + 0x01, 0x61, 0x62, // "b" + 0x82, // array with 2 elements + 0x02, 0x03, + ]; + let mut reader = Reader::new(&map_cbor); + assert_eq!( + reader.decode_complete_data_item(1), + Err(DecoderError::TooMuchNesting) + ); + reader = Reader::new(&map_cbor); + assert!(reader.decode_complete_data_item(2).is_ok()); + } + + #[test] + fn test_read_out_of_order_key_error() { + let cases = vec![ + vec![ + 0xa2, // map with 2 keys with same major type and length + 0x61, 0x62, // key "b" + 0x61, 0x42, // value "B" + 0x61, 0x61, // key "a" (out of order byte-wise lexically) + 0x61, 0x45, // value "E" + ], + vec![ + 0xa2, // map with 2 keys with different major type + 0x61, 0x62, // key "b" + 0x02, // value 2 + // key 1000 (out of order since lower major type sorts first) + 0x19, 0x03, 0xe8, 0x61, 0x61, // value a + ], + vec![ + 0xa2, // map with 2 keys with same major type + 0x19, 0x03, 0xe8, // key 1000 (out of order due to longer length) + 0x61, 0x61, //value "a" + 0x0a, // key 10 + 0x61, 0x62, // value "b" + ], + vec![ + 0xa2, // map with 2 text string keys + 0x62, b'a', b'a', // key text string "aa" + // (out of order due to longer length) + 0x02, 0x61, b'b', // key "b" + 0x01, + ], + vec![ + 0xa2, // map with 2 byte string keys + 0x42, b'x', b'x', // key byte string "xx" + // (out of order due to longer length) + 0x02, 0x41, b'y', // key byte string "y" + 0x01, + ], + ]; + for cbor in cases { + assert_eq!(read(&cbor), Err(DecoderError::OutOfOrderKey)); + } + } + + #[test] + fn test_read_duplicate_key_error() { + let map_with_duplicate_key = vec![ + 0xa6, // map of 6 pairs: + 0x60, // "" + 0x61, 0x2e, // "." + 0x61, 0x62, // "b" + 0x61, 0x42, // "B" + 0x61, 0x62, // "b" (Duplicate key) + 0x61, 0x43, // "C" + 0x61, 0x64, // "d" + 0x61, 0x44, // "D" + 0x61, 0x65, // "e" + 0x61, 0x44, // "D" + 0x62, 0x61, 0x61, // "aa" + 0x62, 0x41, 0x41, // "AA" + ]; + assert_eq!( + read(&map_with_duplicate_key), + Err(DecoderError::OutOfOrderKey) + ); + } + + #[test] + fn test_read_incorrect_string_encoding_error() { + let cases = vec![ + vec![0x63, 0xED, 0x9F, 0xBF], + vec![0x63, 0xEE, 0x80, 0x80], + vec![0x63, 0xEF, 0xBF, 0xBD], + ]; + for cbor in cases { + assert!(read(&cbor).is_ok()); + } + let impossible_utf_byte = vec![0x64, 0xFE, 0xFE, 0xFF, 0xFF]; + assert_eq!(read(&impossible_utf_byte), Err(DecoderError::InvalidUtf8)); + } + + #[test] + fn test_read_extranous_cbor_data_error() { + let cases = vec![ + vec![0x19, 0x03, 0x05, 0x00], + vec![0x44, 0x01, 0x02, 0x03, 0x04, 0x00], + vec![0x64, 0x49, 0x45, 0x54, 0x46, 0x00], + vec![0x82, 0x01, 0x02, 0x00], + vec![0xa1, 0x61, 0x63, 0x02, 0x61, 0x64, 0x03], + ]; + for cbor in cases { + assert_eq!(read(&cbor), Err(DecoderError::ExtranousData)); + } + } + + #[test] + fn test_read_unsupported_simple_type() { + let cases = vec![ + vec![0xE0], + vec![0xF3], + vec![0xF8, 0x18], + vec![0xF8, 0x1C], + vec![0xF8, 0x1D], + vec![0xF8, 0x1E], + vec![0xF8, 0x1F], + vec![0xF8, 0x20], + vec![0xF8, 0xFF], + ]; + for cbor in cases { + assert_eq!(read(&cbor), Err(DecoderError::UnsupportedSimpleValue)); + } + } + + #[test] + fn test_read_super_long_content_dont_crash() { + let cases = vec![ + vec![0x9B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], + vec![0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], + ]; + for cbor in cases { + assert_eq!(read(&cbor), Err(DecoderError::IncompleteCborData)); + } + } + + #[test] + fn test_read_unsupported_major_type() { + let cases = vec![ + vec![0xC0], + vec![0xD8, 0xFF], + // multi-dimensional array example using tags + vec![ + 0x82, 0x82, 0x02, 0x03, 0xd8, 0x41, 0x4a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x03, 0x00, 0x04, 0x00, 0x05, + ], + ]; + for cbor in cases { + assert_eq!(read(&cbor), Err(DecoderError::UnsupportedMajorType)); + } + } +} diff --git a/libraries/cbor/src/values.rs b/libraries/cbor/src/values.rs new file mode 100644 index 0000000..d402730 --- /dev/null +++ b/libraries/cbor/src/values.rs @@ -0,0 +1,268 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use alloc::collections::BTreeMap; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::cmp::Ordering; + +#[derive(Clone, Debug, PartialEq)] +pub enum Value { + KeyValue(KeyType), + Array(Vec), + Map(BTreeMap), + // TAG is omitted + Simple(SimpleValue), +} + +// The specification recommends to limit the available keys. +// Currently supported are both integer and string types. +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum KeyType { + Unsigned(u64), + // We only use 63 bits of information here. + Negative(i64), + ByteString(Vec), + TextString(String), +} + +#[derive(Clone, Debug, PartialEq)] +pub enum SimpleValue { + FalseValue = 20, + TrueValue = 21, + NullValue = 22, + Undefined = 23, +} + +pub struct Constants {} + +impl Constants { + pub const MAJOR_TYPE_BIT_SHIFT: u8 = 5; + pub const ADDITIONAL_INFORMATION_MASK: u8 = 0x1F; + pub const ADDITIONAL_INFORMATION_MAX_INT: u8 = 23; + pub const ADDITIONAL_INFORMATION_1_BYTE: u8 = 24; + pub const ADDITIONAL_INFORMATION_2_BYTES: u8 = 25; + pub const ADDITIONAL_INFORMATION_4_BYTES: u8 = 26; + pub const ADDITIONAL_INFORMATION_8_BYTES: u8 = 27; +} + +impl Value { + pub fn bool_value(b: bool) -> Value { + if b { + Value::Simple(SimpleValue::TrueValue) + } else { + Value::Simple(SimpleValue::FalseValue) + } + } + + pub fn type_label(&self) -> u8 { + match self { + Value::KeyValue(key) => key.type_label(), + Value::Array(_) => 4, + Value::Map(_) => 5, + Value::Simple(_) => 7, + } + } +} + +impl KeyType { + // For simplicity, this only takes i64. Construct directly for the last bit. + pub fn integer(int: i64) -> KeyType { + if int >= 0 { + KeyType::Unsigned(int as u64) + } else { + KeyType::Negative(int) + } + } + + pub fn type_label(&self) -> u8 { + match self { + KeyType::Unsigned(_) => 0, + KeyType::Negative(_) => 1, + KeyType::ByteString(_) => 2, + KeyType::TextString(_) => 3, + } + } +} + +impl Ord for KeyType { + fn cmp(&self, other: &KeyType) -> Ordering { + use super::values::KeyType::{ByteString, Negative, TextString, Unsigned}; + let self_type_value = self.type_label(); + let other_type_value = other.type_label(); + if self_type_value != other_type_value { + return self_type_value.cmp(&other_type_value); + } + match (self, other) { + (Unsigned(u1), Unsigned(u2)) => u1.cmp(u2), + (Negative(n1), Negative(n2)) => n1.cmp(n2).reverse(), + (ByteString(b1), ByteString(b2)) => b1.len().cmp(&b2.len()).then(b1.cmp(b2)), + (TextString(t1), TextString(t2)) => t1.len().cmp(&t2.len()).then(t1.cmp(t2)), + _ => unreachable!(), + } + } +} + +impl PartialOrd for KeyType { + fn partial_cmp(&self, other: &KeyType) -> Option { + Some(self.cmp(other)) + } +} + +impl SimpleValue { + pub fn from_integer(int: u64) -> Option { + match int { + 20 => Some(SimpleValue::FalseValue), + 21 => Some(SimpleValue::TrueValue), + 22 => Some(SimpleValue::NullValue), + 23 => Some(SimpleValue::Undefined), + _ => None, + } + } +} + +impl From for KeyType { + fn from(unsigned: u64) -> Self { + KeyType::Unsigned(unsigned) + } +} + +impl From for KeyType { + fn from(i: i64) -> Self { + KeyType::integer(i) + } +} + +impl From for KeyType { + fn from(i: i32) -> Self { + KeyType::integer(i as i64) + } +} + +impl From> for KeyType { + fn from(bytes: Vec) -> Self { + KeyType::ByteString(bytes) + } +} + +impl From<&[u8]> for KeyType { + fn from(bytes: &[u8]) -> Self { + KeyType::ByteString(bytes.to_vec()) + } +} + +impl From for KeyType { + fn from(text: String) -> Self { + KeyType::TextString(text) + } +} + +impl From<&str> for KeyType { + fn from(text: &str) -> Self { + KeyType::TextString(text.to_string()) + } +} + +impl From for Value +where + KeyType: From, +{ + fn from(t: T) -> Self { + Value::KeyValue(KeyType::from(t)) + } +} + +impl From for Value { + fn from(b: bool) -> Self { + Value::bool_value(b) + } +} + +pub trait IntoCborKey { + fn into_cbor_key(self) -> KeyType; +} + +impl IntoCborKey for T +where + KeyType: From, +{ + fn into_cbor_key(self) -> KeyType { + KeyType::from(self) + } +} + +pub trait IntoCborValue { + fn into_cbor_value(self) -> Value; +} + +impl IntoCborValue for T +where + Value: From, +{ + fn into_cbor_value(self) -> Value { + Value::from(self) + } +} + +pub trait IntoCborValueOption { + fn into_cbor_value_option(self) -> Option; +} + +impl IntoCborValueOption for T +where + Value: From, +{ + fn into_cbor_value_option(self) -> Option { + Some(Value::from(self)) + } +} + +impl IntoCborValueOption for Option +where + Value: From, +{ + fn into_cbor_value_option(self) -> Option { + self.map(Value::from) + } +} + +#[cfg(test)] +mod test { + #[test] + fn test_key_type_ordering() { + assert!(cbor_key_int!(0) < cbor_key_int!(23)); + assert!(cbor_key_int!(23) < cbor_key_int!(24)); + assert!(cbor_key_int!(24) < cbor_key_int!(1000)); + assert!(cbor_key_int!(1000) < cbor_key_int!(1000000)); + assert!(cbor_key_int!(1000000) < cbor_key_int!(std::i64::MAX)); + assert!(cbor_key_int!(std::i64::MAX) < cbor_key_int!(-1)); + assert!(cbor_key_int!(-1) < cbor_key_int!(-23)); + assert!(cbor_key_int!(-23) < cbor_key_int!(-24)); + assert!(cbor_key_int!(-24) < cbor_key_int!(-1000)); + assert!(cbor_key_int!(-1000) < cbor_key_int!(-1000000)); + assert!(cbor_key_int!(-1000000) < cbor_key_int!(std::i64::MIN)); + assert!(cbor_key_int!(std::i64::MIN) < cbor_key_bytes!(vec![])); + assert!(cbor_key_bytes!(vec![]) < cbor_key_bytes!(vec![0x00])); + assert!(cbor_key_bytes!(vec![0x00]) < cbor_key_bytes!(vec![0x01])); + assert!(cbor_key_bytes!(vec![0x01]) < cbor_key_bytes!(vec![0xFF])); + assert!(cbor_key_bytes!(vec![0xFF]) < cbor_key_bytes!(vec![0x00, 0x00])); + assert!(cbor_key_bytes!(vec![0x00, 0x00]) < cbor_key_text!("")); + assert!(cbor_key_text!("") < cbor_key_text!("a")); + assert!(cbor_key_text!("a") < cbor_key_text!("b")); + assert!(cbor_key_text!("b") < cbor_key_text!("aa")); + assert!(cbor_key_int!(1) < cbor_key_bytes!(vec![0x00])); + assert!(cbor_key_int!(1) < cbor_key_text!("s")); + assert!(cbor_key_int!(-1) < cbor_key_text!("s")); + } +} diff --git a/libraries/cbor/src/writer.rs b/libraries/cbor/src/writer.rs new file mode 100644 index 0000000..1273160 --- /dev/null +++ b/libraries/cbor/src/writer.rs @@ -0,0 +1,429 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::values::{Constants, KeyType, Value}; +use alloc::vec::Vec; + +pub fn write(value: Value, encoded_cbor: &mut Vec) -> bool { + let mut writer = Writer::new(encoded_cbor); + writer.encode_cbor(value, Writer::MAX_NESTING_DEPTH) +} + +struct Writer<'a> { + encoded_cbor: &'a mut Vec, +} + +impl<'a> Writer<'a> { + const MAX_NESTING_DEPTH: i8 = 4; + + pub fn new(encoded_cbor: &mut Vec) -> Writer { + Writer { encoded_cbor } + } + + fn encode_cbor(&mut self, value: Value, remaining_depth: i8) -> bool { + if remaining_depth < 0 { + return false; + } + match value { + Value::KeyValue(KeyType::Unsigned(unsigned)) => self.start_item(0, unsigned as u64), + Value::KeyValue(KeyType::Negative(negative)) => { + self.start_item(1, -(negative + 1) as u64) + } + Value::KeyValue(KeyType::ByteString(byte_string)) => { + self.start_item(2, byte_string.len() as u64); + self.encoded_cbor.extend(byte_string); + } + Value::KeyValue(KeyType::TextString(text_string)) => { + self.start_item(3, text_string.len() as u64); + self.encoded_cbor.extend(text_string.into_bytes()); + } + Value::Array(array) => { + self.start_item(4, array.len() as u64); + for el in array { + if !self.encode_cbor(el, remaining_depth - 1) { + return false; + } + } + } + Value::Map(map) => { + self.start_item(5, map.len() as u64); + for (k, v) in map { + if !self.encode_cbor(Value::KeyValue(k), remaining_depth - 1) { + return false; + } + if !self.encode_cbor(v, remaining_depth - 1) { + return false; + } + } + } + Value::Simple(simple_value) => self.start_item(7, simple_value as u64), + } + true + } + + fn start_item(&mut self, type_label: u8, size: u64) { + let (mut first_byte, shift) = match size { + 0..=23 => (size as u8, 0), + 24..=0xFF => (Constants::ADDITIONAL_INFORMATION_1_BYTE, 1), + 0x100..=0xFFFF => (Constants::ADDITIONAL_INFORMATION_2_BYTES, 2), + 0x10000..=0xFFFF_FFFF => (Constants::ADDITIONAL_INFORMATION_4_BYTES, 4), + _ => (Constants::ADDITIONAL_INFORMATION_8_BYTES, 8), + }; + first_byte |= type_label << Constants::MAJOR_TYPE_BIT_SHIFT; + self.encoded_cbor.push(first_byte); + + for i in (0..shift).rev() { + self.encoded_cbor.push((size >> (i * 8)) as u8); + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + fn write_return(value: Value) -> Option> { + let mut encoded_cbor = Vec::new(); + if write(value, &mut encoded_cbor) { + Some(encoded_cbor) + } else { + None + } + } + + #[test] + fn test_write_unsigned() { + let cases = vec![ + (0, vec![0x00]), + (1, vec![0x01]), + (10, vec![0x0A]), + (23, vec![0x17]), + (24, vec![0x18, 0x18]), + (25, vec![0x18, 0x19]), + (100, vec![0x18, 0x64]), + (1000, vec![0x19, 0x03, 0xE8]), + (1000000, vec![0x1A, 0x00, 0x0F, 0x42, 0x40]), + (0xFFFFFFFF, vec![0x1A, 0xFF, 0xFF, 0xFF, 0xFF]), + ( + 0x100000000, + vec![0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00], + ), + ( + std::i64::MAX, + vec![0x1B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], + ), + ]; + for (unsigned, correct_cbor) in cases { + assert_eq!(write_return(cbor_int!(unsigned)), Some(correct_cbor)); + } + } + + #[test] + fn test_write_negative() { + let cases = vec![ + (-1, vec![0x20]), + (-10, vec![0x29]), + (-23, vec![0x36]), + (-24, vec![0x37]), + (-25, vec![0x38, 0x18]), + (-100, vec![0x38, 0x63]), + (-1000, vec![0x39, 0x03, 0xE7]), + (-4294967296, vec![0x3A, 0xFF, 0xFF, 0xFF, 0xFF]), + ( + -4294967297, + vec![0x3B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00], + ), + ( + std::i64::MIN, + vec![0x3B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], + ), + ]; + for (negative, correct_cbor) in cases { + assert_eq!(write_return(cbor_int!(negative)), Some(correct_cbor)); + } + } + + #[test] + fn test_write_byte_string() { + let cases = vec![ + (vec![], vec![0x40]), + ( + vec![0x01, 0x02, 0x03, 0x04], + vec![0x44, 0x01, 0x02, 0x03, 0x04], + ), + ]; + for (byte_string, correct_cbor) in cases { + assert_eq!(write_return(cbor_bytes!(byte_string)), Some(correct_cbor)); + } + } + + #[test] + fn test_write_text_string() { + let unicode_3byte = vec![0xE6, 0xB0, 0xB4]; + let cases = vec![ + ("", vec![0x60]), + ("a", vec![0x61, 0x61]), + ("IETF", vec![0x64, 0x49, 0x45, 0x54, 0x46]), + ("\"\\", vec![0x62, 0x22, 0x5C]), + ("ü", vec![0x62, 0xC3, 0xBC]), + ( + std::str::from_utf8(&unicode_3byte).unwrap(), + vec![0x63, 0xE6, 0xB0, 0xB4], + ), + ("𐅑", vec![0x64, 0xF0, 0x90, 0x85, 0x91]), + ]; + for (text_string, correct_cbor) in cases { + assert_eq!(write_return(cbor_text!(text_string)), Some(correct_cbor)); + } + } + + #[test] + fn test_write_array() { + let value_vec: Vec<_> = (1..26).collect(); + let expected_cbor = vec![ + 0x98, 0x19, // array of 25 elements + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19, + ]; + assert_eq!( + write_return(cbor_array_vec!(value_vec)), + Some(expected_cbor) + ); + } + + #[test] + fn test_write_map() { + let value_map = cbor_map! { + "aa" => "AA", + "e" => "E", + "" => ".", + -1 => "k", + -24 => "l", + -25 => "m", + -256 => "n", + -257 => "o", + -65537 => "p", + -4294967296_i64 => "q", + -4294967297_i64 => "r", + std::i64::MIN => "s", + b"a" => 2, + b"bar" => 3, + b"foo" => 4, + 0 => "a", + 23 => "b", + 24 => "c", + std::u8::MAX as i64 => "d", + 256 => "e", + std::u16::MAX as i64 => "f", + 65536 => "g", + std::u32::MAX as i64 => "h", + 4294967296_i64 => "i", + std::i64::MAX => "j", + }; + let expected_cbor = vec![ + 0xb8, 0x19, // map of 25 pairs: + 0x00, // key 0 + 0x61, 0x61, // value "a" + 0x17, // key 23 + 0x61, 0x62, // value "b" + 0x18, 0x18, // key 24 + 0x61, 0x63, // value "c" + 0x18, 0xFF, // key 255 + 0x61, 0x64, // value "d" + 0x19, 0x01, 0x00, // key 256 + 0x61, 0x65, // value "e" + 0x19, 0xFF, 0xFF, // key 65535 + 0x61, 0x66, // value "f" + 0x1A, 0x00, 0x01, 0x00, 0x00, // key 65536 + 0x61, 0x67, // value "g" + 0x1A, 0xFF, 0xFF, 0xFF, 0xFF, // key 4294967295 + 0x61, 0x68, // value "h" + // key 4294967296 + 0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x61, 0x69, // value "i" + // key INT64_MAX + 0x1b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x61, 0x6a, // value "j" + 0x20, // key -1 + 0x61, 0x6b, // value "k" + 0x37, // key -24 + 0x61, 0x6c, // value "l" + 0x38, 0x18, // key -25 + 0x61, 0x6d, // value "m" + 0x38, 0xFF, // key -256 + 0x61, 0x6e, // value "n" + 0x39, 0x01, 0x00, // key -257 + 0x61, 0x6f, // value "o" + 0x3A, 0x00, 0x01, 0x00, 0x00, // key -65537 + 0x61, 0x70, // value "p" + 0x3A, 0xFF, 0xFF, 0xFF, 0xFF, // key -4294967296 + 0x61, 0x71, // value "q" + // key -4294967297 + 0x3B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x61, 0x72, // value "r" + // key INT64_MIN + 0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x61, 0x73, // value "s" + 0x41, b'a', // byte string "a" + 0x02, 0x43, b'b', b'a', b'r', // byte string "bar" + 0x03, 0x43, b'f', b'o', b'o', // byte string "foo" + 0x04, 0x60, // key "" + 0x61, 0x2e, // value "." + 0x61, 0x65, // key "e" + 0x61, 0x45, // value "E" + 0x62, 0x61, 0x61, // key "aa" + 0x62, 0x41, 0x41, // value "AA" + ]; + assert_eq!(write_return(value_map), Some(expected_cbor)); + } + + #[test] + fn test_write_map_with_array() { + let value_map = cbor_map! { + "a" => 1, + "b" => cbor_array![2, 3], + }; + let expected_cbor = vec![ + 0xa2, // map of 2 pairs + 0x61, 0x61, // "a" + 0x01, 0x61, 0x62, // "b" + 0x82, // array with 2 elements + 0x02, 0x03, + ]; + assert_eq!(write_return(value_map), Some(expected_cbor)); + } + + #[test] + fn test_write_nested_map() { + let value_map = cbor_map! { + "a" => 1, + "b" => cbor_map! { + "c" => 2, + "d" => 3, + }, + }; + let expected_cbor = vec![ + 0xa2, // map of 2 pairs + 0x61, 0x61, // "a" + 0x01, 0x61, 0x62, // "b" + 0xa2, // map of 2 pairs + 0x61, 0x63, // "c" + 0x02, 0x61, 0x64, // "d" + 0x03, + ]; + assert_eq!(write_return(value_map), Some(expected_cbor)); + } + + #[test] + fn test_write_simple() { + let cases = vec![ + (cbor_false!(), vec![0xF4]), + (cbor_true!(), vec![0xF5]), + (cbor_null!(), vec![0xF6]), + (cbor_undefined!(), vec![0xF7]), + ]; + for (value, correct_cbor) in cases { + assert_eq!(write_return(value), Some(correct_cbor)); + } + } + + #[test] + fn test_write_single_levels() { + let simple_array: Value = cbor_array![2]; + let simple_map: Value = cbor_map! {"b" => 3}; + let positive_cases = vec![ + (cbor_int!(1), 0), + (cbor_bytes!(vec![0x01, 0x02, 0x03, 0x04]), 0), + (cbor_text!("a"), 0), + (cbor_array![], 0), + (cbor_map! {}, 0), + (simple_array.clone(), 1), + (simple_map.clone(), 1), + ]; + let negative_cases = vec![(simple_array.clone(), 0), (simple_map.clone(), 0)]; + for (value, level) in positive_cases { + let mut buf = Vec::new(); + let mut writer = Writer::new(&mut buf); + assert!(writer.encode_cbor(value, level)); + } + for (value, level) in negative_cases { + let mut buf = Vec::new(); + let mut writer = Writer::new(&mut buf); + assert!(!writer.encode_cbor(value, level)); + } + } + + #[test] + fn test_write_nested_map_levels() { + let cbor_map: Value = cbor_map! { + "a" => 1, + "b" => cbor_map! { + "c" => 2, + "d" => 3, + }, + }; + + let mut buf = Vec::new(); + let mut writer = Writer::new(&mut buf); + assert!(writer.encode_cbor(cbor_map.clone(), 2)); + writer = Writer::new(&mut buf); + assert!(!writer.encode_cbor(cbor_map, 1)); + } + + #[test] + fn test_write_unbalanced_nested_containers() { + let cbor_array: Value = cbor_array![ + 1, + 2, + 3, + cbor_map! { + "a" => 1, + "b" => cbor_map! { + "c" => 2, + "d" => 3, + }, + }, + ]; + + let mut buf = Vec::new(); + let mut writer = Writer::new(&mut buf); + assert!(writer.encode_cbor(cbor_array.clone(), 3)); + writer = Writer::new(&mut buf); + assert!(!writer.encode_cbor(cbor_array, 2)); + } + + #[test] + fn test_write_overly_nested() { + let cbor_map: Value = cbor_map! { + "a" => 1, + "b" => cbor_map! { + "c" => 2, + "d" => 3, + "h" => cbor_map! { + "e" => 4, + "f" => 5, + "g" => cbor_array![ + 6, + 7, + cbor_array![ + 8 + ] + ], + }, + }, + }; + + let mut buf = Vec::new(); + let mut writer = Writer::new(&mut buf); + assert!(writer.encode_cbor(cbor_map.clone(), 5)); + writer = Writer::new(&mut buf); + assert!(!writer.encode_cbor(cbor_map, 4)); + } +} diff --git a/libraries/crypto/Cargo.toml b/libraries/crypto/Cargo.toml new file mode 100644 index 0000000..d18c5ad --- /dev/null +++ b/libraries/crypto/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "crypto" +version = "0.1.0" +authors = [ + "Fabian Kaczmarczyck ", + "Guillaume Endignoux ", + "Jean-Michel Picod ", +] +license = "Apache-2.0" +edition = "2018" + +[dependencies] +libtock = { path = "../../third_party/libtock-rs" } +cbor = { path = "../cbor" } +arrayref = "0.3.5" +subtle = { version = "2.2", default-features = false, features = ["nightly"] } +byteorder = { version = "1", default-features = false } +hex = { version = "0.3.2", default-features = false, optional = true } +ring = { version = "0.14.6", optional = true } +untrusted = { version = "0.6.2", optional = true } +rand = { version = "0.6.5", optional = true } +serde = { version = "1.0", optional = true, features = ["derive"] } +serde_json = { version = "1.0", optional = true } +regex = { version = "1", optional = true } + +[features] +std = ["cbor/std", "hex", "rand", "ring", "untrusted", "serde", "serde_json", "regex"] +derive_debug = [] +with_ctap1 = [] diff --git a/libraries/crypto/src/aes256.rs b/libraries/crypto/src/aes256.rs new file mode 100644 index 0000000..cdd5905 --- /dev/null +++ b/libraries/crypto/src/aes256.rs @@ -0,0 +1,541 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::util::{xor_block_16, Block16}; +use super::{Decrypt16BytesBlock, Encrypt16BytesBlock}; + +/** A portable and naive textbook implementation of AES-256 **/ +type Word = [u8; 4]; + +/** This structure caches the round keys, to avoid re-computing the key schedule for each block. **/ +pub struct EncryptionKey { + enc_round_keys: [Block16; 15], +} + +pub struct DecryptionKey { + dec_round_keys: [Block16; 15], +} + +impl EncryptionKey { + // Computes the round keys. + pub fn new(key: &[u8; 32]) -> EncryptionKey { + let mut enc_round_keys = [Default::default(); 15]; + + enc_round_keys[0] = *array_ref![key, 0, 16]; + enc_round_keys[1] = *array_ref![key, 16, 16]; + + let mut word: Word = *array_ref![enc_round_keys[1], 12, 4]; + for i in 2..15 { + if i & 1 == 0 { + rotword(&mut word); + subword(&mut word); + word[0] ^= RCON[(i >> 1) - 1]; + } else { + subword(&mut word); + } + + for j in 0..4 { + xorword(&mut word, *array_ref![enc_round_keys[i - 2], 4 * j, 4]); + *array_mut_ref![enc_round_keys[i], 4 * j, 4] = word; + } + } + + EncryptionKey { enc_round_keys } + } +} + +impl Encrypt16BytesBlock for EncryptionKey { + // Encrypt an AES block in place. + fn encrypt_block(&self, block: &mut Block16) { + add_round_key(block, &self.enc_round_keys[0]); + for i in 1..14 { + aes_enc(block, &self.enc_round_keys[i]); + } + aes_enc_last(block, &self.enc_round_keys[14]); + } +} + +impl DecryptionKey { + // Computes the round keys. + pub fn new(key: &EncryptionKey) -> DecryptionKey { + let mut dec_round_keys = [Default::default(); 15]; + dec_round_keys[0] = key.enc_round_keys[14]; + #[allow(clippy::needless_range_loop)] + for i in 1..14 { + let rk = &mut dec_round_keys[i]; + *rk = key.enc_round_keys[14 - i]; + inv_mix_columns(rk); + } + dec_round_keys[14] = key.enc_round_keys[0]; + + DecryptionKey { dec_round_keys } + } +} + +impl Decrypt16BytesBlock for DecryptionKey { + // Decrypt an AES block in place. + fn decrypt_block(&self, block: &mut Block16) { + add_round_key(block, &self.dec_round_keys[0]); + for i in 1..14 { + aes_dec(block, &self.dec_round_keys[i]); + } + aes_dec_last(block, &self.dec_round_keys[14]); + } +} + +/** Helper functions for the key schedule **/ +fn rotword(word: &mut Word) { + let tmp = word[0]; + word[0] = word[1]; + word[1] = word[2]; + word[2] = word[3]; + word[3] = tmp; +} + +fn subword(word: &mut Word) { + for byte in word.iter_mut() { + *byte = SBOX[*byte as usize]; + } +} + +fn xorword(word: &mut Word, src: Word) { + for i in 0..4 { + word[i] ^= src[i]; + } +} + +/** Helper functions for the encryption **/ +fn aes_enc(block: &mut Block16, rkey: &Block16) { + sub_bytes(block); + shift_rows(block); + mix_columns(block); + add_round_key(block, rkey); +} + +fn aes_dec(block: &mut Block16, rkey: &Block16) { + inv_shift_rows(block); + inv_sub_bytes(block); + inv_mix_columns(block); + add_round_key(block, rkey); +} + +fn aes_enc_last(block: &mut Block16, rkey: &Block16) { + sub_bytes(block); + shift_rows(block); + add_round_key(block, rkey); +} + +fn aes_dec_last(block: &mut Block16, rkey: &Block16) { + inv_shift_rows(block); + inv_sub_bytes(block); + add_round_key(block, rkey); +} + +#[inline(always)] +fn add_round_key(block: &mut Block16, rkey: &Block16) { + xor_block_16(block, rkey); +} + +fn sub_bytes(block: &mut Block16) { + for byte in block.iter_mut() { + *byte = SBOX[*byte as usize]; + } +} + +fn inv_sub_bytes(block: &mut Block16) { + for byte in block.iter_mut() { + *byte = SBOX_INV[*byte as usize]; + } +} + +fn shift_rows(block: &mut Block16) { + let tmp = block[1]; + block[1] = block[5]; + block[5] = block[9]; + block[9] = block[13]; + block[13] = tmp; + + block.swap(2, 10); + block.swap(6, 14); + + let tmp = block[3]; + block[3] = block[15]; + block[15] = block[11]; + block[11] = block[7]; + block[7] = tmp; +} + +fn inv_shift_rows(block: &mut Block16) { + let tmp = block[7]; + block[7] = block[11]; + block[11] = block[15]; + block[15] = block[3]; + block[3] = tmp; + + block.swap(2, 10); + block.swap(6, 14); + + let tmp = block[13]; + block[13] = block[9]; + block[9] = block[5]; + block[5] = block[1]; + block[1] = tmp; +} + +// multiplication by 2 in GF(2^256) +fn mul2(x: u8) -> u8 { + (x << 1) ^ (((x >> 7) & 1) * 0x1b) +} + +// multiplication by 3 in GF(2^256) +fn mul3(x: u8) -> u8 { + mul2(x) ^ x +} + +fn mix_columns(block: &mut Block16) { + for i in 0..4 { + let x0 = block[4 * i]; + let x1 = block[4 * i + 1]; + let x2 = block[4 * i + 2]; + let x3 = block[4 * i + 3]; + block[4 * i] = mul2(x0) ^ mul3(x1) ^ x2 ^ x3; + block[4 * i + 1] = x0 ^ mul2(x1) ^ mul3(x2) ^ x3; + block[4 * i + 2] = x0 ^ x1 ^ mul2(x2) ^ mul3(x3); + block[4 * i + 3] = mul3(x0) ^ x1 ^ x2 ^ mul2(x3); + } +} + +// multiplication by 9 in GF(2^256) +fn mul9(x: u8) -> u8 { + mul2(mul2(mul2(x))) ^ x +} + +// multiplication by 11 in GF(2^256) +fn mul11(x: u8) -> u8 { + mul2(mul2(mul2(x)) ^ x) ^ x +} + +// multiplication by 13 in GF(2^256) +fn mul13(x: u8) -> u8 { + mul2(mul2(mul2(x) ^ x)) ^ x +} + +// multiplication by 14 in GF(2^256) +fn mul14(x: u8) -> u8 { + mul2(mul2(mul2(x) ^ x) ^ x) +} + +fn inv_mix_columns(block: &mut Block16) { + for i in 0..4 { + let x0 = block[4 * i]; + let x1 = block[4 * i + 1]; + let x2 = block[4 * i + 2]; + let x3 = block[4 * i + 3]; + block[4 * i] = mul14(x0) ^ mul11(x1) ^ mul13(x2) ^ mul9(x3); + block[4 * i + 1] = mul9(x0) ^ mul14(x1) ^ mul11(x2) ^ mul13(x3); + block[4 * i + 2] = mul13(x0) ^ mul9(x1) ^ mul14(x2) ^ mul11(x3); + block[4 * i + 3] = mul11(x0) ^ mul13(x1) ^ mul9(x2) ^ mul14(x3); + } +} + +/** Constants **/ +// Constants used in the key schedule. +const RCON: [u8; 7] = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40]; + +// AES substitution box. +const SBOX: [u8; 256] = [ + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16, +]; + +const SBOX_INV: [u8; 256] = [ + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d, +]; + +#[cfg(test)] +mod test { + use super::*; + + // Test vector from the NIST obtained at: + // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_ECB.pdf + #[test] + fn test_nist_aes256_ecb_encrypt() { + let src = b"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\ + \xe9\x3d\x7e\x11\x73\x93\x17\x2a"; + let key = b"\x60\x3d\xeb\x10\x15\xca\x71\xbe\ + \x2b\x73\xae\xf0\x85\x7d\x77\x81\ + \x1f\x35\x2c\x07\x3b\x61\x08\xd7\ + \x2d\x98\x10\xa3\x09\x14\xdf\xf4"; + let expected = b"\xf3\xee\xd1\xbd\xb5\xd2\xa0\x3c\ + \x06\x4b\x5a\x7e\x3d\xb1\x81\xf8"; + + let mut dst: Block16 = Default::default(); + dst.copy_from_slice(src); + EncryptionKey::new(key).encrypt_block(&mut dst); + assert_eq!(&dst, expected); + } + + #[test] + fn test_nist_aes256_ecb_decrypt() { + let src = b"\xf3\xee\xd1\xbd\xb5\xd2\xa0\x3c\ + \x06\x4b\x5a\x7e\x3d\xb1\x81\xf8"; + let key = b"\x60\x3d\xeb\x10\x15\xca\x71\xbe\ + \x2b\x73\xae\xf0\x85\x7d\x77\x81\ + \x1f\x35\x2c\x07\x3b\x61\x08\xd7\ + \x2d\x98\x10\xa3\x09\x14\xdf\xf4"; + let expected = b"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\ + \xe9\x3d\x7e\x11\x73\x93\x17\x2a"; + + let mut dst: Block16 = Default::default(); + dst.copy_from_slice(src); + DecryptionKey::new(&EncryptionKey::new(key)).decrypt_block(&mut dst); + assert_eq!(&dst, expected); + } + + #[test] + fn test_encrypt_decrypt() { + // Test that decrypt_block is the inverse of encrypt_block for a bunch of block values. + let key_bytes = b"\x60\x3d\xeb\x10\x15\xca\x71\xbe\ + \x2b\x73\xae\xf0\x85\x7d\x77\x81\ + \x1f\x35\x2c\x07\x3b\x61\x08\xd7\ + \x2d\x98\x10\xa3\x09\x14\xdf\xf4"; + let enc_key = EncryptionKey::new(key_bytes); + let dec_key = DecryptionKey::new(&enc_key); + let mut block: Block16 = [0; 16]; + for i in 0..=255 { + for j in 0..16 { + block[j] = (i + j) as u8; + } + let expected = block; + enc_key.encrypt_block(&mut block); + dec_key.decrypt_block(&mut block); + assert_eq!(block, expected); + } + } + + #[test] + fn test_sbox_is_permutation() { + let mut image = [false; 256]; + for &sboxed in SBOX.iter() { + assert_eq!(image[sboxed as usize], false); + image[sboxed as usize] = true; + } + } + + #[test] + fn test_sbox_inv_is_permutation() { + let mut image = [false; 256]; + for &sboxed in SBOX_INV.iter() { + assert_eq!(image[sboxed as usize], false); + image[sboxed as usize] = true; + } + } + + #[test] + fn test_sbox_inverse() { + for i in 0..=255 { + assert_eq!(SBOX_INV[SBOX[i as usize] as usize], i); + } + } + + #[test] + fn test_subbytes() { + let mut block = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; + let expected = [ + 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, + ]; + sub_bytes(&mut block); + assert_eq!(block, expected); + } + + #[test] + fn test_subbytes_inv() { + // Test that inv_sub_bytes is the inverse of sub_bytes for a bunch of block values. + let mut block: Block16 = [0; 16]; + for i in 0..=255 { + for j in 0..16 { + block[j] = (i + j) as u8; + } + let expected = block; + sub_bytes(&mut block); + inv_sub_bytes(&mut block); + assert_eq!(block, expected); + } + } + + #[test] + fn test_shift_rows() { + let mut block = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; + let expected = [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11]; + shift_rows(&mut block); + assert_eq!(block, expected); + } + + #[test] + fn test_shift_rows_inv() { + // Test that inv_shift_rows is the inverse of shift_rows for a bunch of block values. + let mut block: Block16 = [0; 16]; + for i in 0..=255 { + for j in 0..16 { + block[j] = (i + j) as u8; + } + let expected = block; + shift_rows(&mut block); + inv_shift_rows(&mut block); + assert_eq!(block, expected); + } + } + + #[test] + fn test_mix_columns_inv() { + // Test that inv_mix_columns is the inverse of mix_columns for a bunch of block values. + let mut block: Block16 = [0; 16]; + for i in 0..=255 { + for j in 0..16 { + block[j] = (i + j) as u8; + } + let expected = block; + mix_columns(&mut block); + inv_mix_columns(&mut block); + assert_eq!(block, expected); + } + } + + /** Comparison with AES-NI instructions for CPUs that support them **/ + #[cfg(all(target_arch = "x86_64", target_feature = "aes"))] + mod aesni { + use super::super::*; + + fn aes_enc_ni(block: &mut Block16, rkey: &Block16) { + use core::arch::x86_64::{__m128i, _mm_aesenc_si128}; + + unsafe { + let block_mm: __m128i = core::mem::transmute(*block); + let rkey_mm: __m128i = core::mem::transmute(*rkey); + let encrypted_mm: __m128i = _mm_aesenc_si128(block_mm, rkey_mm); + *block = core::mem::transmute(encrypted_mm) + } + } + + fn aes_enc_last_ni(block: &mut Block16, rkey: &Block16) { + use core::arch::x86_64::{__m128i, _mm_aesenclast_si128}; + + unsafe { + let block_mm: __m128i = core::mem::transmute(*block); + let rkey_mm: __m128i = core::mem::transmute(*rkey); + let encrypted_mm: __m128i = _mm_aesenclast_si128(block_mm, rkey_mm); + *block = core::mem::transmute(encrypted_mm) + } + } + + fn aes_dec_ni(block: &mut Block16, rkey: &Block16) { + use core::arch::x86_64::{__m128i, _mm_aesdec_si128}; + + unsafe { + let block_mm: __m128i = core::mem::transmute(*block); + let rkey_mm: __m128i = core::mem::transmute(*rkey); + let decrypted_mm: __m128i = _mm_aesdec_si128(block_mm, rkey_mm); + *block = core::mem::transmute(decrypted_mm) + } + } + + fn aes_dec_last_ni(block: &mut Block16, rkey: &Block16) { + use core::arch::x86_64::{__m128i, _mm_aesdeclast_si128}; + + unsafe { + let block_mm: __m128i = core::mem::transmute(*block); + let rkey_mm: __m128i = core::mem::transmute(*rkey); + let decrypted_mm: __m128i = _mm_aesdeclast_si128(block_mm, rkey_mm); + *block = core::mem::transmute(decrypted_mm) + } + } + + #[test] + fn test_aes_enc_ni() { + let mut block = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; + let mut block_ni = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; + let rkey = [ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + ]; + aes_enc(&mut block, &rkey); + aes_enc_ni(&mut block_ni, &rkey); + assert_eq!(block, block_ni); + } + + #[test] + fn test_aes_enc_last_ni() { + let mut block = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; + let mut block_ni = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; + let rkey = [ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + ]; + aes_enc_last(&mut block, &rkey); + aes_enc_last_ni(&mut block_ni, &rkey); + assert_eq!(block, block_ni); + } + + #[test] + fn test_aes_dec_ni() { + let mut block = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; + let mut block_ni = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; + let rkey = [ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + ]; + aes_dec(&mut block, &rkey); + aes_dec_ni(&mut block_ni, &rkey); + assert_eq!(block, block_ni); + } + + #[test] + fn test_aes_dec_last_ni() { + let mut block = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; + let mut block_ni = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; + let rkey = [ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + ]; + aes_dec_last(&mut block, &rkey); + aes_dec_last_ni(&mut block_ni, &rkey); + assert_eq!(block, block_ni); + } + } +} diff --git a/libraries/crypto/src/cbc.rs b/libraries/crypto/src/cbc.rs new file mode 100644 index 0000000..fd7dcc2 --- /dev/null +++ b/libraries/crypto/src/cbc.rs @@ -0,0 +1,258 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::util::{xor_block_16, Block16}; +use super::{Decrypt16BytesBlock, Encrypt16BytesBlock}; + +pub fn cbc_encrypt(key: &K, mut iv: Block16, blocks: &mut [Block16]) +where + K: Encrypt16BytesBlock, +{ + for block in blocks { + xor_block_16(block, &iv); + key.encrypt_block(block); + iv = *block; + } +} + +pub fn cbc_decrypt(key: &K, mut iv: Block16, blocks: &mut [Block16]) +where + K: Decrypt16BytesBlock, +{ + for block in blocks { + let tmp = *block; + key.decrypt_block(block); + xor_block_16(block, &iv); + iv = tmp; + } +} + +#[cfg(test)] +mod test { + use super::super::aes256; + use super::*; + + #[test] + fn test_cbc_encrypt_decrypt() { + // Test that cbc_decrypt is the inverse of cbc_encrypt for a bunch of block values. + let enc_key = aes256::EncryptionKey::new(&[ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, + ]); + let dec_key = aes256::DecryptionKey::new(&enc_key); + + for len in 0..16 { + let mut blocks: Vec = vec![Default::default(); len]; + for i in 0..len { + for j in 0..16 { + blocks[i][j] = ((len + i) * 16 + j) as u8; + } + } + let iv = [ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, + ]; + let expected = blocks.clone(); + + cbc_encrypt(&enc_key, iv, &mut blocks); + cbc_decrypt(&dec_key, iv, &mut blocks); + assert_eq!(blocks, expected); + } + } + + #[test] + fn test_cbc_encrypt_1block_zero_iv() { + let key = aes256::EncryptionKey::new(&[ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, + ]); + + let mut blocks = [[ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, + ]]; + let iv = [0; 16]; + cbc_encrypt(&key, iv, &mut blocks); + + let mut expected = [ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, + ]; + key.encrypt_block(&mut expected); + + assert_eq!(blocks, [expected]); + } + + #[test] + fn test_cbc_decrypt_1block_zero_iv() { + let key = aes256::DecryptionKey::new(&aes256::EncryptionKey::new(&[ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, + ])); + + let mut blocks = [[ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, + ]]; + let iv = [0; 16]; + cbc_decrypt(&key, iv, &mut blocks); + + let mut expected = [ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, + ]; + key.decrypt_block(&mut expected); + + assert_eq!(blocks, [expected]); + } + + #[test] + fn test_cbc_encrypt_1block() { + let key = aes256::EncryptionKey::new(&[ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, + ]); + + let mut blocks = [[ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, + ]]; + let iv = [ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, + ]; + cbc_encrypt(&key, iv, &mut blocks); + + let mut expected = [ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, + ]; + xor_block_16(&mut expected, &iv); + key.encrypt_block(&mut expected); + + assert_eq!(blocks, [expected]); + } + + #[test] + fn test_cbc_decrypt_1block() { + let key = aes256::DecryptionKey::new(&aes256::EncryptionKey::new(&[ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, + ])); + + let mut blocks = [[ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, + ]]; + let iv = [ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, + ]; + cbc_decrypt(&key, iv, &mut blocks); + + let mut expected = [ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, + ]; + key.decrypt_block(&mut expected); + xor_block_16(&mut expected, &iv); + + assert_eq!(blocks, [expected]); + } + + #[test] + fn test_cbc_encrypt_2blocks() { + let key = aes256::EncryptionKey::new(&[ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, + ]); + + let mut blocks = [ + [ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, + ], + [ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, + ], + ]; + let iv = [ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, + ]; + cbc_encrypt(&key, iv, &mut blocks); + + let mut expected0 = [ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, + ]; + let mut expected1 = [ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, + ]; + xor_block_16(&mut expected0, &iv); + key.encrypt_block(&mut expected0); + xor_block_16(&mut expected1, &expected0); + key.encrypt_block(&mut expected1); + + assert_eq!(blocks, [expected0, expected1]); + } + + #[test] + fn test_cbc_decrypt_2blocks() { + let key = aes256::DecryptionKey::new(&aes256::EncryptionKey::new(&[ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, + ])); + + let mut blocks = [ + [ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, + ], + [ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, + ], + ]; + let iv = [ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, + ]; + cbc_decrypt(&key, iv, &mut blocks); + + let mut expected0 = [ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, + ]; + let mut expected1 = [ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, + ]; + key.decrypt_block(&mut expected1); + xor_block_16(&mut expected1, &expected0); + key.decrypt_block(&mut expected0); + xor_block_16(&mut expected0, &iv); + + assert_eq!(blocks, [expected0, expected1]); + } +} diff --git a/libraries/crypto/src/ec/exponent256.rs b/libraries/crypto/src/ec/exponent256.rs new file mode 100644 index 0000000..8638eaa --- /dev/null +++ b/libraries/crypto/src/ec/exponent256.rs @@ -0,0 +1,346 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::super::rng256::Rng256; +use super::int256::{Digit, Int256}; +use core::ops::Mul; +use subtle::{self, Choice, ConditionallySelectable, CtOption}; + +// An exponent on the elliptic curve, that is an element modulo the curve order N. +#[derive(Clone, Copy, PartialEq, Eq)] +// TODO: remove this Default once https://github.com/dalek-cryptography/subtle/issues/63 is +// resolved. +#[derive(Default)] +#[cfg_attr(feature = "derive_debug", derive(Debug))] +pub struct ExponentP256 { + int: Int256, +} + +impl ConditionallySelectable for ExponentP256 { + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + Self { + int: Int256::conditional_select(&a.int, &b.int, choice), + } + } +} + +impl ExponentP256 { + /** Constructors **/ + pub fn from_int_checked(int: Int256) -> CtOption { + CtOption::new(ExponentP256 { int }, int.ct_lt(&Int256::N)) + } + + #[cfg(test)] + // Normally the ExponentP256 type guarantees that its values stay in [0, N[ because N is the + // curve order and therefore exponents >= N are equivalent to their reduction modulo N. + // This unsafe function is only used in tests to check that N is indeed the curve order. + pub unsafe fn from_int_unchecked(int: Int256) -> ExponentP256 { + ExponentP256 { int } + } + + pub fn modn(int: Int256) -> ExponentP256 { + ExponentP256 { + int: int.modd(&Int256::N), + } + } + + /** Helpful getters **/ + pub fn bit(&self, i: usize) -> Digit { + self.int.bit(i) + } + + pub fn to_int(self) -> Int256 { + self.int + } + + pub fn is_zero(&self) -> subtle::Choice { + self.int.is_zero() + } + + pub fn non_zero(self) -> CtOption { + CtOption::new(NonZeroExponentP256 { e: self }, !self.is_zero()) + } + + /** Arithmetic **/ + pub fn mul_top(&self, other: &Int256, other_top: Digit) -> ExponentP256 { + ExponentP256 { + int: Int256::modmul_top(&self.int, other, other_top, &Int256::N), + } + } +} + +/** Arithmetic operators **/ +impl Mul for &ExponentP256 { + type Output = ExponentP256; + + fn mul(self, other: &ExponentP256) -> ExponentP256 { + ExponentP256 { + int: Int256::modmul(&self.int, &other.int, &Int256::N), + } + } +} + +// A non-zero exponent on the elliptic curve. +#[derive(Clone, Copy, PartialEq, Eq)] +// TODO: remove this Default once https://github.com/dalek-cryptography/subtle/issues/63 is +// resolved. +#[derive(Default)] +#[cfg_attr(feature = "derive_debug", derive(Debug))] +pub struct NonZeroExponentP256 { + e: ExponentP256, +} + +impl ConditionallySelectable for NonZeroExponentP256 { + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + Self { + e: ExponentP256::conditional_select(&a.e, &b.e, choice), + } + } +} + +impl NonZeroExponentP256 { + /** RNG **/ + // Generates a uniformly distributed element 0 < k < N + pub fn gen_uniform(r: &mut R) -> NonZeroExponentP256 + where + R: Rng256, + { + loop { + let x = Int256::gen_uniform_256(r); + if bool::from(Int256::N_MIN_2.ct_lt(&x)) { + continue; + } + // At this point, x <= n - 2. + // We add 1 so that 0 < result < n. + return NonZeroExponentP256 { + e: ExponentP256 { int: (&x + 1).0 }, + }; + } + } + + /** Constructors **/ + pub fn from_int_checked(int: Int256) -> CtOption { + ExponentP256::from_int_checked(int) + .and_then(|e| CtOption::new(NonZeroExponentP256 { e }, !e.is_zero())) + } + + /** Helpful getters **/ + pub fn to_int(self) -> Int256 { + self.e.to_int() + } + + pub fn as_exponent(&self) -> &ExponentP256 { + &self.e + } + + /** Arithmetic **/ + // Compute the inverse modulo N. This uses Fermat's little theorem for constant-timeness. + pub fn inv(&self) -> NonZeroExponentP256 { + NonZeroExponentP256 { + e: ExponentP256 { + int: self.e.int.modpow(&Int256::N_MIN_2, &Int256::N), + }, + } + } + + #[cfg(test)] + fn inv_vartime(&self) -> NonZeroExponentP256 { + NonZeroExponentP256 { + e: ExponentP256 { + int: self.e.int.modinv_vartime(&Int256::N), + }, + } + } +} + +/** Arithmetic operators **/ +impl Mul for &NonZeroExponentP256 { + type Output = NonZeroExponentP256; + + // The product of two non-zero elements is also non-zero, because the curve order N is prime. + fn mul(self, other: &NonZeroExponentP256) -> NonZeroExponentP256 { + NonZeroExponentP256 { + e: &self.e * &other.e, + } + } +} + +#[cfg(test)] +pub mod test { + use super::super::montgomery::Montgomery; + use super::*; + use crate::util::ToOption; + + const ZERO: ExponentP256 = ExponentP256 { int: Int256::ZERO }; + const ONE: NonZeroExponentP256 = NonZeroExponentP256 { + e: ExponentP256 { int: Int256::ONE }, + }; + const N_MIN_1_INT: Int256 = Int256::new([ + 0xfc632550, 0xf3b9cac2, 0xa7179e84, 0xbce6faad, 0xffffffff, 0xffffffff, 0x00000000, + 0xffffffff, + ]); + const N_MIN_1: NonZeroExponentP256 = NonZeroExponentP256 { + e: ExponentP256 { int: N_MIN_1_INT }, + }; + + fn get_nonzero_test_values() -> Vec { + let mut values: Vec = Montgomery::PRECOMPUTED + .iter() + .flatten() + .flatten() + .map(|x| { + ExponentP256::modn(x.montgomery_to_field().to_int()) + .non_zero() + .unwrap() + }) + .collect(); + values.extend( + super::super::int256::test::get_nonzero_test_values() + .iter() + .filter_map(|&x| { + let y = ExponentP256::modn(x).non_zero(); + if bool::from(y.is_some()) { + Some(y.unwrap()) + } else { + None + } + }), + ); + values.push(ONE); + values + } + + pub fn get_test_values() -> Vec { + let mut values: Vec = get_nonzero_test_values() + .iter() + .map(|x| *x.as_exponent()) + .collect(); + values.push(ZERO); + values + } + + /** Constructors **/ + #[test] + fn test_from_int_checked() { + assert_eq!( + ExponentP256::from_int_checked(Int256::ZERO).to_option(), + Some(ExponentP256 { int: Int256::ZERO }) + ); + assert_eq!( + ExponentP256::from_int_checked(Int256::ONE).to_option(), + Some(ExponentP256 { int: Int256::ONE }) + ); + assert_eq!( + ExponentP256::from_int_checked(N_MIN_1_INT).to_option(), + Some(ExponentP256 { int: N_MIN_1_INT }) + ); + assert_eq!(ExponentP256::from_int_checked(Int256::N).to_option(), None); + } + + #[test] + fn test_modn() { + assert_eq!( + ExponentP256::modn(Int256::ZERO), + ExponentP256 { int: Int256::ZERO } + ); + assert_eq!( + ExponentP256::modn(Int256::ONE), + ExponentP256 { int: Int256::ONE } + ); + assert_eq!( + ExponentP256::modn(N_MIN_1_INT), + ExponentP256 { int: N_MIN_1_INT } + ); + assert_eq!( + ExponentP256::modn(Int256::N), + ExponentP256 { int: Int256::ZERO } + ); + } + + /** Arithmetic operations: inverse **/ + #[test] + fn test_inv_is_inv_vartime() { + for x in &get_nonzero_test_values() { + assert_eq!(x.inv(), x.inv_vartime()); + } + } + + #[test] + fn test_self_times_inv_is_one() { + for x in &get_nonzero_test_values() { + assert_eq!(x * &x.inv(), ONE); + } + } + + #[test] + fn test_inv_inv() { + for x in get_nonzero_test_values() { + assert_eq!(x.inv().inv(), x); + } + } + + #[test] + fn test_well_known_inverses() { + assert_eq!(ONE.inv(), ONE); + assert_eq!(N_MIN_1.inv(), N_MIN_1); + } + + /** RNG **/ + // Mock rng that samples through a list of values, then panics. + struct StressTestingRng { + values: Vec, + index: usize, + } + + impl StressTestingRng { + pub fn new(values: Vec) -> StressTestingRng { + StressTestingRng { values, index: 0 } + } + } + + impl Rng256 for StressTestingRng { + // This function is unused, as we redefine gen_uniform_u32x8. + fn gen_uniform_u8x32(&mut self) -> [u8; 32] { + unreachable!() + } + + fn gen_uniform_u32x8(&mut self) -> [u32; 8] { + let result = self.values[self.index].digits(); + self.index += 1; + result + } + } + + #[test] + fn test_uniform_non_zero_is_below_n() { + let mut rng = StressTestingRng::new(vec![ + Int256::new([ + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, + ]), + Int256::N, + N_MIN_1.to_int(), + Int256::N_MIN_2, + ]); + + assert_eq!(NonZeroExponentP256::gen_uniform(&mut rng), N_MIN_1); + } + + #[test] + fn test_uniform_n_is_above_zero() { + let mut rng = StressTestingRng::new(vec![Int256::ZERO]); + + assert_eq!(NonZeroExponentP256::gen_uniform(&mut rng), ONE); + } +} diff --git a/libraries/crypto/src/ec/gfp256.rs b/libraries/crypto/src/ec/gfp256.rs new file mode 100644 index 0000000..bb3232c --- /dev/null +++ b/libraries/crypto/src/ec/gfp256.rs @@ -0,0 +1,260 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::int256::{Digit, Int256}; +use core::ops::Mul; +use subtle::Choice; + +// A field element on the elliptic curve, that is an element modulo the prime P. +// This is the format used to serialize coordinates of points on the curve. +// This implements enough methods to validate points and to convert them to/from the Montgomery +// form, which is more convenient to operate on. +#[derive(Clone, Copy, PartialEq, Eq)] +pub struct GFP256 { + int: Int256, +} + +impl GFP256 { + pub const ZERO: GFP256 = GFP256 { int: Int256::ZERO }; + pub const ONE: GFP256 = GFP256 { int: Int256::ONE }; + pub const B: GFP256 = GFP256 { int: Int256::B }; + pub const R: GFP256 = GFP256 { int: Int256::R }; + pub const R_INV: GFP256 = GFP256 { int: Int256::R_INV }; + + /** Constructors **/ + pub fn from_int_checked(int: Int256) -> Option { + if bool::from(int.ct_lt(&Int256::P)) { + Some(GFP256 { int }) + } else { + None + } + } + + /** Helpful getters **/ + pub fn to_int(self) -> Int256 { + self.int + } + + fn is_zero(&self) -> Choice { + self.int.is_zero() + } + + /** Arithmetic **/ + pub fn mul_top(&self, other: &Int256, other_top: Digit) -> GFP256 { + GFP256 { + int: Int256::modmul_top(&self.int, other, other_top, &Int256::P), + } + } + + /** Point validation **/ + // Verify that all of the following are true: + // * y^2 == x^3 - 3x + b mod p + // * 0 < x < p + // * 0 < y < p + // + // Not constant time. + pub fn is_valid_point_vartime(x: &GFP256, y: &GFP256) -> bool { + if bool::from(x.is_zero()) || bool::from(y.is_zero()) { + return false; + } + + // y^2 + let y2 = y * y; + + // x^3 + let x2 = x * x; + let x3 = &x2 * x; + + // x^3 - 3x + b + let mut xx = x3; + xx = xx.sub_vartime(x); + xx = xx.sub_vartime(x); + xx = xx.sub_vartime(x); + xx = xx.add_vartime(&GFP256::B); + + xx == y2 + } + + /** Arithmetic operators **/ + fn add_vartime(self, other: &GFP256) -> GFP256 { + GFP256 { + int: Int256::modadd_vartime(&self.int, &other.int, &Int256::P), + } + } + + fn sub_vartime(self, other: &GFP256) -> GFP256 { + GFP256 { + int: Int256::modsub_vartime(&self.int, &other.int, &Int256::P), + } + } +} + +/** Arithmetic operators **/ +impl Mul for &GFP256 { + type Output = GFP256; + + fn mul(self, other: &GFP256) -> GFP256 { + GFP256 { + int: Int256::modmul(&self.int, &other.int, &Int256::P), + } + } +} + +#[cfg(feature = "derive_debug")] +impl core::fmt::Debug for GFP256 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "GFP256::{:?}", self.int) + } +} + +#[cfg(test)] +mod test { + use super::super::montgomery::Montgomery; + use super::*; + use core::ops::{Add, Sub}; + + const P_MIN_1_INT: Int256 = Int256::new([ + 0xfffffffe, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0xffffffff, + ]); + + fn get_test_values() -> Vec { + let mut values: Vec = Montgomery::PRECOMPUTED + .iter() + .flatten() + .flatten() + .map(|x| x.montgomery_to_field()) + .collect(); + values.extend( + super::super::int256::test::get_1bit_one_test_values() + .iter() + .filter_map(|&x| GFP256::from_int_checked(x)), + ); + values.extend( + super::super::int256::test::get_1bit_zero_test_values() + .iter() + .filter_map(|&x| GFP256::from_int_checked(x)), + ); + values.push(GFP256::ZERO); + values.push(GFP256::ONE); + values.push(GFP256::B); + values + } + + /** Arithmetic operators, only for tests as these are not constant time **/ + impl Add for &GFP256 { + type Output = GFP256; + + fn add(self, other: &GFP256) -> GFP256 { + self.add_vartime(other) + } + } + + impl Sub for &GFP256 { + type Output = GFP256; + + fn sub(self, other: &GFP256) -> GFP256 { + self.sub_vartime(other) + } + } + + /** Constructors **/ + #[test] + fn test_from_int_checked() { + assert_eq!( + GFP256::from_int_checked(Int256::ZERO), + Some(GFP256 { int: Int256::ZERO }) + ); + assert_eq!( + GFP256::from_int_checked(Int256::ONE), + Some(GFP256 { int: Int256::ONE }) + ); + assert_eq!( + GFP256::from_int_checked(P_MIN_1_INT), + Some(GFP256 { int: P_MIN_1_INT }) + ); + assert_eq!(GFP256::from_int_checked(Int256::P), None); + } + + /** Point validation **/ + // See point.rs + + /** Arithmetic operators **/ + // Due to the 3 nested loops, this test is super slow with debug assertions enabled. + #[cfg(not(debug_assertions))] + #[test] + fn test_add_is_associative() { + for x in &get_test_values() { + for y in &get_test_values() { + for z in &get_test_values() { + assert_eq!(&(x + y) + z, x + &(y + z)); + } + } + } + } + + #[test] + fn test_add_is_commutative() { + for x in &get_test_values() { + for y in &get_test_values() { + assert_eq!(x + y, y + x); + } + } + } + + #[test] + fn test_add_sub() { + for x in &get_test_values() { + for y in &get_test_values() { + assert_eq!(&(x - y) + y, *x); + assert_eq!(&(x + y) - y, *x); + } + } + } + + // Due to the 3 nested loops, this test is super slow with debug assertions enabled. + #[cfg(not(debug_assertions))] + #[test] + fn test_mul_is_associative() { + for x in &get_test_values() { + for y in &get_test_values() { + for z in &get_test_values() { + assert_eq!(&(x * y) * z, x * &(y * z)); + } + } + } + } + + #[test] + fn test_mul_is_commutative() { + for x in &get_test_values() { + for y in &get_test_values() { + assert_eq!(x * y, y * x); + } + } + } + + // Due to the 3 nested loops, this test is super slow with debug assertions enabled. + #[cfg(not(debug_assertions))] + #[test] + fn test_mul_is_distributive() { + for x in &get_test_values() { + for y in &get_test_values() { + for z in &get_test_values() { + assert_eq!(&(x + y) * z, &(x * z) + &(y * z)); + } + } + } + } +} diff --git a/libraries/crypto/src/ec/int256.rs b/libraries/crypto/src/ec/int256.rs new file mode 100644 index 0000000..2f3a1da --- /dev/null +++ b/libraries/crypto/src/ec/int256.rs @@ -0,0 +1,1181 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::super::rng256::Rng256; +use alloc::vec::Vec; +use byteorder::{BigEndian, ByteOrder}; +use core::ops::{Add, AddAssign, Sub, SubAssign}; +use subtle::{self, Choice, ConditionallySelectable, ConstantTimeEq}; + +const BITS_PER_DIGIT: usize = 32; +const BYTES_PER_DIGIT: usize = BITS_PER_DIGIT >> 3; +const NDIGITS: usize = 8; +pub const NBYTES: usize = NDIGITS * BYTES_PER_DIGIT; + +pub type Digit = u32; +type DoubleDigit = u64; +type SignedDoubleDigit = i64; + +#[derive(Clone, Copy, PartialEq, Eq)] +// TODO: remove this Default once https://github.com/dalek-cryptography/subtle/issues/63 is +// resolved. +#[derive(Default)] +pub struct Int256 { + digits: [Digit; NDIGITS], +} + +impl ConditionallySelectable for Int256 { + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + let mut digits = [0; NDIGITS]; + for (i, digit) in digits.iter_mut().enumerate() { + *digit = Digit::conditional_select(&a.digits[i], &b.digits[i], choice); + } + Self { digits } + } +} + +/** Arithmetic operations on the secp256r1 field, where elements are represented as 8 digits of + * 32 bits. **/ +#[allow(clippy::unreadable_literal)] +impl Int256 { + /** Constants for the secp256r1 curve. **/ + // Curve order (prime) + pub const N: Int256 = Int256 { + digits: [ + 0xfc632551, 0xf3b9cac2, 0xa7179e84, 0xbce6faad, 0xffffffff, 0xffffffff, 0x00000000, + 0xffffffff, + ], + }; + // Curve order - 2 + pub const N_MIN_2: Int256 = Int256 { + digits: [ + 0xfc63254f, 0xf3b9cac2, 0xa7179e84, 0xbce6faad, 0xffffffff, 0xffffffff, 0x00000000, + 0xffffffff, + ], + }; + // Curve field size + pub const P: Int256 = Int256 { + digits: [ + 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0xffffffff, + ], + }; + // Curve b + pub const B: Int256 = Int256 { + digits: [ + 0x27d2604b, 0x3bce3c3e, 0xcc53b0f6, 0x651d06b0, 0x769886bc, 0xb3ebbd55, 0xaa3a93e7, + 0x5ac635d8, + ], + }; + // 2^257 mod P + pub const R: Int256 = Int256 { + digits: [ + 0x00000002, 0x00000000, 0x00000000, 0xfffffffe, 0xffffffff, 0xffffffff, 0xfffffffd, + 0x00000001, + ], + }; + // 1 / 2^257 mod P + pub const R_INV: Int256 = Int256 { + digits: [ + 0x80000000, 0x00000001, 0xffffffff, 0x00000000, 0x80000001, 0xfffffffe, 0x00000001, + 0x7fffffff, + ], + }; + + pub const ZERO: Int256 = Int256 { digits: [0; 8] }; + pub const ONE: Int256 = Int256 { + digits: [1, 0, 0, 0, 0, 0, 0, 0], + }; + + #[cfg(test)] + pub const fn new(digits: [Digit; NDIGITS]) -> Int256 { + Int256 { digits } + } + + #[cfg(test)] + pub fn digits(self) -> [Digit; NDIGITS] { + self.digits + } + + #[cfg(test)] + fn hamming_weight(&self) -> u32 { + self.digits.iter().map(|d| d.count_ones()).sum() + } + + /** RNG **/ + // Generates a uniformly distributed integer 0 <= x < 2^256 + pub fn gen_uniform_256(r: &mut R) -> Int256 + where + R: Rng256, + { + Int256 { + digits: r.gen_uniform_u32x8(), + } + } + + /** Serialization **/ + pub fn from_bin(src: &[u8; NBYTES]) -> Int256 { + let mut digits = [0; NDIGITS]; + for i in 0..NDIGITS { + digits[NDIGITS - 1 - i] = BigEndian::read_u32(array_ref![src, 4 * i, 4]); + } + Int256 { digits } + } + + pub fn to_bin(&self, dst: &mut [u8; NBYTES]) { + for i in 0..NDIGITS { + BigEndian::write_u32(array_mut_ref![dst, 4 * i, 4], self.digits[NDIGITS - 1 - i]); + } + } + + pub fn to_minimal_encoding(self) -> Vec { + let mut bytes_buffer = [0; NBYTES]; + self.to_bin(&mut bytes_buffer); + match bytes_buffer.iter().position(|x| *x != 0) { + Some(pos) => { + let mut encoding = vec![]; + if bytes_buffer[pos] & 0x80 == 0x80 { + encoding.push(0x00); + } + encoding.extend_from_slice(&bytes_buffer[pos..]); + encoding + } + None => vec![0x00], + } + } + + /** Useful getters **/ + #[inline(always)] + pub fn digit(&self, i: usize) -> Digit { + self.digits[i] + } + + pub fn bit(&self, i: usize) -> Digit { + let digit = i / BITS_PER_DIGIT; + let bit = i & (BITS_PER_DIGIT - 1); + (self.digits[digit] >> bit) & 1 + } + + pub fn is_zero(&self) -> subtle::Choice { + // Best effort constant-time comparison, assuming the compiler doesn't optimize that. + Choice::from( + self.digits + .iter() + .fold(1u8, |acc, x| acc & x.ct_eq(&0).unwrap_u8()), + ) + } + + // Helper function to implement variable-time modular inverse. + #[cfg(test)] + fn is_even(&self) -> bool { + self.digits[0] & 1 == 0 + } + + #[cfg(test)] + fn count_ones(&self) -> u32 { + self.digits.iter().map(|x| x.count_ones()).sum() + } + + /** Arithmetic operations: bit shifts **/ + // Shift left by n bits, and return the result as well as the top digit that was shifted out. + // This is valid only for 0 < n < BITS_PER_DIGIT + pub fn shl(&self, n: usize) -> (Int256, Digit) { + let mut digits = [0; NDIGITS]; + digits[0] = self.digits[0] << n; + #[allow(clippy::needless_range_loop)] + for i in 1..NDIGITS { + digits[i] = (self.digits[i] << n) | (self.digits[i - 1] >> (BITS_PER_DIGIT - n)); + } + + ( + Int256 { digits }, + self.digits[NDIGITS - 1] >> (BITS_PER_DIGIT - n), + ) + } + + // Shift right by n bits. + // This is valid only for 0 < n < BITS_PER_DIGIT + pub fn shr(&self, n: usize) -> Int256 { + let mut digits = [0; NDIGITS]; + #[allow(clippy::needless_range_loop)] + for i in 0..(NDIGITS - 1) { + digits[i] = (self.digits[i] >> n) | (self.digits[i + 1] << (BITS_PER_DIGIT - n)); + } + digits[NDIGITS - 1] = self.digits[NDIGITS - 1] >> n; + + Int256 { digits } + } + + // Helper function to implement variable-time modular inverse. + // Shift right by 1 bit, pushing highbit at the top. + #[cfg(test)] + fn shr1(&self, highbit: Digit) -> Int256 { + let mut digits = [0; NDIGITS]; + for i in 0..(NDIGITS - 1) { + digits[i] = (self.digits[i] >> 1) | (self.digits[i + 1] << (BITS_PER_DIGIT - 1)); + } + digits[NDIGITS - 1] = (self.digits[NDIGITS - 1] >> 1) | (highbit << (BITS_PER_DIGIT - 1)); + + Int256 { digits } + } + + /** Arithmetic operations: addition/substraction **/ + // Reduction modulo modd. + pub fn modd(&self, modd: &Int256) -> Int256 { + let mut digits = self.digits; + let choice = Int256::sub_conditional(&mut digits, modd, 0, Choice::from(1u8)); + Int256::add_conditional(&mut digits, modd, 0, choice); + Int256 { digits } + } + + // Computes: dst[], top += if choice { mod[] } else { 0 } + // Returns: new top digit + fn add_conditional( + dst: &mut [Digit; NDIGITS], + modd: &Int256, + top: Digit, + choice: Choice, + ) -> Digit { + let mut carry: DoubleDigit = 0; + + for (i, digit) in dst.iter_mut().enumerate() { + carry += *digit as DoubleDigit; + carry += u32::conditional_select(&0, &modd.digits[i], choice) as DoubleDigit; + *digit = carry as Digit; + carry >>= BITS_PER_DIGIT; + } + + (carry as Digit) + top + } + + // Computes: dst[], top -= if choice { mod[] } else { 0 } + // Returns: new top digit + fn sub_conditional( + dst: &mut [Digit; NDIGITS], + modd: &Int256, + top: Digit, + choice: Choice, + ) -> Choice { + let mut borrow: SignedDoubleDigit = 0; + + for (i, digit) in dst.iter_mut().enumerate() { + borrow += *digit as SignedDoubleDigit; + borrow -= u32::conditional_select(&0, &modd.digits[i], choice) as SignedDoubleDigit; + *digit = borrow as Digit; + borrow >>= BITS_PER_DIGIT; + } + + ((borrow + (top as SignedDoubleDigit)) as Digit).ct_eq(&!0) + } + + /** Modular arithmetic operations **/ + // Modular addition. + pub fn modadd_vartime(&self, other: &Int256, modd: &Int256) -> Int256 { + let (sum, carry) = (self as &Int256) + other; + let tmp = if carry != 0 { (&sum - modd).0 } else { sum }; + + // At this point, the sum can be >= modd, even without carry. + // We substract modd to handle this case. + tmp.modsub_vartime(modd, modd) + } + + // Modular substraction. + pub fn modsub_vartime(&self, other: &Int256, modd: &Int256) -> Int256 { + let (diff, borrow) = (self as &Int256) - other; + if borrow != 0 { + (&diff + modd).0 + } else { + diff + } + } + + // Requires: the most-significant word of the modulus is 0xffffffff. + // Computes: a * b modulo modd. + pub fn modmul(a: &Int256, b: &Int256, modd: &Int256) -> Int256 { + Int256::modmul_top(a, b, 0, modd) + } + + // Requires: the most-significant word of the modulus is 0xffffffff. + // Computes: a * (b, top_b) modulo modd. + pub fn modmul_top(a: &Int256, b: &Int256, top_b: Digit, modd: &Int256) -> Int256 { + let mut tmp = [0; NDIGITS * 2 + 1]; + let mut top = 0; + + // Multiply/add into tmp. + for i in 0..NDIGITS { + if i != 0 { + tmp[i + NDIGITS - 1] = top; + } + top = Int256::mul_add(array_mut_ref![tmp, i, NDIGITS], a, b.digits[i]); + } + + tmp[2 * NDIGITS - 1] = top; + top = Int256::mul_add(array_mut_ref![tmp, NDIGITS, NDIGITS], a, top_b); + + // Reduce tmp, digit by digit. + for j in 0..=NDIGITS { + let i = NDIGITS - j; + + // Estimate the reducer as top * modd, because the most significant word of modd is + // 0xffffffff. + let mut reducer = Int256::ZERO; + let top_reducer = Int256::mul_add(&mut reducer.digits, modd, top); + top = Int256::sub_top(array_mut_ref![tmp, i, NDIGITS], &reducer, top, top_reducer); + + #[cfg(test)] + assert!(top <= 1); + + let _top = + Int256::sub_conditional(array_mut_ref![tmp, i, NDIGITS], modd, top, top.ct_eq(&1)); + + #[cfg(test)] + assert_eq!(bool::from(_top), false); + + top = tmp[i + NDIGITS - 1]; + } + + let choice = + Int256::sub_conditional(array_mut_ref![tmp, 0, NDIGITS], modd, 0, Choice::from(1u8)); + Int256::add_conditional(array_mut_ref![tmp, 0, NDIGITS], modd, 0, choice); + + Int256 { + digits: *array_ref![tmp, 0, NDIGITS], + } + } + + // Helper function to implement modular multiplication. + // Computes: dst[] += src[] * factor + // Returns: carry digit + fn mul_add(dst: &mut [Digit; NDIGITS], src: &Int256, factor: Digit) -> Digit { + let mut carry: DoubleDigit = 0; + + for (i, digit) in dst.iter_mut().enumerate() { + carry += *digit as DoubleDigit; + carry += (src.digits[i] as DoubleDigit) * (factor as DoubleDigit); + *digit = carry as Digit; + carry >>= BITS_PER_DIGIT; + } + + carry as Digit + } + + // Helper function to implement modular multiplication. + // Computes: dst[], top -= src[], src_top + // Returns: borrow digit (new top) + fn sub_top(dst: &mut [Digit; NDIGITS], src: &Int256, top: Digit, src_top: Digit) -> Digit { + let mut borrow: SignedDoubleDigit = 0; + + for (i, digit) in dst.iter_mut().enumerate() { + borrow += *digit as SignedDoubleDigit; + borrow -= src.digits[i] as SignedDoubleDigit; + *digit = borrow as Digit; + borrow >>= BITS_PER_DIGIT; + } + + borrow += top as SignedDoubleDigit; + borrow -= src_top as SignedDoubleDigit; + + #[cfg(test)] + assert_eq!(borrow >> BITS_PER_DIGIT, 0); + + borrow as Digit + } + + /** Constant-time helpers **/ + // Helper function to implement constant-time modular inverse. + // Best-effort constant time function that computes: + // if idx == 0 { + // *tbl0 = Int256::ONE + // } else { + // *tbl0 = tbl[idx - 1] + // } + fn set_zero_to_idx(tbl0: &mut Int256, tbl: &[Int256; 15], idx: u32) { + *tbl0 = Int256::ONE; + for i in 1u32..16 { + tbl0.conditional_assign(&tbl[(i - 1) as usize], i.ct_eq(&idx)); + } + } + + /** Arithmetic operations: modular exponentiation **/ + pub fn modpow(&self, power: &Int256, modd: &Int256) -> Int256 { + let mut tbl0 = Int256::ZERO; + let mut tbl = [Int256::ZERO; 15]; + // tbl[i-1] = self^i + tbl[0] = *self; + for i in 1..15 { + tbl[i] = Int256::modmul(&tbl[i - 1], self, modd); + } + + let mut result = Int256::ONE; + for j in (0..256).step_by(4) { + let i = 256 - j; + result = Int256::modmul(&result, &result, modd); + result = Int256::modmul(&result, &result, modd); + result = Int256::modmul(&result, &result, modd); + result = Int256::modmul(&result, &result, modd); + + let idx = power.bit(i - 1) << 3 + | power.bit(i - 2) << 2 + | power.bit(i - 3) << 1 + | power.bit(i - 4); + + Int256::set_zero_to_idx(&mut tbl0, &tbl, idx); // tbl0 = tbl[idx-1]; + tbl0 = Int256::modmul(&tbl0, &result, modd); + result.conditional_assign(&tbl0, !idx.ct_eq(&0)); + } + + result + } + + /** Arithmetic operations: modular inverse **/ + // Variable time function to compute modular inverse. This uses Euclid's theorem. + #[cfg(test)] + #[allow(clippy::many_single_char_names)] + pub fn modinv_vartime(&self, modd: &Int256) -> Int256 { + let mut r = Int256::ZERO; + let mut s = Int256::ONE; + let mut u = *modd; + let mut v = *self; + + loop { + if u.is_even() { + u = u.shr1(0); + if r.is_even() { + r = r.shr1(0); + } else { + let (rr, highbit) = &r + modd; + r = rr.shr1(highbit); + } + } else if v.is_even() { + v = v.shr1(0); + if s.is_even() { + s = s.shr1(0); + } else { + let (ss, highbit) = &s + modd; + s = ss.shr1(highbit); + } + } else { + let (w, borrow) = &v - &u; + if borrow == 0 { + v = w; + let (ss, borrow) = &s - &r; + s = if borrow != 0 { (&ss + modd).0 } else { ss }; + if bool::from(v.is_zero()) { + break; + } + } else { + u = (&u - &v).0; + let (rr, borrow) = &r - &s; + r = if borrow != 0 { (&rr + modd).0 } else { rr }; + } + } + } + + r.modd(modd) + } + + /** Comparison between field elements. **/ + // Best-effort constant-time less-than operation. + // FIXME: This code is currently required because subtle only supports constant-time equality + // comparisons. This should be removed once + // https://github.com/dalek-cryptography/subtle/issues/61 is fixed + pub fn ct_lt(&self, other: &Int256) -> Choice { + let mut borrow: SignedDoubleDigit = 0; + + for i in 0..NDIGITS { + // The following statement updates the borrow according to this table. + // +-------------------------------------+----------------+------------------+ + // | self.digits[i].cmp(other.digits[i]) | borrow += ? | resulting borrow | + // +-------------------------------------+----------------+------------------+ + // | Less | ffffffff_xx... | ffffffff_yy... | + // | Equal | 0 | unchanged | + // | Greater | 00000000_xx... | 00000000_yy... | + // +-------------------------------------+----------------+------------------+ + borrow += + (self.digits[i] as SignedDoubleDigit) - (other.digits[i] as SignedDoubleDigit); + // This is a signed shift. After this operation, the borrow can take two values: + // - 00...00 (so far, self >= other) + // - ff...ff (so far, self < other) + borrow >>= BITS_PER_DIGIT; + } + + Choice::from((borrow & 1) as u8) + } + + // Best-effort constant time comparison. + // * 0 = equal + // * 1 = self > other + // * -1 = self < other + #[cfg(test)] + pub fn compare(&self, other: &Int256) -> u32 { + let mut borrow: SignedDoubleDigit = 0; + let mut notzero: Digit = 0; + + for i in 0..NDIGITS { + borrow += + (self.digits[i] as SignedDoubleDigit) - (other.digits[i] as SignedDoubleDigit); + notzero |= (borrow as Digit != 0) as Digit; + borrow >>= BITS_PER_DIGIT; + } + + (borrow as Digit) | notzero + } + + #[cfg(test)] + fn compare_vartime(&self, other: &Int256) -> u32 { + use core::cmp::Ordering; + + for i in 0..NDIGITS { + match self.digits[NDIGITS - i - 1].cmp(&other.digits[NDIGITS - i - 1]) { + Ordering::Equal => continue, + Ordering::Greater => return 1, + Ordering::Less => return 0xffffffff, + } + } + 0 + } +} + +/** Addition with carry **/ +impl Add for &Int256 { + type Output = (Int256, Digit); + + // Returns sum and carry (0 or 1). + fn add(self, other: &Int256) -> (Int256, Digit) { + let mut digits = [0; NDIGITS]; + let mut carry: DoubleDigit = 0; + + for (i, digit) in digits.iter_mut().enumerate() { + carry += (self.digits[i] as DoubleDigit) + (other.digits[i] as DoubleDigit); + *digit = carry as Digit; + carry >>= BITS_PER_DIGIT; + } + + (Int256 { digits }, carry as Digit) + } +} + +impl AddAssign<&Int256> for Int256 { + // Adds to self, ignoring carry. + fn add_assign(&mut self, other: &Int256) { + let mut carry: DoubleDigit = 0; + for i in 0..NDIGITS { + carry += (self.digits[i] as DoubleDigit) + (other.digits[i] as DoubleDigit); + self.digits[i] = carry as Digit; + carry >>= BITS_PER_DIGIT; + } + } +} + +impl Add for &Int256 { + type Output = (Int256, Digit); + + // Returns sum and carry (0 or 1). + fn add(self, digit: Digit) -> (Int256, Digit) { + let mut digits = [0; NDIGITS]; + let mut carry = digit as DoubleDigit; + + for (i, digit) in digits.iter_mut().enumerate() { + carry += self.digits[i] as DoubleDigit; + *digit = carry as Digit; + carry >>= BITS_PER_DIGIT; + } + + (Int256 { digits }, carry as Digit) + } +} + +/** Substraction with borrow **/ +impl Sub for &Int256 { + type Output = (Int256, Digit); + + // Returns difference and borrow (0 or -1). + fn sub(self, other: &Int256) -> (Int256, Digit) { + let mut digits = [0; NDIGITS]; + let mut borrow: SignedDoubleDigit = 0; + + for (i, digit) in digits.iter_mut().enumerate() { + borrow += + (self.digits[i] as SignedDoubleDigit) - (other.digits[i] as SignedDoubleDigit); + *digit = borrow as Digit; + borrow >>= BITS_PER_DIGIT; + } + + (Int256 { digits }, borrow as Digit) + } +} + +impl SubAssign<&Int256> for Int256 { + // Substract from self, ignoring carry. + fn sub_assign(&mut self, other: &Int256) { + let mut borrow: SignedDoubleDigit = 0; + for i in 0..NDIGITS { + borrow += + (self.digits[i] as SignedDoubleDigit) - (other.digits[i] as SignedDoubleDigit); + self.digits[i] = borrow as Digit; + borrow >>= BITS_PER_DIGIT; + } + } +} + +#[cfg(feature = "derive_debug")] +impl core::fmt::Debug for Int256 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "Int256 {{ digits: {:08x?} }}", self.digits) + } +} + +#[cfg(test)] +pub mod test { + use super::super::montgomery::Montgomery; + use super::*; + + /** Extra constants for tests **/ + const TWO: Int256 = Int256 { + digits: [2, 0, 0, 0, 0, 0, 0, 0], + }; + const P_MIN_1: Int256 = Int256 { + digits: [ + 0xfffffffe, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0xffffffff, + ], + }; + const P_MIN_2: Int256 = Int256 { + digits: [ + 0xfffffffd, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0xffffffff, + ], + }; + + // Generate all 256-bit integers that have exactly one bit set to 1. + pub fn get_1bit_one_test_values() -> Vec { + let mut values = Vec::new(); + for &byte in &[0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80] { + for &int in &[byte, byte << 8, byte << 16, byte << 24] { + values.push(Int256 { + digits: [int, 0, 0, 0, 0, 0, 0, 0], + }); + values.push(Int256 { + digits: [0, int, 0, 0, 0, 0, 0, 0], + }); + values.push(Int256 { + digits: [0, 0, int, 0, 0, 0, 0, 0], + }); + values.push(Int256 { + digits: [0, 0, 0, int, 0, 0, 0, 0], + }); + values.push(Int256 { + digits: [0, 0, 0, 0, int, 0, 0, 0], + }); + values.push(Int256 { + digits: [0, 0, 0, 0, 0, int, 0, 0], + }); + values.push(Int256 { + digits: [0, 0, 0, 0, 0, 0, int, 0], + }); + values.push(Int256 { + digits: [0, 0, 0, 0, 0, 0, 0, int], + }); + } + } + values + } + + // Generate all 256-bit integers that have exactly one bit set to 0. + pub fn get_1bit_zero_test_values() -> Vec { + let values: Vec = get_1bit_one_test_values() + .iter() + .map(|x| { + let mut digits = [Default::default(); NDIGITS]; + for i in 0..NDIGITS { + digits[i] = !x.digits[i]; + } + Int256 { digits } + }) + .collect(); + values + } + + pub fn get_nonzero_test_values() -> Vec { + let mut values: Vec = Montgomery::PRECOMPUTED + .iter() + .flatten() + .flatten() + .map(|x| x.montgomery_to_field().to_int()) + .collect(); + values.append(&mut get_1bit_one_test_values()); + values.append(&mut get_1bit_zero_test_values()); + values.push(Int256::B); + values.push(P_MIN_1); + values.push(P_MIN_2); + values + } + + fn get_test_values() -> Vec { + let mut values = get_nonzero_test_values(); + values.push(Int256::ZERO); + values + } + + #[test] + fn test_1bit_one() { + let values = get_1bit_one_test_values(); + assert_eq!(values.len(), 256); + for x in &values { + assert_eq!(x.hamming_weight(), 1); + } + } + + #[test] + fn test_1bit_zero() { + let values = get_1bit_zero_test_values(); + assert_eq!(values.len(), 256); + for x in &values { + assert_eq!(x.hamming_weight(), 255); + } + } + + /** Serialization **/ + #[test] + fn test_to_bin_from_bin() { + for &x in &get_test_values() { + let mut buf = [Default::default(); NBYTES]; + x.to_bin(&mut buf); + assert_eq!(Int256::from_bin(&buf), x); + } + } + + #[test] + fn test_minimal_encoding_zero() { + let test_int = Int256::ZERO; + let expected_encoding = vec![0x00]; + + assert_eq!(test_int.to_minimal_encoding(), expected_encoding); + } + + #[test] + fn test_minimal_encoding_one() { + let test_int = Int256::ONE; + let expected_encoding = vec![0x01]; + + assert_eq!(test_int.to_minimal_encoding(), expected_encoding); + } + + #[test] + fn test_minimal_encoding_one_full_byte() { + let bytes = [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, + ]; + let test_int = Int256::from_bin(&bytes); + let expected_encoding = vec![0x00, 0xFF]; + + assert_eq!(test_int.to_minimal_encoding(), expected_encoding); + } + + #[test] + fn test_minimal_encoding_most_bytes_full() { + let bytes = [ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + ]; + let test_int = Int256::from_bin(&bytes); + let expected_encoding = bytes.to_vec(); + + assert_eq!(test_int.to_minimal_encoding(), expected_encoding); + } + + #[test] + fn test_minimal_encoding_no_leading_byte() { + let bytes = [ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + ]; + let test_int = Int256::from_bin(&bytes); + let expected_encoding = bytes.to_vec(); + + assert_eq!(test_int.to_minimal_encoding(), expected_encoding); + } + + #[test] + fn test_minimal_encoding_with_leading_byte() { + let bytes = [ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + ]; + let test_int = Int256::from_bin(&bytes); + let mut expected_encoding = vec![0x00]; + expected_encoding.extend(&bytes); + + assert_eq!(test_int.to_minimal_encoding(), expected_encoding); + } + + #[test] + fn test_from_bin_is_big_endian_bits_with_little_endian_words() { + let buf = b"\x01\x23\x45\x67\x89\xab\xcd\xef\ + \x12\x34\x56\x78\x9a\xbc\xde\xf0\ + \x23\x45\x67\x89\xab\xcd\xef\x01\ + \x34\x56\x78\x9a\xbc\xde\xf0\x12"; + assert_eq!( + Int256::from_bin(&buf), + Int256 { + digits: [ + 0xbcdef012, 0x3456789a, 0xabcdef01, 0x23456789, 0x9abcdef0, 0x12345678, + 0x89abcdef, 0x01234567, + ] + } + ); + } + + /** Useful getters **/ + #[test] + fn test_is_zero() { + assert!(bool::from(Int256::ZERO.is_zero())); + for x in get_nonzero_test_values() { + assert!(!bool::from(x.is_zero())); + } + } + + #[test] + fn test_is_even() { + assert!(Int256::ZERO.is_even()); + assert!(!Int256::ONE.is_even()); + assert!(TWO.is_even()); + assert!(!Int256::N.is_even()); + assert!(!Int256::P.is_even()); + assert!(!Int256::B.is_even()); + } + + /** Arithmetic operations: bit shifts **/ + #[test] + fn test_shift_zero() { + for i in 1..BITS_PER_DIGIT { + assert_eq!(Int256::ZERO.shl(i), (Int256::ZERO, 0)); + } + for i in 1..BITS_PER_DIGIT { + assert_eq!(Int256::ZERO.shr(i), Int256::ZERO); + } + } + + #[test] + fn test_shifts() { + let mut a = Int256::ONE; + + // Shift left. + for i in 0..255 { + assert_eq!(a.bit(i), 1); + assert!(!bool::from(a.is_zero())); + let (shifted, carry) = a.shl(1); + assert_eq!(carry, 0); + a = shifted; + assert_eq!(a.bit(i), 0); + assert_eq!(a.count_ones(), 1); + } + + assert_eq!(a.bit(255), 1); + assert!(!bool::from(a.is_zero())); + let (shifted, carry) = a.shl(1); + assert_eq!(carry, 1); + assert_eq!(shifted.bit(255), 0); + assert!(bool::from(shifted.is_zero())); + + // Shift right. + for i in (1..256).rev() { + assert_eq!(a.bit(i), 1); + assert!(!bool::from(a.is_zero())); + a = a.shr(1); + assert_eq!(a.bit(i), 0); + assert_eq!(a.count_ones(), 1); + } + + assert_eq!(a.bit(0), 1); + assert!(!bool::from(a.is_zero())); + a = a.shr(1); + assert_eq!(a.bit(0), 0); + assert!(bool::from(a.is_zero())); + } + + #[test] + fn test_shl_shr1() { + for x in &get_test_values() { + let (shifted, carry) = x.shl(1); + assert_eq!(&shifted.shr1(carry), x); + } + } + + #[test] + fn test_shr1_is_shr_one() { + for x in &get_test_values() { + assert_eq!(x.shr(1), x.shr1(0)); + } + for x in &get_test_values() { + let mut y = *x; + for i in 1..BITS_PER_DIGIT { + y = y.shr1(0); + assert_eq!(x.shr(i), y); + } + } + } + + /** Constant-time helpers **/ + #[test] + fn test_set_zero_to_idx() { + let mut tbl = [Int256::ZERO; 15]; + for (i, x) in tbl.iter_mut().enumerate() { + *x = Int256 { + digits: [i as u32; NDIGITS], + }; + } + + for i in 0..16 { + let mut tbl0 = Int256::ZERO; + Int256::set_zero_to_idx(&mut tbl0, &tbl, i as u32); + if i == 0 { + assert_eq!(tbl0, Int256::ONE); + } else { + assert_eq!(tbl0, tbl[i - 1]); + } + } + } + + /** Arithmetic: constant-time conditional addition/substraction **/ + #[test] + fn test_add_conditional() { + for x in &get_test_values() { + for y in &get_test_values() { + let mut z = *x; + let carry = Int256::add_conditional(&mut z.digits, y, 0, Choice::from(0u8)); + assert_eq!(carry, 0); + assert_eq!(z, *x); + let carry = Int256::add_conditional(&mut z.digits, y, 0, Choice::from(1u8)); + assert_eq!((z, carry), x + y); + } + } + } + + #[test] + fn test_sub_conditional() { + for x in &get_test_values() { + for y in &get_test_values() { + let mut z = *x; + let borrow = Int256::sub_conditional(&mut z.digits, y, 0, Choice::from(0u8)); + assert_eq!(bool::from(borrow), false); + assert_eq!(z, *x); + let borrow = Int256::sub_conditional(&mut z.digits, y, 0, Choice::from(1u8)); + assert_eq!((z, Digit::conditional_select(&0, &!0, borrow)), x - y); + } + } + } + + /** Arithmetic operators **/ + #[test] + fn test_add_sub() { + for x in &get_test_values() { + for y in &get_test_values() { + let (sum, carry) = x + y; + let (diff, borrow) = &sum - y; + assert_eq!(diff, *x); + assert_eq!(carry.wrapping_add(borrow), 0); + } + } + } + + #[test] + fn test_sub_add() { + for x in &get_test_values() { + for y in &get_test_values() { + let (diff, borrow) = x - y; + let (sum, carry) = &diff + y; + assert_eq!(sum, *x); + assert_eq!(carry.wrapping_add(borrow), 0); + } + } + } + + /** Arithmetic: modular exponentiation **/ + #[test] + fn test_modpow() { + const MODULUS: Int256 = Int256::P; + for x in &get_test_values() { + let mut result = Int256::ONE; + let mut power = Int256::ZERO; + + // This test is super slow with debug assertions enabled. + #[cfg(not(debug_assertions))] + const ITERATIONS: u32 = 100; + #[cfg(debug_assertions)] + const ITERATIONS: u32 = 5; + + for _ in 0..ITERATIONS { + assert_eq!(x.modpow(&power, &MODULUS), result); + result = Int256::modmul(&result, x, &MODULUS); + power += &Int256::ONE; + } + } + } + + #[test] + fn test_self_times_modinv_is_one() { + const MODULUS: Int256 = Int256::P; + for x in &get_nonzero_test_values() { + let inv = x.modinv_vartime(&MODULUS); + let product = Int256::modmul(&x, &inv, &MODULUS); + assert_eq!(product, Int256::ONE); + } + } + + #[test] + fn test_modinv_modinv() { + const MODULUS: Int256 = Int256::P; + for &x in &get_nonzero_test_values() { + // By construction, this test only works if x is less than the modulus. + if x.compare(&MODULUS) != 0xffffffff { + continue; + } + assert_eq!(x.modinv_vartime(&MODULUS).modinv_vartime(&MODULUS), x); + } + } + + /** Other arithmetic **/ + #[test] + fn test_add_digit() { + for x in &get_test_values() { + for y in &get_test_values() { + for &digit in &y.digits { + assert_eq!( + x + digit, + x + &Int256 { + digits: [digit, 0, 0, 0, 0, 0, 0, 0] + } + ); + } + } + } + } + + #[test] + fn test_add_assign() { + for x in &get_test_values() { + for y in &get_test_values() { + let mut z = *x; + z += y; + assert_eq!(z, (x + y).0); + } + } + } + + #[test] + fn test_sub_assign() { + for x in &get_test_values() { + for y in &get_test_values() { + let mut z = *x; + z -= y; + assert_eq!(z, (x - y).0); + } + } + } + + #[test] + fn test_mul_add() { + for x in &get_test_values() { + for y in &get_test_values() { + let mut result = *x; + let mut carries = 0; + + // This test is super slow with debug assertions enabled. + #[cfg(not(debug_assertions))] + const ITERATIONS: u32 = 1000; + #[cfg(debug_assertions)] + const ITERATIONS: u32 = 5; + + for factor in 0..ITERATIONS { + let mut z = *x; + let ma_carry = Int256::mul_add(&mut z.digits, y, factor); + assert_eq!(ma_carry, carries); + assert_eq!(z, result); + + let (sum, carry) = &result + y; + result = sum; + carries += carry; + } + } + } + } + + /** Comparison between field elements. **/ + #[test] + fn test_compare() { + for x in &get_test_values() { + for y in &get_test_values() { + let cmp = x.compare(y); + assert!(cmp == 0 || cmp == 1 || cmp == 0xffffffff); + assert_eq!(cmp, x.compare_vartime(y)); + } + } + } + + #[test] + fn test_compare_is_reflexive() { + for x in &get_test_values() { + assert_eq!(x.compare(x), 0); + } + } + + #[test] + fn test_compare_is_antisymetric() { + for x in &get_test_values() { + for y in &get_test_values() { + let a = x.compare(y); + let b = y.compare(x); + assert_eq!(a.wrapping_add(b), 0); + } + } + } + + #[test] + fn test_lt() { + for x in &get_test_values() { + for y in &get_test_values() { + let ct_lt = bool::from(x.ct_lt(y)); + let lt = x.compare_vartime(y) == 0xffffffff; + assert_eq!(ct_lt, lt); + } + } + } + + #[test] + fn test_lt_is_antireflexive() { + for x in &get_test_values() { + assert!(!bool::from(x.ct_lt(x))); + } + } + + #[test] + fn test_lt_is_antisymetric() { + for x in &get_test_values() { + for y in &get_test_values() { + let a = x.ct_lt(y).unwrap_u8(); + let b = y.ct_lt(x).unwrap_u8(); + let c = (x == y) as u8; + assert_eq!(a + b + c, 1); + } + } + } + + // TODO: more tests +} diff --git a/libraries/crypto/src/ec/mod.rs b/libraries/crypto/src/ec/mod.rs new file mode 100644 index 0000000..20c469f --- /dev/null +++ b/libraries/crypto/src/ec/mod.rs @@ -0,0 +1,20 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod exponent256; +mod gfp256; +pub mod int256; +mod montgomery; +pub mod point; +mod precomputed; diff --git a/libraries/crypto/src/ec/montgomery.rs b/libraries/crypto/src/ec/montgomery.rs new file mode 100644 index 0000000..c197b52 --- /dev/null +++ b/libraries/crypto/src/ec/montgomery.rs @@ -0,0 +1,1109 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::gfp256::GFP256; +use super::int256::Int256; +use super::precomputed; +use core::ops::{Add, Mul, Sub}; +use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; + +pub const NLIMBS: usize = 9; +pub const BOTTOM_28_BITS: u32 = 0x0fff_ffff; +pub const BOTTOM_29_BITS: u32 = 0x1fff_ffff; + +/** Field element on the secp256r1 curve, represented in Montgomery form **/ +#[derive(Clone, Copy)] +pub struct Montgomery { + // The 9 limbs use 28 or 29 bits, alternatively: even limbs use 29 bits, odd limbs use 28 bits. + // The Montgomery form stores a field element x as (x * 2^257) mod P. + pub limbs: [u32; NLIMBS], +} + +impl ConditionallySelectable for Montgomery { + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + let mut limbs = [0; NLIMBS]; + for (i, limb) in limbs.iter_mut().enumerate() { + *limb = u32::conditional_select(&a.limbs[i], &b.limbs[i], choice); + } + Self { limbs } + } +} + +#[allow(clippy::unreadable_literal)] +impl Montgomery { + /** Constants for the secp256r1 field **/ + pub const ZERO: Montgomery = Montgomery { + limbs: [ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, + ], + }; + pub const ONE: Montgomery = Montgomery { + limbs: [ + 0x00000002, 0x00000000, 0x00000000, 0x0ffff800, 0x1fffffff, 0x0fffffff, 0x1fbfffff, + 0x01ffffff, 0x00000000, + ], + }; + pub const A: Montgomery = Montgomery { + limbs: [ + 0x1ffffff8, 0x0fffffff, 0x1fffffff, 0x10001fff, 0x1fffffff, 0x0fffffff, 0x20ffffff, + 0x07ffffff, 0x1fffffff, + ], + }; + pub const B: Montgomery = Montgomery { + limbs: [ + 0x13897bbf, 0x09cdf622, 0x043090d8, 0x002e67c4, 0x176b5678, 0x02afdc84, 0x0d196888, + 0x0b090e90, 0x0b8600c3, + ], + }; + pub const THREE_B: Montgomery = Montgomery { + limbs: [ + 0x1a9c733f, 0x0d69e267, 0x0c91b289, 0x108b2f4c, 0x26420367, 0x180f958d, 0x270c3997, + 0x031b2bb0, 0x0292024b, + ], + }; + const P: Montgomery = Montgomery { + limbs: [ + 0x1fffffff, 0x0fffffff, 0x1fffffff, 0x000003ff, 0x00000000, 0x00000000, 0x00200000, + 0x0f000000, 0x0fffffff, + ], + }; + const TWO_P: Montgomery = Montgomery { + limbs: [ + 0x1ffffffe, 0x0fffffff, 0x1fffffff, 0x000007ff, 0x00000000, 0x00000000, 0x00400000, + 0x0e000000, 0x1fffffff, + ], + }; + // A constant equal to 0 mod p. This is used to implement substraction arithmetic. + const ZERO31: Montgomery = Montgomery { + limbs: [ + (1 << 31) - (1 << 3), + (1 << 30) - (1 << 2), + (1 << 31) - (1 << 2), + (1 << 30) + (1 << 13) - (1 << 2), + (1 << 31) - (1 << 2), + (1 << 30) - (1 << 2), + (1 << 31) + (1 << 24) - (1 << 2), + (1 << 30) - (1 << 27) - (1 << 2), + (1 << 31) - (1 << 2), + ], + }; + + /** Precomputed multiples of the base point of the elliptic curve **/ + pub const fn new(limbs: [u32; NLIMBS]) -> Montgomery { + Montgomery { limbs } + } + + // This contains two tables of 15 points, each represented by its x and y coordinates in + // Montgomery form. + pub const PRECOMPUTED: [[[Montgomery; 2]; 15]; 2] = precomputed::PRECOMPUTED; + + /** Conversion to/from Montgomery form **/ + pub fn field_to_montgomery(gf: &GFP256) -> Montgomery { + let mut limbs = [0; NLIMBS]; + + let mut shifted = (gf * &GFP256::R).to_int(); + for (i, limb) in limbs.iter_mut().enumerate() { + if i & 1 == 0 { + *limb = shifted.digit(0) & BOTTOM_29_BITS; + shifted = shifted.shr(29); + } else { + *limb = shifted.digit(0) & BOTTOM_28_BITS; + shifted = shifted.shr(28); + } + } + + Montgomery { limbs } + } + + pub fn montgomery_to_field(&self) -> GFP256 { + let (mut result, _) = Int256::ZERO.add(self.limbs[NLIMBS - 1]); + let mut top = 0; + + for j in 0..=(NLIMBS - 2) { + let i = NLIMBS - 2 - j; + + let shift = if i & 1 == 0 { 29 } else { 28 }; + let (tmp, top1) = result.shl(shift); + + let (r, top2) = tmp.add(self.limbs[i]); + result = r; + top = top1 | top2; + } + + GFP256::R_INV.mul_top(&result, top) + } + + /** Useful getters **/ + #[inline(always)] + fn get64(&self, i: usize) -> u64 { + self.limbs[i] as u64 + } + + /** Advanced arithmetic **/ + // Squaring. + pub fn square(&self) -> Montgomery { + let mut big_limbs: [u64; 17] = [0; 17]; + + big_limbs[0] = self.get64(0) * self.get64(0); + big_limbs[1] = self.get64(0) * (self.get64(1) << 1); + big_limbs[2] = self.get64(0) * (self.get64(2) << 1) + self.get64(1) * (self.get64(1) << 1); + big_limbs[3] = self.get64(0) * (self.get64(3) << 1) + self.get64(1) * (self.get64(2) << 1); + big_limbs[4] = self.get64(0) * (self.get64(4) << 1) + + self.get64(1) * (self.get64(3) << 2) + + self.get64(2) * self.get64(2); + big_limbs[5] = self.get64(0) * (self.get64(5) << 1) + + self.get64(1) * (self.get64(4) << 1) + + self.get64(2) * (self.get64(3) << 1); + big_limbs[6] = self.get64(0) * (self.get64(6) << 1) + + self.get64(1) * (self.get64(5) << 2) + + self.get64(2) * (self.get64(4) << 1) + + self.get64(3) * (self.get64(3) << 1); + big_limbs[7] = self.get64(0) * (self.get64(7) << 1) + + self.get64(1) * (self.get64(6) << 1) + + self.get64(2) * (self.get64(5) << 1) + + self.get64(3) * (self.get64(4) << 1); + big_limbs[8] = self.get64(0) * (self.get64(8) << 1) + + self.get64(1) * (self.get64(7) << 2) + + self.get64(2) * (self.get64(6) << 1) + + self.get64(3) * (self.get64(5) << 2) + + self.get64(4) * self.get64(4); + big_limbs[9] = self.get64(1) * (self.get64(8) << 1) + + self.get64(2) * (self.get64(7) << 1) + + self.get64(3) * (self.get64(6) << 1) + + self.get64(4) * (self.get64(5) << 1); + big_limbs[10] = self.get64(2) * (self.get64(8) << 1) + + self.get64(3) * (self.get64(7) << 2) + + self.get64(4) * (self.get64(6) << 1) + + self.get64(5) * (self.get64(5) << 1); + big_limbs[11] = self.get64(3) * (self.get64(8) << 1) + + self.get64(4) * (self.get64(7) << 1) + + self.get64(5) * (self.get64(6) << 1); + big_limbs[12] = self.get64(4) * (self.get64(8) << 1) + + self.get64(5) * (self.get64(7) << 2) + + self.get64(6) * self.get64(6); + big_limbs[13] = self.get64(5) * (self.get64(8) << 1) + self.get64(6) * (self.get64(7) << 1); + big_limbs[14] = self.get64(6) * (self.get64(8) << 1) + self.get64(7) * (self.get64(7) << 1); + big_limbs[15] = self.get64(7) * (self.get64(8) << 1); + big_limbs[16] = self.get64(8) * self.get64(8); + + Montgomery::reduce_degree(&big_limbs) + } + + // Modular inverse. + pub fn inv(&self) -> Montgomery { + let mut tmp = self.square(); + tmp = &tmp * self; + let e2 = tmp; // 2^2 - 2^0 + + tmp = tmp.square(); + tmp = tmp.square(); + tmp = &tmp * &e2; + let e4 = tmp; // 2^4 - 2^0 + + for _ in 0..4 { + tmp = tmp.square(); + } + tmp = &tmp * &e4; + let e8 = tmp; // 2^8 - 2^0 + + for _ in 0..8 { + tmp = tmp.square(); + } + tmp = &tmp * &e8; + let e16 = tmp; // 2^16 - 2^0 + + for _ in 0..16 { + tmp = tmp.square(); + } + tmp = &tmp * &e16; + let e32 = tmp; // 2^32 - 2^0 + + for _ in 0..32 { + tmp = tmp.square(); + } + let e64 = tmp; // 2^64 - 2^32 + tmp = &tmp * self; + + for _ in 0..192 { + tmp = tmp.square(); + } // 2^256 - 2^224 + 2^192 + + // 2^64 - 2^0 + let mut tmp2 = &e64 * &e32; + for _ in 0..16 { + tmp2 = tmp2.square(); + } + // 2^80 - 2^0 + tmp2 = &tmp2 * &e16; + for _ in 0..8 { + tmp2 = tmp2.square(); + } + // 2^88 - 2^0 + tmp2 = &tmp2 * &e8; + for _ in 0..4 { + tmp2 = tmp2.square(); + } + // 2^92 - 2^0 + tmp2 = &tmp2 * &e4; + tmp2 = tmp2.square(); + tmp2 = tmp2.square(); + // 2^94 - 2^0 + tmp2 = &tmp2 * &e2; + tmp2 = tmp2.square(); + tmp2 = tmp2.square(); + // 2^96 - 3 + tmp2 = &tmp2 * self; + + // 2^256 - 2^224 + 2^192 + 2^96 - 3 + &tmp2 * &tmp + } + + // Multiplication by 2. + pub fn mul_scalar2(&mut self) { + let mut carry = 0; + + let mut i = 0; + loop { + let next_carry = self.limbs[i] >> 28; + self.limbs[i] <<= 1; + self.limbs[i] &= BOTTOM_29_BITS; + self.limbs[i] += carry; + carry = next_carry + (self.limbs[i] >> 29); + self.limbs[i] &= BOTTOM_29_BITS; + + i += 1; + if i == NLIMBS { + break; + } + + let next_carry = self.limbs[i] >> 27; + self.limbs[i] <<= 1; + self.limbs[i] &= BOTTOM_28_BITS; + self.limbs[i] += carry; + carry = next_carry + (self.limbs[i] >> 28); + self.limbs[i] &= BOTTOM_28_BITS; + + i += 1; + } + + self.reduce_carry(carry); + } + + // Multiplication by 3. + pub fn mul_scalar3(&mut self) { + let mut carry = 0; + + let mut i = 0; + loop { + self.limbs[i] *= 3; + self.limbs[i] += carry; + carry = self.limbs[i] >> 29; + self.limbs[i] &= BOTTOM_29_BITS; + + i += 1; + if i == NLIMBS { + break; + } + + self.limbs[i] *= 3; + self.limbs[i] += carry; + carry = self.limbs[i] >> 28; + self.limbs[i] &= BOTTOM_28_BITS; + + i += 1; + } + + self.reduce_carry(carry); + } + + // Multiplication by 4. + pub fn mul_scalar4(&mut self) { + let mut carry = 0; + + let mut i = 0; + loop { + let next_carry = self.limbs[i] >> 27; + self.limbs[i] <<= 2; + self.limbs[i] &= BOTTOM_29_BITS; + self.limbs[i] += carry; + carry = next_carry + (self.limbs[i] >> 29); + self.limbs[i] &= BOTTOM_29_BITS; + + i += 1; + if i == NLIMBS { + break; + } + + let next_carry = self.limbs[i] >> 26; + self.limbs[i] <<= 2; + self.limbs[i] &= BOTTOM_28_BITS; + self.limbs[i] += carry; + carry = next_carry + (self.limbs[i] >> 28); + self.limbs[i] &= BOTTOM_28_BITS; + + i += 1; + } + + self.reduce_carry(carry); + } + + // Multiplication by 8. + pub fn mul_scalar8(&mut self) { + let mut carry = 0; + + let mut i = 0; + loop { + let next_carry = self.limbs[i] >> 26; + self.limbs[i] <<= 3; + self.limbs[i] &= BOTTOM_29_BITS; + self.limbs[i] += carry; + carry = next_carry + (self.limbs[i] >> 29); + self.limbs[i] &= BOTTOM_29_BITS; + + i += 1; + if i == NLIMBS { + break; + } + + let next_carry = self.limbs[i] >> 25; + self.limbs[i] <<= 3; + self.limbs[i] &= BOTTOM_28_BITS; + self.limbs[i] += carry; + carry = next_carry + (self.limbs[i] >> 28); + self.limbs[i] &= BOTTOM_28_BITS; + + i += 1; + } + + self.reduce_carry(carry); + } + + /** Comparison **/ + pub fn is_zero_vartime(&self) -> bool { + // Reduce to a minimal form. + let tmp = self.reduced_vartime(); + + tmp.limbs == Montgomery::ZERO.limbs + || tmp.limbs == Montgomery::P.limbs + || tmp.limbs == Montgomery::TWO_P.limbs + } + + fn reduced_vartime(&self) -> Montgomery { + let mut reduced = *self; + + // Reduce to a minimal form. + loop { + let mut carry = 0; + let mut i = 0; + loop { + reduced.limbs[i] += carry; + carry = reduced.limbs[i] >> 29; + reduced.limbs[i] &= BOTTOM_29_BITS; + + i += 1; + if i == NLIMBS { + break; + } + + reduced.limbs[i] += carry; + carry = reduced.limbs[i] >> 28; + reduced.limbs[i] &= BOTTOM_28_BITS; + + i += 1; + } + + if carry == 0 { + break; + } + reduced.reduce_carry(carry); + } + + reduced + } + + /** Reduction of saturated limbs **/ + // Adds a multiple of p in order to cancel |carry|, which is a term at 2**257. + // On entry: carry < 2**3, self[0,2,...] < 2**29, self[1,3,...] < 2**28. + // On exit: self[0,2,..] < 2**30, self[1,3,...] < 2**29. + fn reduce_carry(&mut self, carry: u32) { + let carry_choice = carry.ct_eq(&0); + self.limbs[0] += carry << 1; + self.limbs[3] += u32::conditional_select(&0x10000000, &0, carry_choice); + self.limbs[3] -= carry << 11; + self.limbs[4] += u32::conditional_select(&(0x20000000 - 1), &0, carry_choice); + self.limbs[5] += u32::conditional_select(&(0x10000000 - 1), &0, carry_choice); + self.limbs[6] += u32::conditional_select(&(0x20000000 - 1), &0, carry_choice); + self.limbs[6] -= carry << 22; + self.limbs[7] += carry << 25; + self.limbs[7] -= u32::conditional_select(&1, &0, carry_choice); + } + + // Reduce the output of a multiplication or squaring. + fn reduce_degree(big_limbs: &[u64; 17]) -> Montgomery { + let mut limbs: [u32; 18] = Montgomery::propagate_carry(big_limbs); + Montgomery::eliminate_terms(&mut limbs); + Montgomery::compact_limbs(limbs) + } + + // Helper function for reduce_degree(). + // Converts 17 saturated 64-bit limbs to 18 unsaturated limbs of 28 or 29 bits. + fn propagate_carry(big_limbs: &[u64; 17]) -> [u32; 18] { + let mut limbs: [u32; 18] = [0; 18]; + + limbs[0] = (big_limbs[0] as u32) & BOTTOM_29_BITS; + limbs[1] = (big_limbs[0] as u32) >> 29; + limbs[1] |= (((big_limbs[0] >> 32) as u32) << 3) & BOTTOM_28_BITS; + limbs[1] += (big_limbs[1] as u32) & BOTTOM_28_BITS; + let mut carry = limbs[1] >> 28; + limbs[1] &= BOTTOM_28_BITS; + + let mut i = 2; + loop { + limbs[i] = ((big_limbs[i - 2] >> 32) as u32) >> 25; + limbs[i] += (big_limbs[i - 1] as u32) >> 28; + limbs[i] += (((big_limbs[i - 1] >> 32) as u32) << 4) & BOTTOM_29_BITS; + limbs[i] += (big_limbs[i] as u32) & BOTTOM_29_BITS; + limbs[i] += carry; + carry = limbs[i] >> 29; + limbs[i] &= BOTTOM_29_BITS; + + i += 1; + if i == 17 { + break; + } + + limbs[i] = ((big_limbs[i - 2] >> 32) as u32) >> 25; + limbs[i] += (big_limbs[i - 1] as u32) >> 29; + limbs[i] += (((big_limbs[i - 1] >> 32) as u32) << 3) & BOTTOM_28_BITS; + limbs[i] += (big_limbs[i] as u32) & BOTTOM_28_BITS; + limbs[i] += carry; + carry = limbs[i] >> 28; + limbs[i] &= BOTTOM_28_BITS; + + i += 1; + } + limbs[17] = ((big_limbs[15] >> 32) as u32) >> 25; + limbs[17] += (big_limbs[16] as u32) >> 29; + limbs[17] += ((big_limbs[16] >> 32) as u32) << 3; + limbs[17] += carry; + + limbs + } + + // Helper function for reduce_degree(). + // Montgomery elimination of terms. + fn eliminate_terms(limbs: &mut [u32; 18]) { + let mut i = 0; + loop { + limbs[i + 1] += limbs[i] >> 29; + let x = limbs[i] & BOTTOM_29_BITS; + let choice = x.ct_eq(&0); + limbs[i] = 0; + + limbs[i + 3] += (x << 10) & BOTTOM_28_BITS; + limbs[i + 4] += x >> 18; + + limbs[i + 6] += (x << 21) & BOTTOM_29_BITS; + limbs[i + 7] += x >> 8; + + limbs[i + 7] += u32::conditional_select(&0x10000000, &0, choice); + limbs[i + 8] += u32::conditional_select(&x.wrapping_sub(1), &0, choice); + limbs[i + 7] -= (x << 24) & BOTTOM_28_BITS; + limbs[i + 8] -= x >> 4; + + limbs[i + 8] += u32::conditional_select(&0x20000000, &0, choice); + limbs[i + 8] -= x; + limbs[i + 8] += (x << 28) & BOTTOM_29_BITS; + limbs[i + 9] = limbs[i + 9].wrapping_add(u32::conditional_select( + &(x >> 1).wrapping_sub(1), + &0, + choice, + )); + + if i + 1 == NLIMBS { + break; + } + + limbs[i + 2] += limbs[i + 1] >> 28; + let x = limbs[i + 1] & BOTTOM_28_BITS; + let choice = x.ct_eq(&0); + limbs[i + 1] = 0; + + limbs[i + 4] += (x << 11) & BOTTOM_29_BITS; + limbs[i + 5] += x >> 18; + + limbs[i + 7] += (x << 21) & BOTTOM_28_BITS; + limbs[i + 8] += x >> 7; + + limbs[i + 8] += u32::conditional_select(&0x20000000, &0, choice); + limbs[i + 9] += u32::conditional_select(&x.wrapping_sub(1), &0, choice); + limbs[i + 8] -= (x << 25) & BOTTOM_29_BITS; + limbs[i + 9] -= x >> 4; + + limbs[i + 9] += u32::conditional_select(&0x10000000, &0, choice); + limbs[i + 9] -= x; + limbs[i + 10] += u32::conditional_select(&x.wrapping_sub(1), &0, choice); + + i += 2; + } + } + + // Helper function for reduce_degree(). + // Extract the final limbs from Montgomery-eliminated terms. + fn compact_limbs(tmp: [u32; 18]) -> Montgomery { + let mut limbs = [0; NLIMBS]; + let mut carry = 0; + let mut i = 0; + loop { + limbs[i] = tmp[i + 9]; + limbs[i] += carry; + limbs[i] += (tmp[i + 10] << 28) & BOTTOM_29_BITS; + carry = limbs[i] >> 29; + limbs[i] &= BOTTOM_29_BITS; + + i += 1; + + limbs[i] = tmp[i + 9] >> 1; + limbs[i] += carry; + carry = limbs[i] >> 28; + limbs[i] &= BOTTOM_28_BITS; + + i += 1; + if i == 8 { + break; + } + } + + limbs[8] = tmp[17]; + limbs[8] = limbs[8].wrapping_add(carry); + carry = limbs[8] >> 29; + limbs[8] &= BOTTOM_29_BITS; + + let mut result = Montgomery { limbs }; + result.reduce_carry(carry); + result + } +} + +/** Arithmetic operators **/ +// Clippy warns when it sees a subtraction being done in Add implementation +// which here is completely fine. +#[allow(clippy::suspicious_arithmetic_impl)] +impl Add for &Montgomery { + type Output = Montgomery; + + fn add(self, other: &Montgomery) -> Montgomery { + let mut carry = 0; + let mut limbs = [0; NLIMBS]; + + let mut i = 0; + loop { + limbs[i] = self.limbs[i] + other.limbs[i]; + limbs[i] += carry; + carry = limbs[i] >> 29; + limbs[i] &= BOTTOM_29_BITS; + + i += 1; + if i == NLIMBS { + break; + } + + limbs[i] = self.limbs[i] + other.limbs[i]; + limbs[i] += carry; + carry = limbs[i] >> 28; + limbs[i] &= BOTTOM_28_BITS; + + i += 1; + } + + let mut result = Montgomery { limbs }; + result.reduce_carry(carry); + result + } +} + +#[allow(clippy::suspicious_arithmetic_impl)] +// Clippy warns when it sees an addition being done in Sub implementation +// which here is completely fine. +impl Sub for &Montgomery { + type Output = Montgomery; + + fn sub(self, other: &Montgomery) -> Montgomery { + let mut carry = 0; + let mut limbs = [0; NLIMBS]; + + let mut i = 0; + loop { + limbs[i] = self.limbs[i] + (Montgomery::ZERO31.limbs[i] - other.limbs[i]); + limbs[i] += carry; + carry = limbs[i] >> 29; + limbs[i] &= BOTTOM_29_BITS; + + i += 1; + if i == NLIMBS { + break; + } + + limbs[i] = self.limbs[i] + (Montgomery::ZERO31.limbs[i] - other.limbs[i]); + limbs[i] += carry; + carry = limbs[i] >> 28; + limbs[i] &= BOTTOM_28_BITS; + + i += 1; + } + + let mut result = Montgomery { limbs }; + result.reduce_carry(carry); + result + } +} + +impl Mul for &Montgomery { + type Output = Montgomery; + + fn mul(self, other: &Montgomery) -> Montgomery { + let mut big_limbs: [u64; 17] = [0; 17]; + + big_limbs[0] = self.get64(0) * other.get64(0); + big_limbs[1] = self.get64(0) * other.get64(1) + self.get64(1) * other.get64(0); + big_limbs[2] = self.get64(0) * other.get64(2) + + self.get64(1) * (other.get64(1) << 1) + + self.get64(2) * other.get64(0); + big_limbs[3] = self.get64(0) * other.get64(3) + + self.get64(1) * other.get64(2) + + self.get64(2) * other.get64(1) + + self.get64(3) * other.get64(0); + big_limbs[4] = self.get64(0) * other.get64(4) + + self.get64(1) * (other.get64(3) << 1) + + self.get64(2) * other.get64(2) + + self.get64(3) * (other.get64(1) << 1) + + self.get64(4) * other.get64(0); + big_limbs[5] = self.get64(0) * other.get64(5) + + self.get64(1) * other.get64(4) + + self.get64(2) * other.get64(3) + + self.get64(3) * other.get64(2) + + self.get64(4) * other.get64(1) + + self.get64(5) * other.get64(0); + big_limbs[6] = self.get64(0) * other.get64(6) + + self.get64(1) * (other.get64(5) << 1) + + self.get64(2) * other.get64(4) + + self.get64(3) * (other.get64(3) << 1) + + self.get64(4) * other.get64(2) + + self.get64(5) * (other.get64(1) << 1) + + self.get64(6) * other.get64(0); + big_limbs[7] = self.get64(0) * other.get64(7) + + self.get64(1) * other.get64(6) + + self.get64(2) * other.get64(5) + + self.get64(3) * other.get64(4) + + self.get64(4) * other.get64(3) + + self.get64(5) * other.get64(2) + + self.get64(6) * other.get64(1) + + self.get64(7) * other.get64(0); + big_limbs[8] = self.get64(0) * other.get64(8) + + self.get64(1) * (other.get64(7) << 1) + + self.get64(2) * other.get64(6) + + self.get64(3) * (other.get64(5) << 1) + + self.get64(4) * other.get64(4) + + self.get64(5) * (other.get64(3) << 1) + + self.get64(6) * other.get64(2) + + self.get64(7) * (other.get64(1) << 1) + + self.get64(8) * other.get64(0); + big_limbs[9] = self.get64(1) * other.get64(8) + + self.get64(2) * other.get64(7) + + self.get64(3) * other.get64(6) + + self.get64(4) * other.get64(5) + + self.get64(5) * other.get64(4) + + self.get64(6) * other.get64(3) + + self.get64(7) * other.get64(2) + + self.get64(8) * other.get64(1); + big_limbs[10] = self.get64(2) * other.get64(8) + + self.get64(3) * (other.get64(7) << 1) + + self.get64(4) * other.get64(6) + + self.get64(5) * (other.get64(5) << 1) + + self.get64(6) * other.get64(4) + + self.get64(7) * (other.get64(3) << 1) + + self.get64(8) * other.get64(2); + big_limbs[11] = self.get64(3) * other.get64(8) + + self.get64(4) * other.get64(7) + + self.get64(5) * other.get64(6) + + self.get64(6) * other.get64(5) + + self.get64(7) * other.get64(4) + + self.get64(8) * other.get64(3); + big_limbs[12] = self.get64(4) * other.get64(8) + + self.get64(5) * (other.get64(7) << 1) + + self.get64(6) * other.get64(6) + + self.get64(7) * (other.get64(5) << 1) + + self.get64(8) * other.get64(4); + big_limbs[13] = self.get64(5) * other.get64(8) + + self.get64(6) * other.get64(7) + + self.get64(7) * other.get64(6) + + self.get64(8) * other.get64(5); + big_limbs[14] = self.get64(6) * other.get64(8) + + self.get64(7) * (other.get64(7) << 1) + + self.get64(8) * other.get64(6); + big_limbs[15] = self.get64(7) * other.get64(8) + self.get64(8) * other.get64(7); + big_limbs[16] = self.get64(8) * other.get64(8); + + Montgomery::reduce_degree(&big_limbs) + } +} + +#[cfg(test)] +pub mod test { + use super::*; + + impl PartialEq for Montgomery { + fn eq(&self, other: &Montgomery) -> bool { + (self - other).is_zero_vartime() + } + } + + impl core::fmt::Debug for Montgomery { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "Montgomery {{ limbs: {:08x?} }}", self.limbs) + } + } + + pub fn get_nonzero_test_values() -> Vec { + let mut values: Vec = Montgomery::PRECOMPUTED + .iter() + .flatten() + .flatten() + .cloned() + .collect(); + values.push(Montgomery::ONE); + values.push(Montgomery::A); + values.push(Montgomery::B); + values.push(Montgomery::THREE_B); + // TODO: Add more test values. + values + } + + fn get_test_values() -> Vec { + let mut values = get_nonzero_test_values(); + values.push(Montgomery::ZERO); + values + } + + /** Constants for the secp256r1 field **/ + #[test] + fn test_zero31_is_zero_mod_p() { + assert!(Montgomery::ZERO31.is_zero_vartime()); + } + + #[test] + fn test_2p() { + assert_eq!( + Montgomery::TWO_P.limbs, + (&Montgomery::P + &Montgomery::P).limbs + ); + } + + #[test] + fn test_a() { + // a == -3 + let mut a = GFP256::ZERO; + a = &a - &GFP256::ONE; + a = &a - &GFP256::ONE; + a = &a - &GFP256::ONE; + assert_eq!(Montgomery::A, Montgomery::field_to_montgomery(&a)); + } + + #[test] + fn test_b() { + assert_eq!(Montgomery::B, Montgomery::field_to_montgomery(&GFP256::B)); + } + + #[test] + fn test_3b() { + let mut b3 = GFP256::B; + b3 = &b3 + &GFP256::B; + b3 = &b3 + &GFP256::B; + assert_eq!(Montgomery::THREE_B, Montgomery::field_to_montgomery(&b3)); + } + + /** Conversion to/from Montgomery form **/ + #[test] + fn test_conversion_round_trip() { + for x in get_test_values() { + assert_eq!(x, Montgomery::field_to_montgomery(&x.montgomery_to_field())); + } + } + + #[test] + fn test_conversion_for_constants() { + assert_eq!( + Montgomery::ZERO.limbs, + Montgomery::field_to_montgomery(&GFP256::ZERO).limbs + ); + assert_eq!( + Montgomery::ONE.limbs, + Montgomery::field_to_montgomery(&GFP256::ONE).limbs + ); + } + + /** Constant-time helpers **/ + + /** Arithmetic operators **/ + #[test] + fn test_add_is_associative() { + for x in &get_test_values() { + for y in &get_test_values() { + for z in &get_test_values() { + assert_eq!(&(x + y) + z, x + &(y + z)); + } + } + } + } + + #[test] + fn test_add_is_commutative() { + for x in &get_test_values() { + for y in &get_test_values() { + assert_eq!(x + y, y + x); + } + } + } + + #[test] + fn test_add_sub() { + for x in &get_test_values() { + for y in &get_test_values() { + assert_eq!(&(x - y) + y, *x); + assert_eq!(&(x + y) - y, *x); + } + } + } + + #[test] + fn test_mul_is_associative() { + for x in &get_test_values() { + for y in &get_test_values() { + for z in &get_test_values() { + assert_eq!(&(x * y) * z, x * &(y * z)); + } + } + } + } + + #[test] + fn test_mul_is_commutative() { + for x in &get_test_values() { + for y in &get_test_values() { + assert_eq!(x * y, y * x); + } + } + } + + #[test] + fn test_mul_is_distributive() { + for x in &get_test_values() { + for y in &get_test_values() { + for z in &get_test_values() { + assert_eq!(&(x + y) * z, &(x * z) + &(y * z)); + } + } + } + } + + /** Advanced arithmetic **/ + #[test] + fn test_square_is_mul_self() { + for x in &get_test_values() { + let multiplied = x * x; + let squared = x.square(); + assert_eq!(multiplied, squared); + } + } + + #[test] + fn test_self_times_inv_is_one() { + for x in &get_nonzero_test_values() { + let inv = x.inv(); + let product = x * &inv; + assert_eq!(product, Montgomery::ONE); + } + } + + #[test] + fn test_inv_inv() { + for x in get_nonzero_test_values() { + assert_eq!(x.inv().inv(), x); + } + } + + #[test] + fn test_well_known_inverses() { + assert_eq!(Montgomery::ONE.inv(), Montgomery::ONE); + let p_min_1 = &Montgomery::P - &Montgomery::ONE; + assert_eq!(p_min_1.inv(), p_min_1); + } + + #[test] + fn test_mul_scalar2_from_add() { + for x in get_test_values() { + let mut multiplied = x; + multiplied.mul_scalar2(); + + let added = &x + &x; + + assert_eq!(multiplied, added); + } + } + + #[test] + fn test_mul_scalar2_from_mul() { + let two = &Montgomery::ONE + &Montgomery::ONE; + + for x in get_test_values() { + let mut multiplied = x; + multiplied.mul_scalar2(); + + assert_eq!(multiplied, &x * &two); + } + } + + #[test] + fn test_mul_scalar3_from_add() { + for x in get_test_values() { + let mut multiplied = x; + multiplied.mul_scalar3(); + + let mut added = x; + for _ in 0..2 { + added = &added + &x; + } + + assert_eq!(multiplied, added); + } + } + + #[test] + fn test_mul_scalar3_from_mul() { + let mut three = Montgomery::ONE; + for _ in 0..2 { + three = &three + &Montgomery::ONE; + } + + for x in get_test_values() { + let mut multiplied = x; + multiplied.mul_scalar3(); + + assert_eq!(multiplied, &x * &three); + } + } + + #[test] + fn test_mul_scalar4_from_add() { + for x in get_test_values() { + let mut multiplied = x; + multiplied.mul_scalar4(); + + let mut added = x; + for _ in 0..3 { + added = &added + &x; + } + + assert_eq!(multiplied, added); + } + } + + #[test] + fn test_mul_scalar4_from_mul() { + let mut four = Montgomery::ONE; + for _ in 0..3 { + four = &four + &Montgomery::ONE; + } + + for x in get_test_values() { + let mut multiplied = x; + multiplied.mul_scalar4(); + + assert_eq!(multiplied, &x * &four); + } + } + + #[test] + fn test_mul_scalar8_from_add() { + for x in get_test_values() { + let mut multiplied = x; + multiplied.mul_scalar8(); + + let mut added = x; + for _ in 0..7 { + added = &added + &x; + } + + assert_eq!(multiplied, added); + } + } + + #[test] + fn test_mul_scalar8_from_mul() { + let mut eight = Montgomery::ONE; + for _ in 0..7 { + eight = &eight + &Montgomery::ONE; + } + + for x in get_test_values() { + let mut multiplied = x; + multiplied.mul_scalar8(); + + assert_eq!(multiplied, &x * &eight); + } + } + + /** Comparison **/ + #[test] + fn test_is_zero() { + assert!(Montgomery::ZERO.is_zero_vartime()); + for x in get_nonzero_test_values() { + assert!(!x.is_zero_vartime()); + } + } + + /** Reduction of saturated limbs **/ + #[test] + fn test_reduced_carry_is_one() { + let mut x = Montgomery::ZERO; + x.reduce_carry(1); + assert_eq!(x.limbs, Montgomery::ONE.limbs); + } + + #[test] + fn test_reduce_carry_works_until_8() { + let mut reduced = Montgomery::ZERO; + for i in 0..8 { + let mut x = Montgomery::ZERO; + x.reduce_carry(i); + assert_eq!(x.limbs, reduced.limbs); + reduced = &reduced + &Montgomery::ONE; + } + } + + #[test] + fn test_reduce_no_carry_is_noop() { + for x in get_test_values() { + let mut y = x; + y.reduce_carry(0); + assert_eq!(y.limbs, x.limbs); + } + } + + #[test] + fn test_reduce_degree() { + // TODO: Add a meaningful test for this. + } +} diff --git a/libraries/crypto/src/ec/point.rs b/libraries/crypto/src/ec/point.rs new file mode 100644 index 0000000..d9a6a76 --- /dev/null +++ b/libraries/crypto/src/ec/point.rs @@ -0,0 +1,1034 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::exponent256::ExponentP256; +use super::gfp256::GFP256; +use super::int256::Int256; +use super::montgomery::Montgomery; +use core::ops::Add; +use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; + +// A point on the elliptic curve is represented by two field elements. +// The "direct" representation with GFP256 (integer modulo p) is used for serialization of public +// keys. +#[derive(Clone, Copy)] +pub struct PointP256 { + x: GFP256, + y: GFP256, +} + +impl PointP256 { + // The point at infinity. + // Although this point is not "valid" on the curve (as it doesn't have an order of N), it is + // useful for tests. + #[cfg(test)] + const INFINITY: PointP256 = PointP256 { + x: GFP256::ZERO, + y: GFP256::ZERO, + }; + + /** Serialization **/ + // This uses uncompressed point format from "SEC 1: Elliptic Curve Cryptography" ("Standards for + // Efficient Cryptography"). + #[cfg(feature = "std")] + pub fn from_bytes_uncompressed_vartime(bytes: &[u8]) -> Option { + if bytes.len() != 65 || bytes[0] != 0x04 { + None + } else { + PointP256::new_checked_vartime( + Int256::from_bin(array_ref![bytes, 1, 32]), + Int256::from_bin(array_ref![bytes, 33, 32]), + ) + } + } + + #[cfg(test)] + pub fn to_bytes_uncompressed(&self, bytes: &mut [u8; 65]) { + bytes[0] = 0x04; + self.x.to_int().to_bin(array_mut_ref![bytes, 1, 32]); + self.y.to_int().to_bin(array_mut_ref![bytes, 33, 32]); + } + + /** Constructors **/ + pub fn new_checked_vartime(x: Int256, y: Int256) -> Option { + let gfx = GFP256::from_int_checked(x)?; + let gfy = GFP256::from_int_checked(y)?; + if GFP256::is_valid_point_vartime(&gfx, &gfy) { + Some(PointP256 { x: gfx, y: gfy }) + } else { + None + } + } + + fn from_projective(point: &PointProjective) -> PointP256 { + PointP256::from_affine(&point.to_affine()) + } + + fn from_affine(affine: &PointAffine) -> PointP256 { + PointP256 { + x: affine.x.montgomery_to_field(), + y: affine.y.montgomery_to_field(), + } + } + + fn to_affine(&self) -> PointAffine { + PointAffine { + x: Montgomery::field_to_montgomery(&self.x), + y: Montgomery::field_to_montgomery(&self.y), + } + } + + /** Useful getters **/ + #[cfg(test)] + pub fn is_valid_vartime(&self) -> bool { + GFP256::is_valid_point_vartime(&self.x, &self.y) + } + + pub fn getx(self) -> GFP256 { + self.x + } + + pub fn gety(self) -> GFP256 { + self.y + } + + /** Arithmetic **/ + pub fn base_point_mul(n: &ExponentP256) -> PointP256 { + let point = PointProjective::scalar_base_mul(n); + PointP256::from_projective(&point) + } + + pub fn mul(&self, n: &ExponentP256) -> PointP256 { + let p = self.to_affine(); + let point = p.scalar_mul(n); + PointP256::from_projective(&point) + } + + // Computes n1*G + n2*self + #[cfg(feature = "std")] + pub fn points_mul(&self, n1: &ExponentP256, n2: &ExponentP256) -> PointP256 { + let p = self.to_affine(); + let p1 = PointProjective::scalar_base_mul(n1); + let p2 = p.scalar_mul(n2); + + let point = &p1 + &p2; + PointP256::from_projective(&point) + } +} + +// A point on the elliptic curve in projective form. +// This uses Montgomery representation for field elements. +// This is in projective coordinates, i.e. it represents the point { x: x / z, y: y / z }. +// This representation is more convenient to implement complete formulas for elliptic curve +// arithmetic. +#[derive(Clone, Copy)] +pub struct PointProjective { + x: Montgomery, + y: Montgomery, + z: Montgomery, +} + +impl ConditionallySelectable for PointProjective { + #[allow(clippy::many_single_char_names)] + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + let x = Montgomery::conditional_select(&a.x, &b.x, choice); + let y = Montgomery::conditional_select(&a.y, &b.y, choice); + let z = Montgomery::conditional_select(&a.z, &b.z, choice); + Self { x, y, z } + } +} + +// Equivalent to PointProjective { x, y, z: 1 } +#[derive(Clone, Copy)] +pub struct PointAffine { + x: Montgomery, + y: Montgomery, +} + +impl PointProjective { + #[cfg(test)] + pub const INFINITY: PointProjective = PointProjective { + x: Montgomery::ZERO, + y: Montgomery::ONE, + z: Montgomery::ZERO, + }; + + /** Constructors **/ + pub fn from_affine(point: &PointAffine) -> PointProjective { + PointProjective { + x: point.x, + y: point.y, + z: Montgomery::ONE, + } + } + + #[cfg(test)] + // Construct a point in projective coordinates, with a given z value. + // This point is equivalent to { x, y, z: 1 } + pub fn from_affine_shuffled(point: &PointAffine, z: Montgomery) -> PointProjective { + PointProjective { + x: &point.x * &z, + y: &point.y * &z, + z, + } + } + + fn to_affine(&self) -> PointAffine { + let zinv = self.z.inv(); + let x = &self.x * &zinv; + let y = &self.y * &zinv; + PointAffine { x, y } + } + + /** Constant-time helpers **/ + fn select_point(table: &[PointProjective; 15], index: u32) -> PointProjective { + let mut point = PointProjective { + x: Montgomery::ZERO, + y: Montgomery::ZERO, + z: Montgomery::ZERO, + }; + + for i in 0..15 { + let choice = (i + 1).ct_eq(&index); + point.conditional_assign(&table[i as usize], choice); + } + + point + } + + /** Arithmetic **/ + // Complete formula from https://eprint.iacr.org/2015/1060.pdf, Algorithm 5. + fn add_mixed(&self, other: &PointAffine) -> PointProjective { + // Steps 1-2 (same as add). + let mut t0 = &self.x * &other.x; + let t1 = &self.y * &other.y; + let mut t2 = self.z; + + // Steps 3-7 (same as add). + let t3 = &self.x + &self.y; + let t4 = &other.x + &other.y; + let t3 = &t3 * &t4; + let t4 = &t0 + &t1; + let t3 = &t3 - &t4; + + // Steps 8-11 (add_mixed optimization). + let t4 = &other.y * &self.z; + let t4 = &t4 + &self.y; + let y = &other.x * &self.z; + let y = &y + &self.x; + + // Steps 12-17 (same as add). + let z = &Montgomery::B * &t2; + let mut x = &y - &z; + x.mul_scalar3(); // 14-15 + let z = &t1 - &x; + let x = &t1 + &x; + + // Steps 18-22 (same as add). + let y = &Montgomery::B * &y; + t2.mul_scalar3(); // 19-20 + let y = &y - &t2; + let mut y = &y - &t0; + + // Steps 23-27 (same as add). + y.mul_scalar3(); // 23-24 + t0.mul_scalar3(); // 25-26 + let t0 = &t0 - &t2; + + // Steps 28-36 (same as add). + let t1 = &t4 * &y; + let t2 = &t0 * &y; + let y = &x * &z; + let y = &y + &t2; + let x = &t3 * &x; + let x = &x - &t1; + let z = &t4 * &z; + let t1 = &t3 * &t0; + let z = &z + &t1; + + PointProjective { x, y, z } + } + + // Complete formula from https://eprint.iacr.org/2015/1060.pdf, Algorithm 6. + fn double(&self) -> PointProjective { + // Steps 1-3 (same as add). + let mut t0 = self.x.square(); + let t1 = self.y.square(); + let mut t2 = self.z.square(); + + // Steps 4-7. + let mut t3 = &self.x * &self.y; + t3.mul_scalar2(); + let mut z = &self.x * &self.z; + z.mul_scalar2(); + + // Steps 8-13 (same as add). + let y = &Montgomery::B * &t2; + let mut y = &y - &z; + y.mul_scalar3(); // 10-11 + let x = &t1 - &y; + let y = &t1 + &y; + + // Steps 14-15. + let y = &x * &y; + let x = &x * &t3; + + // Steps 16-20 (same as add). + t2.mul_scalar3(); // 16-17 + let z = &Montgomery::B * &z; + let z = &z - &t2; + let mut z = &z - &t0; + + // Steps 21-26 (same as add). + z.mul_scalar3(); // 21-22 + t0.mul_scalar3(); // 23-24 + let t0 = &t0 - &t2; + + // Steps 27-34. + let t0 = &t0 * &z; + let y = &y + &t0; + let mut t0 = &self.y * &self.z; + t0.mul_scalar2(); + let z = &t0 * &z; + let x = &x - &z; + let mut z = &t0 * &t1; + z.mul_scalar4(); // 33-34 + + PointProjective { x, y, z } + } + + // Compute scalar*G + fn scalar_base_mul(scalar: &ExponentP256) -> PointProjective { + let mut n = PointProjective { + x: Montgomery::ZERO, + y: Montgomery::ZERO, + z: Montgomery::ZERO, + }; + let mut choice_n_is_inf = Choice::from(1u8); + + for i in 0..32 { + if i != 0 { + n = n.double(); + } + + for table_offset in 0..2 { + let j = 32 * table_offset; + let bit0 = scalar.bit(31 - i + j); + let bit1 = scalar.bit(95 - i + j); + let bit2 = scalar.bit(159 - i + j); + let bit3 = scalar.bit(223 - i + j); + let index = bit0 | (bit1 << 1) | (bit2 << 2) | (bit3 << 3); + + let p = PointAffine::select_point(&Montgomery::PRECOMPUTED[table_offset], index); + let t = n.add_mixed(&p); + + n.conditional_assign(&PointProjective::from_affine(&p), choice_n_is_inf); + + let choice_p_is_inf = index.ct_eq(&0); + n.conditional_assign(&t, !(choice_p_is_inf | choice_n_is_inf)); + + choice_n_is_inf &= choice_p_is_inf; + } + } + + n + } + + // Complete formula from https://eprint.iacr.org/2015/1060.pdf, Algorithm 1. + #[cfg(test)] + fn add_complete_general(self, other: &PointProjective) -> PointProjective { + // Steps 1-3. + let t0 = &self.x * &other.x; + let t1 = &self.y * &other.y; + let t2 = &self.z * &other.z; + + // Steps 4-8. + let t3 = &self.x + &self.y; + let t4 = &other.x + &other.y; + let t3 = &t3 * &t4; + let t4 = &t0 + &t1; + let t3 = &t3 - &t4; + + // Steps 9-13. + let t4 = &self.x + &self.z; + let t5 = &other.x + &other.z; + let t4 = &t4 * &t5; + let t5 = &t0 + &t2; + let t4 = &t4 - &t5; + + // Steps 14-18. + let t5 = &self.y + &self.z; + let x = &other.y + &other.z; + let t5 = &t5 * &x; + let x = &t1 + &t2; + let t5 = &t5 - &x; + + // Steps 19-24. + let z = &Montgomery::A * &t4; + let x = &Montgomery::THREE_B * &t2; + let z = &x + &z; + let x = &t1 - &z; + let z = &t1 + &z; + let y = &x * &z; + + // Steps 25-34. + let t1 = &t0 + &t0; + let t1 = &t1 + &t0; + let t2 = &Montgomery::A * &t2; + let t4 = &Montgomery::THREE_B * &t4; + let t1 = &t1 + &t2; + let t2 = &t0 - &t2; + let t2 = &Montgomery::A * &t2; + let t4 = &t4 + &t2; + let t0 = &t1 * &t4; + let y = &y + &t0; + + // Steps 35-37. + let t0 = &t5 * &t4; + let x = &t3 * &x; + let x = &x - &t0; + + // Steps 38-40. + let t0 = &t3 * &t1; + let z = &t5 * &z; + let z = &z + &t0; + + PointProjective { x, y, z } + } +} + +impl PointAffine { + /** Constant-time helpers **/ + fn select_point(table: &[[Montgomery; 2]; 15], index: u32) -> PointAffine { + let mut x = Montgomery::ZERO; + let mut y = Montgomery::ZERO; + + for i in 0..15 { + let choice = (i + 1).ct_eq(&index); + x.conditional_assign(&table[i as usize][0], choice); + y.conditional_assign(&table[i as usize][1], choice); + } + + PointAffine { x, y } + } + + /** Arithmetic **/ + fn scalar_mul(&self, scalar: &ExponentP256) -> PointProjective { + let mut precomp = [PointProjective { + x: Montgomery::ZERO, + y: Montgomery::ZERO, + z: Montgomery::ZERO, + }; 15]; + + precomp[0] = PointProjective::from_affine(self); + + for i in (1..15).step_by(2) { + precomp[i] = precomp[i >> 1].double(); + precomp[i + 1] = precomp[i].add_mixed(self); + } + + let mut n = PointProjective { + x: Montgomery::ZERO, + y: Montgomery::ZERO, + z: Montgomery::ZERO, + }; + let mut choice_n_is_inf = Choice::from(1u8); + + for i in (0..256).step_by(4) { + if i != 0 { + n = n.double(); + n = n.double(); + n = n.double(); + n = n.double(); + } + let index = scalar.bit(255 - i) << 3 + | scalar.bit(255 - i - 1) << 2 + | scalar.bit(255 - i - 2) << 1 + | scalar.bit(255 - i - 3); + + let p = PointProjective::select_point(&precomp, index); + let t = n.add(&p); + + n.conditional_assign(&p, choice_n_is_inf); + + let choice_p_is_inf = index.ct_eq(&0); + n.conditional_assign(&t, !(choice_p_is_inf | choice_n_is_inf)); + + choice_n_is_inf &= choice_p_is_inf; + } + + n + } +} + +/** Arithmetic operators **/ +#[allow(clippy::suspicious_arithmetic_impl)] +impl Add for &PointProjective { + type Output = PointProjective; + + // Complete formula from https://eprint.iacr.org/2015/1060.pdf, Algorithm 4. + fn add(self, other: &PointProjective) -> PointProjective { + // Steps 1-3. + let mut t0 = &self.x * &other.x; + let t1 = &self.y * &other.y; + let mut t2 = &self.z * &other.z; + + // Steps 4-8. + let t3 = &self.x + &self.y; + let t4 = &other.x + &other.y; + let t3 = &t3 * &t4; + let t4 = &t0 + &t1; + let t3 = &t3 - &t4; + + // Steps 9-13. + let t4 = &self.y + &self.z; + let x = &other.y + &other.z; + let t4 = &t4 * &x; + let x = &t1 + &t2; + let t4 = &t4 - &x; + + // Steps 14-18. + let x = &self.x + &self.z; + let y = &other.x + &other.z; + let x = &x * &y; + let y = &t0 + &t2; + let y = &x - &y; + + // Steps 19-24. + let z = &Montgomery::B * &t2; + let mut x = &y - &z; + x.mul_scalar3(); // 21-22 + let z = &t1 - &x; + let x = &t1 + &x; + + // Steps 25-29. + let y = &Montgomery::B * &y; + t2.mul_scalar3(); // 26-27 + let y = &y - &t2; + let mut y = &y - &t0; + + // Steps 30-34. + y.mul_scalar3(); // 30-31 + t0.mul_scalar3(); // 32-33 + let t0 = &t0 - &t2; + + // Steps 35-43. + let t1 = &t4 * &y; + let t2 = &t0 * &y; + let y = &x * &z; + let y = &y + &t2; + let x = &t3 * &x; + let x = &x - &t1; + let z = &t4 * &z; + let t1 = &t3 * &t0; + let z = &z + &t1; + + PointProjective { x, y, z } + } +} + +#[cfg(feature = "derive_debug")] +impl core::fmt::Debug for PointP256 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("PointP256") + .field("x", &self.x) + .field("y", &self.y) + .finish() + } +} + +#[cfg(feature = "derive_debug")] +impl PartialEq for PointP256 { + fn eq(&self, other: &PointP256) -> bool { + self.x == other.x && self.y == other.y + } +} + +#[cfg(test)] +pub mod test { + use super::*; + + impl PartialEq for PointAffine { + fn eq(&self, other: &PointAffine) -> bool { + self.x == other.x && self.y == other.y + } + } + + impl core::fmt::Debug for PointAffine { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("PointAffine") + .field("x", &self.x) + .field("y", &self.y) + .finish() + } + } + + impl PartialEq for PointProjective { + fn eq(&self, other: &PointProjective) -> bool { + self.to_affine() == other.to_affine() + } + } + + impl core::fmt::Debug for PointProjective { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("PointProjective") + .field("x", &self.x) + .field("y", &self.y) + .field("z", &self.z) + .finish() + } + } + + pub fn precomputed(i: usize, j: usize) -> PointAffine { + PointAffine { + x: Montgomery::PRECOMPUTED[i][j][0], + y: Montgomery::PRECOMPUTED[i][j][1], + } + } + + fn get_test_values_affine() -> Vec { + let mut values = Vec::new(); + for table in 0..2 { + for index in 0..15 { + values.push(precomputed(table, index)); + } + } + values + } + + fn get_test_values_projective() -> Vec { + let mut values: Vec<_> = get_test_values_affine() + .iter() + .map(|p| PointProjective::from_affine(p)) + .collect(); + values.push(PointProjective::INFINITY); + values + } + + fn get_test_values() -> Vec { + get_test_values_affine() + .iter() + .map(|p| PointP256::from_affine(p)) + .collect() + } + + /** Serialization **/ + #[test] + fn test_to_bytes_from_bytes() { + for &x in &get_test_values() { + let mut buf = [Default::default(); 65]; + x.to_bytes_uncompressed(&mut buf); + assert_eq!(PointP256::from_bytes_uncompressed_vartime(&buf), Some(x)); + } + } + + #[test] + fn test_from_bytes_infinity_is_invalid() { + let mut buf = [0; 65]; + buf[0] = 0x04; + assert_eq!(PointP256::from_bytes_uncompressed_vartime(&buf), None); + } + + /** Conversion between point types **/ + #[test] + fn test_convert_p256_affine() { + for x in &get_test_values_affine() { + assert_eq!(PointP256::from_affine(x).to_affine(), *x); + } + } + + #[test] + fn test_convert_projective_affine() { + for x in &get_test_values_affine() { + assert_eq!(PointProjective::from_affine(x).to_affine(), *x); + } + } + + #[test] + fn test_projective_shuffle() { + for x in &get_test_values_affine() { + for &shuffle in &super::super::montgomery::test::get_nonzero_test_values() { + assert_eq!( + PointProjective::from_affine_shuffled(x, shuffle).to_affine(), + *x + ); + } + } + } + + /** Point validation **/ + // Edge cases generated with the following Sage script. + // + // ``` + // k = GF(2^256 - 2^224 + 2^192 + 2^96 - 1, 't'); + // R = PolynomialRing(k, 'u'); + // u = R.gen() + // b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b + // + // def print_point(x, y): + // print "x = 0x%x" % x + // print "y = 0x%x" % y + // print "x^3 - 3*x + b = 0x%x" % (x^3 - 3*x + b) + // print "y^2 = 0x%x" % y^2 + // + // def find_point_at_x(x): + // f = x^3 - 3*x + b - u^2 + // r = f.roots() + // if len(r) > 0: + // y = r[0][0] + // print_point(x, y) + // + // def find_point_at_y(y): + // f = u^3 - 3*u + b - y^2 + // r = f.roots() + // if len(r) > 0: + // x = r[0][0] + // print_point(x, y) + // + // ITERATIONS = 16 + // + // print "*" * 40 + // print "Small x" + // print "*" * 40 + // for i in range(ITERATIONS): + // x = k(i) + // find_point_at_x(x) + // + // print "*" * 40 + // print "Small y" + // print "*" * 40 + // for i in range(ITERATIONS): + // y = k(i) + // find_point_at_y(y) + // + // print "*" * 40 + // print "High-weight x" + // print "*" * 40 + // for i in range(ITERATIONS): + // x = k(2^255 - 1 - 2^i) + // find_point_at_x(x) + // + // print "*" * 40 + // print "High-weight y" + // print "*" * 40 + // for i in range(ITERATIONS): + // y = k(2^255 - 1 - 2^i) + // find_point_at_y(y) + // ``` + #[rustfmt::skip] + const POINTS_SMALL_X: &[[[u32; 8]; 2]] = &[ +[ + [0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000], + [0xcdb70433, 0xccbea3f7, 0x9b265c3a, 0xee35afc4, 0x667e8521, 0x016ec431, 0x55a7e7fa, 0xba6dbc45], +], +[ + [0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000], + [0x7d7ddc34, 0xddf2aed7, 0xf0183f16, 0x232efd48, 0xcc8dffb8, 0xb9967a1a, 0xabdaf53e, 0xc94db3d2], +], +[ + [0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000], + [0x636041b3, 0x2242d085, 0xd631ff69, 0x27249b16, 0x3f37f6a6, 0xd624d1d2, 0xca290db0, 0xb706288a], +], +[ + [0x00000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000], + [0x8fe7b297, 0xdb1812e4, 0x3c63a432, 0xfbc52276, 0xd33315cb, 0xcaaa94f7, 0x2caf2e23, 0x8e14e843], +], +[ + [0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000], + [0xb2b74387, 0x6abbc3b4, 0x9de5be82, 0xc726c883, 0x6c4b6500, 0xc653e363, 0xcb0680c1, 0x93fbd29a], +], + ]; + #[rustfmt::skip] + const POINTS_SMALL_Y: &[[[u32; 8]; 2]] = &[ +[ + [0x0069d2c7, 0x875d877f, 0x7b70f611, 0x6375e8a9, 0x95dbac0d, 0x10db6dd0, 0xab9c6e9e, 0x8d0177eb], + [0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000], +], +[ + [0x7607ce12, 0xc9fe1bd7, 0x8b283fbb, 0x53eb03e0, 0xddcaac96, 0xa62f56d3, 0xc6825c8a, 0xcfe9c22c], + [0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000], +], +[ + [0xde8de1d7, 0xb176f692, 0x841022ca, 0x4cffaf35, 0xeb345f84, 0x0a92738c, 0x46cd60d8, 0xd7325d76], + [0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000], +], +[ + [0x87914a78, 0x077d5a71, 0x8e3dc5b2, 0x979131e2, 0x97d7ab3f, 0x731dbdaf, 0x1da31d68, 0x9b21c2de], + [0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000], +], +[ + [0xd56ac453, 0xd7acceae, 0xc6693e4f, 0xcffa296d, 0xe4df51fc, 0x564d94b7, 0xbc9f7da8, 0xb2ed6eac], + [0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000], +], + ]; + #[rustfmt::skip] + const POINTS_HIGH_WEIGHT: &[[[u32; 8]; 2]] = &[ +// High-weight x coordinate. +[ + [0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xefffffff], + [0xf0e94c90, 0x722ff8d6, 0x66ebf289, 0x9b17896c, 0x334f0e43, 0xc4e1c5d1, 0x1ea63e81, 0xa120f8da], +], +[ + [0xfffffffd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xefffffff], + [0x5ad8aa4b, 0x717d6de4, 0x2af77820, 0x04ce8429, 0xefb80898, 0xd004a68e, 0xe4b30001, 0x887ce5d3], +], +// High-weight y coordinate. +[ + [0x98619b11, 0xae2e447c, 0x02bcee26, 0x1fcb1b9b, 0xed3ee2d9, 0xefb6ff97, 0x77ee5948, 0xe063d049], + [0xfffffffd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xefffffff], +], +[ + [0xcaf4e99c, 0x494eac75, 0x3237de43, 0x695ba4d4, 0x68339d6f, 0xbca064f3, 0x4910c02a, 0xaefca662], + [0xfffffffb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xefffffff], +], + ]; + + #[test] + fn test_zero_x_point() { + // Even though this point verifies the equation y^2 = x^3 - 3x + b, none of the (x, y) + // coordinates is allowed to be zero. + #[rustfmt::skip] + let x = Int256::new( + [0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000] + ); + #[rustfmt::skip] + let y = Int256::new( + [0xe8b06c0b, 0xd7407a95, 0xe25178e8, 0xabe3d50d, 0x7b5f9449, 0xdbcc42a2, 0xf1d07c29, 0x99b7a386] + ); + assert!(PointP256::new_checked_vartime(x, y).is_none()); + } + + #[test] + fn test_small_x_points() { + for p in POINTS_SMALL_X { + let x = Int256::new(p[0]); + let y = Int256::new(p[1]); + // These points are valid. + assert!(PointP256::new_checked_vartime(x, y).is_some()); + // Adding p to the x coordinate doesn't invalidate the equation y^2 = x^3 - 3x + b (as + // we work in GF(p)), however the coordinates must be serialized in a canonical form + // modulo p. + assert!(PointP256::new_checked_vartime((&x + &Int256::P).0, y).is_none()); + } + } + + #[test] + fn test_small_y_points() { + for p in POINTS_SMALL_Y { + let x = Int256::new(p[0]); + let y = Int256::new(p[1]); + // These points are valid. + assert!(PointP256::new_checked_vartime(x, y).is_some()); + // Adding p to the y coordinate doesn't invalidate the equation y^2 = x^3 - 3x + b (as + // we work in GF(p)), however the coordinates must be serialized in a canonical form + // modulo p. + assert!(PointP256::new_checked_vartime(x, (&y + &Int256::P).0).is_none()); + } + } + + #[test] + fn test_high_weight_points() { + // These points are all valid, with one coordinate of high Hamming weight. This is a sanity + // check that arithmetic works on such high weight values. + for p in POINTS_HIGH_WEIGHT { + let x = Int256::new(p[0]); + let y = Int256::new(p[1]); + assert!(PointP256::new_checked_vartime(x, y).is_some()); + } + } + + #[test] + fn test_infinity_is_invalid() { + assert!(PointP256::new_checked_vartime( + PointP256::INFINITY.x.to_int(), + PointP256::INFINITY.y.to_int() + ) + .is_none()); + } + + /** Constant-time helpers **/ + #[test] + fn test_select_point_projective() { + let mut table = Vec::new(); + for i in 0..15 { + table.push(PointProjective::from_affine(&precomputed(0, i))); + } + + assert_eq!( + PointProjective::select_point(array_ref![table, 0, 15], 0), + PointProjective { + x: Montgomery::ZERO, + y: Montgomery::ZERO, + z: Montgomery::ZERO, + } + ); + for index in 1..16 { + assert_eq!( + PointProjective::select_point(array_ref![table, 0, 15], index as u32), + table[index - 1] + ); + } + } + + #[test] + fn test_select_point_affine() { + let table = &Montgomery::PRECOMPUTED[0]; + + assert_eq!( + PointAffine::select_point(table, 0), + PointAffine { + x: Montgomery::ZERO, + y: Montgomery::ZERO, + } + ); + for index in 1..16 { + assert_eq!( + PointAffine::select_point(table, index as u32), + precomputed(0, index - 1) + ); + } + } + + /** Arithmetic operators **/ + #[test] + fn test_add_is_add_complete_general() { + for x in &get_test_values_projective() { + for y in &get_test_values_projective() { + let left = x.add_complete_general(y); + let right = x + y; + assert_eq!(left, right); + } + } + } + + #[test] + fn test_add_is_associative() { + for x in &get_test_values_projective() { + for y in &get_test_values_projective() { + for z in &get_test_values_projective() { + // (x + y) + z + let left = &(x + y) + z; + // x + (y + z) + let right = x + &(y + z); + assert_eq!(left, right); + } + } + } + } + + #[test] + fn test_add_is_commutative() { + for x in &get_test_values_projective() { + for y in &get_test_values_projective() { + assert_eq!(x + y, y + x); + } + } + } + + #[test] + fn test_add_mixed() { + for x in &get_test_values_projective() { + for y in &get_test_values_affine() { + assert_eq!(x.add_mixed(y), x + &PointProjective::from_affine(y)); + } + } + } + + #[test] + fn test_double() { + for x in &get_test_values_projective() { + println!("doubling {:?}", x); + assert_eq!(x.double(), x + x); + } + } + + #[test] + fn test_add_infinity() { + for &x in &get_test_values_projective() { + assert_eq!(&x + &PointProjective::INFINITY, x); + } + } + + #[test] + fn test_add_mixed_infinity() { + for x in &get_test_values_affine() { + assert_eq!( + PointProjective::INFINITY.add_mixed(x), + PointProjective::from_affine(x) + ); + } + } + + #[test] + fn test_double_infinity() { + assert_eq!( + PointProjective::INFINITY.double(), + PointProjective::INFINITY + ); + } + + #[test] + fn test_generator_is_valid_point() { + let gen = precomputed(0, 0); + assert!(PointP256::from_affine(&gen).is_valid_vartime()); + } + + #[test] + fn test_generator_has_correct_order() { + let gen = precomputed(0, 0); + // Normally the ExponentP256 type guarantees that its values stay in [0, N[ because N is + // the curve order and therefore exponents >= N are equivalent to their reduction modulo N. + // In this test we check that N is indeed the curve order and therefore we need an unsafe + // block to construct an exponent of N. + let order = unsafe { ExponentP256::from_int_unchecked(Int256::N) }; + assert_eq!( + PointP256::from_projective(&gen.scalar_mul(&order)), + PointP256::INFINITY + ); + } + + #[test] + fn test_scalar_base_mul_is_scalar_mul_generator() { + let gen = precomputed(0, 0); + // TODO: more scalars + for scalar in &super::super::exponent256::test::get_test_values() { + assert_eq!( + PointProjective::scalar_base_mul(scalar), + gen.scalar_mul(scalar) + ); + } + } + + #[test] + fn test_base_point_mul_is_mul_generator() { + let gen = precomputed(0, 0); + // TODO: more scalars + for scalar in &super::super::exponent256::test::get_test_values() { + assert_eq!( + PointP256::base_point_mul(scalar), + PointP256::from_affine(&gen).mul(scalar) + ); + } + } + + // Helper function to compute the point 2^power * p. + pub fn power_of_two(mut p: PointProjective, power: usize) -> PointProjective { + for _ in 0..power { + p = p.double(); + } + p + } + + // TODO: more tests +} diff --git a/libraries/crypto/src/ec/precomputed.rs b/libraries/crypto/src/ec/precomputed.rs new file mode 100644 index 0000000..809fad6 --- /dev/null +++ b/libraries/crypto/src/ec/precomputed.rs @@ -0,0 +1,324 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::montgomery::{Montgomery, NLIMBS}; + +pub const PRECOMPUTED: [[[Montgomery; 2]; 15]; 2] = [ + [ + [ + Montgomery::new(PRECOMPUTED_LIMBS[0]), + Montgomery::new(PRECOMPUTED_LIMBS[1]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[2]), + Montgomery::new(PRECOMPUTED_LIMBS[3]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[4]), + Montgomery::new(PRECOMPUTED_LIMBS[5]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[6]), + Montgomery::new(PRECOMPUTED_LIMBS[7]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[8]), + Montgomery::new(PRECOMPUTED_LIMBS[9]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[10]), + Montgomery::new(PRECOMPUTED_LIMBS[11]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[12]), + Montgomery::new(PRECOMPUTED_LIMBS[13]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[14]), + Montgomery::new(PRECOMPUTED_LIMBS[15]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[16]), + Montgomery::new(PRECOMPUTED_LIMBS[17]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[18]), + Montgomery::new(PRECOMPUTED_LIMBS[19]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[20]), + Montgomery::new(PRECOMPUTED_LIMBS[21]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[22]), + Montgomery::new(PRECOMPUTED_LIMBS[23]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[24]), + Montgomery::new(PRECOMPUTED_LIMBS[25]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[26]), + Montgomery::new(PRECOMPUTED_LIMBS[27]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[28]), + Montgomery::new(PRECOMPUTED_LIMBS[29]), + ], + ], + [ + [ + Montgomery::new(PRECOMPUTED_LIMBS[30]), + Montgomery::new(PRECOMPUTED_LIMBS[31]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[32]), + Montgomery::new(PRECOMPUTED_LIMBS[33]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[34]), + Montgomery::new(PRECOMPUTED_LIMBS[35]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[36]), + Montgomery::new(PRECOMPUTED_LIMBS[37]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[38]), + Montgomery::new(PRECOMPUTED_LIMBS[39]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[40]), + Montgomery::new(PRECOMPUTED_LIMBS[41]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[42]), + Montgomery::new(PRECOMPUTED_LIMBS[43]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[44]), + Montgomery::new(PRECOMPUTED_LIMBS[45]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[46]), + Montgomery::new(PRECOMPUTED_LIMBS[47]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[48]), + Montgomery::new(PRECOMPUTED_LIMBS[49]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[50]), + Montgomery::new(PRECOMPUTED_LIMBS[51]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[52]), + Montgomery::new(PRECOMPUTED_LIMBS[53]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[54]), + Montgomery::new(PRECOMPUTED_LIMBS[55]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[56]), + Montgomery::new(PRECOMPUTED_LIMBS[57]), + ], + [ + Montgomery::new(PRECOMPUTED_LIMBS[58]), + Montgomery::new(PRECOMPUTED_LIMBS[59]), + ], + ], +]; + +#[rustfmt::skip] +#[allow(clippy::unreadable_literal)] +const PRECOMPUTED_LIMBS: [[u32; NLIMBS]; 60] = [ +[0x11522878, 0x0e730d41, 0x0db60179, 0x04afe2ff, 0x12883add, 0x0caddd88, 0x119e7edc, 0x0d4a6eab, 0x03120bee], +[0x1d2aac15, 0x0f25357c, 0x19e45cdd, 0x05c721d0, 0x1992c5a5, 0x0a237487, 0x0154ba21, 0x014b10bb, 0x00ae3fe3], +[0x0d41a576, 0x0922fc51, 0x0234994f, 0x060b60d3, 0x164586ae, 0x0ce95f18, 0x1fe49073, 0x03fa36cc, 0x05ebcd2c], +[0x0b402f2f, 0x015c70bf, 0x1561925c, 0x05a26704, 0x0da91e90, 0x0cdc1c7f, 0x1ea12446, 0x0e1ade1e, 0x0ec91f22], +[0x026f7778, 0x0566847e, 0x0a0bec9e, 0x0234f453, 0x1a31f21a, 0x0d85e75c, 0x056c7109, 0x0a267a00, 0x0b57c050], +[0x0098fb57, 0x0aa837cc, 0x060c0792, 0x0cfa5e19, 0x061bab9e, 0x0589e39b, 0x00a324c5, 0x07d6dee7, 0x02976e4b], +[0x1fc4124a, 0x0a8c244b, 0x1ce86762, 0x0cd61c7e, 0x1831c8e0, 0x075774e1, 0x1d96a5a9, 0x0843a649, 0x0c3ab0fa], +[0x06e2e7d5, 0x07673a2a, 0x178b65e8, 0x04003e9b, 0x1a1f11c2, 0x007816ea, 0x0f643e11, 0x058c43df, 0x0f423fc2], +[0x19633ffa, 0x0891f2b2, 0x123c231c, 0x046add8c, 0x054700dd, 0x059e2b17, 0x172db40f, 0x083e277d, 0x0b0dd609], +[0x0fd1da12, 0x035c6e52, 0x19ede20c, 0x0d19e0c0, 0x097d0f40, 0x0b015b19, 0x0449e3f5, 0x00e10c9e, 0x033ab581], +[0x056a67ab, 0x0577734d, 0x1dddc062, 0x0c57b10d, 0x0149b39d, 0x026a9e7b, 0x0c35df9f, 0x048764cd, 0x076dbcca], +[0x0ca4b366, 0x0e9303ab, 0x1a7480e7, 0x057e9e81, 0x1e13eb50, 0x0f466cf3, 0x06f16b20, 0x04ba3173, 0x0c168c33], +[0x15cb5439, 0x06a38e11, 0x073658bd, 0x0b29564f, 0x03f6dc5b, 0x0053b97e, 0x1322c4c0, 0x065dd7ff, 0x03a1e4f6], +[0x14e614aa, 0x09246317, 0x1bc83aca, 0x0ad97eed, 0x0d38ce4a, 0x0f82b006, 0x0341f077, 0x0a6add89, 0x04894acd], +[0x09f162d5, 0x0f8410ef, 0x1b266a56, 0x00d7f223, 0x03e0cb92, 0x0e39b672, 0x06a2901a, 0x069a8556, 0x0007e7c0], +[0x09b7d8d3, 0x00309a80, 0x1ad05f7f, 0x0c2fb5dd, 0x0cbfd41d, 0x09ceb638, 0x1051825c, 0x0da0cf5b, 0x0812e881], +[0x06f35669, 0x06a56f2c, 0x1df8d184, 0x00345820, 0x1477d477, 0x01645db1, 0x0be80c51, 0x0c22be3e, 0x0e35e65a], +[0x1aeb7aa0, 0x0c375315, 0x0f67bc99, 0x07fdd7b9, 0x191fc1be, 0x0061235d, 0x02c184e9, 0x01c5a839, 0x047a1e26], +[0x0b7cb456, 0x093e225d, 0x14f3c6ed, 0x0ccc1ac9, 0x17fe37f3, 0x04988989, 0x1a90c502, 0x02f32042, 0x0a17769b], +[0x0afd8c7c, 0x08191c6e, 0x1dcdb237, 0x016200c0, 0x107b32a1, 0x066c08db, 0x10d06a02, 0x0003fc93, 0x05620023], +[0x16722b27, 0x068b5c59, 0x0270fcfc, 0x0fad0ecc, 0x0e5de1c2, 0x0eab466b, 0x02fc513c, 0x0407f75c, 0x0baab133], +[0x09705fe9, 0x0b88b8e7, 0x0734c993, 0x01e1ff8f, 0x19156970, 0x0abd0f00, 0x10469ea7, 0x03293ac0, 0x0cdc98aa], +[0x01d843fd, 0x0e14bfe8, 0x15be825f, 0x008b5212, 0x0eb3fb67, 0x081cbd29, 0x0bc62f16, 0x02b6fcc7, 0x0f5a4e29], +[0x13560b66, 0x0c0b6ac2, 0x051ae690, 0x0d41e271, 0x0f3e9bd4, 0x01d70aab, 0x01029f72, 0x073e1c35, 0x0ee70fbc], +[0x0ad81baf, 0x09ecc49a, 0x086c741e, 0x0fe6be30, 0x176752e7, 0x0023d416, 0x1f83de85, 0x027de188, 0x066f70b8], +[0x181cd51f, 0x096b6e4c, 0x188f2335, 0x0a5df759, 0x17a77eb6, 0x0feb0e73, 0x154ae914, 0x02f3ec51, 0x03826b59], +[0x0b91f17d, 0x01c72949, 0x1362bf0a, 0x0e23fddf, 0x0a5614b0, 0x000f7d8f, 0x00079061, 0x0823d9d2, 0x08213f39], +[0x1128ae0b, 0x0d095d05, 0x0b85c0c2, 0x01ecb2ef, 0x024ddc84, 0x0e35e901, 0x18411a4a, 0x0f5ddc3d, 0x03786689], +[0x052260e8, 0x05ae3564, 0x0542b10d, 0x08d93a45, 0x19952aa4, 0x0996cc41, 0x1051a729, 0x04be3499, 0x052b23aa], +[0x109f307e, 0x06f5b6bb, 0x1f84e1e7, 0x077a0cfa, 0x10c4df3f, 0x025a02ea, 0x0b048035, 0x0e31de66, 0x0c6ecaa3], +[0x028ea335, 0x02886024, 0x1372f020, 0x00f55d35, 0x15e4684c, 0x0f2a9e17, 0x1a4a7529, 0x0cb7beb1, 0x0b2a78a1], +[0x1ab21f1f, 0x06361ccf, 0x06c9179d, 0x0b135627, 0x1267b974, 0x04408bad, 0x1cbff658, 0x0e3d6511, 0x00c7d76f], +[0x01cc7a69, 0x0e7ee31b, 0x054fab4f, 0x002b914f, 0x1ad27a30, 0x0cd3579e, 0x0c50124c, 0x050daa90, 0x00b13f72], +[0x0b06aa75, 0x070f5cc6, 0x1649e5aa, 0x084a5312, 0x0329043c, 0x041c4011, 0x13d32411, 0x0b04a838, 0x0d760d2d], +[0x1713b532, 0x0baa0c03, 0x084022ab, 0x06bcf5c1, 0x02f45379, 0x018ae070, 0x18c9e11e, 0x020bca9a, 0x066f496b], +[0x03eef294, 0x067500d2, 0x0d7f613c, 0x002dbbeb, 0x0b741038, 0x0e04133f, 0x1582968d, 0x0be985f7, 0x01acbc1a], +[0x1a6a939f, 0x033e50f6, 0x0d665ed4, 0x0b4b7bd6, 0x1e5a3799, 0x06b33847, 0x17fa56ff, 0x065ef930, 0x0021dc4a], +[0x02b37659, 0x0450fe17, 0x0b357b65, 0x0df5efac, 0x15397bef, 0x09d35a7f, 0x112ac15f, 0x0624e62e, 0x0a90ae2f], +[0x107eecd2, 0x01f69bbe, 0x077d6bce, 0x05741394, 0x13c684fc, 0x0950c910, 0x0725522b, 0x0dc78583, 0x040eeabb], +[0x1fde328a, 0x0bd61d96, 0x0d28c387, 0x09e77d89, 0x12550c40, 0x0759cb7d, 0x0367ef34, 0x0ae2a960, 0x091b8bdc], +[0x093462a9, 0x00f469ef, 0x0b2e9aef, 0x0d2ca771, 0x054e1f42, 0x007aaa49, 0x06316abb, 0x02413c8e, 0x05425bf9], +[0x1bed3e3a, 0x0f272274, 0x1f5e7326, 0x06416517, 0x0ea27072, 0x09cedea7, 0x006e7633, 0x07c91952, 0x0d806dce], +[0x08e2a7e1, 0x0e421e1a, 0x0418c9e1, 0x01dbc890, 0x1b395c36, 0x0a1dc175, 0x1dc4ef73, 0x08956f34, 0x0e4b5cf2], +[0x1b0d3a18, 0x03194a36, 0x06c2641f, 0x0e44124c, 0x0a2f4eaa, 0x0a8c25ba, 0x0f927ed7, 0x0627b614, 0x07371cca], +[0x0ba16694, 0x0417bc03, 0x07c0a7e3, 0x09c35c19, 0x1168a205, 0x08b6b00d, 0x10e3edc9, 0x09c19bf2, 0x05882229], +[0x1b2b4162, 0x0a5cef1a, 0x1543622b, 0x09bd433e, 0x0364e04d, 0x07480792, 0x05c9b5b3, 0x0e85ff25, 0x0408ef57], +[0x1814cfa4, 0x0121b41b, 0x0d248a0f, 0x03b05222, 0x039bb16a, 0x0c75966d, 0x0a038113, 0x0a4a1769, 0x011fbc6c], +[0x0917e50e, 0x0eec3da8, 0x169d6eac, 0x010c1699, 0x0a416153, 0x0f724912, 0x15cd60b7, 0x04acbad9, 0x05efc5fa], +[0x0f150ed7, 0x00122b51, 0x1104b40a, 0x0cb7f442, 0x0fbb28ff, 0x06ac53ca, 0x196142cc, 0x07bf0fa9, 0x00957651], +[0x04e0f215, 0x0ed439f8, 0x03f46bd5, 0x05ace82f, 0x110916b6, 0x006db078, 0x0ffd7d57, 0x0f2ecaac, 0x0ca86dec], +[0x15d6b2da, 0x0965ecc9, 0x1c92b4c2, 0x001f3811, 0x1cb080f5, 0x02d8b804, 0x19d1c12d, 0x0f20bd46, 0x01951fa7], +[0x0a3656c3, 0x0523a425, 0x0fcd0692, 0x0d44ddc8, 0x131f0f5b, 0x0af80e4a, 0x0cd9fc74, 0x099bb618, 0x02db944c], +[0x0a673090, 0x01c210e1, 0x178c8d23, 0x01474383, 0x10b8743d, 0x0985a55b, 0x02e74779, 0x00576138, 0x09587927], +[0x133130fa, 0x0be05516, 0x09f4d619, 0x0bb62570, 0x099ec591, 0x0d9468fe, 0x1d07782d, 0x0fc72e0b, 0x0701b298], +[0x1863863b, 0x085954b8, 0x121a0c36, 0x09e7fedf, 0x0f64b429, 0x09b9d71e, 0x14e2f5d8, 0x0f858d3a, 0x0942eea8], +[0x0da5b765, 0x06edafff, 0x0a9d18cc, 0x0c65e4ba, 0x1c747e86, 0x0e4ea915, 0x1981d7a1, 0x08395659, 0x052ed4e2], +[0x087d43b7, 0x037ab11b, 0x19d292ce, 0x0f8d4692, 0x18c3053f, 0x08863e13, 0x04c146c0, 0x06bdf55a, 0x04e4457d], +[0x16152289, 0x0ac78ec2, 0x1a59c5a2, 0x02028b97, 0x071c2d01, 0x0295851f, 0x0404747b, 0x0878558d, 0x07d29aa4], +[0x13d8341f, 0x08daefd7, 0x139c972d, 0x06b7ea75, 0x0d4a9dde, 0x0ff163d8, 0x081d55d7, 0x0a5bef68, 0x0b7b30d8], +[0x0be73d6f, 0x0aa88141, 0x0d976c81, 0x07e7a9cc, 0x18beb771, 0x0d773cbd, 0x13f51951, 0x09d0c177, 0x01c49a78], +]; + +#[cfg(test)] +mod test { + use super::super::montgomery::{BOTTOM_28_BITS, BOTTOM_29_BITS}; + use super::super::point::test::{power_of_two, precomputed}; + use super::super::point::PointProjective; + use super::*; + + #[test] + fn test_precomputed_bits() { + for x in PRECOMPUTED_LIMBS.iter() { + for (i, &limb) in x.iter().enumerate() { + if i & 1 == 0 { + assert_eq!(limb & BOTTOM_29_BITS, limb); + } else { + assert_eq!(limb & BOTTOM_28_BITS, limb); + } + } + } + } + + #[test] + fn test_precomputed_powers_of_g_are_correct() { + let gen = PointProjective::from_affine(&precomputed(0, 0)); + let g32 = power_of_two(gen, 32); + let g64 = power_of_two(gen, 64); + let g96 = power_of_two(gen, 96); + let g128 = power_of_two(gen, 128); + let g160 = power_of_two(gen, 160); + let g192 = power_of_two(gen, 192); + let g224 = power_of_two(gen, 224); + + assert_eq!( + PointProjective::from_affine(&precomputed(0, 0b0001 - 1)), + gen + ); + assert_eq!( + PointProjective::from_affine(&precomputed(0, 0b0010 - 1)), + g64 + ); + assert_eq!( + PointProjective::from_affine(&precomputed(0, 0b0100 - 1)), + g128 + ); + assert_eq!( + PointProjective::from_affine(&precomputed(0, 0b1000 - 1)), + g192 + ); + assert_eq!( + PointProjective::from_affine(&precomputed(1, 0b0001 - 1)), + g32 + ); + assert_eq!( + PointProjective::from_affine(&precomputed(1, 0b0010 - 1)), + g96 + ); + assert_eq!( + PointProjective::from_affine(&precomputed(1, 0b0100 - 1)), + g160 + ); + assert_eq!( + PointProjective::from_affine(&precomputed(1, 0b1000 - 1)), + g224 + ); + } + + #[test] + fn test_precomputed_table_0_is_correct() { + let gen = PointProjective::from_affine(&precomputed(0, 0)); + let g64 = power_of_two(gen, 64); + let g128 = power_of_two(gen, 128); + let g192 = power_of_two(gen, 192); + + for i in 1..16 { + let mut x = PointProjective::INFINITY; + if i & 1 != 0 { + x = &x + &gen; + } + if i & 2 != 0 { + x = &x + &g64; + } + if i & 4 != 0 { + x = &x + &g128; + } + if i & 8 != 0 { + x = &x + &g192; + } + assert_eq!(PointProjective::from_affine(&precomputed(0, i - 1)), x); + } + } + + #[test] + fn test_precomputed_table_1_is_correct() { + let gen = PointProjective::from_affine(&precomputed(0, 0)); + let g32 = power_of_two(gen, 32); + let g96 = power_of_two(gen, 96); + let g160 = power_of_two(gen, 160); + let g224 = power_of_two(gen, 224); + + for i in 1..16 { + let mut x = PointProjective::INFINITY; + if i & 1 != 0 { + x = &x + &g32; + } + if i & 2 != 0 { + x = &x + &g96; + } + if i & 4 != 0 { + x = &x + &g160; + } + if i & 8 != 0 { + x = &x + &g224; + } + assert_eq!(PointProjective::from_affine(&precomputed(1, i - 1)), x); + } + } +} diff --git a/libraries/crypto/src/ecdh.rs b/libraries/crypto/src/ecdh.rs new file mode 100644 index 0000000..7a4b250 --- /dev/null +++ b/libraries/crypto/src/ecdh.rs @@ -0,0 +1,154 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::ec::exponent256::NonZeroExponentP256; +use super::ec::int256; +use super::ec::int256::Int256; +use super::ec::point::PointP256; +use super::rng256::Rng256; +use super::sha256::Sha256; +use super::Hash256; + +pub const NBYTES: usize = int256::NBYTES; + +pub struct SecKey { + a: NonZeroExponentP256, +} + +#[cfg_attr(feature = "derive_debug", derive(Clone, PartialEq, Debug))] +pub struct PubKey { + p: PointP256, +} + +impl SecKey { + pub fn gensk(rng: &mut R) -> SecKey + where + R: Rng256, + { + SecKey { + a: NonZeroExponentP256::gen_uniform(rng), + } + } + + pub fn genpk(&self) -> PubKey { + PubKey { + p: PointP256::base_point_mul(self.a.as_exponent()), + } + } + + fn exchange_raw(&self, other: &PubKey) -> PointP256 { + // At this point, the PubKey type guarantees that other.p is a valid point on the curve. + // It's the responsibility of the caller to handle errors when converting serialized bytes + // to a PubKey. + other.p.mul(self.a.as_exponent()) + // TODO: Do we need to check that the exchanged point is not infinite, and if yes handle + // the error? The following argument should be reviewed: + // + // In principle this isn't needed on the P-256 curve, which has a prime order and a + // cofactor of 1. + // + // Some pointers on this: + // - https://www.secg.org/sec1-v2.pdf + } + + // DH key agreement method defined in the FIDO2 specification, Section 5.5.4. "Getting + // sharedSecret from Authenticator" + pub fn exchange_x_sha256(&self, other: &PubKey) -> [u8; 32] { + let p = self.exchange_raw(other); + let mut x: [u8; 32] = [Default::default(); 32]; + p.getx().to_int().to_bin(&mut x); + Sha256::hash(&x) + } +} + +impl PubKey { + #[cfg(test)] + fn from_bytes_uncompressed(bytes: &[u8]) -> Option { + PointP256::from_bytes_uncompressed_vartime(bytes).map(|p| PubKey { p }) + } + + #[cfg(test)] + fn to_bytes_uncompressed(&self, bytes: &mut [u8; 65]) { + self.p.to_bytes_uncompressed(bytes); + } + + pub fn from_coordinates(x: &[u8; NBYTES], y: &[u8; NBYTES]) -> Option { + PointP256::new_checked_vartime(Int256::from_bin(x), Int256::from_bin(y)) + .map(|p| PubKey { p }) + } + + pub fn to_coordinates(&self, x: &mut [u8; NBYTES], y: &mut [u8; NBYTES]) { + self.p.getx().to_int().to_bin(x); + self.p.gety().to_int().to_bin(y); + } +} + +#[cfg(test)] +mod test { + use super::super::rng256::ThreadRng256; + use super::*; + + // Run more test iterations in release mode, as the code should be faster. + #[cfg(not(debug_assertions))] + const ITERATIONS: u32 = 10000; + #[cfg(debug_assertions)] + const ITERATIONS: u32 = 1000; + + /** Test that key generation creates valid keys **/ + #[test] + fn test_gen_pub_is_valid_random() { + let mut rng = ThreadRng256 {}; + + for _ in 0..ITERATIONS { + let sk = SecKey::gensk(&mut rng); + let pk = sk.genpk(); + assert!(pk.p.is_valid_vartime()); + } + } + + /** Test that the exchanged key is the same on both sides **/ + #[test] + fn test_exchange_x_sha256_is_symmetric() { + let mut rng = ThreadRng256 {}; + + for _ in 0..ITERATIONS { + let sk_a = SecKey::gensk(&mut rng); + let pk_a = sk_a.genpk(); + let sk_b = SecKey::gensk(&mut rng); + let pk_b = sk_b.genpk(); + assert_eq!(sk_a.exchange_x_sha256(&pk_b), sk_b.exchange_x_sha256(&pk_a)); + } + } + + #[test] + fn test_exchange_x_sha256_bytes_is_symmetric() { + let mut rng = ThreadRng256 {}; + + for _ in 0..ITERATIONS { + let sk_a = SecKey::gensk(&mut rng); + let mut pk_bytes_a = [Default::default(); 65]; + sk_a.genpk().to_bytes_uncompressed(&mut pk_bytes_a); + + let sk_b = SecKey::gensk(&mut rng); + let mut pk_bytes_b = [Default::default(); 65]; + sk_b.genpk().to_bytes_uncompressed(&mut pk_bytes_b); + + let pk_a = PubKey::from_bytes_uncompressed(&pk_bytes_a).unwrap(); + let pk_b = PubKey::from_bytes_uncompressed(&pk_bytes_b).unwrap(); + assert_eq!(sk_a.exchange_x_sha256(&pk_b), sk_b.exchange_x_sha256(&pk_a)); + } + } + + // TODO: tests with invalid public shares. +} diff --git a/libraries/crypto/src/ecdsa.rs b/libraries/crypto/src/ecdsa.rs new file mode 100644 index 0000000..2d39311 --- /dev/null +++ b/libraries/crypto/src/ecdsa.rs @@ -0,0 +1,643 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::ec::exponent256::{ExponentP256, NonZeroExponentP256}; +use super::ec::int256; +use super::ec::int256::Int256; +use super::ec::point::PointP256; +use super::hmac::hmac_256; +use super::rng256::Rng256; +use super::{Hash256, HashBlockSize64Bytes}; +use alloc::vec::Vec; +use core::marker::PhantomData; + +#[derive(Clone, PartialEq)] +#[cfg_attr(feature = "derive_debug", derive(Debug))] +pub struct SecKey { + k: NonZeroExponentP256, +} + +pub struct Signature { + r: NonZeroExponentP256, + s: NonZeroExponentP256, +} + +pub struct PubKey { + p: PointP256, +} + +impl SecKey { + pub fn gensk(rng: &mut R) -> SecKey + where + R: Rng256, + { + SecKey { + k: NonZeroExponentP256::gen_uniform(rng), + } + } + + pub fn genpk(&self) -> PubKey { + PubKey { + p: PointP256::base_point_mul(self.k.as_exponent()), + } + } + + // ECDSA signature based on a RNG to generate a suitable randomization parameter. + // Under the hood, rejection sampling is used to make sure that the randomization parameter is + // uniformly distributed. + // The provided RNG must be cryptographically secure; otherwise this method is insecure. + pub fn sign_rng(&self, msg: &[u8], rng: &mut R) -> Signature + where + H: Hash256, + R: Rng256, + { + let m = ExponentP256::modn(Int256::from_bin(&H::hash(msg))); + + loop { + let k = NonZeroExponentP256::gen_uniform(rng); + if let Some(sign) = self.try_sign(&k, &m) { + return sign; + } + } + } + + // Deterministic ECDSA signature based on RFC 6979 to generate a suitable randomization + // parameter. + pub fn sign_rfc6979(&self, msg: &[u8]) -> Signature + where + H: Hash256 + HashBlockSize64Bytes, + { + let m = ExponentP256::modn(Int256::from_bin(&H::hash(msg))); + + let mut rfc_6979 = Rfc6979::::new(self, &msg); + loop { + let k = NonZeroExponentP256::from_int_checked(rfc_6979.next()); + // The branching here is fine. By design the algorithm of RFC 6976 has a running time + // that depends on the sequence of generated k. + if bool::from(k.is_none()) { + continue; + } + let k = k.unwrap(); + + if let Some(sign) = self.try_sign(&k, &m) { + return sign; + } + } + } + + // Try signing a curve element given a randomization parameter k. If no signature can be + // obtained from this k, None is returned and the caller should try again with another value. + fn try_sign(&self, k: &NonZeroExponentP256, msg: &ExponentP256) -> Option { + let r = ExponentP256::modn(PointP256::base_point_mul(k.as_exponent()).getx().to_int()); + // The branching here is fine because all this reveals is that k generated an unsuitable r. + let r = r.non_zero(); + if bool::from(r.is_none()) { + return None; + } + let r = r.unwrap(); + + let (s, top) = &(&r * &self.k).to_int() + &msg.to_int(); + let s = k.inv().as_exponent().mul_top(&s, top); + + // The branching here is fine because all this reveals is that k generated an unsuitable s. + let s = s.non_zero(); + if bool::from(s.is_none()) { + return None; + } + let s = s.unwrap(); + + Some(Signature { r, s }) + } + + #[cfg(test)] + pub fn get_k_rfc6979(&self, msg: &[u8]) -> NonZeroExponentP256 + where + H: Hash256 + HashBlockSize64Bytes, + { + let m = ExponentP256::modn(Int256::from_bin(&H::hash(msg))); + + let mut rfc_6979 = Rfc6979::::new(self, &msg); + loop { + let k = NonZeroExponentP256::from_int_checked(rfc_6979.next()); + if bool::from(k.is_none()) { + continue; + } + let k = k.unwrap(); + if self.try_sign(&k, &m).is_some() { + return k; + } + } + } + + pub fn from_bytes(bytes: &[u8; 32]) -> Option { + let k = NonZeroExponentP256::from_int_checked(Int256::from_bin(bytes)); + // The branching here is fine because all this reveals is whether the key was invalid. + if bool::from(k.is_none()) { + return None; + } + let k = k.unwrap(); + Some(SecKey { k }) + } + + pub fn to_bytes(&self, bytes: &mut [u8; 32]) { + self.k.to_int().to_bin(bytes); + } +} + +impl Signature { + pub fn to_asn1_der(&self) -> Vec { + const DER_INTEGER_TYPE: u8 = 0x02; + const DER_DEF_LENGTH_SEQUENCE: u8 = 0x30; + + let r_encoding = self.r.to_int().to_minimal_encoding(); + let s_encoding = self.s.to_int().to_minimal_encoding(); + // We rely on the encoding to be short enough such that + // sum of lengths + 4 still fits into 7 bits. + #[cfg(test)] + assert!(r_encoding.len() <= 33); + #[cfg(test)] + assert!(s_encoding.len() <= 33); + // The ASN1 of a signature is a two member sequence. Its length is the + // sum of the integer encoding lengths and 2 header bytes per integer. + let mut encoding = vec![ + DER_DEF_LENGTH_SEQUENCE, + (r_encoding.len() + s_encoding.len() + 4) as u8, + ]; + encoding.push(DER_INTEGER_TYPE); + encoding.push(r_encoding.len() as u8); + encoding.extend(r_encoding); + encoding.push(DER_INTEGER_TYPE); + encoding.push(s_encoding.len() as u8); + encoding.extend(s_encoding); + encoding + } + + #[cfg(feature = "std")] + pub fn from_bytes(bytes: &[u8]) -> Option { + if bytes.len() != 64 { + None + } else { + let r = + NonZeroExponentP256::from_int_checked(Int256::from_bin(array_ref![bytes, 0, 32])); + let s = + NonZeroExponentP256::from_int_checked(Int256::from_bin(array_ref![bytes, 32, 32])); + if bool::from(r.is_none()) || bool::from(s.is_none()) { + return None; + } + let r = r.unwrap(); + let s = s.unwrap(); + Some(Signature { r, s }) + } + } + + #[cfg(test)] + fn to_bytes(&self, bytes: &mut [u8; 64]) { + self.r.to_int().to_bin(array_mut_ref![bytes, 0, 32]); + self.s.to_int().to_bin(array_mut_ref![bytes, 32, 32]); + } +} + +impl PubKey { + pub const ES256_ALGORITHM: i64 = -7; + #[cfg(feature = "with_ctap1")] + const UNCOMPRESSED_LENGTH: usize = 1 + 2 * int256::NBYTES; + + #[cfg(feature = "std")] + pub fn from_bytes_uncompressed(bytes: &[u8]) -> Option { + PointP256::from_bytes_uncompressed_vartime(bytes).map(|p| PubKey { p }) + } + + #[cfg(test)] + fn to_bytes_uncompressed(&self, bytes: &mut [u8; 65]) { + self.p.to_bytes_uncompressed(bytes); + } + + #[cfg(feature = "with_ctap1")] + pub fn to_uncompressed(&self) -> [u8; PubKey::UNCOMPRESSED_LENGTH] { + // Formatting according to: + // https://tools.ietf.org/id/draft-jivsov-ecc-compact-05.html#overview + const B0_BYTE_MARKER: u8 = 0x04; + let mut representation = [0; PubKey::UNCOMPRESSED_LENGTH]; + let (marker, x, y) = + mut_array_refs![&mut representation, 1, int256::NBYTES, int256::NBYTES]; + marker[0] = B0_BYTE_MARKER; + self.p.getx().to_int().to_bin(x); + self.p.gety().to_int().to_bin(y); + representation + } + + // Encodes the key according to CBOR Object Signing and Encryption, defined in RFC 8152. + pub fn to_cose_key(&self) -> Option> { + const EC2_KEY_TYPE: i64 = 2; + const P_256_CURVE: i64 = 1; + let mut x_bytes = vec![0; int256::NBYTES]; + self.p + .getx() + .to_int() + .to_bin(array_mut_ref![x_bytes.as_mut_slice(), 0, int256::NBYTES]); + let x_byte_cbor: cbor::Value = cbor_bytes!(x_bytes); + let mut y_bytes = vec![0; int256::NBYTES]; + self.p + .gety() + .to_int() + .to_bin(array_mut_ref![y_bytes.as_mut_slice(), 0, int256::NBYTES]); + let y_byte_cbor: cbor::Value = cbor_bytes!(y_bytes); + let cbor_value = cbor_map_options! { + 1 => EC2_KEY_TYPE, + 3 => PubKey::ES256_ALGORITHM, + -1 => P_256_CURVE, + -2 => x_byte_cbor, + -3 => y_byte_cbor, + }; + let mut encoded_key = Vec::new(); + if cbor::write(cbor_value, &mut encoded_key) { + Some(encoded_key) + } else { + None + } + } + + #[cfg(feature = "std")] + pub fn verify_vartime(&self, msg: &[u8], sign: &Signature) -> bool + where + H: Hash256, + { + let m = ExponentP256::modn(Int256::from_bin(&H::hash(msg))); + + let v = sign.s.inv(); + let u = &m * v.as_exponent(); + let v = &sign.r * &v; + + let u = self.p.points_mul(&u, v.as_exponent()).getx(); + + ExponentP256::modn(u.to_int()) == *sign.r.as_exponent() + } +} + +struct Rfc6979 +where + H: Hash256 + HashBlockSize64Bytes, +{ + k: [u8; 32], + v: [u8; 32], + hash_marker: PhantomData, +} + +impl Rfc6979 +where + H: Hash256 + HashBlockSize64Bytes, +{ + pub fn new(sk: &SecKey, msg: &[u8]) -> Rfc6979 { + let h1 = H::hash(msg); + let v = [0x01; 32]; + let k = [0x00; 32]; + + let mut contents = [0; 3 * 32 + 1]; + let (contents_v, marker, contents_k, contents_h1) = + mut_array_refs![&mut contents, 32, 1, 32, 32]; + contents_v.copy_from_slice(&v); + marker[0] = 0x00; + Int256::to_bin(&sk.k.to_int(), contents_k); + Int256::to_bin(&Int256::from_bin(&h1).modd(&Int256::N), contents_h1); + + let k = hmac_256::(&k, &contents); + let v = hmac_256::(&k, &v); + + let (contents_v, marker, _) = mut_array_refs![&mut contents, 32, 1, 64]; + contents_v.copy_from_slice(&v); + marker[0] = 0x01; + + let k = hmac_256::(&k, &contents); + let v = hmac_256::(&k, &v); + + Rfc6979 { + k, + v, + hash_marker: PhantomData, + } + } + + fn next(&mut self) -> Int256 { + // Note: at this step, the logic from RFC 6979 is simplified, because the HMAC produces 256 + // bits and we need 256 bits. + let t = hmac_256::(&self.k, &self.v); + let result = Int256::from_bin(&t); + + let mut v1 = [0; 33]; + v1[..32].copy_from_slice(&self.v); + v1[32] = 0x00; + self.k = hmac_256::(&self.k, &v1); + self.v = hmac_256::(&self.k, &self.v); + + result + } +} + +#[cfg(test)] +mod test { + use super::super::rng256::ThreadRng256; + use super::super::sha256::Sha256; + use super::*; + extern crate hex; + extern crate ring; + extern crate untrusted; + + // Run more test iterations in release mode, as the code should be faster. + #[cfg(not(debug_assertions))] + const ITERATIONS: u32 = 10000; + #[cfg(debug_assertions)] + const ITERATIONS: u32 = 1000; + + /** Test that key generation creates valid keys **/ + #[test] + fn test_genpk_is_valid_random() { + let mut rng = ThreadRng256 {}; + + for _ in 0..ITERATIONS { + let sk = SecKey::gensk(&mut rng); + let pk = sk.genpk(); + assert!(pk.p.is_valid_vartime()); + } + } + + /** Serialization **/ + #[test] + fn test_seckey_to_bytes_from_bytes() { + let mut rng = ThreadRng256 {}; + + for _ in 0..ITERATIONS { + let sk = SecKey::gensk(&mut rng); + let mut bytes = [0; 32]; + sk.to_bytes(&mut bytes); + let decoded_sk = SecKey::from_bytes(&bytes); + assert_eq!(decoded_sk, Some(sk)); + } + } + + #[test] + fn test_seckey_from_bytes_zero() { + // Zero is not a valid exponent for a secret key. + let bytes = [0; 32]; + let sk = SecKey::from_bytes(&bytes); + assert!(sk.is_none()); + } + + #[test] + fn test_seckey_from_bytes_n() { + let mut bytes = [0; 32]; + Int256::N.to_bin(&mut bytes); + let sk = SecKey::from_bytes(&bytes); + assert!(sk.is_none()); + } + + #[test] + fn test_seckey_from_bytes_ge_n() { + let bytes = [0xFF; 32]; + let sk = SecKey::from_bytes(&bytes); + assert!(sk.is_none()); + } + + /** Test vectors from RFC6979 **/ + fn int256_from_hex(x: &str) -> Int256 { + let bytes = hex::decode(x).unwrap(); + assert_eq!(bytes.len(), 32); + Int256::from_bin(array_ref![bytes.as_slice(), 0, 32]) + } + + // Test vectors from RFC6979, Section A.2.5. + const RFC6979_X: &str = "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721"; + const RFC6979_UX: &str = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"; + const RFC6979_UY: &str = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299"; + + #[test] + fn test_rfc6979_keypair() { + let sk = SecKey { + k: NonZeroExponentP256::from_int_checked(int256_from_hex(RFC6979_X)).unwrap(), + }; + let pk = sk.genpk(); + assert_eq!(pk.p.getx().to_int(), int256_from_hex(RFC6979_UX)); + assert_eq!(pk.p.gety().to_int(), int256_from_hex(RFC6979_UY)); + } + + fn test_rfc6979(msg: &str, k: &str, r: &str, s: &str) { + let sk = SecKey { + k: NonZeroExponentP256::from_int_checked(int256_from_hex(RFC6979_X)).unwrap(), + }; + assert_eq!( + sk.get_k_rfc6979::(msg.as_bytes()).to_int(), + int256_from_hex(k) + ); + let sign = sk.sign_rfc6979::(msg.as_bytes()); + assert_eq!(sign.r.to_int(), int256_from_hex(r)); + assert_eq!(sign.s.to_int(), int256_from_hex(s)); + } + + #[test] + fn test_rfc6979_sample() { + let msg = "sample"; + let k = "A6E3C57DD01ABE90086538398355DD4C3B17AA873382B0F24D6129493D8AAD60"; + let r = "EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716"; + let s = "F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8"; + test_rfc6979(msg, k, r, s); + } + + #[test] + fn test_rfc6979_test() { + let msg = "test"; + let k = "D16B6AE827F17175E040871A1C7EC3500192C4C92677336EC2537ACAEE0008E0"; + let r = "F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367"; + let s = "019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083"; + test_rfc6979(msg, k, r, s); + } + + /** Tests that sign and verify are consistent **/ + // Test that signed messages are correctly verified. + #[test] + fn test_sign_rfc6979_verify_random() { + let mut rng = ThreadRng256 {}; + + for _ in 0..ITERATIONS { + let msg = rng.gen_uniform_u8x32(); + let sk = SecKey::gensk(&mut rng); + let pk = sk.genpk(); + let sign = sk.sign_rfc6979::(&msg); + assert!(pk.verify_vartime::(&msg, &sign)); + } + } + + // Test that signed messages are correctly verified. + #[test] + fn test_sign_verify_random() { + let mut rng = ThreadRng256 {}; + + for _ in 0..ITERATIONS { + let msg = rng.gen_uniform_u8x32(); + let sk = SecKey::gensk(&mut rng); + let pk = sk.genpk(); + let sign = sk.sign_rng::(&msg, &mut rng); + assert!(pk.verify_vartime::(&msg, &sign)); + } + } + + /** Tests that this code is compatible with the ring crate **/ + // Test that the ring crate works properly. + #[test] + fn test_ring_sign_ring_verify() { + use ring::rand::SecureRandom; + use ring::signature::KeyPair; + + let ring_rng = ring::rand::SystemRandom::new(); + + for _ in 0..ITERATIONS { + let mut msg_bytes: [u8; 64] = [Default::default(); 64]; + ring_rng.fill(&mut msg_bytes).unwrap(); + let msg = untrusted::Input::from(&msg_bytes); + + let pkcs8_bytes = ring::signature::EcdsaKeyPair::generate_pkcs8( + &ring::signature::ECDSA_P256_SHA256_FIXED_SIGNING, + &ring_rng, + ) + .unwrap(); + let key_pair = ring::signature::EcdsaKeyPair::from_pkcs8( + &ring::signature::ECDSA_P256_SHA256_FIXED_SIGNING, + untrusted::Input::from(pkcs8_bytes.as_ref()), + ) + .unwrap(); + let public_key_bytes = key_pair.public_key().as_ref(); + + let sig = key_pair.sign(&ring_rng, msg).unwrap(); + let sig_bytes = sig.as_ref(); + + assert!(ring::signature::verify( + &ring::signature::ECDSA_P256_SHA256_FIXED, + untrusted::Input::from(public_key_bytes), + msg, + untrusted::Input::from(sig_bytes) + ) + .is_ok()); + } + } + + // Test that messages signed by the ring crate are correctly verified by this code. + #[test] + fn test_ring_sign_self_verify() { + use ring::rand::SecureRandom; + use ring::signature::KeyPair; + + let ring_rng = ring::rand::SystemRandom::new(); + + for _ in 0..ITERATIONS { + let mut msg_bytes: [u8; 64] = [Default::default(); 64]; + ring_rng.fill(&mut msg_bytes).unwrap(); + + let pkcs8_bytes = ring::signature::EcdsaKeyPair::generate_pkcs8( + &ring::signature::ECDSA_P256_SHA256_FIXED_SIGNING, + &ring_rng, + ) + .unwrap(); + let key_pair = ring::signature::EcdsaKeyPair::from_pkcs8( + &ring::signature::ECDSA_P256_SHA256_FIXED_SIGNING, + untrusted::Input::from(pkcs8_bytes.as_ref()), + ) + .unwrap(); + let public_key_bytes = key_pair.public_key().as_ref(); + + let sig = key_pair + .sign(&ring_rng, untrusted::Input::from(&msg_bytes)) + .unwrap(); + let sig_bytes = sig.as_ref(); + + let pk = PubKey::from_bytes_uncompressed(public_key_bytes).unwrap(); + let sign = Signature::from_bytes(sig_bytes).unwrap(); + assert!(pk.verify_vartime::(&msg_bytes, &sign)); + } + } + + // Test that messages signed by this code are correctly verified by the ring crate. + #[test] + fn test_self_sign_ring_verify() { + let mut rng = ThreadRng256 {}; + + for _ in 0..ITERATIONS { + let msg_bytes = rng.gen_uniform_u8x32(); + let sk = SecKey::gensk(&mut rng); + let pk = sk.genpk(); + let sign = sk.sign_rng::(&msg_bytes, &mut rng); + + let mut public_key_bytes: [u8; 65] = [Default::default(); 65]; + pk.to_bytes_uncompressed(&mut public_key_bytes); + let mut sig_bytes: [u8; 64] = [Default::default(); 64]; + sign.to_bytes(&mut sig_bytes); + + assert!(ring::signature::verify( + &ring::signature::ECDSA_P256_SHA256_FIXED, + untrusted::Input::from(&public_key_bytes), + untrusted::Input::from(&msg_bytes), + untrusted::Input::from(&sig_bytes) + ) + .is_ok()); + } + } + + #[test] + fn test_signature_to_asn1_der_short_encodings() { + let r_bytes = [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + ]; + let r = NonZeroExponentP256::from_int_checked(Int256::from_bin(&r_bytes)).unwrap(); + let s_bytes = [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, + ]; + let s = NonZeroExponentP256::from_int_checked(Int256::from_bin(&s_bytes)).unwrap(); + let signature = Signature { r, s }; + let expected_encoding = vec![0x30, 0x07, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0xFF]; + + assert_eq!(signature.to_asn1_der(), expected_encoding); + } + + #[test] + fn test_signature_to_asn1_der_long_encodings() { + let r_bytes = [ + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, + ]; + let r = NonZeroExponentP256::from_int_checked(Int256::from_bin(&r_bytes)).unwrap(); + let s_bytes = [ + 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, + 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, + 0xBB, 0xBB, 0xBB, 0xBB, + ]; + let s = NonZeroExponentP256::from_int_checked(Int256::from_bin(&s_bytes)).unwrap(); + let signature = Signature { r, s }; + let expected_encoding = vec![ + 0x30, 0x46, 0x02, 0x21, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x02, 0x21, 0x00, 0xBB, 0xBB, + 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, + 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, + 0xBB, 0xBB, + ]; + + assert_eq!(signature.to_asn1_der(), expected_encoding); + } + + // TODO: Test edge-cases and compare the behavior with ring. + // - Invalid public key (at infinity, values not less than the prime p), but ring doesn't + // directly exposes key validation in its API. +} diff --git a/libraries/crypto/src/hmac.rs b/libraries/crypto/src/hmac.rs new file mode 100644 index 0000000..f09e2b9 --- /dev/null +++ b/libraries/crypto/src/hmac.rs @@ -0,0 +1,281 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::{Hash256, HashBlockSize64Bytes}; +use subtle::ConstantTimeEq; + +const BLOCK_SIZE: usize = 64; +const HASH_SIZE: usize = 32; + +pub fn verify_hmac_256(key: &[u8], contents: &[u8], mac: &[u8; HASH_SIZE]) -> bool +where + H: Hash256 + HashBlockSize64Bytes, +{ + let expected_mac = hmac_256::(key, contents); + bool::from(expected_mac.ct_eq(mac)) +} + +// FIDO2's PIN verification is just matching the first 16 bytes of the HMAC +// against the pin ¯\_(ツ)_/¯ +pub fn verify_hmac_256_first_128bits(key: &[u8], contents: &[u8], pin: &[u8; 16]) -> bool +where + H: Hash256 + HashBlockSize64Bytes, +{ + let expected_mac = hmac_256::(key, contents); + bool::from(array_ref![expected_mac, 0, 16].ct_eq(pin)) +} + +pub fn hmac_256(key: &[u8], contents: &[u8]) -> [u8; HASH_SIZE] +where + H: Hash256 + HashBlockSize64Bytes, +{ + let mut ipad: [u8; BLOCK_SIZE] = [0x36; BLOCK_SIZE]; + let mut opad: [u8; BLOCK_SIZE] = [0x5c; BLOCK_SIZE]; + if key.len() <= BLOCK_SIZE { + xor_pads(&mut ipad, &mut opad, key); + } else { + xor_pads(&mut ipad, &mut opad, &H::hash(key)); + } + + let mut ihasher = H::new(); + ihasher.update(&ipad); + ihasher.update(contents); + let ihash = ihasher.finalize(); + + let mut ohasher = H::new(); + ohasher.update(&opad); + ohasher.update(&ihash); + + ohasher.finalize() +} + +fn xor_pads(ipad: &mut [u8; BLOCK_SIZE], opad: &mut [u8; BLOCK_SIZE], key: &[u8]) { + for (i, k) in key.iter().enumerate() { + ipad[i] ^= k; + opad[i] ^= k; + } +} + +#[cfg(test)] +mod test { + use super::super::sha256::Sha256; + use super::*; + extern crate hex; + + #[test] + fn test_verify_hmac_valid() { + // Test for various lengths of the key and contents. + for len in 0..128 { + let key = vec![0; len]; + let contents = vec![0; len]; + let mac = hmac_256::(&key, &contents); + assert!(verify_hmac_256::(&key, &contents, &mac)); + } + } + + #[test] + fn test_verify_hmac_invalid() { + // Test for various lengths of the key and contents. + for len in 0..128 { + let key = vec![0; len]; + let contents = vec![0; len]; + let mac = hmac_256::(&key, &contents); + + // Check that invalid MACs don't verify, by changing any byte of the valid MAC. + for i in 0..HASH_SIZE { + let mut bad_mac = mac; + bad_mac[i] ^= 0x01; + assert!(!verify_hmac_256::(&key, &contents, &bad_mac)); + } + } + } + + #[test] + fn test_hmac_sha256_empty() { + let mut buf = [0; 96]; + buf[..64].copy_from_slice(&[0x5c; 64]); + buf[64..].copy_from_slice(&Sha256::hash(&[0x36; 64])); + assert_eq!(hmac_256::(&[], &[]), Sha256::hash(&buf)); + } + + #[test] + fn test_hmac_sha256_examples() { + assert_eq!( + hmac_256::(&[], &[]), + hex::decode("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad") + .unwrap() + .as_slice() + ); + assert_eq!( + hmac_256::(b"key", b"The quick brown fox jumps over the lazy dog"), + hex::decode("f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8") + .unwrap() + .as_slice() + ); + } + + #[test] + fn test_hash_sha256_for_various_lengths() { + // This test makes sure that the key hashing and hash padding are implemented properly. + // + // Test vectors generated with the following Python script: + // + // import hashlib + // import hmac + // for n in range(128): + // print('b"' + hmac.new('A' * n, 'A' * n, hashlib.sha256).hexdigest() + '",') + // + let hashes: [&[u8; 64]; 128] = [ + b"b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad", + b"ff333794c5afd126a4e75aef1a35595a846e9e1d4053017d78d7aa3d8373182a", + b"7c1d0c177d40e7fa03cd1fa9cfc314888985aecde8f586edfb05e71e5f109c20", + b"8f7afbaef39ad155ba09bcbb386a08257731fc06fb2c1d3cff451af5386c0e7d", + b"a4dbd2915084ba3bed9306ba674c1eb22fae1dffd971c95b62ab17f0711480cd", + b"f59d521db107b4265d995f197b189de468b984816d2a01dc8ca3fcfc24d6ff37", + b"29e0656a90f3975e41c8b7e55d225353c3bb8bc0b36328c8066a61763df70b83", + b"25a85cdd13b683f3cac732fa1f19757afffe7013ddbea6e441af883379bf4232", + b"5d0b0812ecb57fb4be7f29a8978cc4f2c35b32417cc9854e2702f7fb08f6d84d", + b"d5e12df428ebd9d991a280c714c9197b977520a7fea87200177cf03618868cb3", + b"fa311e0cd19106ab33f8ee84cafdc2f03be787679c1fe7b6e64df2b2e7466ca2", + b"9a481f04a2f40d561e8e6c4850498699b36e915993153e9f9b5a4485cb0541b1", + b"c8ae9a117e3a5c9125cc21c7f9df09de50de1a6846caf13586d1e5efdfcc1ce6", + b"5ef3a488aaffb5db9173ef59e65c2dd27f4cd1a10e1b464ef5bf82d2e35eddd5", + b"e5753e8febbb38a97c1dfee23a6103fc58416b7172bab834fe5684b00800abd5", + b"0ed714c729a3db2ffde2c4ccb9f5da498c5a73a2c7010d463a7b5da8d18127aa", + b"950918cfdb0cb20f327ba0b5095d53c0befb66b9f639d389020453fcf18e8c40", + b"699470b9775ec45e9024394e7ebb16463534ed7a617bafddca11a3a0e61a3694", + b"95e8c0520fc4dc4c85e00e3868c16ab22a82e8c71ca8ea329ae1ecef0ee3968a", + b"7964fba6a123164167cbf51dc2c53948e13b2fee67d09f532e8b7bc56447c091", + b"c7d07a5f715b3ea44c258de03f2000ba79a44dd8213feb6e6006e1c3becbedff", + b"3eb1a7bf7e4f5c2d9b8cc12667ada8d7773cb9e9424104a30063778567df9422", + b"19cc344ad67db96ea936ef15cc751b29fa0409f5c9894d2cfeb100d604653ffc", + b"91001e472df16d68ee8033cd13d76a26543ccdfe1426cc6e969759b05ee7d115", + b"65f1f4670f8537f37263dabedce049b0e7d1e71f741781413cc2d5c81ecd6ac3", + b"0cf5de0ada8b717296a34fc386a8b77f60b607a48a899bee37650891a616dae7", + b"de3d56f0c83c992163aac087c999ed8eb5a039f21b0536a1967e747868dafd56", + b"0bc3fd1d46d2dc4e2d357d1f6b437d168051d6f19975223505fc2d0abddc3faa", + b"1e30596f4144ca58f3e306548cd079cc92a51ab825a4ad3246393c22283af640", + b"c2fbc726bf3eb7f0216c7e1d5f5b475a93b033b3f901a4a4dca6bbefc65b68b2", + b"1c4ef56d530bb8b627df49ea7b31cf9520e067a2fd0c671896103e146dd4564a", + b"9aeed0f7808bd6c13ce54aa5724484f41bd7cbb5e39fd1d7730befbbf056a957", + b"e58aa85e83553b7fec841cbaf42cede943b6b7ded22661cd3b1867effe91b745", + b"790fc5689193ac57c97dd25729003f2a0d8d3e5f9d2a39e007b794282a51cd3e", + b"be067b95a45cdc0060d2c3757597d8d9b858128435e93346c28ce2e82a68e951", + b"8734f497f5cd2c8667c7d8e1c2328e7e11fa80fc26c7d933937490d37718871f", + b"e8a2d0e77dfad5b046bcff0340a975300b051a21ac403dd802348511a80ba8c8", + b"4afec38787117ab6e71c34a4be7575643d8e74fc16b9d5666157fd9aee0f6e86", + b"ac8b2831d636384d1d3ff5dd77b249860bd88d5aa9af3e1d4ee70be2a1b03db9", + b"e92e1ab3934d3ed2073973204aaba03de3bc4e864cc74677b560c42971b26ab1", + b"312effff0c19cf410b9e227654211133f29276c781baadbe00a1e8319e06e361", + b"d46158da3c64439f8f176fd5e3d5ac59dcaa6c0835715c5ef30abedf34b13c59", + b"693d18266ec508515b9a3839e5336918d41ec7891feadd684b49c03093bd2061", + b"440b6a14be7bc2a1ec475a197fe4bea720d1214883e4d1e2029cf0f75fcdba29", + b"ca8e30319508df21a851a06f543f59bf6fd3b241e5a52b36fb674b0d9d5e8f67", + b"fa4f327635ff5c7051d6968daf5ffcc827bbd0da1e1c56d59918895bc418be98", + b"0e6d0dd75bc42aa6e245a212ff027bc701a7ef61179b335365a29f545bcf45e0", + b"57a08bef7822c2111ac79062240e725611322543f10758763c1c6467021c4fe7", + b"29768d5fb640a46e0129303128669eb3c7fb357ef1c49506f6300cc8e451d5e2", + b"009a868f1065ccb4227dc28084484263495ad90378dc928fc61d361eef2d072e", + b"6808e39e343af0fd53309fc02b05da1a0e68b87d5cd434e94521c635a78d7fdb", + b"8fe1668eba03be5444e0956396ac9d81ac1c4a7beb6a01151ad679f5ca0cd206", + b"01f41c1cc6d9d260ec3d938d681fc476415aae96a318862a492ba1a56f1b0a88", + b"3100bc758eeccb959376b334f999a2b4e5fcced5b5d4956510a86b654f1f0c04", + b"6225330aedced9909d4a190dba55e807624f44e7c6e0c50cac5e4ccf8e2e0029", + b"783111276f7218e3e525c83cdf117e2d5ce251f6a04beabb65ef565f513a9301", + b"4b365ab05720ad517f46df03ff441f9e0769a2ce5279663b7d90eb7d980625ef", + b"52431871c39a881c63df82860e32ccf05c1addbc630aaa580733f2e6a2fff5a6", + b"f017486486b0e308a10862e910f22545c29670daa26bf0c6791827a7f9f625a4", + b"85efd1eface951759a4642e882d0ef8d0be58afd483e0945d03a7a35fac789ac", + b"880872df19c7ff14105ba59cebc07d9e9d7e67f4896a14acae5346c66c6ce2da", + b"85ba2aa3634c619d604a964d62ae3c97f9eba7fcb7e4db2ebfa2bd23338c2d60", + b"5aa9736d405016676878fcc63e84b286cfbc843799ea786d089b2200281d5a5c", + b"30f43d84f3d5ffac60323a126fe321c6cc1e9c440249a8d69abe172494cba7ae", + b"7dce62ce40f8f4cda666341730e7dfcde8839eed4236c58ae273e6687d229d85", + b"83d670a41779f63fad0ece766a19920e0cfdd9d02f5a5900c888de21f6ae0526", + b"bb2acf0d6d39e58b09204dedcc2fe68ad829ba471a077e6e03246d8a0b0c0858", + b"1f94db9ee970a9fcc9089865eb2aa485765345f6d4de54815507ce363bc20711", + b"b4bceedc935c574935117f7ad280a7d858da7ca5a6b0920b4975111206fcac77", + b"b9da394c337e9aa150c12e54c574978773ff953270f5aefde88a766e9874c260", + b"1769fcb5d31c8c09868e4e3dcd9db92b4cccefb5660e72bfc52159fda9da8518", + b"d8ceb568f85e30cb48cabf8e84d577369033511cbbdac6a7996cf9f397c2e203", + b"64c35795b87cbb02afcdc6a5e6bacb10d98cdd1bd810ccf12c847fbdcf4d2634", + b"76ccd4e2b71a826128b60bc9fe33613d82f0ae1f57fa192f107ed54d25a842e0", + b"095450e0f61a4201bb2197371247bb7ced09056d86e901202ecc561c3568e032", + b"0e928f8e201fd3019f11037bf164cc3d719ecf08e6eac985f429702c41f25d0a", + b"135f37174ff19409cef67f3263511ed9286901090eec2b54d9444036308a72cf", + b"51eafe6978c32396022a31230b8b9120ac7bd79ad7a3303e6b6979063275c9b8", + b"fd2fb9443156429b2bc042248bf022f18ee6ed11fefea222893c49e8fef6a17e", + b"ed9a240e63644aa55c71fb339d79e1a38de71002c30baf14af38359c513de2e0", + b"c925e74d4740558277a55fe57ba88ed05ce8f5d5c35c19e7228adc09351ecfa4", + b"cd99660a7c2aded095152bc6d5fa160077355819fbf421acb95ab39ad8c27862", + b"42cf7593a535a1e79299c2839f4e0ffba5b429cb0df6c77d3fe86b6a1535d505", + b"348c6014dcb0cd583862c09ad24aa5d93e81e2f6ca4b04f4e77e50067f34e625", + b"8b00c1d89bd10b24bda2c8f6e45c4112112baacab29d0330b377d811a7b0184e", + b"dfe3960732f8e5958085a581859f6ccf40169df965bb8ff5feb4b0229a02c6f8", + b"de0aa4189c97d17df38c0ea3bc9376287076939afd515336d5d7d851f81f2517", + b"543190454858ff5396a1de3f753f84bdd2869fd2b59e3a89f090ce06bd94d626", + b"541ddbe00a0237c5c8bd043e6cced9ce78209dd83b057272cd46c2cc2f39a88c", + b"11c82017445f7e295d4c734a40cf28793df855dd321d507d4a0f3e212293ca2b", + b"cda1ecd6ca2f3858352985b4833170589e17e1f7f464e279cc78051911b8e8d3", + b"5feb471949318b26898b3339ac7a66e464a752223cf764aa0af9292fe087c39a", + b"eb48e5de63ecd22f7b305c7e74ce8cc714ab858cf834cf485727868e017e473e", + b"03428482b5208a35032777c7d628a6c8f3b07c5c87c641ddfb3adf46ffefe449", + b"a8e0cd1dfcf6e1a29ba032d3889fca2f25e3fad1a9b1c36e4978e48945b06092", + b"6cf4280b75da3bb22ddee9a9a3fdd1d0cd04627c00f73b608e44be9ce84869db", + b"9fa7648f23c405938b6fb8eaf6a24c476dafd05625a9a8f6c52e1abb9d432a76", + b"2906f0a6276e9a1ba4fbca2f335d9f7d3c331684814ac5407145d86891ba37f7", + b"1b667ee18a909e3f828f2bd6a162e3aa1361f3801b7cbc863b1b54a1ccfbf580", + b"a75e75962b3f950f7718839ef06cc09112806dbf88b142e369cf1ef99069c226", + b"71b2e2f6d66f13b919a842843b201c25249ff4b4caa4c7ab079b2980de8a18f6", + b"c4a9e73df196f876f5a3af1c8836504ee61daac5d9e15cc043a511310c22ddd8", + b"88e3303a6a2ab03430652fea942ae7cd96618fae4addcf8e92989d542777e496", + b"9a727095299564e2f5e1598f1a4095a2a000cb9196fe4eb13447932af777be3c", + b"5643a1c72b189d462236a43afc7d0b9504cbf81b4fa9a6c9cca49bd50da299df", + b"caebc47e2204fe19e757372c2e0469a34051415a09c927e63be7747903d80af5", + b"e5c9fd4bd27e7a55958cb5f66ff88baf80ab40d9690e81a9cf03ada5bd08cd44", + b"dc606eb9a631ca3f080f6d6f610444201608f47b5b49c75c2c0ec03ba9000009", + b"bce230b32a7dc676fb98a4a3d41c4171e9e173e840b92c194fb1dc4accc079b9", + b"51542ff3b57cd2ff6b1542649f7a44dbed32194b98c3af32b6ff3eefe6b490cf", + b"703f5dea8c9e3ed75c691fc17699b9648a65a331add554fa3613ddcb7267565a", + b"d74f9f60763467ce0b35ced0630ecf58605da0ca49e058de21524b5c532b5de8", + b"e9dacaf1fefaad6d9d372affab8fb5216004fb3fa7a9b86b25ecd00e583c22a5", + b"abe2c75f1ac881b743da99c543506c4b7532f3fc445fa8cbf1df22689770d66a", + b"7be506d2fd6dc79f0b14ddfff0147c79d78d99140547efcd03d0a73819b84c5a", + b"78dbc5c946ee8aa147ccfa8b5d9231c95c4257d8c79bd219ab95d53303367309", + b"1d75ee600f2ba216d211189493d793aa610aa57ccbfc4d9a7f44194e7166a062", + b"368a4d0ae1b139d71f35ba5f917a7ad4c18e6aa51b095cb135193dcd09e299b4", + b"a9d3202db927be8f0d15d2dfb83ea09db32fec3b1fc10a6acfb91da8c3c5eaf3", + b"c2284f8efeee554cc29a8802aadd7cd88e84561d353282ee31322ed497a3336c", + b"7695648a111e2ea51013f03c9de91d81a2435a7777f303e51d027750f8381680", + b"719fc44e0f64f7da9ac5d33d9ca912fdc839bb4535c66a21f0804f2cdf800666", + b"6940c082413b0c1ced6f9cb6583588c472ff72b48b00a4fb6d2710d7ac4dad99", + b"af1f26fcf070d9f5926dd41db3c09ec6b4c3f2208775cf983330cd0ff5aa239e", + b"ae50df4404a7f46146d8112bfb1cde876e591abe5ef1640e27c4d178a84b6335", + b"50f91f48df7f0f96af954be7e1b518bac537173cea38be300d98761da1d9b10f", + b"9c9aee382b3e3417e87352bdcb48837e88335e9dd0112fc22ecf61e766a6ac43", + b"d53cee1696c613f988520cf9c923c7cb6e6933b4faf57e640867d5f45a0f2569", + ]; + + let mut input = Vec::new(); + for i in 0..128 { + assert_eq!( + hmac_256::(&input, &input), + hex::decode(hashes[i] as &[u8]).unwrap().as_slice() + ); + input.push(b'A'); + } + } + + // TODO: more tests +} diff --git a/libraries/crypto/src/lib.rs b/libraries/crypto/src/lib.rs new file mode 100644 index 0000000..bfc129e --- /dev/null +++ b/libraries/crypto/src/lib.rs @@ -0,0 +1,67 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg_attr(not(feature = "std"), no_std)] +#![feature(wrapping_int_impl)] + +#[macro_use] +extern crate alloc; +extern crate subtle; +#[macro_use] +extern crate arrayref; +extern crate byteorder; +extern crate libtock; +#[macro_use] +extern crate cbor; + +pub mod aes256; +pub mod cbc; +mod ec; +pub mod ecdh; +pub mod ecdsa; +pub mod hmac; +pub mod rng256; +pub mod sha256; +pub mod util; + +// Trait for hash functions that returns a 256-bit hash. +// The type must be Sized (size known at compile time) so that we can instanciate one on the stack +// in the hash() method. +pub trait Hash256: Sized { + fn new() -> Self; + fn update(&mut self, contents: &[u8]); + fn finalize(self) -> [u8; 32]; + + fn hash(contents: &[u8]) -> [u8; 32] { + let mut h = Self::new(); + h.update(contents); + h.finalize() + } +} + +// Traits for block ciphers that operate on 16-byte blocks. +pub trait Encrypt16BytesBlock { + fn encrypt_block(&self, block: &mut [u8; 16]); +} + +pub trait Decrypt16BytesBlock { + fn decrypt_block(&self, block: &mut [u8; 16]); +} + +// Trait for hash functions that operate on 64-byte input blocks. +pub trait HashBlockSize64Bytes { + type State; + + fn hash_block(state: &mut Self::State, block: &[u8; 64]); +} diff --git a/libraries/crypto/src/rng256.rs b/libraries/crypto/src/rng256.rs new file mode 100644 index 0000000..572e21e --- /dev/null +++ b/libraries/crypto/src/rng256.rs @@ -0,0 +1,91 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use libtock::rng; + +// Lightweight RNG trait to generate uniformly distributed 256 bits. +pub trait Rng256 { + fn gen_uniform_u8x32(&mut self) -> [u8; 32]; + + fn gen_uniform_u32x8(&mut self) -> [u32; 8] { + bytes_to_u32(self.gen_uniform_u8x32()) + } +} + +// The TockOS rng driver fills a buffer of bytes, but we need 32-bit words for ECDSA. +// This function does the conversion in safe Rust, using the native endianness to avoid unnecessary +// instructions. +// An unsafe one-line equivalent could be implemented with mem::transmute, but let's use safe Rust +// when possible. +fn bytes_to_u32(bytes: [u8; 32]) -> [u32; 8] { + let mut result: [u32; 8] = [Default::default(); 8]; + for (i, r) in result.iter_mut().enumerate() { + *r = u32::from_ne_bytes(*array_ref![bytes, 4 * i, 4]); + } + result +} + +// RNG backed by the TockOS rng driver. +pub struct TockRng256 {} + +impl Rng256 for TockRng256 { + fn gen_uniform_u8x32(&mut self) -> [u8; 32] { + let mut buf: [u8; 32] = [Default::default(); 32]; + rng::fill_buffer(&mut buf); + buf + } +} + +// For tests on the desktop, we use the cryptographically secure thread rng as entropy source. +#[cfg(feature = "std")] +pub struct ThreadRng256 {} + +#[cfg(feature = "std")] +impl Rng256 for ThreadRng256 { + fn gen_uniform_u8x32(&mut self) -> [u8; 32] { + use rand::Rng; + + let mut rng = rand::thread_rng(); + let mut result = [Default::default(); 32]; + rng.fill(&mut result); + result + } +} + +#[cfg(test)] +pub mod test { + use super::*; + + #[test] + fn test_bytes_to_u32() { + // This tests that all bytes of the input are indeed used in the output, once each. + // Otherwise the result of gen_uniform_u32x8 wouldn't be uniformly distributed. + let bytes = b"\x00\x01\x02\x03\x04\x05\x06\x07\ + \x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\ + \x10\x11\x12\x13\x14\x15\x16\x17\ + \x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"; + #[cfg(target_endian = "big")] + let expected = [ + 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, 0x10111213, 0x14151617, 0x18191a1b, + 0x1c1d1e1f, + ]; + #[cfg(target_endian = "little")] + let expected = [ + 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c, 0x13121110, 0x17161514, 0x1b1a1918, + 0x1f1e1d1c, + ]; + + assert_eq!(bytes_to_u32(*bytes), expected); + } +} diff --git a/libraries/crypto/src/sha256.rs b/libraries/crypto/src/sha256.rs new file mode 100644 index 0000000..7ad54a8 --- /dev/null +++ b/libraries/crypto/src/sha256.rs @@ -0,0 +1,423 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::{Hash256, HashBlockSize64Bytes}; +use byteorder::{BigEndian, ByteOrder}; +use core::num::Wrapping; + +const BLOCK_SIZE: usize = 64; + +pub struct Sha256 { + state: [Wrapping; 8], + block: [u8; BLOCK_SIZE], + total_len: usize, +} + +impl Hash256 for Sha256 { + fn new() -> Self { + Sha256 { + state: Sha256::H, + block: [0; BLOCK_SIZE], + total_len: 0, + } + } + + fn update(&mut self, mut contents: &[u8]) { + let cursor_in_block = self.total_len % BLOCK_SIZE; + let left_in_block = BLOCK_SIZE - cursor_in_block; + + // Increment the total length before we mutate the contents slice. + self.total_len += contents.len(); + + if contents.len() < left_in_block { + // The contents don't fill the current block. Simply copy the bytes. + self.block[cursor_in_block..(cursor_in_block + contents.len())] + .copy_from_slice(contents); + } else { + // First, fill and process the current block. + let (this_block, rest) = contents.split_at(left_in_block); + self.block[cursor_in_block..].copy_from_slice(this_block); + Sha256::hash_block(&mut self.state, &self.block); + contents = rest; + + // Process full blocks. + while contents.len() >= 64 { + let (block, rest) = contents.split_at(64); + Sha256::hash_block(&mut self.state, array_ref![block, 0, 64]); + contents = rest; + } + + // Copy the last block for further processing. + self.block[..contents.len()].copy_from_slice(contents); + } + } + + fn finalize(mut self) -> [u8; 32] { + // Last block and padding. + let cursor_in_block = self.total_len % BLOCK_SIZE; + self.block[cursor_in_block] = 0x80; + // Clear the rest of the block. + for byte in self.block[(cursor_in_block + 1)..].iter_mut() { + *byte = 0; + } + + if cursor_in_block >= 56 { + // Padding doesn't fit in this block, so we first hash this block and then hash a + // padding block. + Sha256::hash_block(&mut self.state, &self.block); + // Clear buffer for the padding block. + for byte in self.block.iter_mut() { + *byte = 0; + } + } + + // The last 8 bytes of the last block contain the length of the contents. It must be + // expressed in bits, whereas `total_len` is in bytes. + BigEndian::write_u64(array_mut_ref![self.block, 56, 8], self.total_len as u64 * 8); + Sha256::hash_block(&mut self.state, &self.block); + + // Encode the state's 32-bit words into bytes, using big-endian. + let mut result: [u8; 32] = [0; 32]; + for i in 0..8 { + BigEndian::write_u32(array_mut_ref![result, 4 * i, 4], self.state[i].0); + } + result + } +} + +impl HashBlockSize64Bytes for Sha256 { + type State = [Wrapping; 8]; + + #[allow(clippy::many_single_char_names)] + fn hash_block(state: &mut Self::State, block: &[u8; 64]) { + let mut w: [Wrapping; 64] = [Wrapping(0); 64]; + + // Read the block as big-endian 32-bit words. + for (i, item) in w.iter_mut().take(16).enumerate() { + *item = Wrapping(BigEndian::read_u32(array_ref![block, 4 * i, 4])); + } + + for i in 16..64 { + w[i] = w[i - 16] + Sha256::ssig0(w[i - 15]) + w[i - 7] + Sha256::ssig1(w[i - 2]); + } + + let mut a = state[0]; + let mut b = state[1]; + let mut c = state[2]; + let mut d = state[3]; + let mut e = state[4]; + let mut f = state[5]; + let mut g = state[6]; + let mut h = state[7]; + + for (i, item) in w.iter().enumerate() { + let tmp1 = + h + Sha256::bsig1(e) + Sha256::choice(e, f, g) + Wrapping(Sha256::K[i]) + *item; + let tmp2 = Sha256::bsig0(a) + Sha256::majority(a, b, c); + + h = g; + g = f; + f = e; + e = d + tmp1; + d = c; + c = b; + b = a; + a = tmp1 + tmp2; + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + } +} + +impl Sha256 { + // SHA-256 constants. + #[allow(clippy::unreadable_literal)] + const H: [Wrapping; 8] = [ + Wrapping(0x6a09e667), + Wrapping(0xbb67ae85), + Wrapping(0x3c6ef372), + Wrapping(0xa54ff53a), + Wrapping(0x510e527f), + Wrapping(0x9b05688c), + Wrapping(0x1f83d9ab), + Wrapping(0x5be0cd19), + ]; + + #[allow(clippy::unreadable_literal)] + const K: [u32; 64] = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, + 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, + 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, + 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, + 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, + 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, + 0xc67178f2, + ]; + + // SHA-256 helper functions. + #[inline(always)] + fn choice(e: Wrapping, f: Wrapping, g: Wrapping) -> Wrapping { + (e & f) ^ (!e & g) + } + + #[inline(always)] + fn majority(a: Wrapping, b: Wrapping, c: Wrapping) -> Wrapping { + (a & b) ^ (a & c) ^ (b & c) + } + + #[inline(always)] + fn bsig0(x: Wrapping) -> Wrapping { + x.rotate_right(2) ^ x.rotate_right(13) ^ x.rotate_right(22) + } + + #[inline(always)] + fn bsig1(x: Wrapping) -> Wrapping { + x.rotate_right(6) ^ x.rotate_right(11) ^ x.rotate_right(25) + } + + #[inline(always)] + fn ssig0(x: Wrapping) -> Wrapping { + x.rotate_right(7) ^ x.rotate_right(18) ^ (x >> 3) + } + + #[inline(always)] + fn ssig1(x: Wrapping) -> Wrapping { + x.rotate_right(17) ^ x.rotate_right(19) ^ (x >> 10) + } +} + +#[cfg(test)] +mod test { + use super::*; + extern crate hex; + + #[test] + fn test_choice() { + assert_eq!( + Sha256::choice( + Wrapping(0b00001111), + Wrapping(0b00110011), + Wrapping(0b01010101) + ), + Wrapping(0b01010011) + ); + } + + #[test] + fn test_majority() { + assert_eq!( + Sha256::majority( + Wrapping(0b00001111), + Wrapping(0b00110011), + Wrapping(0b01010101) + ), + Wrapping(0b00010111) + ); + } + + #[test] + fn test_hash_empty() { + assert_eq!( + Sha256::hash(&[]), + hex::decode("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") + .unwrap() + .as_slice() + ); + } + + #[test] + fn test_update_for_various_splits() { + // Test vector generated with the following Python script: + // + // import hashlib + // print(hashlib.sha256('A' * 512).hexdigest()) + // + let input = vec![b'A'; 512]; + let hash = hex::decode("32beecb58a128af8248504600bd203dcc676adf41045300485655e6b8780a01d") + .unwrap(); + + for i in 0..512 { + for j in i..512 { + let mut h = Sha256::new(); + h.update(&input[..i]); + h.update(&input[i..j]); + h.update(&input[j..]); + assert_eq!(h.finalize(), hash.as_slice()); + } + } + } + + #[test] + fn test_hash_for_various_lengths() { + // This test makes sure that the padding is implemented properly. + // + // Test vectors generated with the following Python script: + // + // import hashlib + // for n in range(128): + // print('b"' + hashlib.sha256('A' * n).hexdigest() + '",') + // + let hashes: [&[u8; 64]; 128] = [ + b"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + b"559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd", + b"58bb119c35513a451d24dc20ef0e9031ec85b35bfc919d263e7e5d9868909cb5", + b"cb1ad2119d8fafb69566510ee712661f9f14b83385006ef92aec47f523a38358", + b"63c1dd951ffedf6f7fd968ad4efa39b8ed584f162f46e715114ee184f8de9201", + b"11770b3ea657fe68cba19675143e4715c8de9d763d3c21a85af6b7513d43997d", + b"69dc6c3210e25e62c5938ff4e841e81ce3c7d2cde583553478a77d7fcb389f30", + b"0f0cf9286f065a2f38e3c4e4886578e35af4050c108e507998a05888c98667ea", + b"c34ab6abb7b2bb595bc25c3b388c872fd1d575819a8f55cc689510285e212385", + b"e5f9176ecd90317cf2d4673926c9db65475b0b58e7f468586ddaef280a98cdbd", + b"1d65bf29403e4fb1767522a107c827b8884d16640cf0e3b18c4c1dd107e0d49d", + b"dd20088919031875b7bcca29995545dd40ca994be0558183f9b942b51b3b2249", + b"0592cedeabbf836d8d1c7456417c7653ac208f71e904d3d0ab37faf711021aff", + b"3461164897596e65b79bc0b7bee8cc7685487e37f52ecf0b34c000329675b859", + b"14f99c4b0a6493e3a3f52022cd75276b4cff9a7c8eef74793267f687b600af96", + b"6f9f84c09a5950e1ea7888f17922a69e5292dcbcb1e682ddfc977a9b4ea1a8c0", + b"991204fba2b6216d476282d375ab88d20e6108d109aecded97ef424ddd114706", + b"444074d5328d52b4e0036d37b1b6ea0a9fe3b0c96872d1157fbf01b6fdb2ce8d", + b"d273c6b6de3f5260e123348e0feb270126fa06e164bb82818df7c71b30ab0ef5", + b"234b7f9389f9b521f407805760775940d79a48188338d02a1fe654e826a83f69", + b"edfcaac579024f574adbcaa3c13e4fd2b7f1797826afe679f2144af2cb5c062d", + b"f48de1653fdfa9b637b7fb4da9c169a1f2be6a1ec001e3d2cca44c669a693ecf", + b"8a5bdb4cc15164126c6ef2668de9dd240d299ce6397a42c95a9411b93d080ed8", + b"1786ac1492c6c922c2734e4d3d8e9b030cfba291a72bc135989c49fc31171ac2", + b"1bda9f0aed80857d43c9329457f28b1ca29f736a0c539901e1ba16a909eb07b4", + b"6724431fc312ba42c98b38b8595a49749419526aa89722c77a85c6c813dfdb5a", + b"06f469c97c14e84c74853bb96aa79305eb4f6635291bf1202c4fdadb82706204", + b"568f214d529544bf4430513c2993495a5b434611533c63d1cf095b51c5e1f8af", + b"c84f7630cbe823fc4d80f605b98294592f15b14db1f78d6f18e686c1f8cb5ded", + b"a7951e0ca2e9612a985a36747309822a67a9b8c1a5abd848c03e82216c85f1b3", + b"37b9403cf88cc2639d0a118d757a43a0ff6d4871823707ab6a8bb56bc68e8e79", + b"55ee740f58335c97d42c32125218eb7c325fbe34206912f1aa7af7fd6580c9a1", + b"22a48051594c1949deed7040850c1f0f8764537f5191be56732d16a54c1d8153", + b"5d873590851b7b00b60490c8e6966b3409c385adcc9590d801f0e03e268b5ba5", + b"1e98a405718c430a4067d75125015a947a971449bc433b078418438c48bc6046", + b"015c50632207f69408c05d20e36facfad9bde74c727f933023f54cd6e8b87372", + b"a3b99d59dbb025726312e812c2821cfbe55189f515414bdabd5e3d284c8ad6f9", + b"7d24c321bfb2a5b6d2c7a3c2948855cef421d08352dc296ed95c6f645fcce441", + b"876fc5bf6bde065afea543aceb645ce17ffe3c9d8df9c6073ab31f3a562f4257", + b"b9b515854e040b8de31d85d597aba28db4467fd0a7d6eb77a31005f4a67a8fb3", + b"f0a2fb80ac0699075fb6c7b0ee2bcc204a1d909ee3149571216ec9cc1d4b9f8e", + b"b78244167af116f2b3597b4a81421bd2b28f3d8bf616025a5ae424f689fd7632", + b"d85ce644bf4e82cee032eaa5c3d9030a090276d9bae3703112bdfc6f8fdde307", + b"0f007385b6f9d4b7eeb2748605afe1a984a0a3bfa3f014d09e2a784ce9e5cd1a", + b"b06b3f20c246db70a136e3ae4787d0df96db4f693d215c21883d3c19700fb276", + b"ac752ced452069c55c7567a0717b87615824c568dc98c8626ac85fc34b234c3b", + b"91a07088de2d0fe9f31567b05d290e65feb06758d000ec463f7f5a6e82ce00a5", + b"abf6c5d1b6512e188f1da6a72e974f7b98b5bac62453f1748c8f9ab180803fdb", + b"4739dcdbab0c377161c539af55d47c5c90c87807d0728aabe91697b66e29096c", + b"ff85f0693c8e6bbeeaa1f90c32e1159b9b545d830ffe58cd80cb94d9d8140d21", + b"509ddb85fdf92f197d32570c005cdcb6dffa398f088bd1a013459f6fb1f730ef", + b"1d31616e307323bd80775ae7483fce654a3b65bced7134c22e179a2e25155009", + b"3e1ae21112ec8fad05e3676e1940da52d56771162142aac4d73743e7df70b686", + b"5f2671f97427c8873e5af72686d244e4c8126a4f618983bae880a48a834a0607", + b"2d0009d7df28cdc6b5a4c36063d97415a8fe99515317458fcb0b0e2a821dbcb9", + b"8963cc0afd622cc7574ac2011f93a3059b3d65548a77542a1559e3d202e6ab00", + b"6ea719cefa4b31862035a7fa606b7cc3602f46231117d135cc7119b3c1412314", + b"a00df74fbdadd9eb0e7742a019e5b2d77374de5417eba5b7a0730a60cce5e7bf", + b"cee244d999f8cf49f2a4ee4d89695130c9c95c33538cedf0306881ebd42714d2", + b"5b29354ee33cba5b924ded5e3c873a76e1d12527d824ace01ff9683d24e06816", + b"c5fb235befd875b915fa6c4702a7abb93cacf3d7c414b71cbeff9e1b0a9fbd41", + b"0ae45129ef1edf64309559f6cb7bb0af16eff14ad82f24d55fa029c1b4144078", + b"5a2aafcacb9828e41fb7c8f8098952638645874b3a8ca45d2523fb2d5fc7166d", + b"1b58d00f5b1fbd2a1884d666a2be33c2fa7463dff32cd60ef200c0f750a6b70f", + b"d53eda7a637c99cc7fb566d96e9fa109bf15c478410a3f5eb4d4c4e26cd081f6", + b"836203944f4c0280461ad73d31457c22ba19d1d99e232dc231000085899e00a2", + b"fd8afe9151793a84a21af054ba985d1486a705561e2a50d4a50f814664f5e806", + b"f495547fca5a5a2c40dccebefe40160efb8bc2888e8afef712b096b5f2585b44", + b"ba31b89f9486439fdf551f597fede0c10260f9b404866dba4a6555375f486359", + b"46f23cc7ccba8af67978bea568e63cd045be72aba974132b1b14cc59277329f1", + b"01d3a187638cc1a7740a74fbeb57aa2648dbdec42d497321912bf393d283ccd1", + b"96b437b3df7c62fc877a121b087899f5e36a58f6d87ba52d997e92bb016aa575", + b"6a6d691ac9ba70955046757cd685b6257773ff3ad93f43d4d4812c5b106f4b5b", + b"beb869adc22a7e8fbd5af12cbf3ad36dd92dca6ebf52ef3441ed6cd0dff24dc6", + b"0f40cb2f3661d73dfaec511e8ebea082fb1f77db45bf8c9ba7c9708da6ba6301", + b"ddd5d1ecc7af6a5b0d18e0825004d3bc9d52e2cdf14bc00c7474f16941a64acc", + b"6a10b9a8a33d7814ce73679ace5c43657aa6d63169ce215fd85177c77a94147d", + b"9d887d47c78267827dac4afb2cbdcc593d1b89c1d0c1f22c3800cae7916962cd", + b"e45ca598e970afb0f1f57bd34e87065839d2fac524421048fbec489f68e1fd0d", + b"1581baebc5f9dcfd89c658b3c3303203fc0e2f93e3f9e0b593d8b2b8112c6eda", + b"d9b1f3e2c6d528668a73f22575c44ed9f98d9c684964761b621417efd80d7a60", + b"9feacd760dfda20e5e0accf9ddeb8b5c01276a56dc3518046a26f5276fe15041", + b"6aacf5279e24979684fab16fb5495c3ac1dfcf7138b0825376af83473d07cae9", + b"cd2f0deb953014ee400eddef094602d9676e0fd2269d22818f0d5bc198d44d8d", + b"ff9265df14681e44d170fd2b10c6cdf3991f731601d6b89cafe39691d3b42559", + b"6c99e32b005a3a4956b9406ab15411e666c7f67982db170ae1fb111ec634b9c4", + b"e1659ad54063a379f77fee108a376a6a7d5ae3d0c437bf847203963bd0078dfc", + b"572d07a66fccf05d5f73c913552e12d9ffb39a15d01a8fd48cd6aaaab86f4f14", + b"ca97d312ef8551820844548f300f9528f27d53f6ad3910ed2709f2b35c9591f3", + b"97654dc78f4f7d4cec4b4870e6ee0a87abacc89337ed0629e2e511e4466df56d", + b"fde923c1ed5e5cd32c629bdf341db32c0f72ba8f1e2afd9c194e87e0e3d9da5f", + b"d6624a66f3bcc4adef8a17abf9eeb1fbf23746165b2f90f9cb3a679a58e4958e", + b"8676909e9578a790f84be31fe94f4d22488f912b754ee816ba0a5c4a392305a5", + b"57f65fd8a95ff738b95dba0f1606025535e34591f1b58b00d33958093808360c", + b"f6afcaf794fe0e04d6ec18bbde55412a60c0c5ef55e75223b817e97f208bbccc", + b"6121f27b52c1f17ddce365143ba58a720fa303707faa32a4e5e89029f34ac618", + b"69d62c062d67d8d2ce9068c1898fb9746c911839aa88ad1628d090f4c8e47f05", + b"eb9f8b69313e19e14b1043b3cac05d18d40321536ad485be8145007aefa9295d", + b"b1cfb0f511886ca07ade919740ca95e1b3d998ba7cb66ba2badd53be28f5f509", + b"d0118863549f990558685da9090ca8eae8c809c5545c4aa85f8e5eec413b2555", + b"d82c6aa133a0fc25b087f46ad7ed2a3042772e612e015571e61753ff55ba6da8", + b"aac76dab773c00c8ad4bb128147945c70798eae5a2511fef01e853c6e3051ab9", + b"ccd77d7adb6178ee3e3560ba4583044a36b296257ae4c5cfead96d46af31fccd", + b"3c4f48a886b2de7e908d6a626074e7515265cc9d1188c161cf159fd376d3d5f8", + b"7f9578a31905e95a16cc9d3e7b57dc3158a23dccf359a1f2cf09e73eb13e5cde", + b"770492ebaee89a20d19f9972c3e3d0c7d51c9baaedf06fdfe9a7b69da3394779", + b"893785aaddea396621c31dc5d465e2775cbc6b7423dc3498e80aa5da7a6a819d", + b"1b2b69fbec485ef3f347ee6dc9c87d73505e45b5c9b02599b823ac94f5d642a1", + b"724b4b3d3e8ac7588561ca00eec11693f6b85c03bb6b1302d458a7a4ce4b39e4", + b"6a30ef4094128b6fa463b70cb21d141da92711d80ea94c9b73fb8a0471cc49a9", + b"50968cf735e3f6a47834ae3745816234f72fd156aef1bec4b6a7d3a3151773bc", + b"3ed01dd816dc93ea2d445681df11aa24e9fd1441de429eb0ee7816ccc09a2b7a", + b"64bdc48c731313c7b37c1f1d13d6265ac7a2604ff630b50f591a86e610cb3005", + b"96666c386cf99a74ec9eb55a5545aa90a3e53a8bbbe74cd3334b32d4968a3214", + b"33555a41335654a29d5b7799bf180915e09095d21991dacf071583957b9e3f35", + b"ffd391d554ce0672ae818a149dd55325f4cb933c97017b8148934474355d5a88", + b"cf2050114ccaefd8a0ea6cf31d85e0232eadc8fd61277ff16496d2234b55c7d7", + b"e42142b4243d5a2c59a2977d0385d49eab288085f8d38ead3ae5d87145c562ec", + b"3bb810492422cc5c7466d86dcd8095b0d87e97634656a3fa5fe2270a2244c16b", + b"17d2f0f7197a6612e311d141781f2b9539c4aef7affd729246c401890e000dde", + b"a4f4256159ea6fb23b27eb8c5eb9cfb9083475985f355a85c78de8f2fef2b3ac", + b"a36c4cf85204c67047c00d5dcc16677978839af0f0fde7ff973c98b66e244552", + b"4a596559f450ce5e3a777d952d8d2ed8611e9f3facc8400483371f6eadc4bdb2", + b"64855e54c94d14ab53afc6109d3c0033c665fab85b57c0e7d4e8da55b3b26952", + b"a2ee2228d4798988ce3ac273c0cd8b9bbc4e3e58413eb22dfbe6395758659a2b", + b"35c28ee2e25f5ad70384f1ca9723f520c955fb5fe9f2e56b9dc809479a9ca8cc", + b"da3f6a7f55f821760330dd14495e68e7d153b05e472d38459d4728d63ad9df26", + b"026134f6117e45a37c5c2dc2f330bdd274c6dc087526b91ecec4d6dac9bb7346", + ]; + + let mut input = Vec::new(); + for i in 0..128 { + assert_eq!( + Sha256::hash(&input), + hex::decode(hashes[i] as &[u8]).unwrap().as_slice() + ); + input.push(b'A'); + } + } + + // TODO: more tests +} diff --git a/libraries/crypto/src/util.rs b/libraries/crypto/src/util.rs new file mode 100644 index 0000000..47a5ec5 --- /dev/null +++ b/libraries/crypto/src/util.rs @@ -0,0 +1,41 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#[cfg(test)] +use subtle::CtOption; + +pub type Block16 = [u8; 16]; + +#[inline(always)] +pub fn xor_block_16(block: &mut Block16, mask: &Block16) { + for i in 0..16 { + block[i] ^= mask[i]; + } +} + +#[cfg(test)] +pub trait ToOption { + fn to_option(self) -> Option; +} + +#[cfg(test)] +impl ToOption for CtOption { + fn to_option(self) -> Option { + if bool::from(self.is_some()) { + Some(self.unwrap()) + } else { + None + } + } +} diff --git a/libraries/crypto/tests/aesavs.rs b/libraries/crypto/tests/aesavs.rs new file mode 100644 index 0000000..e3798e4 --- /dev/null +++ b/libraries/crypto/tests/aesavs.rs @@ -0,0 +1,103 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/// Test vectors for AES-ECB from NIST's validation suite. +/// +/// See also https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/aes/AESAVS.pdf +#[macro_use] +extern crate arrayref; +extern crate hex; +extern crate regex; + +use crypto::{aes256, Decrypt16BytesBlock, Encrypt16BytesBlock}; +use regex::Regex; +use std::fs::File; +use std::io::{BufRead, BufReader}; +use std::path::Path; + +#[test] +fn aesavs() { + // These data files are taken from https://csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip. + test_aesavs_file("tests/data/ECBVarKey256.rsp"); + test_aesavs_file("tests/data/ECBVarTxt256.rsp"); +} + +fn test_aesavs_file>(path: P) { + // Implements some custom parsing for NIST's test vectors. + let re_count = Regex::new("^COUNT = ([0-9]+)$").unwrap(); + let re_key = Regex::new("^KEY = ([0-9a-f]{64})$").unwrap(); + let re_plaintext = Regex::new("^PLAINTEXT = ([0-9a-f]{32})$").unwrap(); + let re_ciphertext = Regex::new("^CIPHERTEXT = ([0-9a-f]{32})$").unwrap(); + + let file = BufReader::new(File::open(path).unwrap()); + let mut lines = file.lines(); + + loop { + let line = lines.next().unwrap().unwrap(); + if line == "[ENCRYPT]" { + break; + } + } + + for i in 0.. { + // empty line + let line = lines.next().unwrap().unwrap(); + assert_eq!(line, ""); + + let line = lines.next().unwrap().unwrap(); + if line == "[DECRYPT]" { + // Skip the decryption tests, they are the same as the encryption tests. + break; + } + // "COUNT = " + let captures = re_count.captures(&line).unwrap(); + let count = captures.get(1).unwrap().as_str().parse::().unwrap(); + assert_eq!(count, i); + + // "KEY = " + let line = lines.next().unwrap().unwrap(); + let captures = re_key.captures(&line).unwrap(); + let key = hex::decode(captures.get(1).unwrap().as_str()).unwrap(); + assert_eq!(key.len(), 32); + + // "PLAINTEXT = " + let line = lines.next().unwrap().unwrap(); + let captures = re_plaintext.captures(&line).unwrap(); + let plaintext = hex::decode(captures.get(1).unwrap().as_str()).unwrap(); + assert_eq!(plaintext.len(), 16); + + // "CIPHERTEXT = " + let line = lines.next().unwrap().unwrap(); + let captures = re_ciphertext.captures(&line).unwrap(); + let ciphertext = hex::decode(captures.get(1).unwrap().as_str()).unwrap(); + assert_eq!(ciphertext.len(), 16); + + { + let encryption_key = aes256::EncryptionKey::new(array_ref![key, 0, 32]); + let mut block: [u8; 16] = [Default::default(); 16]; + block.copy_from_slice(&plaintext); + encryption_key.encrypt_block(&mut block); + assert_eq!(&block, ciphertext.as_slice()); + } + + { + let encryption_key = aes256::EncryptionKey::new(array_ref![key, 0, 32]); + let decryption_key = aes256::DecryptionKey::new(&encryption_key); + let mut block: [u8; 16] = [Default::default(); 16]; + block.copy_from_slice(&ciphertext); + decryption_key.decrypt_block(&mut block); + assert_eq!(&block, plaintext.as_slice()); + } + } +} diff --git a/libraries/crypto/tests/asn1.rs b/libraries/crypto/tests/asn1.rs new file mode 100644 index 0000000..6056253 --- /dev/null +++ b/libraries/crypto/tests/asn1.rs @@ -0,0 +1,232 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/// A minimalist parser for ASN.1 encoded ECDSA signatures in DER form. +use arrayref::mut_array_refs; +use crypto::ecdsa; +use std::convert::TryFrom; +use std::io::Read; + +#[derive(Debug)] +pub enum Asn1Error { + IoError(std::io::Error), + InvalidTagClass, + InvalidLongFormEncoding, + ArithmeticOverflow, + ExpectedSequenceTag(Tag), + ExpectedIntegerTag(Tag), + InvalidSequenceLen(usize), + InvalidIntegerLen(usize), + UnexpectedTrailingBytes, + InvalidSignature, +} + +impl From for Asn1Error { + fn from(e: std::io::Error) -> Asn1Error { + Asn1Error::IoError(e) + } +} + +#[derive(PartialEq, Debug)] +pub enum TagClass { + Universal = 0, + Application = 1, + ContextSpecific = 2, + Private = 3, +} + +impl TryFrom for TagClass { + type Error = Asn1Error; + + fn try_from(x: u8) -> Result { + match x { + 0 => Ok(TagClass::Universal), + 1 => Ok(TagClass::Application), + 2 => Ok(TagClass::ContextSpecific), + 3 => Ok(TagClass::Private), + _ => Err(Asn1Error::InvalidTagClass), + } + } +} + +#[allow(dead_code)] +enum UniversalTag { + Boolean = 1, + Integer = 2, + BitString = 3, + OctetString = 4, + Null = 5, + ObjectIdentifier = 6, + Utf8String = 12, + Sequence = 16, + Set = 17, + PrintableString = 19, + UtcTime = 23, + GeneralizedTime = 24, +} + +#[derive(Debug)] +pub struct Tag { + class: TagClass, + constructed: bool, + number: u64, +} + +impl Tag { + fn is_sequence(&self) -> bool { + self.class == TagClass::Universal + && self.constructed + && self.number == UniversalTag::Sequence as u64 + } + + fn is_number(&self) -> bool { + self.class == TagClass::Universal + && !self.constructed + && self.number == UniversalTag::Integer as u64 + } + + // Parse an ASN.1 tag encoded in DER form. + fn parse(input: &mut R) -> Result { + let mut buf = [0u8; 1]; + + input.read_exact(&mut buf)?; + let mut tag = buf[0]; + let class = TagClass::try_from(tag >> 6)?; + let constructed = tag & 0x20 != 0; + tag &= 0x1F; + + if tag < 31 { + // Short tag number + let number = tag as u64; + Ok(Tag { + class, + constructed, + number, + }) + } else { + // Long tag number + let mut number: u64 = 0; + loop { + input.read_exact(&mut buf)?; + let x = buf[0]; + if number == 0 && x == 0 { + return Err(Asn1Error::InvalidLongFormEncoding); + } + if number >> ((8 * std::mem::size_of::()) - 7) != 0 { + return Err(Asn1Error::ArithmeticOverflow); + } + number = (number << 7) | (x & 0x7F) as u64; + if (x & 0x80) == 0 { + if number < 31 { + return Err(Asn1Error::InvalidLongFormEncoding); + } + return Ok(Tag { + class, + constructed, + number, + }); + } + } + } + } +} + +// Parse an ASN.1 length encoded in DER form. +fn parse_len(input: &mut R) -> Result { + let mut buf = [0u8; 1]; + + input.read_exact(&mut buf)?; + let first_byte = buf[0]; + if (first_byte & 0x80) == 0 { + // Short form + Ok(first_byte as usize) + } else { + // Long form + let nbytes = (first_byte & 0x7F) as usize; + + let mut length: usize = 0; + for _ in 0..nbytes { + input.read_exact(&mut buf)?; + let x = buf[0]; + if length == 0 && x == 0 { + return Err(Asn1Error::InvalidLongFormEncoding); + } + if length >> (8 * (std::mem::size_of::() - 1)) != 0 { + return Err(Asn1Error::ArithmeticOverflow); + } + length = (length << 8) | x as usize; + } + if length < 0x80 { + return Err(Asn1Error::InvalidLongFormEncoding); + } + Ok(length) + } +} + +fn parse_coordinate(mut input: R, bytes: &mut [u8; 32]) -> Result { + let tag = Tag::parse(&mut input)?; + if !tag.is_number() { + return Err(Asn1Error::ExpectedIntegerTag(tag)); + } + let len = parse_len(&mut input)?; + if len > 33 { + return Err(Asn1Error::InvalidIntegerLen(len)); + } + + let mut buf = vec![0; len]; + input.read_exact(&mut buf)?; + + if len == 33 { + if buf.remove(0) != 0 { + return Err(Asn1Error::InvalidIntegerLen(len)); + } + } + + bytes[(32 - buf.len())..].copy_from_slice(&buf); + Ok(len) +} + +pub fn parse_signature(mut input: R) -> Result { + let tag = Tag::parse(&mut input)?; + if !tag.is_sequence() { + return Err(Asn1Error::ExpectedSequenceTag(tag)); + } + let len = parse_len(&mut input)?; + + let mut bytes = [0; 64]; + let (xbytes, ybytes) = mut_array_refs![&mut bytes, 32, 32]; + + let xlen = parse_coordinate(&mut input, xbytes)?; + let ylen = parse_coordinate(&mut input, ybytes)?; + + // Each coordinate has, besides (x|y)len bytes of integer, one byte for the tag and one + // byte for the length (the length is at most 33 and therefore encoded on one byte). + if len != xlen + ylen + 4 { + return Err(Asn1Error::InvalidSequenceLen(len)); + } + + // Check for unexpected bytes at the end. + let is_eof = { + let mut buf = [0u8; 1]; + match input.read_exact(&mut buf) { + Ok(_) => false, + Err(e) => e.kind() == std::io::ErrorKind::UnexpectedEof, + } + }; + if !is_eof { + return Err(Asn1Error::UnexpectedTrailingBytes); + } + + ecdsa::Signature::from_bytes(&bytes).ok_or(Asn1Error::InvalidSignature) +} diff --git a/libraries/crypto/tests/data/ECBVarKey256.rsp b/libraries/crypto/tests/data/ECBVarKey256.rsp new file mode 100644 index 0000000..bfdd1a8 --- /dev/null +++ b/libraries/crypto/tests/data/ECBVarKey256.rsp @@ -0,0 +1,2571 @@ +# CAVS 11.1 +# Config info for aes_values +# AESVS VarKey test data for ECB +# State : Encrypt and Decrypt +# Key Length : 256 +# Generated on Fri Apr 22 15:11:30 2011 + +[ENCRYPT] + +COUNT = 0 +KEY = 8000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = e35a6dcb19b201a01ebcfa8aa22b5759 + +COUNT = 1 +KEY = c000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = b29169cdcf2d83e838125a12ee6aa400 + +COUNT = 2 +KEY = e000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = d8f3a72fc3cdf74dfaf6c3e6b97b2fa6 + +COUNT = 3 +KEY = f000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 1c777679d50037c79491a94da76a9a35 + +COUNT = 4 +KEY = f800000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 9cf4893ecafa0a0247a898e040691559 + +COUNT = 5 +KEY = fc00000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 8fbb413703735326310a269bd3aa94b2 + +COUNT = 6 +KEY = fe00000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 60e32246bed2b0e859e55c1cc6b26502 + +COUNT = 7 +KEY = ff00000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ec52a212f80a09df6317021bc2a9819e + +COUNT = 8 +KEY = ff80000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = f23e5b600eb70dbccf6c0b1d9a68182c + +COUNT = 9 +KEY = ffc0000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = a3f599d63a82a968c33fe26590745970 + +COUNT = 10 +KEY = ffe0000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = d1ccb9b1337002cbac42c520b5d67722 + +COUNT = 11 +KEY = fff0000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = cc111f6c37cf40a1159d00fb59fb0488 + +COUNT = 12 +KEY = fff8000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = dc43b51ab609052372989a26e9cdd714 + +COUNT = 13 +KEY = fffc000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 4dcede8da9e2578f39703d4433dc6459 + +COUNT = 14 +KEY = fffe000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 1a4c1c263bbccfafc11782894685e3a8 + +COUNT = 15 +KEY = ffff000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 937ad84880db50613423d6d527a2823d + +COUNT = 16 +KEY = ffff800000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 610b71dfc688e150d8152c5b35ebc14d + +COUNT = 17 +KEY = ffffc00000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 27ef2495dabf323885aab39c80f18d8b + +COUNT = 18 +KEY = ffffe00000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 633cafea395bc03adae3a1e2068e4b4e + +COUNT = 19 +KEY = fffff00000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 6e1b482b53761cf631819b749a6f3724 + +COUNT = 20 +KEY = fffff80000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 976e6f851ab52c771998dbb2d71c75a9 + +COUNT = 21 +KEY = fffffc0000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 85f2ba84f8c307cf525e124c3e22e6cc + +COUNT = 22 +KEY = fffffe0000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 6bcca98bf6a835fa64955f72de4115fe + +COUNT = 23 +KEY = ffffff0000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 2c75e2d36eebd65411f14fd0eb1d2a06 + +COUNT = 24 +KEY = ffffff8000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = bd49295006250ffca5100b6007a0eade + +COUNT = 25 +KEY = ffffffc000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = a190527d0ef7c70f459cd3940df316ec + +COUNT = 26 +KEY = ffffffe000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = bbd1097a62433f79449fa97d4ee80dbf + +COUNT = 27 +KEY = fffffff000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 07058e408f5b99b0e0f061a1761b5b3b + +COUNT = 28 +KEY = fffffff800000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 5fd1f13fa0f31e37fabde328f894eac2 + +COUNT = 29 +KEY = fffffffc00000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = fc4af7c948df26e2ef3e01c1ee5b8f6f + +COUNT = 30 +KEY = fffffffe00000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 829fd7208fb92d44a074a677ee9861ac + +COUNT = 31 +KEY = ffffffff00000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ad9fc613a703251b54c64a0e76431711 + +COUNT = 32 +KEY = ffffffff80000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 33ac9eccc4cc75e2711618f80b1548e8 + +COUNT = 33 +KEY = ffffffffc0000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 2025c74b8ad8f4cda17ee2049c4c902d + +COUNT = 34 +KEY = ffffffffe0000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = f85ca05fe528f1ce9b790166e8d551e7 + +COUNT = 35 +KEY = fffffffff0000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 6f6238d8966048d4967154e0dad5a6c9 + +COUNT = 36 +KEY = fffffffff8000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = f2b21b4e7640a9b3346de8b82fb41e49 + +COUNT = 37 +KEY = fffffffffc000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = f836f251ad1d11d49dc344628b1884e1 + +COUNT = 38 +KEY = fffffffffe000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 077e9470ae7abea5a9769d49182628c3 + +COUNT = 39 +KEY = ffffffffff000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = e0dcc2d27fc9865633f85223cf0d611f + +COUNT = 40 +KEY = ffffffffff800000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = be66cfea2fecd6bf0ec7b4352c99bcaa + +COUNT = 41 +KEY = ffffffffffc00000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = df31144f87a2ef523facdcf21a427804 + +COUNT = 42 +KEY = ffffffffffe00000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = b5bb0f5629fb6aae5e1839a3c3625d63 + +COUNT = 43 +KEY = fffffffffff00000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 3c9db3335306fe1ec612bdbfae6b6028 + +COUNT = 44 +KEY = fffffffffff80000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 3dd5c34634a79d3cfcc8339760e6f5f4 + +COUNT = 45 +KEY = fffffffffffc0000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 82bda118a3ed7af314fa2ccc5c07b761 + +COUNT = 46 +KEY = fffffffffffe0000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 2937a64f7d4f46fe6fea3b349ec78e38 + +COUNT = 47 +KEY = ffffffffffff0000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 225f068c28476605735ad671bb8f39f3 + +COUNT = 48 +KEY = ffffffffffff8000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ae682c5ecd71898e08942ac9aa89875c + +COUNT = 49 +KEY = ffffffffffffc000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 5e031cb9d676c3022d7f26227e85c38f + +COUNT = 50 +KEY = ffffffffffffe000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = a78463fb064db5d52bb64bfef64f2dda + +COUNT = 51 +KEY = fffffffffffff000000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 8aa9b75e784593876c53a00eae5af52b + +COUNT = 52 +KEY = fffffffffffff800000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 3f84566df23da48af692722fe980573a + +COUNT = 53 +KEY = fffffffffffffc00000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 31690b5ed41c7eb42a1e83270a7ff0e6 + +COUNT = 54 +KEY = fffffffffffffe00000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 77dd7702646d55f08365e477d3590eda + +COUNT = 55 +KEY = ffffffffffffff00000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 4c022ac62b3cb78d739cc67b3e20bb7e + +COUNT = 56 +KEY = ffffffffffffff80000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 092fa137ce18b5dfe7906f550bb13370 + +COUNT = 57 +KEY = ffffffffffffffc0000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 3e0cdadf2e68353c0027672c97144dd3 + +COUNT = 58 +KEY = ffffffffffffffe0000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = d8c4b200b383fc1f2b2ea677618a1d27 + +COUNT = 59 +KEY = fffffffffffffff0000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 11825f99b0e9bb3477c1c0713b015aac + +COUNT = 60 +KEY = fffffffffffffff8000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = f8b9fffb5c187f7ddc7ab10f4fb77576 + +COUNT = 61 +KEY = fffffffffffffffc000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ffb4e87a32b37d6f2c8328d3b5377802 + +COUNT = 62 +KEY = fffffffffffffffe000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = d276c13a5d220f4da9224e74896391ce + +COUNT = 63 +KEY = ffffffffffffffff000000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 94efe7a0e2e031e2536da01df799c927 + +COUNT = 64 +KEY = ffffffffffffffff800000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 8f8fd822680a85974e53a5a8eb9d38de + +COUNT = 65 +KEY = ffffffffffffffffc00000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = e0f0a91b2e45f8cc37b7805a3042588d + +COUNT = 66 +KEY = ffffffffffffffffe00000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 597a6252255e46d6364dbeeda31e279c + +COUNT = 67 +KEY = fffffffffffffffff00000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = f51a0f694442b8f05571797fec7ee8bf + +COUNT = 68 +KEY = fffffffffffffffff80000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 9ff071b165b5198a93dddeebc54d09b5 + +COUNT = 69 +KEY = fffffffffffffffffc0000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = c20a19fd5758b0c4bc1a5df89cf73877 + +COUNT = 70 +KEY = fffffffffffffffffe0000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 97120166307119ca2280e9315668e96f + +COUNT = 71 +KEY = ffffffffffffffffff0000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 4b3b9f1e099c2a09dc091e90e4f18f0a + +COUNT = 72 +KEY = ffffffffffffffffff8000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = eb040b891d4b37f6851f7ec219cd3f6d + +COUNT = 73 +KEY = ffffffffffffffffffc000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 9f0fdec08b7fd79aa39535bea42db92a + +COUNT = 74 +KEY = ffffffffffffffffffe000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 2e70f168fc74bf911df240bcd2cef236 + +COUNT = 75 +KEY = fffffffffffffffffff000000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 462ccd7f5fd1108dbc152f3cacad328b + +COUNT = 76 +KEY = fffffffffffffffffff800000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = a4af534a7d0b643a01868785d86dfb95 + +COUNT = 77 +KEY = fffffffffffffffffffc00000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ab980296197e1a5022326c31da4bf6f3 + +COUNT = 78 +KEY = fffffffffffffffffffe00000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = f97d57b3333b6281b07d486db2d4e20c + +COUNT = 79 +KEY = ffffffffffffffffffff00000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = f33fa36720231afe4c759ade6bd62eb6 + +COUNT = 80 +KEY = ffffffffffffffffffff80000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = fdcfac0c02ca538343c68117e0a15938 + +COUNT = 81 +KEY = ffffffffffffffffffffc0000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ad4916f5ee5772be764fc027b8a6e539 + +COUNT = 82 +KEY = ffffffffffffffffffffe0000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 2e16873e1678610d7e14c02d002ea845 + +COUNT = 83 +KEY = fffffffffffffffffffff0000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 4e6e627c1acc51340053a8236d579576 + +COUNT = 84 +KEY = fffffffffffffffffffff8000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ab0c8410aeeead92feec1eb430d652cb + +COUNT = 85 +KEY = fffffffffffffffffffffc000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = e86f7e23e835e114977f60e1a592202e + +COUNT = 86 +KEY = fffffffffffffffffffffe000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = e68ad5055a367041fade09d9a70a794b + +COUNT = 87 +KEY = ffffffffffffffffffffff000000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 0791823a3c666bb6162825e78606a7fe + +COUNT = 88 +KEY = ffffffffffffffffffffff800000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = dcca366a9bf47b7b868b77e25c18a364 + +COUNT = 89 +KEY = ffffffffffffffffffffffc00000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 684c9efc237e4a442965f84bce20247a + +COUNT = 90 +KEY = ffffffffffffffffffffffe00000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = a858411ffbe63fdb9c8aa1bfaed67b52 + +COUNT = 91 +KEY = fffffffffffffffffffffff00000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 04bc3da2179c3015498b0e03910db5b8 + +COUNT = 92 +KEY = fffffffffffffffffffffff80000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 40071eeab3f935dbc25d00841460260f + +COUNT = 93 +KEY = fffffffffffffffffffffffc0000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 0ebd7c30ed2016e08ba806ddb008bcc8 + +COUNT = 94 +KEY = fffffffffffffffffffffffe0000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 15c6becf0f4cec7129cbd22d1a79b1b8 + +COUNT = 95 +KEY = ffffffffffffffffffffffff0000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 0aeede5b91f721700e9e62edbf60b781 + +COUNT = 96 +KEY = ffffffffffffffffffffffff8000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 266581af0dcfbed1585e0a242c64b8df + +COUNT = 97 +KEY = ffffffffffffffffffffffffc000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 6693dc911662ae473216ba22189a511a + +COUNT = 98 +KEY = ffffffffffffffffffffffffe000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 7606fa36d86473e6fb3a1bb0e2c0adf5 + +COUNT = 99 +KEY = fffffffffffffffffffffffff000000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 112078e9e11fbb78e26ffb8899e96b9a + +COUNT = 100 +KEY = fffffffffffffffffffffffff800000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 40b264e921e9e4a82694589ef3798262 + +COUNT = 101 +KEY = fffffffffffffffffffffffffc00000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 8d4595cb4fa7026715f55bd68e2882f9 + +COUNT = 102 +KEY = fffffffffffffffffffffffffe00000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = b588a302bdbc09197df1edae68926ed9 + +COUNT = 103 +KEY = ffffffffffffffffffffffffff00000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 33f7502390b8a4a221cfecd0666624ba + +COUNT = 104 +KEY = ffffffffffffffffffffffffff80000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 3d20253adbce3be2373767c4d822c566 + +COUNT = 105 +KEY = ffffffffffffffffffffffffffc0000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = a42734a3929bf84cf0116c9856a3c18c + +COUNT = 106 +KEY = ffffffffffffffffffffffffffe0000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = e3abc4939457422bb957da3c56938c6d + +COUNT = 107 +KEY = fffffffffffffffffffffffffff0000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 972bdd2e7c525130fadc8f76fc6f4b3f + +COUNT = 108 +KEY = fffffffffffffffffffffffffff8000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 84a83d7b94c699cbcb8a7d9b61f64093 + +COUNT = 109 +KEY = fffffffffffffffffffffffffffc000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ce61d63514aded03d43e6ebfc3a9001f + +COUNT = 110 +KEY = fffffffffffffffffffffffffffe000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 6c839dd58eeae6b8a36af48ed63d2dc9 + +COUNT = 111 +KEY = ffffffffffffffffffffffffffff000000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = cd5ece55b8da3bf622c4100df5de46f9 + +COUNT = 112 +KEY = ffffffffffffffffffffffffffff800000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 3b6f46f40e0ac5fc0a9c1105f800f48d + +COUNT = 113 +KEY = ffffffffffffffffffffffffffffc00000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ba26d47da3aeb028de4fb5b3a854a24b + +COUNT = 114 +KEY = ffffffffffffffffffffffffffffe00000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 87f53bf620d3677268445212904389d5 + +COUNT = 115 +KEY = fffffffffffffffffffffffffffff00000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 10617d28b5e0f4605492b182a5d7f9f6 + +COUNT = 116 +KEY = fffffffffffffffffffffffffffff80000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 9aaec4fabbf6fae2a71feff02e372b39 + +COUNT = 117 +KEY = fffffffffffffffffffffffffffffc0000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 3a90c62d88b5c42809abf782488ed130 + +COUNT = 118 +KEY = fffffffffffffffffffffffffffffe0000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = f1f1c5a40899e15772857ccb65c7a09a + +COUNT = 119 +KEY = ffffffffffffffffffffffffffffff0000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 190843d29b25a3897c692ce1dd81ee52 + +COUNT = 120 +KEY = ffffffffffffffffffffffffffffff8000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = a866bc65b6941d86e8420a7ffb0964db + +COUNT = 121 +KEY = ffffffffffffffffffffffffffffffc000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 8193c6ff85225ced4255e92f6e078a14 + +COUNT = 122 +KEY = ffffffffffffffffffffffffffffffe000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 9661cb2424d7d4a380d547f9e7ec1cb9 + +COUNT = 123 +KEY = fffffffffffffffffffffffffffffff000000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 86f93d9ec08453a071e2e2877877a9c8 + +COUNT = 124 +KEY = fffffffffffffffffffffffffffffff800000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 27eefa80ce6a4a9d598e3fec365434d2 + +COUNT = 125 +KEY = fffffffffffffffffffffffffffffffc00000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = d62068444578e3ab39ce7ec95dd045dc + +COUNT = 126 +KEY = fffffffffffffffffffffffffffffffe00000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = b5f71d4dd9a71fe5d8bc8ba7e6ea3048 + +COUNT = 127 +KEY = ffffffffffffffffffffffffffffffff00000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 6825a347ac479d4f9d95c5cb8d3fd7e9 + +COUNT = 128 +KEY = ffffffffffffffffffffffffffffffff80000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = e3714e94a5778955cc0346358e94783a + +COUNT = 129 +KEY = ffffffffffffffffffffffffffffffffc0000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = d836b44bb29e0c7d89fa4b2d4b677d2a + +COUNT = 130 +KEY = ffffffffffffffffffffffffffffffffe0000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 5d454b75021d76d4b84f873a8f877b92 + +COUNT = 131 +KEY = fffffffffffffffffffffffffffffffff0000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = c3498f7eced2095314fc28115885b33f + +COUNT = 132 +KEY = fffffffffffffffffffffffffffffffff8000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 6e668856539ad8e405bd123fe6c88530 + +COUNT = 133 +KEY = fffffffffffffffffffffffffffffffffc000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 8680db7f3a87b8605543cfdbe6754076 + +COUNT = 134 +KEY = fffffffffffffffffffffffffffffffffe000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 6c5d03b13069c3658b3179be91b0800c + +COUNT = 135 +KEY = ffffffffffffffffffffffffffffffffff000000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ef1b384ac4d93eda00c92add0995ea5f + +COUNT = 136 +KEY = ffffffffffffffffffffffffffffffffff800000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = bf8115805471741bd5ad20a03944790f + +COUNT = 137 +KEY = ffffffffffffffffffffffffffffffffffc00000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = c64c24b6894b038b3c0d09b1df068b0b + +COUNT = 138 +KEY = ffffffffffffffffffffffffffffffffffe00000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 3967a10cffe27d0178545fbf6a40544b + +COUNT = 139 +KEY = fffffffffffffffffffffffffffffffffff00000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 7c85e9c95de1a9ec5a5363a8a053472d + +COUNT = 140 +KEY = fffffffffffffffffffffffffffffffffff80000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = a9eec03c8abec7ba68315c2c8c2316e0 + +COUNT = 141 +KEY = fffffffffffffffffffffffffffffffffffc0000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = cac8e414c2f388227ae14986fc983524 + +COUNT = 142 +KEY = fffffffffffffffffffffffffffffffffffe0000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 5d942b7f4622ce056c3ce3ce5f1dd9d6 + +COUNT = 143 +KEY = ffffffffffffffffffffffffffffffffffff0000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = d240d648ce21a3020282c3f1b528a0b6 + +COUNT = 144 +KEY = ffffffffffffffffffffffffffffffffffff8000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 45d089c36d5c5a4efc689e3b0de10dd5 + +COUNT = 145 +KEY = ffffffffffffffffffffffffffffffffffffc000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = b4da5df4becb5462e03a0ed00d295629 + +COUNT = 146 +KEY = ffffffffffffffffffffffffffffffffffffe000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = dcf4e129136c1a4b7a0f38935cc34b2b + +COUNT = 147 +KEY = fffffffffffffffffffffffffffffffffffff000000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = d9a4c7618b0ce48a3d5aee1a1c0114c4 + +COUNT = 148 +KEY = fffffffffffffffffffffffffffffffffffff800000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ca352df025c65c7b0bf306fbee0f36ba + +COUNT = 149 +KEY = fffffffffffffffffffffffffffffffffffffc00000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 238aca23fd3409f38af63378ed2f5473 + +COUNT = 150 +KEY = fffffffffffffffffffffffffffffffffffffe00000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 59836a0e06a79691b36667d5380d8188 + +COUNT = 151 +KEY = ffffffffffffffffffffffffffffffffffffff00000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 33905080f7acf1cdae0a91fc3e85aee4 + +COUNT = 152 +KEY = ffffffffffffffffffffffffffffffffffffff80000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 72c9e4646dbc3d6320fc6689d93e8833 + +COUNT = 153 +KEY = ffffffffffffffffffffffffffffffffffffffc0000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ba77413dea5925b7f5417ea47ff19f59 + +COUNT = 154 +KEY = ffffffffffffffffffffffffffffffffffffffe0000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 6cae8129f843d86dc786a0fb1a184970 + +COUNT = 155 +KEY = fffffffffffffffffffffffffffffffffffffff0000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = fcfefb534100796eebbd990206754e19 + +COUNT = 156 +KEY = fffffffffffffffffffffffffffffffffffffff8000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 8c791d5fdddf470da04f3e6dc4a5b5b5 + +COUNT = 157 +KEY = fffffffffffffffffffffffffffffffffffffffc000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = c93bbdc07a4611ae4bb266ea5034a387 + +COUNT = 158 +KEY = fffffffffffffffffffffffffffffffffffffffe000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = c102e38e489aa74762f3efc5bb23205a + +COUNT = 159 +KEY = ffffffffffffffffffffffffffffffffffffffff000000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 93201481665cbafc1fcc220bc545fb3d + +COUNT = 160 +KEY = ffffffffffffffffffffffffffffffffffffffff800000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 4960757ec6ce68cf195e454cfd0f32ca + +COUNT = 161 +KEY = ffffffffffffffffffffffffffffffffffffffffc00000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = feec7ce6a6cbd07c043416737f1bbb33 + +COUNT = 162 +KEY = ffffffffffffffffffffffffffffffffffffffffe00000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 11c5413904487a805d70a8edd9c35527 + +COUNT = 163 +KEY = fffffffffffffffffffffffffffffffffffffffff00000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 347846b2b2e36f1f0324c86f7f1b98e2 + +COUNT = 164 +KEY = fffffffffffffffffffffffffffffffffffffffff80000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 332eee1a0cbd19ca2d69b426894044f0 + +COUNT = 165 +KEY = fffffffffffffffffffffffffffffffffffffffffc0000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 866b5b3977ba6efa5128efbda9ff03cd + +COUNT = 166 +KEY = fffffffffffffffffffffffffffffffffffffffffe0000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = cc1445ee94c0f08cdee5c344ecd1e233 + +COUNT = 167 +KEY = ffffffffffffffffffffffffffffffffffffffffff0000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = be288319029363c2622feba4b05dfdfe + +COUNT = 168 +KEY = ffffffffffffffffffffffffffffffffffffffffff8000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = cfd1875523f3cd21c395651e6ee15e56 + +COUNT = 169 +KEY = ffffffffffffffffffffffffffffffffffffffffffc000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = cb5a408657837c53bf16f9d8465dce19 + +COUNT = 170 +KEY = ffffffffffffffffffffffffffffffffffffffffffe000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ca0bf42cb107f55ccff2fc09ee08ca15 + +COUNT = 171 +KEY = fffffffffffffffffffffffffffffffffffffffffff000000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = fdd9bbb4a7dc2e4a23536a5880a2db67 + +COUNT = 172 +KEY = fffffffffffffffffffffffffffffffffffffffffff800000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ede447b362c484993dec9442a3b46aef + +COUNT = 173 +KEY = fffffffffffffffffffffffffffffffffffffffffffc00000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 10dffb05904bff7c4781df780ad26837 + +COUNT = 174 +KEY = fffffffffffffffffffffffffffffffffffffffffffe00000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = c33bc13e8de88ac25232aa7496398783 + +COUNT = 175 +KEY = ffffffffffffffffffffffffffffffffffffffffffff00000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ca359c70803a3b2a3d542e8781dea975 + +COUNT = 176 +KEY = ffffffffffffffffffffffffffffffffffffffffffff80000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = bcc65b526f88d05b89ce8a52021fdb06 + +COUNT = 177 +KEY = ffffffffffffffffffffffffffffffffffffffffffffc0000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = db91a38855c8c4643851fbfb358b0109 + +COUNT = 178 +KEY = ffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ca6e8893a114ae8e27d5ab03a5499610 + +COUNT = 179 +KEY = fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 6629d2b8df97da728cdd8b1e7f945077 + +COUNT = 180 +KEY = fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 4570a5a18cfc0dd582f1d88d5c9a1720 + +COUNT = 181 +KEY = fffffffffffffffffffffffffffffffffffffffffffffc000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 72bc65aa8e89562e3f274d45af1cd10b + +COUNT = 182 +KEY = fffffffffffffffffffffffffffffffffffffffffffffe000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 98551da1a6503276ae1c77625f9ea615 + +COUNT = 183 +KEY = ffffffffffffffffffffffffffffffffffffffffffffff000000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 0ddfe51ced7e3f4ae927daa3fe452cee + +COUNT = 184 +KEY = ffffffffffffffffffffffffffffffffffffffffffffff800000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = db826251e4ce384b80218b0e1da1dd4c + +COUNT = 185 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffc00000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 2cacf728b88abbad7011ed0e64a1680c + +COUNT = 186 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffe00000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 330d8ee7c5677e099ac74c9994ee4cfb + +COUNT = 187 +KEY = fffffffffffffffffffffffffffffffffffffffffffffff00000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = edf61ae362e882ddc0167474a7a77f3a + +COUNT = 188 +KEY = fffffffffffffffffffffffffffffffffffffffffffffff80000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 6168b00ba7859e0970ecfd757efecf7c + +COUNT = 189 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffc0000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = d1415447866230d28bb1ea18a4cdfd02 + +COUNT = 190 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 516183392f7a8763afec68a060264141 + +COUNT = 191 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 77565c8d73cfd4130b4aa14d8911710f + +COUNT = 192 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 37232a4ed21ccc27c19c9610078cabac + +COUNT = 193 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffc000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 804f32ea71828c7d329077e712231666 + +COUNT = 194 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = d64424f23cb97215e9c2c6f28d29eab7 + +COUNT = 195 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 023e82b533f68c75c238cebdb2ee89a2 + +COUNT = 196 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffff800000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 193a3d24157a51f1ee0893f6777417e7 + +COUNT = 197 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffc00000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 84ecacfcd400084d078612b1945f2ef5 + +COUNT = 198 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffe00000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 1dcd8bb173259eb33a5242b0de31a455 + +COUNT = 199 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 35e9eddbc375e792c19992c19165012b + +COUNT = 200 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 8a772231c01dfdd7c98e4cfddcc0807a + +COUNT = 201 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffc0000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 6eda7ff6b8319180ff0d6e65629d01c3 + +COUNT = 202 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = c267ef0e2d01a993944dd397101413cb + +COUNT = 203 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = e9f80e9d845bcc0f62926af72eabca39 + +COUNT = 204 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffff8000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 6702990727aa0878637b45dcd3a3b074 + +COUNT = 205 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffc000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 2e2e647d5360e09230a5d738ca33471e + +COUNT = 206 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 1f56413c7add6f43d1d56e4f02190330 + +COUNT = 207 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 69cd0606e15af729d6bca143016d9842 + +COUNT = 208 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffff800000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = a085d7c1a500873a20099c4caa3c3f5b + +COUNT = 209 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffc00000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 4fc0d230f8891415b87b83f95f2e09d1 + +COUNT = 210 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 4327d08c523d8eba697a4336507d1f42 + +COUNT = 211 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 7a15aab82701efa5ae36ab1d6b76290f + +COUNT = 212 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 5bf0051893a18bb30e139a58fed0fa54 + +COUNT = 213 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffc0000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 97e8adf65638fd9cdf3bc22c17fe4dbd + +COUNT = 214 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 1ee6ee326583a0586491c96418d1a35d + +COUNT = 215 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 26b549c2ec756f82ecc48008e529956b + +COUNT = 216 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 70377b6da669b072129e057cc28e9ca5 + +COUNT = 217 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffc000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 9c94b8b0cb8bcc919072262b3fa05ad9 + +COUNT = 218 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 2fbb83dfd0d7abcb05cd28cad2dfb523 + +COUNT = 219 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 96877803de77744bb970d0a91f4debae + +COUNT = 220 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffff800000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 7379f3370cf6e5ce12ae5969c8eea312 + +COUNT = 221 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffc00000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 02dc99fa3d4f98ce80985e7233889313 + +COUNT = 222 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 1e38e759075ba5cab6457da51844295a + +COUNT = 223 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 70bed8dbf615868a1f9d9b05d3e7a267 + +COUNT = 224 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 234b148b8cb1d8c32b287e896903d150 + +COUNT = 225 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 294b033df4da853f4be3e243f7e513f4 + +COUNT = 226 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 3f58c950f0367160adec45f2441e7411 + +COUNT = 227 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 37f655536a704e5ace182d742a820cf4 + +COUNT = 228 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ea7bd6bb63418731aeac790fe42d61e8 + +COUNT = 229 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffc000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = e74a4c999b4c064e48bb1e413f51e5ea + +COUNT = 230 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = ba9ebefdb4ccf30f296cecb3bc1943e8 + +COUNT = 231 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 3194367a4898c502c13bb7478640a72d + +COUNT = 232 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = da797713263d6f33a5478a65ef60d412 + +COUNT = 233 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = d1ac39bb1ef86b9c1344f214679aa376 + +COUNT = 234 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 2fdea9e650532be5bc0e7325337fd363 + +COUNT = 235 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = d3a204dbd9c2af158b6ca67a5156ce4a + +COUNT = 236 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 3a0a0e75a8da36735aee6684d965a778 + +COUNT = 237 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 52fc3e620492ea99641ea168da5b6d52 + +COUNT = 238 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = d2e0c7f15b4772467d2cfc873000b2ca + +COUNT = 239 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 563531135e0c4d70a38f8bdb190ba04e + +COUNT = 240 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = a8a39a0f5663f4c0fe5f2d3cafff421a + +COUNT = 241 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = d94b5e90db354c1e42f61fabe167b2c0 + +COUNT = 242 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 50e6d3c9b6698a7cd276f96b1473f35a + +COUNT = 243 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 9338f08e0ebee96905d8f2e825208f43 + +COUNT = 244 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 8b378c86672aa54a3a266ba19d2580ca + +COUNT = 245 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = cca7c3086f5f9511b31233da7cab9160 + +COUNT = 246 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 5b40ff4ec9be536ba23035fa4f06064c + +COUNT = 247 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 60eb5af8416b257149372194e8b88749 + +COUNT = 248 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 2f005a8aed8a361c92e440c15520cbd1 + +COUNT = 249 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 7b03627611678a997717578807a800e2 + +COUNT = 250 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = cf78618f74f6f3696e0a4779b90b5a77 + +COUNT = 251 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 03720371a04962eaea0a852e69972858 + +COUNT = 252 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8 +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 1f8a8133aa8ccf70e2bd3285831ca6b7 + +COUNT = 253 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 27936bd27fb1468fc8b48bc483321725 + +COUNT = 254 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = b07d4f3e2cd2ef2eb545980754dfea0f + +COUNT = 255 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +PLAINTEXT = 00000000000000000000000000000000 +CIPHERTEXT = 4bf85f1b5d54adbc307b0a048389adcb + +[DECRYPT] + +COUNT = 0 +KEY = 8000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = e35a6dcb19b201a01ebcfa8aa22b5759 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 1 +KEY = c000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = b29169cdcf2d83e838125a12ee6aa400 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 2 +KEY = e000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = d8f3a72fc3cdf74dfaf6c3e6b97b2fa6 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 3 +KEY = f000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 1c777679d50037c79491a94da76a9a35 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 4 +KEY = f800000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 9cf4893ecafa0a0247a898e040691559 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 5 +KEY = fc00000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 8fbb413703735326310a269bd3aa94b2 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 6 +KEY = fe00000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 60e32246bed2b0e859e55c1cc6b26502 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 7 +KEY = ff00000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = ec52a212f80a09df6317021bc2a9819e +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 8 +KEY = ff80000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = f23e5b600eb70dbccf6c0b1d9a68182c +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 9 +KEY = ffc0000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = a3f599d63a82a968c33fe26590745970 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 10 +KEY = ffe0000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = d1ccb9b1337002cbac42c520b5d67722 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 11 +KEY = fff0000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = cc111f6c37cf40a1159d00fb59fb0488 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 12 +KEY = fff8000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = dc43b51ab609052372989a26e9cdd714 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 13 +KEY = fffc000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 4dcede8da9e2578f39703d4433dc6459 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 14 +KEY = fffe000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 1a4c1c263bbccfafc11782894685e3a8 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 15 +KEY = ffff000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 937ad84880db50613423d6d527a2823d +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 16 +KEY = ffff800000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 610b71dfc688e150d8152c5b35ebc14d +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 17 +KEY = ffffc00000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 27ef2495dabf323885aab39c80f18d8b +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 18 +KEY = ffffe00000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 633cafea395bc03adae3a1e2068e4b4e +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 19 +KEY = fffff00000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 6e1b482b53761cf631819b749a6f3724 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 20 +KEY = fffff80000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 976e6f851ab52c771998dbb2d71c75a9 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 21 +KEY = fffffc0000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 85f2ba84f8c307cf525e124c3e22e6cc +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 22 +KEY = fffffe0000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 6bcca98bf6a835fa64955f72de4115fe +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 23 +KEY = ffffff0000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 2c75e2d36eebd65411f14fd0eb1d2a06 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 24 +KEY = ffffff8000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = bd49295006250ffca5100b6007a0eade +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 25 +KEY = ffffffc000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = a190527d0ef7c70f459cd3940df316ec +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 26 +KEY = ffffffe000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = bbd1097a62433f79449fa97d4ee80dbf +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 27 +KEY = fffffff000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 07058e408f5b99b0e0f061a1761b5b3b +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 28 +KEY = fffffff800000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 5fd1f13fa0f31e37fabde328f894eac2 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 29 +KEY = fffffffc00000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = fc4af7c948df26e2ef3e01c1ee5b8f6f +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 30 +KEY = fffffffe00000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 829fd7208fb92d44a074a677ee9861ac +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 31 +KEY = ffffffff00000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = ad9fc613a703251b54c64a0e76431711 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 32 +KEY = ffffffff80000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 33ac9eccc4cc75e2711618f80b1548e8 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 33 +KEY = ffffffffc0000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 2025c74b8ad8f4cda17ee2049c4c902d +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 34 +KEY = ffffffffe0000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = f85ca05fe528f1ce9b790166e8d551e7 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 35 +KEY = fffffffff0000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 6f6238d8966048d4967154e0dad5a6c9 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 36 +KEY = fffffffff8000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = f2b21b4e7640a9b3346de8b82fb41e49 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 37 +KEY = fffffffffc000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = f836f251ad1d11d49dc344628b1884e1 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 38 +KEY = fffffffffe000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 077e9470ae7abea5a9769d49182628c3 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 39 +KEY = ffffffffff000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = e0dcc2d27fc9865633f85223cf0d611f +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 40 +KEY = ffffffffff800000000000000000000000000000000000000000000000000000 +CIPHERTEXT = be66cfea2fecd6bf0ec7b4352c99bcaa +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 41 +KEY = ffffffffffc00000000000000000000000000000000000000000000000000000 +CIPHERTEXT = df31144f87a2ef523facdcf21a427804 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 42 +KEY = ffffffffffe00000000000000000000000000000000000000000000000000000 +CIPHERTEXT = b5bb0f5629fb6aae5e1839a3c3625d63 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 43 +KEY = fffffffffff00000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 3c9db3335306fe1ec612bdbfae6b6028 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 44 +KEY = fffffffffff80000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 3dd5c34634a79d3cfcc8339760e6f5f4 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 45 +KEY = fffffffffffc0000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 82bda118a3ed7af314fa2ccc5c07b761 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 46 +KEY = fffffffffffe0000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 2937a64f7d4f46fe6fea3b349ec78e38 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 47 +KEY = ffffffffffff0000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 225f068c28476605735ad671bb8f39f3 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 48 +KEY = ffffffffffff8000000000000000000000000000000000000000000000000000 +CIPHERTEXT = ae682c5ecd71898e08942ac9aa89875c +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 49 +KEY = ffffffffffffc000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 5e031cb9d676c3022d7f26227e85c38f +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 50 +KEY = ffffffffffffe000000000000000000000000000000000000000000000000000 +CIPHERTEXT = a78463fb064db5d52bb64bfef64f2dda +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 51 +KEY = fffffffffffff000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 8aa9b75e784593876c53a00eae5af52b +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 52 +KEY = fffffffffffff800000000000000000000000000000000000000000000000000 +CIPHERTEXT = 3f84566df23da48af692722fe980573a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 53 +KEY = fffffffffffffc00000000000000000000000000000000000000000000000000 +CIPHERTEXT = 31690b5ed41c7eb42a1e83270a7ff0e6 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 54 +KEY = fffffffffffffe00000000000000000000000000000000000000000000000000 +CIPHERTEXT = 77dd7702646d55f08365e477d3590eda +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 55 +KEY = ffffffffffffff00000000000000000000000000000000000000000000000000 +CIPHERTEXT = 4c022ac62b3cb78d739cc67b3e20bb7e +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 56 +KEY = ffffffffffffff80000000000000000000000000000000000000000000000000 +CIPHERTEXT = 092fa137ce18b5dfe7906f550bb13370 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 57 +KEY = ffffffffffffffc0000000000000000000000000000000000000000000000000 +CIPHERTEXT = 3e0cdadf2e68353c0027672c97144dd3 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 58 +KEY = ffffffffffffffe0000000000000000000000000000000000000000000000000 +CIPHERTEXT = d8c4b200b383fc1f2b2ea677618a1d27 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 59 +KEY = fffffffffffffff0000000000000000000000000000000000000000000000000 +CIPHERTEXT = 11825f99b0e9bb3477c1c0713b015aac +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 60 +KEY = fffffffffffffff8000000000000000000000000000000000000000000000000 +CIPHERTEXT = f8b9fffb5c187f7ddc7ab10f4fb77576 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 61 +KEY = fffffffffffffffc000000000000000000000000000000000000000000000000 +CIPHERTEXT = ffb4e87a32b37d6f2c8328d3b5377802 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 62 +KEY = fffffffffffffffe000000000000000000000000000000000000000000000000 +CIPHERTEXT = d276c13a5d220f4da9224e74896391ce +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 63 +KEY = ffffffffffffffff000000000000000000000000000000000000000000000000 +CIPHERTEXT = 94efe7a0e2e031e2536da01df799c927 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 64 +KEY = ffffffffffffffff800000000000000000000000000000000000000000000000 +CIPHERTEXT = 8f8fd822680a85974e53a5a8eb9d38de +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 65 +KEY = ffffffffffffffffc00000000000000000000000000000000000000000000000 +CIPHERTEXT = e0f0a91b2e45f8cc37b7805a3042588d +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 66 +KEY = ffffffffffffffffe00000000000000000000000000000000000000000000000 +CIPHERTEXT = 597a6252255e46d6364dbeeda31e279c +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 67 +KEY = fffffffffffffffff00000000000000000000000000000000000000000000000 +CIPHERTEXT = f51a0f694442b8f05571797fec7ee8bf +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 68 +KEY = fffffffffffffffff80000000000000000000000000000000000000000000000 +CIPHERTEXT = 9ff071b165b5198a93dddeebc54d09b5 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 69 +KEY = fffffffffffffffffc0000000000000000000000000000000000000000000000 +CIPHERTEXT = c20a19fd5758b0c4bc1a5df89cf73877 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 70 +KEY = fffffffffffffffffe0000000000000000000000000000000000000000000000 +CIPHERTEXT = 97120166307119ca2280e9315668e96f +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 71 +KEY = ffffffffffffffffff0000000000000000000000000000000000000000000000 +CIPHERTEXT = 4b3b9f1e099c2a09dc091e90e4f18f0a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 72 +KEY = ffffffffffffffffff8000000000000000000000000000000000000000000000 +CIPHERTEXT = eb040b891d4b37f6851f7ec219cd3f6d +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 73 +KEY = ffffffffffffffffffc000000000000000000000000000000000000000000000 +CIPHERTEXT = 9f0fdec08b7fd79aa39535bea42db92a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 74 +KEY = ffffffffffffffffffe000000000000000000000000000000000000000000000 +CIPHERTEXT = 2e70f168fc74bf911df240bcd2cef236 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 75 +KEY = fffffffffffffffffff000000000000000000000000000000000000000000000 +CIPHERTEXT = 462ccd7f5fd1108dbc152f3cacad328b +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 76 +KEY = fffffffffffffffffff800000000000000000000000000000000000000000000 +CIPHERTEXT = a4af534a7d0b643a01868785d86dfb95 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 77 +KEY = fffffffffffffffffffc00000000000000000000000000000000000000000000 +CIPHERTEXT = ab980296197e1a5022326c31da4bf6f3 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 78 +KEY = fffffffffffffffffffe00000000000000000000000000000000000000000000 +CIPHERTEXT = f97d57b3333b6281b07d486db2d4e20c +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 79 +KEY = ffffffffffffffffffff00000000000000000000000000000000000000000000 +CIPHERTEXT = f33fa36720231afe4c759ade6bd62eb6 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 80 +KEY = ffffffffffffffffffff80000000000000000000000000000000000000000000 +CIPHERTEXT = fdcfac0c02ca538343c68117e0a15938 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 81 +KEY = ffffffffffffffffffffc0000000000000000000000000000000000000000000 +CIPHERTEXT = ad4916f5ee5772be764fc027b8a6e539 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 82 +KEY = ffffffffffffffffffffe0000000000000000000000000000000000000000000 +CIPHERTEXT = 2e16873e1678610d7e14c02d002ea845 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 83 +KEY = fffffffffffffffffffff0000000000000000000000000000000000000000000 +CIPHERTEXT = 4e6e627c1acc51340053a8236d579576 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 84 +KEY = fffffffffffffffffffff8000000000000000000000000000000000000000000 +CIPHERTEXT = ab0c8410aeeead92feec1eb430d652cb +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 85 +KEY = fffffffffffffffffffffc000000000000000000000000000000000000000000 +CIPHERTEXT = e86f7e23e835e114977f60e1a592202e +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 86 +KEY = fffffffffffffffffffffe000000000000000000000000000000000000000000 +CIPHERTEXT = e68ad5055a367041fade09d9a70a794b +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 87 +KEY = ffffffffffffffffffffff000000000000000000000000000000000000000000 +CIPHERTEXT = 0791823a3c666bb6162825e78606a7fe +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 88 +KEY = ffffffffffffffffffffff800000000000000000000000000000000000000000 +CIPHERTEXT = dcca366a9bf47b7b868b77e25c18a364 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 89 +KEY = ffffffffffffffffffffffc00000000000000000000000000000000000000000 +CIPHERTEXT = 684c9efc237e4a442965f84bce20247a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 90 +KEY = ffffffffffffffffffffffe00000000000000000000000000000000000000000 +CIPHERTEXT = a858411ffbe63fdb9c8aa1bfaed67b52 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 91 +KEY = fffffffffffffffffffffff00000000000000000000000000000000000000000 +CIPHERTEXT = 04bc3da2179c3015498b0e03910db5b8 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 92 +KEY = fffffffffffffffffffffff80000000000000000000000000000000000000000 +CIPHERTEXT = 40071eeab3f935dbc25d00841460260f +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 93 +KEY = fffffffffffffffffffffffc0000000000000000000000000000000000000000 +CIPHERTEXT = 0ebd7c30ed2016e08ba806ddb008bcc8 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 94 +KEY = fffffffffffffffffffffffe0000000000000000000000000000000000000000 +CIPHERTEXT = 15c6becf0f4cec7129cbd22d1a79b1b8 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 95 +KEY = ffffffffffffffffffffffff0000000000000000000000000000000000000000 +CIPHERTEXT = 0aeede5b91f721700e9e62edbf60b781 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 96 +KEY = ffffffffffffffffffffffff8000000000000000000000000000000000000000 +CIPHERTEXT = 266581af0dcfbed1585e0a242c64b8df +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 97 +KEY = ffffffffffffffffffffffffc000000000000000000000000000000000000000 +CIPHERTEXT = 6693dc911662ae473216ba22189a511a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 98 +KEY = ffffffffffffffffffffffffe000000000000000000000000000000000000000 +CIPHERTEXT = 7606fa36d86473e6fb3a1bb0e2c0adf5 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 99 +KEY = fffffffffffffffffffffffff000000000000000000000000000000000000000 +CIPHERTEXT = 112078e9e11fbb78e26ffb8899e96b9a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 100 +KEY = fffffffffffffffffffffffff800000000000000000000000000000000000000 +CIPHERTEXT = 40b264e921e9e4a82694589ef3798262 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 101 +KEY = fffffffffffffffffffffffffc00000000000000000000000000000000000000 +CIPHERTEXT = 8d4595cb4fa7026715f55bd68e2882f9 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 102 +KEY = fffffffffffffffffffffffffe00000000000000000000000000000000000000 +CIPHERTEXT = b588a302bdbc09197df1edae68926ed9 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 103 +KEY = ffffffffffffffffffffffffff00000000000000000000000000000000000000 +CIPHERTEXT = 33f7502390b8a4a221cfecd0666624ba +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 104 +KEY = ffffffffffffffffffffffffff80000000000000000000000000000000000000 +CIPHERTEXT = 3d20253adbce3be2373767c4d822c566 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 105 +KEY = ffffffffffffffffffffffffffc0000000000000000000000000000000000000 +CIPHERTEXT = a42734a3929bf84cf0116c9856a3c18c +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 106 +KEY = ffffffffffffffffffffffffffe0000000000000000000000000000000000000 +CIPHERTEXT = e3abc4939457422bb957da3c56938c6d +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 107 +KEY = fffffffffffffffffffffffffff0000000000000000000000000000000000000 +CIPHERTEXT = 972bdd2e7c525130fadc8f76fc6f4b3f +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 108 +KEY = fffffffffffffffffffffffffff8000000000000000000000000000000000000 +CIPHERTEXT = 84a83d7b94c699cbcb8a7d9b61f64093 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 109 +KEY = fffffffffffffffffffffffffffc000000000000000000000000000000000000 +CIPHERTEXT = ce61d63514aded03d43e6ebfc3a9001f +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 110 +KEY = fffffffffffffffffffffffffffe000000000000000000000000000000000000 +CIPHERTEXT = 6c839dd58eeae6b8a36af48ed63d2dc9 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 111 +KEY = ffffffffffffffffffffffffffff000000000000000000000000000000000000 +CIPHERTEXT = cd5ece55b8da3bf622c4100df5de46f9 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 112 +KEY = ffffffffffffffffffffffffffff800000000000000000000000000000000000 +CIPHERTEXT = 3b6f46f40e0ac5fc0a9c1105f800f48d +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 113 +KEY = ffffffffffffffffffffffffffffc00000000000000000000000000000000000 +CIPHERTEXT = ba26d47da3aeb028de4fb5b3a854a24b +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 114 +KEY = ffffffffffffffffffffffffffffe00000000000000000000000000000000000 +CIPHERTEXT = 87f53bf620d3677268445212904389d5 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 115 +KEY = fffffffffffffffffffffffffffff00000000000000000000000000000000000 +CIPHERTEXT = 10617d28b5e0f4605492b182a5d7f9f6 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 116 +KEY = fffffffffffffffffffffffffffff80000000000000000000000000000000000 +CIPHERTEXT = 9aaec4fabbf6fae2a71feff02e372b39 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 117 +KEY = fffffffffffffffffffffffffffffc0000000000000000000000000000000000 +CIPHERTEXT = 3a90c62d88b5c42809abf782488ed130 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 118 +KEY = fffffffffffffffffffffffffffffe0000000000000000000000000000000000 +CIPHERTEXT = f1f1c5a40899e15772857ccb65c7a09a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 119 +KEY = ffffffffffffffffffffffffffffff0000000000000000000000000000000000 +CIPHERTEXT = 190843d29b25a3897c692ce1dd81ee52 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 120 +KEY = ffffffffffffffffffffffffffffff8000000000000000000000000000000000 +CIPHERTEXT = a866bc65b6941d86e8420a7ffb0964db +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 121 +KEY = ffffffffffffffffffffffffffffffc000000000000000000000000000000000 +CIPHERTEXT = 8193c6ff85225ced4255e92f6e078a14 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 122 +KEY = ffffffffffffffffffffffffffffffe000000000000000000000000000000000 +CIPHERTEXT = 9661cb2424d7d4a380d547f9e7ec1cb9 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 123 +KEY = fffffffffffffffffffffffffffffff000000000000000000000000000000000 +CIPHERTEXT = 86f93d9ec08453a071e2e2877877a9c8 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 124 +KEY = fffffffffffffffffffffffffffffff800000000000000000000000000000000 +CIPHERTEXT = 27eefa80ce6a4a9d598e3fec365434d2 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 125 +KEY = fffffffffffffffffffffffffffffffc00000000000000000000000000000000 +CIPHERTEXT = d62068444578e3ab39ce7ec95dd045dc +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 126 +KEY = fffffffffffffffffffffffffffffffe00000000000000000000000000000000 +CIPHERTEXT = b5f71d4dd9a71fe5d8bc8ba7e6ea3048 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 127 +KEY = ffffffffffffffffffffffffffffffff00000000000000000000000000000000 +CIPHERTEXT = 6825a347ac479d4f9d95c5cb8d3fd7e9 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 128 +KEY = ffffffffffffffffffffffffffffffff80000000000000000000000000000000 +CIPHERTEXT = e3714e94a5778955cc0346358e94783a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 129 +KEY = ffffffffffffffffffffffffffffffffc0000000000000000000000000000000 +CIPHERTEXT = d836b44bb29e0c7d89fa4b2d4b677d2a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 130 +KEY = ffffffffffffffffffffffffffffffffe0000000000000000000000000000000 +CIPHERTEXT = 5d454b75021d76d4b84f873a8f877b92 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 131 +KEY = fffffffffffffffffffffffffffffffff0000000000000000000000000000000 +CIPHERTEXT = c3498f7eced2095314fc28115885b33f +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 132 +KEY = fffffffffffffffffffffffffffffffff8000000000000000000000000000000 +CIPHERTEXT = 6e668856539ad8e405bd123fe6c88530 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 133 +KEY = fffffffffffffffffffffffffffffffffc000000000000000000000000000000 +CIPHERTEXT = 8680db7f3a87b8605543cfdbe6754076 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 134 +KEY = fffffffffffffffffffffffffffffffffe000000000000000000000000000000 +CIPHERTEXT = 6c5d03b13069c3658b3179be91b0800c +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 135 +KEY = ffffffffffffffffffffffffffffffffff000000000000000000000000000000 +CIPHERTEXT = ef1b384ac4d93eda00c92add0995ea5f +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 136 +KEY = ffffffffffffffffffffffffffffffffff800000000000000000000000000000 +CIPHERTEXT = bf8115805471741bd5ad20a03944790f +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 137 +KEY = ffffffffffffffffffffffffffffffffffc00000000000000000000000000000 +CIPHERTEXT = c64c24b6894b038b3c0d09b1df068b0b +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 138 +KEY = ffffffffffffffffffffffffffffffffffe00000000000000000000000000000 +CIPHERTEXT = 3967a10cffe27d0178545fbf6a40544b +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 139 +KEY = fffffffffffffffffffffffffffffffffff00000000000000000000000000000 +CIPHERTEXT = 7c85e9c95de1a9ec5a5363a8a053472d +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 140 +KEY = fffffffffffffffffffffffffffffffffff80000000000000000000000000000 +CIPHERTEXT = a9eec03c8abec7ba68315c2c8c2316e0 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 141 +KEY = fffffffffffffffffffffffffffffffffffc0000000000000000000000000000 +CIPHERTEXT = cac8e414c2f388227ae14986fc983524 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 142 +KEY = fffffffffffffffffffffffffffffffffffe0000000000000000000000000000 +CIPHERTEXT = 5d942b7f4622ce056c3ce3ce5f1dd9d6 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 143 +KEY = ffffffffffffffffffffffffffffffffffff0000000000000000000000000000 +CIPHERTEXT = d240d648ce21a3020282c3f1b528a0b6 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 144 +KEY = ffffffffffffffffffffffffffffffffffff8000000000000000000000000000 +CIPHERTEXT = 45d089c36d5c5a4efc689e3b0de10dd5 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 145 +KEY = ffffffffffffffffffffffffffffffffffffc000000000000000000000000000 +CIPHERTEXT = b4da5df4becb5462e03a0ed00d295629 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 146 +KEY = ffffffffffffffffffffffffffffffffffffe000000000000000000000000000 +CIPHERTEXT = dcf4e129136c1a4b7a0f38935cc34b2b +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 147 +KEY = fffffffffffffffffffffffffffffffffffff000000000000000000000000000 +CIPHERTEXT = d9a4c7618b0ce48a3d5aee1a1c0114c4 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 148 +KEY = fffffffffffffffffffffffffffffffffffff800000000000000000000000000 +CIPHERTEXT = ca352df025c65c7b0bf306fbee0f36ba +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 149 +KEY = fffffffffffffffffffffffffffffffffffffc00000000000000000000000000 +CIPHERTEXT = 238aca23fd3409f38af63378ed2f5473 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 150 +KEY = fffffffffffffffffffffffffffffffffffffe00000000000000000000000000 +CIPHERTEXT = 59836a0e06a79691b36667d5380d8188 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 151 +KEY = ffffffffffffffffffffffffffffffffffffff00000000000000000000000000 +CIPHERTEXT = 33905080f7acf1cdae0a91fc3e85aee4 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 152 +KEY = ffffffffffffffffffffffffffffffffffffff80000000000000000000000000 +CIPHERTEXT = 72c9e4646dbc3d6320fc6689d93e8833 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 153 +KEY = ffffffffffffffffffffffffffffffffffffffc0000000000000000000000000 +CIPHERTEXT = ba77413dea5925b7f5417ea47ff19f59 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 154 +KEY = ffffffffffffffffffffffffffffffffffffffe0000000000000000000000000 +CIPHERTEXT = 6cae8129f843d86dc786a0fb1a184970 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 155 +KEY = fffffffffffffffffffffffffffffffffffffff0000000000000000000000000 +CIPHERTEXT = fcfefb534100796eebbd990206754e19 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 156 +KEY = fffffffffffffffffffffffffffffffffffffff8000000000000000000000000 +CIPHERTEXT = 8c791d5fdddf470da04f3e6dc4a5b5b5 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 157 +KEY = fffffffffffffffffffffffffffffffffffffffc000000000000000000000000 +CIPHERTEXT = c93bbdc07a4611ae4bb266ea5034a387 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 158 +KEY = fffffffffffffffffffffffffffffffffffffffe000000000000000000000000 +CIPHERTEXT = c102e38e489aa74762f3efc5bb23205a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 159 +KEY = ffffffffffffffffffffffffffffffffffffffff000000000000000000000000 +CIPHERTEXT = 93201481665cbafc1fcc220bc545fb3d +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 160 +KEY = ffffffffffffffffffffffffffffffffffffffff800000000000000000000000 +CIPHERTEXT = 4960757ec6ce68cf195e454cfd0f32ca +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 161 +KEY = ffffffffffffffffffffffffffffffffffffffffc00000000000000000000000 +CIPHERTEXT = feec7ce6a6cbd07c043416737f1bbb33 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 162 +KEY = ffffffffffffffffffffffffffffffffffffffffe00000000000000000000000 +CIPHERTEXT = 11c5413904487a805d70a8edd9c35527 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 163 +KEY = fffffffffffffffffffffffffffffffffffffffff00000000000000000000000 +CIPHERTEXT = 347846b2b2e36f1f0324c86f7f1b98e2 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 164 +KEY = fffffffffffffffffffffffffffffffffffffffff80000000000000000000000 +CIPHERTEXT = 332eee1a0cbd19ca2d69b426894044f0 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 165 +KEY = fffffffffffffffffffffffffffffffffffffffffc0000000000000000000000 +CIPHERTEXT = 866b5b3977ba6efa5128efbda9ff03cd +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 166 +KEY = fffffffffffffffffffffffffffffffffffffffffe0000000000000000000000 +CIPHERTEXT = cc1445ee94c0f08cdee5c344ecd1e233 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 167 +KEY = ffffffffffffffffffffffffffffffffffffffffff0000000000000000000000 +CIPHERTEXT = be288319029363c2622feba4b05dfdfe +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 168 +KEY = ffffffffffffffffffffffffffffffffffffffffff8000000000000000000000 +CIPHERTEXT = cfd1875523f3cd21c395651e6ee15e56 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 169 +KEY = ffffffffffffffffffffffffffffffffffffffffffc000000000000000000000 +CIPHERTEXT = cb5a408657837c53bf16f9d8465dce19 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 170 +KEY = ffffffffffffffffffffffffffffffffffffffffffe000000000000000000000 +CIPHERTEXT = ca0bf42cb107f55ccff2fc09ee08ca15 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 171 +KEY = fffffffffffffffffffffffffffffffffffffffffff000000000000000000000 +CIPHERTEXT = fdd9bbb4a7dc2e4a23536a5880a2db67 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 172 +KEY = fffffffffffffffffffffffffffffffffffffffffff800000000000000000000 +CIPHERTEXT = ede447b362c484993dec9442a3b46aef +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 173 +KEY = fffffffffffffffffffffffffffffffffffffffffffc00000000000000000000 +CIPHERTEXT = 10dffb05904bff7c4781df780ad26837 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 174 +KEY = fffffffffffffffffffffffffffffffffffffffffffe00000000000000000000 +CIPHERTEXT = c33bc13e8de88ac25232aa7496398783 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 175 +KEY = ffffffffffffffffffffffffffffffffffffffffffff00000000000000000000 +CIPHERTEXT = ca359c70803a3b2a3d542e8781dea975 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 176 +KEY = ffffffffffffffffffffffffffffffffffffffffffff80000000000000000000 +CIPHERTEXT = bcc65b526f88d05b89ce8a52021fdb06 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 177 +KEY = ffffffffffffffffffffffffffffffffffffffffffffc0000000000000000000 +CIPHERTEXT = db91a38855c8c4643851fbfb358b0109 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 178 +KEY = ffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000 +CIPHERTEXT = ca6e8893a114ae8e27d5ab03a5499610 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 179 +KEY = fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000 +CIPHERTEXT = 6629d2b8df97da728cdd8b1e7f945077 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 180 +KEY = fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000 +CIPHERTEXT = 4570a5a18cfc0dd582f1d88d5c9a1720 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 181 +KEY = fffffffffffffffffffffffffffffffffffffffffffffc000000000000000000 +CIPHERTEXT = 72bc65aa8e89562e3f274d45af1cd10b +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 182 +KEY = fffffffffffffffffffffffffffffffffffffffffffffe000000000000000000 +CIPHERTEXT = 98551da1a6503276ae1c77625f9ea615 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 183 +KEY = ffffffffffffffffffffffffffffffffffffffffffffff000000000000000000 +CIPHERTEXT = 0ddfe51ced7e3f4ae927daa3fe452cee +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 184 +KEY = ffffffffffffffffffffffffffffffffffffffffffffff800000000000000000 +CIPHERTEXT = db826251e4ce384b80218b0e1da1dd4c +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 185 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffc00000000000000000 +CIPHERTEXT = 2cacf728b88abbad7011ed0e64a1680c +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 186 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffe00000000000000000 +CIPHERTEXT = 330d8ee7c5677e099ac74c9994ee4cfb +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 187 +KEY = fffffffffffffffffffffffffffffffffffffffffffffff00000000000000000 +CIPHERTEXT = edf61ae362e882ddc0167474a7a77f3a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 188 +KEY = fffffffffffffffffffffffffffffffffffffffffffffff80000000000000000 +CIPHERTEXT = 6168b00ba7859e0970ecfd757efecf7c +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 189 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffc0000000000000000 +CIPHERTEXT = d1415447866230d28bb1ea18a4cdfd02 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 190 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000 +CIPHERTEXT = 516183392f7a8763afec68a060264141 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 191 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 +CIPHERTEXT = 77565c8d73cfd4130b4aa14d8911710f +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 192 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000 +CIPHERTEXT = 37232a4ed21ccc27c19c9610078cabac +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 193 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffc000000000000000 +CIPHERTEXT = 804f32ea71828c7d329077e712231666 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 194 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000 +CIPHERTEXT = d64424f23cb97215e9c2c6f28d29eab7 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 195 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000 +CIPHERTEXT = 023e82b533f68c75c238cebdb2ee89a2 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 196 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffff800000000000000 +CIPHERTEXT = 193a3d24157a51f1ee0893f6777417e7 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 197 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffc00000000000000 +CIPHERTEXT = 84ecacfcd400084d078612b1945f2ef5 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 198 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffe00000000000000 +CIPHERTEXT = 1dcd8bb173259eb33a5242b0de31a455 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 199 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000 +CIPHERTEXT = 35e9eddbc375e792c19992c19165012b +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 200 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000 +CIPHERTEXT = 8a772231c01dfdd7c98e4cfddcc0807a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 201 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffc0000000000000 +CIPHERTEXT = 6eda7ff6b8319180ff0d6e65629d01c3 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 202 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000 +CIPHERTEXT = c267ef0e2d01a993944dd397101413cb +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 203 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000 +CIPHERTEXT = e9f80e9d845bcc0f62926af72eabca39 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 204 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffff8000000000000 +CIPHERTEXT = 6702990727aa0878637b45dcd3a3b074 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 205 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffc000000000000 +CIPHERTEXT = 2e2e647d5360e09230a5d738ca33471e +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 206 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000 +CIPHERTEXT = 1f56413c7add6f43d1d56e4f02190330 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 207 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 +CIPHERTEXT = 69cd0606e15af729d6bca143016d9842 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 208 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffff800000000000 +CIPHERTEXT = a085d7c1a500873a20099c4caa3c3f5b +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 209 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffc00000000000 +CIPHERTEXT = 4fc0d230f8891415b87b83f95f2e09d1 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 210 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000000 +CIPHERTEXT = 4327d08c523d8eba697a4336507d1f42 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 211 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000 +CIPHERTEXT = 7a15aab82701efa5ae36ab1d6b76290f +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 212 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000 +CIPHERTEXT = 5bf0051893a18bb30e139a58fed0fa54 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 213 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffc0000000000 +CIPHERTEXT = 97e8adf65638fd9cdf3bc22c17fe4dbd +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 214 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000 +CIPHERTEXT = 1ee6ee326583a0586491c96418d1a35d +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 215 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000 +CIPHERTEXT = 26b549c2ec756f82ecc48008e529956b +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 216 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000000 +CIPHERTEXT = 70377b6da669b072129e057cc28e9ca5 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 217 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffc000000000 +CIPHERTEXT = 9c94b8b0cb8bcc919072262b3fa05ad9 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 218 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000 +CIPHERTEXT = 2fbb83dfd0d7abcb05cd28cad2dfb523 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 219 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000 +CIPHERTEXT = 96877803de77744bb970d0a91f4debae +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 220 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffff800000000 +CIPHERTEXT = 7379f3370cf6e5ce12ae5969c8eea312 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 221 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffc00000000 +CIPHERTEXT = 02dc99fa3d4f98ce80985e7233889313 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 222 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000 +CIPHERTEXT = 1e38e759075ba5cab6457da51844295a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 223 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000 +CIPHERTEXT = 70bed8dbf615868a1f9d9b05d3e7a267 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 224 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 +CIPHERTEXT = 234b148b8cb1d8c32b287e896903d150 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 225 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0000000 +CIPHERTEXT = 294b033df4da853f4be3e243f7e513f4 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 226 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000 +CIPHERTEXT = 3f58c950f0367160adec45f2441e7411 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 227 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000 +CIPHERTEXT = 37f655536a704e5ace182d742a820cf4 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 228 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000 +CIPHERTEXT = ea7bd6bb63418731aeac790fe42d61e8 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 229 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffc000000 +CIPHERTEXT = e74a4c999b4c064e48bb1e413f51e5ea +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 230 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000 +CIPHERTEXT = ba9ebefdb4ccf30f296cecb3bc1943e8 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 231 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 +CIPHERTEXT = 3194367a4898c502c13bb7478640a72d +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 232 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000 +CIPHERTEXT = da797713263d6f33a5478a65ef60d412 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 233 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00000 +CIPHERTEXT = d1ac39bb1ef86b9c1344f214679aa376 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 234 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000 +CIPHERTEXT = 2fdea9e650532be5bc0e7325337fd363 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 235 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000 +CIPHERTEXT = d3a204dbd9c2af158b6ca67a5156ce4a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 236 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000 +CIPHERTEXT = 3a0a0e75a8da36735aee6684d965a778 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 237 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0000 +CIPHERTEXT = 52fc3e620492ea99641ea168da5b6d52 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 238 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000 +CIPHERTEXT = d2e0c7f15b4772467d2cfc873000b2ca +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 239 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 +CIPHERTEXT = 563531135e0c4d70a38f8bdb190ba04e +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 240 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 +CIPHERTEXT = a8a39a0f5663f4c0fe5f2d3cafff421a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 241 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc000 +CIPHERTEXT = d94b5e90db354c1e42f61fabe167b2c0 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 242 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000 +CIPHERTEXT = 50e6d3c9b6698a7cd276f96b1473f35a +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 243 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000 +CIPHERTEXT = 9338f08e0ebee96905d8f2e825208f43 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 244 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800 +CIPHERTEXT = 8b378c86672aa54a3a266ba19d2580ca +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 245 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00 +CIPHERTEXT = cca7c3086f5f9511b31233da7cab9160 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 246 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00 +CIPHERTEXT = 5b40ff4ec9be536ba23035fa4f06064c +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 247 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00 +CIPHERTEXT = 60eb5af8416b257149372194e8b88749 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 248 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80 +CIPHERTEXT = 2f005a8aed8a361c92e440c15520cbd1 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 249 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0 +CIPHERTEXT = 7b03627611678a997717578807a800e2 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 250 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0 +CIPHERTEXT = cf78618f74f6f3696e0a4779b90b5a77 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 251 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0 +CIPHERTEXT = 03720371a04962eaea0a852e69972858 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 252 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8 +CIPHERTEXT = 1f8a8133aa8ccf70e2bd3285831ca6b7 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 253 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc +CIPHERTEXT = 27936bd27fb1468fc8b48bc483321725 +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 254 +KEY = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +CIPHERTEXT = b07d4f3e2cd2ef2eb545980754dfea0f +PLAINTEXT = 00000000000000000000000000000000 + +COUNT = 255 +KEY = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +CIPHERTEXT = 4bf85f1b5d54adbc307b0a048389adcb +PLAINTEXT = 00000000000000000000000000000000 + diff --git a/libraries/crypto/tests/data/ECBVarTxt256.rsp b/libraries/crypto/tests/data/ECBVarTxt256.rsp new file mode 100644 index 0000000..6833f60 --- /dev/null +++ b/libraries/crypto/tests/data/ECBVarTxt256.rsp @@ -0,0 +1,1291 @@ +# CAVS 11.1 +# Config info for aes_values +# AESVS VarTxt test data for ECB +# State : Encrypt and Decrypt +# Key Length : 256 +# Generated on Fri Apr 22 15:11:30 2011 + +[ENCRYPT] + +COUNT = 0 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = 80000000000000000000000000000000 +CIPHERTEXT = ddc6bf790c15760d8d9aeb6f9a75fd4e + +COUNT = 1 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = c0000000000000000000000000000000 +CIPHERTEXT = 0a6bdc6d4c1e6280301fd8e97ddbe601 + +COUNT = 2 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = e0000000000000000000000000000000 +CIPHERTEXT = 9b80eefb7ebe2d2b16247aa0efc72f5d + +COUNT = 3 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = f0000000000000000000000000000000 +CIPHERTEXT = 7f2c5ece07a98d8bee13c51177395ff7 + +COUNT = 4 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = f8000000000000000000000000000000 +CIPHERTEXT = 7818d800dcf6f4be1e0e94f403d1e4c2 + +COUNT = 5 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fc000000000000000000000000000000 +CIPHERTEXT = e74cd1c92f0919c35a0324123d6177d3 + +COUNT = 6 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fe000000000000000000000000000000 +CIPHERTEXT = 8092a4dcf2da7e77e93bdd371dfed82e + +COUNT = 7 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ff000000000000000000000000000000 +CIPHERTEXT = 49af6b372135acef10132e548f217b17 + +COUNT = 8 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ff800000000000000000000000000000 +CIPHERTEXT = 8bcd40f94ebb63b9f7909676e667f1e7 + +COUNT = 9 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffc00000000000000000000000000000 +CIPHERTEXT = fe1cffb83f45dcfb38b29be438dbd3ab + +COUNT = 10 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffe00000000000000000000000000000 +CIPHERTEXT = 0dc58a8d886623705aec15cb1e70dc0e + +COUNT = 11 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fff00000000000000000000000000000 +CIPHERTEXT = c218faa16056bd0774c3e8d79c35a5e4 + +COUNT = 12 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fff80000000000000000000000000000 +CIPHERTEXT = 047bba83f7aa841731504e012208fc9e + +COUNT = 13 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffc0000000000000000000000000000 +CIPHERTEXT = dc8f0e4915fd81ba70a331310882f6da + +COUNT = 14 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffe0000000000000000000000000000 +CIPHERTEXT = 1569859ea6b7206c30bf4fd0cbfac33c + +COUNT = 15 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffff0000000000000000000000000000 +CIPHERTEXT = 300ade92f88f48fa2df730ec16ef44cd + +COUNT = 16 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffff8000000000000000000000000000 +CIPHERTEXT = 1fe6cc3c05965dc08eb0590c95ac71d0 + +COUNT = 17 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffc000000000000000000000000000 +CIPHERTEXT = 59e858eaaa97fec38111275b6cf5abc0 + +COUNT = 18 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffe000000000000000000000000000 +CIPHERTEXT = 2239455e7afe3b0616100288cc5a723b + +COUNT = 19 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffff000000000000000000000000000 +CIPHERTEXT = 3ee500c5c8d63479717163e55c5c4522 + +COUNT = 20 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffff800000000000000000000000000 +CIPHERTEXT = d5e38bf15f16d90e3e214041d774daa8 + +COUNT = 21 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffc00000000000000000000000000 +CIPHERTEXT = b1f4066e6f4f187dfe5f2ad1b17819d0 + +COUNT = 22 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffe00000000000000000000000000 +CIPHERTEXT = 6ef4cc4de49b11065d7af2909854794a + +COUNT = 23 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffff00000000000000000000000000 +CIPHERTEXT = ac86bc606b6640c309e782f232bf367f + +COUNT = 24 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffff80000000000000000000000000 +CIPHERTEXT = 36aff0ef7bf3280772cf4cac80a0d2b2 + +COUNT = 25 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffc0000000000000000000000000 +CIPHERTEXT = 1f8eedea0f62a1406d58cfc3ecea72cf + +COUNT = 26 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffe0000000000000000000000000 +CIPHERTEXT = abf4154a3375a1d3e6b1d454438f95a6 + +COUNT = 27 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffff0000000000000000000000000 +CIPHERTEXT = 96f96e9d607f6615fc192061ee648b07 + +COUNT = 28 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffff8000000000000000000000000 +CIPHERTEXT = cf37cdaaa0d2d536c71857634c792064 + +COUNT = 29 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffc000000000000000000000000 +CIPHERTEXT = fbd6640c80245c2b805373f130703127 + +COUNT = 30 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffe000000000000000000000000 +CIPHERTEXT = 8d6a8afe55a6e481badae0d146f436db + +COUNT = 31 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffff000000000000000000000000 +CIPHERTEXT = 6a4981f2915e3e68af6c22385dd06756 + +COUNT = 32 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffff800000000000000000000000 +CIPHERTEXT = 42a1136e5f8d8d21d3101998642d573b + +COUNT = 33 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffc00000000000000000000000 +CIPHERTEXT = 9b471596dc69ae1586cee6158b0b0181 + +COUNT = 34 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffe00000000000000000000000 +CIPHERTEXT = 753665c4af1eff33aa8b628bf8741cfd + +COUNT = 35 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffff00000000000000000000000 +CIPHERTEXT = 9a682acf40be01f5b2a4193c9a82404d + +COUNT = 36 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffff80000000000000000000000 +CIPHERTEXT = 54fafe26e4287f17d1935f87eb9ade01 + +COUNT = 37 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffc0000000000000000000000 +CIPHERTEXT = 49d541b2e74cfe73e6a8e8225f7bd449 + +COUNT = 38 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffe0000000000000000000000 +CIPHERTEXT = 11a45530f624ff6f76a1b3826626ff7b + +COUNT = 39 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffff0000000000000000000000 +CIPHERTEXT = f96b0c4a8bc6c86130289f60b43b8fba + +COUNT = 40 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffff8000000000000000000000 +CIPHERTEXT = 48c7d0e80834ebdc35b6735f76b46c8b + +COUNT = 41 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffc000000000000000000000 +CIPHERTEXT = 2463531ab54d66955e73edc4cb8eaa45 + +COUNT = 42 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffe000000000000000000000 +CIPHERTEXT = ac9bd8e2530469134b9d5b065d4f565b + +COUNT = 43 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffff000000000000000000000 +CIPHERTEXT = 3f5f9106d0e52f973d4890e6f37e8a00 + +COUNT = 44 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffff800000000000000000000 +CIPHERTEXT = 20ebc86f1304d272e2e207e59db639f0 + +COUNT = 45 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffc00000000000000000000 +CIPHERTEXT = e67ae6426bf9526c972cff072b52252c + +COUNT = 46 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffe00000000000000000000 +CIPHERTEXT = 1a518dddaf9efa0d002cc58d107edfc8 + +COUNT = 47 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffff00000000000000000000 +CIPHERTEXT = ead731af4d3a2fe3b34bed047942a49f + +COUNT = 48 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffff80000000000000000000 +CIPHERTEXT = b1d4efe40242f83e93b6c8d7efb5eae9 + +COUNT = 49 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffc0000000000000000000 +CIPHERTEXT = cd2b1fec11fd906c5c7630099443610a + +COUNT = 50 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffe0000000000000000000 +CIPHERTEXT = a1853fe47fe29289d153161d06387d21 + +COUNT = 51 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffff0000000000000000000 +CIPHERTEXT = 4632154179a555c17ea604d0889fab14 + +COUNT = 52 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffff8000000000000000000 +CIPHERTEXT = dd27cac6401a022e8f38f9f93e774417 + +COUNT = 53 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffc000000000000000000 +CIPHERTEXT = c090313eb98674f35f3123385fb95d4d + +COUNT = 54 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffe000000000000000000 +CIPHERTEXT = cc3526262b92f02edce548f716b9f45c + +COUNT = 55 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffff000000000000000000 +CIPHERTEXT = c0838d1a2b16a7c7f0dfcc433c399c33 + +COUNT = 56 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffff800000000000000000 +CIPHERTEXT = 0d9ac756eb297695eed4d382eb126d26 + +COUNT = 57 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffc00000000000000000 +CIPHERTEXT = 56ede9dda3f6f141bff1757fa689c3e1 + +COUNT = 58 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffe00000000000000000 +CIPHERTEXT = 768f520efe0f23e61d3ec8ad9ce91774 + +COUNT = 59 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffff00000000000000000 +CIPHERTEXT = b1144ddfa75755213390e7c596660490 + +COUNT = 60 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffff80000000000000000 +CIPHERTEXT = 1d7c0c4040b355b9d107a99325e3b050 + +COUNT = 61 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffc0000000000000000 +CIPHERTEXT = d8e2bb1ae8ee3dcf5bf7d6c38da82a1a + +COUNT = 62 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffe0000000000000000 +CIPHERTEXT = faf82d178af25a9886a47e7f789b98d7 + +COUNT = 63 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffff0000000000000000 +CIPHERTEXT = 9b58dbfd77fe5aca9cfc190cd1b82d19 + +COUNT = 64 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffff8000000000000000 +CIPHERTEXT = 77f392089042e478ac16c0c86a0b5db5 + +COUNT = 65 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffc000000000000000 +CIPHERTEXT = 19f08e3420ee69b477ca1420281c4782 + +COUNT = 66 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffe000000000000000 +CIPHERTEXT = a1b19beee4e117139f74b3c53fdcb875 + +COUNT = 67 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffff000000000000000 +CIPHERTEXT = a37a5869b218a9f3a0868d19aea0ad6a + +COUNT = 68 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffff800000000000000 +CIPHERTEXT = bc3594e865bcd0261b13202731f33580 + +COUNT = 69 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffc00000000000000 +CIPHERTEXT = 811441ce1d309eee7185e8c752c07557 + +COUNT = 70 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffe00000000000000 +CIPHERTEXT = 959971ce4134190563518e700b9874d1 + +COUNT = 71 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffff00000000000000 +CIPHERTEXT = 76b5614a042707c98e2132e2e805fe63 + +COUNT = 72 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffff80000000000000 +CIPHERTEXT = 7d9fa6a57530d0f036fec31c230b0cc6 + +COUNT = 73 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffc0000000000000 +CIPHERTEXT = 964153a83bf6989a4ba80daa91c3e081 + +COUNT = 74 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffe0000000000000 +CIPHERTEXT = a013014d4ce8054cf2591d06f6f2f176 + +COUNT = 75 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffff0000000000000 +CIPHERTEXT = d1c5f6399bf382502e385eee1474a869 + +COUNT = 76 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffff8000000000000 +CIPHERTEXT = 0007e20b8298ec354f0f5fe7470f36bd + +COUNT = 77 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffc000000000000 +CIPHERTEXT = b95ba05b332da61ef63a2b31fcad9879 + +COUNT = 78 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffe000000000000 +CIPHERTEXT = 4620a49bd967491561669ab25dce45f4 + +COUNT = 79 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffff000000000000 +CIPHERTEXT = 12e71214ae8e04f0bb63d7425c6f14d5 + +COUNT = 80 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffff800000000000 +CIPHERTEXT = 4cc42fc1407b008fe350907c092e80ac + +COUNT = 81 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffc00000000000 +CIPHERTEXT = 08b244ce7cbc8ee97fbba808cb146fda + +COUNT = 82 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffe00000000000 +CIPHERTEXT = 39b333e8694f21546ad1edd9d87ed95b + +COUNT = 83 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffff00000000000 +CIPHERTEXT = 3b271f8ab2e6e4a20ba8090f43ba78f3 + +COUNT = 84 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffff80000000000 +CIPHERTEXT = 9ad983f3bf651cd0393f0a73cccdea50 + +COUNT = 85 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffc0000000000 +CIPHERTEXT = 8f476cbff75c1f725ce18e4bbcd19b32 + +COUNT = 86 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffe0000000000 +CIPHERTEXT = 905b6267f1d6ab5320835a133f096f2a + +COUNT = 87 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffff0000000000 +CIPHERTEXT = 145b60d6d0193c23f4221848a892d61a + +COUNT = 88 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffff8000000000 +CIPHERTEXT = 55cfb3fb6d75cad0445bbc8dafa25b0f + +COUNT = 89 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffc000000000 +CIPHERTEXT = 7b8e7098e357ef71237d46d8b075b0f5 + +COUNT = 90 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffe000000000 +CIPHERTEXT = 2bf27229901eb40f2df9d8398d1505ae + +COUNT = 91 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffff000000000 +CIPHERTEXT = 83a63402a77f9ad5c1e931a931ecd706 + +COUNT = 92 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffff800000000 +CIPHERTEXT = 6f8ba6521152d31f2bada1843e26b973 + +COUNT = 93 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffc00000000 +CIPHERTEXT = e5c3b8e30fd2d8e6239b17b44bd23bbd + +COUNT = 94 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffe00000000 +CIPHERTEXT = 1ac1f7102c59933e8b2ddc3f14e94baa + +COUNT = 95 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffff00000000 +CIPHERTEXT = 21d9ba49f276b45f11af8fc71a088e3d + +COUNT = 96 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffff80000000 +CIPHERTEXT = 649f1cddc3792b4638635a392bc9bade + +COUNT = 97 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffc0000000 +CIPHERTEXT = e2775e4b59c1bc2e31a2078c11b5a08c + +COUNT = 98 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffe0000000 +CIPHERTEXT = 2be1fae5048a25582a679ca10905eb80 + +COUNT = 99 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffff0000000 +CIPHERTEXT = da86f292c6f41ea34fb2068df75ecc29 + +COUNT = 100 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffff8000000 +CIPHERTEXT = 220df19f85d69b1b562fa69a3c5beca5 + +COUNT = 101 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffffc000000 +CIPHERTEXT = 1f11d5d0355e0b556ccdb6c7f5083b4d + +COUNT = 102 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffffe000000 +CIPHERTEXT = 62526b78be79cb384633c91f83b4151b + +COUNT = 103 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffff000000 +CIPHERTEXT = 90ddbcb950843592dd47bbef00fdc876 + +COUNT = 104 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffff800000 +CIPHERTEXT = 2fd0e41c5b8402277354a7391d2618e2 + +COUNT = 105 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffffc00000 +CIPHERTEXT = 3cdf13e72dee4c581bafec70b85f9660 + +COUNT = 106 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffffe00000 +CIPHERTEXT = afa2ffc137577092e2b654fa199d2c43 + +COUNT = 107 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffffff00000 +CIPHERTEXT = 8d683ee63e60d208e343ce48dbc44cac + +COUNT = 108 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffffff80000 +CIPHERTEXT = 705a4ef8ba2133729c20185c3d3a4763 + +COUNT = 109 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffffffc0000 +CIPHERTEXT = 0861a861c3db4e94194211b77ed761b9 + +COUNT = 110 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffffffe0000 +CIPHERTEXT = 4b00c27e8b26da7eab9d3a88dec8b031 + +COUNT = 111 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffffff0000 +CIPHERTEXT = 5f397bf03084820cc8810d52e5b666e9 + +COUNT = 112 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffffff8000 +CIPHERTEXT = 63fafabb72c07bfbd3ddc9b1203104b8 + +COUNT = 113 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffffffc000 +CIPHERTEXT = 683e2140585b18452dd4ffbb93c95df9 + +COUNT = 114 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffffffe000 +CIPHERTEXT = 286894e48e537f8763b56707d7d155c8 + +COUNT = 115 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffffffff000 +CIPHERTEXT = a423deabc173dcf7e2c4c53e77d37cd1 + +COUNT = 116 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffffffff800 +CIPHERTEXT = eb8168313e1cfdfdb5e986d5429cf172 + +COUNT = 117 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffffffffc00 +CIPHERTEXT = 27127daafc9accd2fb334ec3eba52323 + +COUNT = 118 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffffffffe00 +CIPHERTEXT = ee0715b96f72e3f7a22a5064fc592f4c + +COUNT = 119 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffffffff00 +CIPHERTEXT = 29ee526770f2a11dcfa989d1ce88830f + +COUNT = 120 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffffffff80 +CIPHERTEXT = 0493370e054b09871130fe49af730a5a + +COUNT = 121 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffffffffc0 +CIPHERTEXT = 9b7b940f6c509f9e44a4ee140448ee46 + +COUNT = 122 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffffffffe0 +CIPHERTEXT = 2915be4a1ecfdcbe3e023811a12bb6c7 + +COUNT = 123 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffffffffff0 +CIPHERTEXT = 7240e524bc51d8c4d440b1be55d1062c + +COUNT = 124 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffffffffff8 +CIPHERTEXT = da63039d38cb4612b2dc36ba26684b93 + +COUNT = 125 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffffffffffc +CIPHERTEXT = 0f59cb5a4b522e2ac56c1a64f558ad9a + +COUNT = 126 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = fffffffffffffffffffffffffffffffe +CIPHERTEXT = 7bfe9d876c6d63c1d035da8fe21c409d + +COUNT = 127 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +PLAINTEXT = ffffffffffffffffffffffffffffffff +CIPHERTEXT = acdace8078a32b1a182bfa4987ca1347 + +[DECRYPT] + +COUNT = 0 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = ddc6bf790c15760d8d9aeb6f9a75fd4e +PLAINTEXT = 80000000000000000000000000000000 + +COUNT = 1 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 0a6bdc6d4c1e6280301fd8e97ddbe601 +PLAINTEXT = c0000000000000000000000000000000 + +COUNT = 2 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 9b80eefb7ebe2d2b16247aa0efc72f5d +PLAINTEXT = e0000000000000000000000000000000 + +COUNT = 3 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 7f2c5ece07a98d8bee13c51177395ff7 +PLAINTEXT = f0000000000000000000000000000000 + +COUNT = 4 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 7818d800dcf6f4be1e0e94f403d1e4c2 +PLAINTEXT = f8000000000000000000000000000000 + +COUNT = 5 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = e74cd1c92f0919c35a0324123d6177d3 +PLAINTEXT = fc000000000000000000000000000000 + +COUNT = 6 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 8092a4dcf2da7e77e93bdd371dfed82e +PLAINTEXT = fe000000000000000000000000000000 + +COUNT = 7 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 49af6b372135acef10132e548f217b17 +PLAINTEXT = ff000000000000000000000000000000 + +COUNT = 8 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 8bcd40f94ebb63b9f7909676e667f1e7 +PLAINTEXT = ff800000000000000000000000000000 + +COUNT = 9 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = fe1cffb83f45dcfb38b29be438dbd3ab +PLAINTEXT = ffc00000000000000000000000000000 + +COUNT = 10 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 0dc58a8d886623705aec15cb1e70dc0e +PLAINTEXT = ffe00000000000000000000000000000 + +COUNT = 11 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = c218faa16056bd0774c3e8d79c35a5e4 +PLAINTEXT = fff00000000000000000000000000000 + +COUNT = 12 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 047bba83f7aa841731504e012208fc9e +PLAINTEXT = fff80000000000000000000000000000 + +COUNT = 13 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = dc8f0e4915fd81ba70a331310882f6da +PLAINTEXT = fffc0000000000000000000000000000 + +COUNT = 14 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 1569859ea6b7206c30bf4fd0cbfac33c +PLAINTEXT = fffe0000000000000000000000000000 + +COUNT = 15 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 300ade92f88f48fa2df730ec16ef44cd +PLAINTEXT = ffff0000000000000000000000000000 + +COUNT = 16 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 1fe6cc3c05965dc08eb0590c95ac71d0 +PLAINTEXT = ffff8000000000000000000000000000 + +COUNT = 17 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 59e858eaaa97fec38111275b6cf5abc0 +PLAINTEXT = ffffc000000000000000000000000000 + +COUNT = 18 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 2239455e7afe3b0616100288cc5a723b +PLAINTEXT = ffffe000000000000000000000000000 + +COUNT = 19 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 3ee500c5c8d63479717163e55c5c4522 +PLAINTEXT = fffff000000000000000000000000000 + +COUNT = 20 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = d5e38bf15f16d90e3e214041d774daa8 +PLAINTEXT = fffff800000000000000000000000000 + +COUNT = 21 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = b1f4066e6f4f187dfe5f2ad1b17819d0 +PLAINTEXT = fffffc00000000000000000000000000 + +COUNT = 22 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 6ef4cc4de49b11065d7af2909854794a +PLAINTEXT = fffffe00000000000000000000000000 + +COUNT = 23 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = ac86bc606b6640c309e782f232bf367f +PLAINTEXT = ffffff00000000000000000000000000 + +COUNT = 24 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 36aff0ef7bf3280772cf4cac80a0d2b2 +PLAINTEXT = ffffff80000000000000000000000000 + +COUNT = 25 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 1f8eedea0f62a1406d58cfc3ecea72cf +PLAINTEXT = ffffffc0000000000000000000000000 + +COUNT = 26 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = abf4154a3375a1d3e6b1d454438f95a6 +PLAINTEXT = ffffffe0000000000000000000000000 + +COUNT = 27 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 96f96e9d607f6615fc192061ee648b07 +PLAINTEXT = fffffff0000000000000000000000000 + +COUNT = 28 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = cf37cdaaa0d2d536c71857634c792064 +PLAINTEXT = fffffff8000000000000000000000000 + +COUNT = 29 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = fbd6640c80245c2b805373f130703127 +PLAINTEXT = fffffffc000000000000000000000000 + +COUNT = 30 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 8d6a8afe55a6e481badae0d146f436db +PLAINTEXT = fffffffe000000000000000000000000 + +COUNT = 31 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 6a4981f2915e3e68af6c22385dd06756 +PLAINTEXT = ffffffff000000000000000000000000 + +COUNT = 32 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 42a1136e5f8d8d21d3101998642d573b +PLAINTEXT = ffffffff800000000000000000000000 + +COUNT = 33 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 9b471596dc69ae1586cee6158b0b0181 +PLAINTEXT = ffffffffc00000000000000000000000 + +COUNT = 34 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 753665c4af1eff33aa8b628bf8741cfd +PLAINTEXT = ffffffffe00000000000000000000000 + +COUNT = 35 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 9a682acf40be01f5b2a4193c9a82404d +PLAINTEXT = fffffffff00000000000000000000000 + +COUNT = 36 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 54fafe26e4287f17d1935f87eb9ade01 +PLAINTEXT = fffffffff80000000000000000000000 + +COUNT = 37 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 49d541b2e74cfe73e6a8e8225f7bd449 +PLAINTEXT = fffffffffc0000000000000000000000 + +COUNT = 38 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 11a45530f624ff6f76a1b3826626ff7b +PLAINTEXT = fffffffffe0000000000000000000000 + +COUNT = 39 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = f96b0c4a8bc6c86130289f60b43b8fba +PLAINTEXT = ffffffffff0000000000000000000000 + +COUNT = 40 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 48c7d0e80834ebdc35b6735f76b46c8b +PLAINTEXT = ffffffffff8000000000000000000000 + +COUNT = 41 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 2463531ab54d66955e73edc4cb8eaa45 +PLAINTEXT = ffffffffffc000000000000000000000 + +COUNT = 42 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = ac9bd8e2530469134b9d5b065d4f565b +PLAINTEXT = ffffffffffe000000000000000000000 + +COUNT = 43 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 3f5f9106d0e52f973d4890e6f37e8a00 +PLAINTEXT = fffffffffff000000000000000000000 + +COUNT = 44 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 20ebc86f1304d272e2e207e59db639f0 +PLAINTEXT = fffffffffff800000000000000000000 + +COUNT = 45 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = e67ae6426bf9526c972cff072b52252c +PLAINTEXT = fffffffffffc00000000000000000000 + +COUNT = 46 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 1a518dddaf9efa0d002cc58d107edfc8 +PLAINTEXT = fffffffffffe00000000000000000000 + +COUNT = 47 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = ead731af4d3a2fe3b34bed047942a49f +PLAINTEXT = ffffffffffff00000000000000000000 + +COUNT = 48 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = b1d4efe40242f83e93b6c8d7efb5eae9 +PLAINTEXT = ffffffffffff80000000000000000000 + +COUNT = 49 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = cd2b1fec11fd906c5c7630099443610a +PLAINTEXT = ffffffffffffc0000000000000000000 + +COUNT = 50 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = a1853fe47fe29289d153161d06387d21 +PLAINTEXT = ffffffffffffe0000000000000000000 + +COUNT = 51 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 4632154179a555c17ea604d0889fab14 +PLAINTEXT = fffffffffffff0000000000000000000 + +COUNT = 52 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = dd27cac6401a022e8f38f9f93e774417 +PLAINTEXT = fffffffffffff8000000000000000000 + +COUNT = 53 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = c090313eb98674f35f3123385fb95d4d +PLAINTEXT = fffffffffffffc000000000000000000 + +COUNT = 54 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = cc3526262b92f02edce548f716b9f45c +PLAINTEXT = fffffffffffffe000000000000000000 + +COUNT = 55 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = c0838d1a2b16a7c7f0dfcc433c399c33 +PLAINTEXT = ffffffffffffff000000000000000000 + +COUNT = 56 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 0d9ac756eb297695eed4d382eb126d26 +PLAINTEXT = ffffffffffffff800000000000000000 + +COUNT = 57 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 56ede9dda3f6f141bff1757fa689c3e1 +PLAINTEXT = ffffffffffffffc00000000000000000 + +COUNT = 58 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 768f520efe0f23e61d3ec8ad9ce91774 +PLAINTEXT = ffffffffffffffe00000000000000000 + +COUNT = 59 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = b1144ddfa75755213390e7c596660490 +PLAINTEXT = fffffffffffffff00000000000000000 + +COUNT = 60 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 1d7c0c4040b355b9d107a99325e3b050 +PLAINTEXT = fffffffffffffff80000000000000000 + +COUNT = 61 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = d8e2bb1ae8ee3dcf5bf7d6c38da82a1a +PLAINTEXT = fffffffffffffffc0000000000000000 + +COUNT = 62 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = faf82d178af25a9886a47e7f789b98d7 +PLAINTEXT = fffffffffffffffe0000000000000000 + +COUNT = 63 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 9b58dbfd77fe5aca9cfc190cd1b82d19 +PLAINTEXT = ffffffffffffffff0000000000000000 + +COUNT = 64 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 77f392089042e478ac16c0c86a0b5db5 +PLAINTEXT = ffffffffffffffff8000000000000000 + +COUNT = 65 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 19f08e3420ee69b477ca1420281c4782 +PLAINTEXT = ffffffffffffffffc000000000000000 + +COUNT = 66 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = a1b19beee4e117139f74b3c53fdcb875 +PLAINTEXT = ffffffffffffffffe000000000000000 + +COUNT = 67 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = a37a5869b218a9f3a0868d19aea0ad6a +PLAINTEXT = fffffffffffffffff000000000000000 + +COUNT = 68 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = bc3594e865bcd0261b13202731f33580 +PLAINTEXT = fffffffffffffffff800000000000000 + +COUNT = 69 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 811441ce1d309eee7185e8c752c07557 +PLAINTEXT = fffffffffffffffffc00000000000000 + +COUNT = 70 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 959971ce4134190563518e700b9874d1 +PLAINTEXT = fffffffffffffffffe00000000000000 + +COUNT = 71 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 76b5614a042707c98e2132e2e805fe63 +PLAINTEXT = ffffffffffffffffff00000000000000 + +COUNT = 72 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 7d9fa6a57530d0f036fec31c230b0cc6 +PLAINTEXT = ffffffffffffffffff80000000000000 + +COUNT = 73 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 964153a83bf6989a4ba80daa91c3e081 +PLAINTEXT = ffffffffffffffffffc0000000000000 + +COUNT = 74 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = a013014d4ce8054cf2591d06f6f2f176 +PLAINTEXT = ffffffffffffffffffe0000000000000 + +COUNT = 75 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = d1c5f6399bf382502e385eee1474a869 +PLAINTEXT = fffffffffffffffffff0000000000000 + +COUNT = 76 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 0007e20b8298ec354f0f5fe7470f36bd +PLAINTEXT = fffffffffffffffffff8000000000000 + +COUNT = 77 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = b95ba05b332da61ef63a2b31fcad9879 +PLAINTEXT = fffffffffffffffffffc000000000000 + +COUNT = 78 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 4620a49bd967491561669ab25dce45f4 +PLAINTEXT = fffffffffffffffffffe000000000000 + +COUNT = 79 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 12e71214ae8e04f0bb63d7425c6f14d5 +PLAINTEXT = ffffffffffffffffffff000000000000 + +COUNT = 80 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 4cc42fc1407b008fe350907c092e80ac +PLAINTEXT = ffffffffffffffffffff800000000000 + +COUNT = 81 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 08b244ce7cbc8ee97fbba808cb146fda +PLAINTEXT = ffffffffffffffffffffc00000000000 + +COUNT = 82 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 39b333e8694f21546ad1edd9d87ed95b +PLAINTEXT = ffffffffffffffffffffe00000000000 + +COUNT = 83 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 3b271f8ab2e6e4a20ba8090f43ba78f3 +PLAINTEXT = fffffffffffffffffffff00000000000 + +COUNT = 84 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 9ad983f3bf651cd0393f0a73cccdea50 +PLAINTEXT = fffffffffffffffffffff80000000000 + +COUNT = 85 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 8f476cbff75c1f725ce18e4bbcd19b32 +PLAINTEXT = fffffffffffffffffffffc0000000000 + +COUNT = 86 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 905b6267f1d6ab5320835a133f096f2a +PLAINTEXT = fffffffffffffffffffffe0000000000 + +COUNT = 87 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 145b60d6d0193c23f4221848a892d61a +PLAINTEXT = ffffffffffffffffffffff0000000000 + +COUNT = 88 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 55cfb3fb6d75cad0445bbc8dafa25b0f +PLAINTEXT = ffffffffffffffffffffff8000000000 + +COUNT = 89 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 7b8e7098e357ef71237d46d8b075b0f5 +PLAINTEXT = ffffffffffffffffffffffc000000000 + +COUNT = 90 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 2bf27229901eb40f2df9d8398d1505ae +PLAINTEXT = ffffffffffffffffffffffe000000000 + +COUNT = 91 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 83a63402a77f9ad5c1e931a931ecd706 +PLAINTEXT = fffffffffffffffffffffff000000000 + +COUNT = 92 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 6f8ba6521152d31f2bada1843e26b973 +PLAINTEXT = fffffffffffffffffffffff800000000 + +COUNT = 93 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = e5c3b8e30fd2d8e6239b17b44bd23bbd +PLAINTEXT = fffffffffffffffffffffffc00000000 + +COUNT = 94 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 1ac1f7102c59933e8b2ddc3f14e94baa +PLAINTEXT = fffffffffffffffffffffffe00000000 + +COUNT = 95 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 21d9ba49f276b45f11af8fc71a088e3d +PLAINTEXT = ffffffffffffffffffffffff00000000 + +COUNT = 96 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 649f1cddc3792b4638635a392bc9bade +PLAINTEXT = ffffffffffffffffffffffff80000000 + +COUNT = 97 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = e2775e4b59c1bc2e31a2078c11b5a08c +PLAINTEXT = ffffffffffffffffffffffffc0000000 + +COUNT = 98 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 2be1fae5048a25582a679ca10905eb80 +PLAINTEXT = ffffffffffffffffffffffffe0000000 + +COUNT = 99 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = da86f292c6f41ea34fb2068df75ecc29 +PLAINTEXT = fffffffffffffffffffffffff0000000 + +COUNT = 100 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 220df19f85d69b1b562fa69a3c5beca5 +PLAINTEXT = fffffffffffffffffffffffff8000000 + +COUNT = 101 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 1f11d5d0355e0b556ccdb6c7f5083b4d +PLAINTEXT = fffffffffffffffffffffffffc000000 + +COUNT = 102 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 62526b78be79cb384633c91f83b4151b +PLAINTEXT = fffffffffffffffffffffffffe000000 + +COUNT = 103 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 90ddbcb950843592dd47bbef00fdc876 +PLAINTEXT = ffffffffffffffffffffffffff000000 + +COUNT = 104 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 2fd0e41c5b8402277354a7391d2618e2 +PLAINTEXT = ffffffffffffffffffffffffff800000 + +COUNT = 105 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 3cdf13e72dee4c581bafec70b85f9660 +PLAINTEXT = ffffffffffffffffffffffffffc00000 + +COUNT = 106 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = afa2ffc137577092e2b654fa199d2c43 +PLAINTEXT = ffffffffffffffffffffffffffe00000 + +COUNT = 107 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 8d683ee63e60d208e343ce48dbc44cac +PLAINTEXT = fffffffffffffffffffffffffff00000 + +COUNT = 108 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 705a4ef8ba2133729c20185c3d3a4763 +PLAINTEXT = fffffffffffffffffffffffffff80000 + +COUNT = 109 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 0861a861c3db4e94194211b77ed761b9 +PLAINTEXT = fffffffffffffffffffffffffffc0000 + +COUNT = 110 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 4b00c27e8b26da7eab9d3a88dec8b031 +PLAINTEXT = fffffffffffffffffffffffffffe0000 + +COUNT = 111 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 5f397bf03084820cc8810d52e5b666e9 +PLAINTEXT = ffffffffffffffffffffffffffff0000 + +COUNT = 112 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 63fafabb72c07bfbd3ddc9b1203104b8 +PLAINTEXT = ffffffffffffffffffffffffffff8000 + +COUNT = 113 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 683e2140585b18452dd4ffbb93c95df9 +PLAINTEXT = ffffffffffffffffffffffffffffc000 + +COUNT = 114 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 286894e48e537f8763b56707d7d155c8 +PLAINTEXT = ffffffffffffffffffffffffffffe000 + +COUNT = 115 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = a423deabc173dcf7e2c4c53e77d37cd1 +PLAINTEXT = fffffffffffffffffffffffffffff000 + +COUNT = 116 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = eb8168313e1cfdfdb5e986d5429cf172 +PLAINTEXT = fffffffffffffffffffffffffffff800 + +COUNT = 117 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 27127daafc9accd2fb334ec3eba52323 +PLAINTEXT = fffffffffffffffffffffffffffffc00 + +COUNT = 118 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = ee0715b96f72e3f7a22a5064fc592f4c +PLAINTEXT = fffffffffffffffffffffffffffffe00 + +COUNT = 119 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 29ee526770f2a11dcfa989d1ce88830f +PLAINTEXT = ffffffffffffffffffffffffffffff00 + +COUNT = 120 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 0493370e054b09871130fe49af730a5a +PLAINTEXT = ffffffffffffffffffffffffffffff80 + +COUNT = 121 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 9b7b940f6c509f9e44a4ee140448ee46 +PLAINTEXT = ffffffffffffffffffffffffffffffc0 + +COUNT = 122 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 2915be4a1ecfdcbe3e023811a12bb6c7 +PLAINTEXT = ffffffffffffffffffffffffffffffe0 + +COUNT = 123 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 7240e524bc51d8c4d440b1be55d1062c +PLAINTEXT = fffffffffffffffffffffffffffffff0 + +COUNT = 124 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = da63039d38cb4612b2dc36ba26684b93 +PLAINTEXT = fffffffffffffffffffffffffffffff8 + +COUNT = 125 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 0f59cb5a4b522e2ac56c1a64f558ad9a +PLAINTEXT = fffffffffffffffffffffffffffffffc + +COUNT = 126 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = 7bfe9d876c6d63c1d035da8fe21c409d +PLAINTEXT = fffffffffffffffffffffffffffffffe + +COUNT = 127 +KEY = 0000000000000000000000000000000000000000000000000000000000000000 +CIPHERTEXT = acdace8078a32b1a182bfa4987ca1347 +PLAINTEXT = ffffffffffffffffffffffffffffffff + diff --git a/libraries/crypto/tests/data/ecdsa_secp256r1_sha256_test.json b/libraries/crypto/tests/data/ecdsa_secp256r1_sha256_test.json new file mode 100644 index 0000000..0b8ab9f --- /dev/null +++ b/libraries/crypto/tests/data/ecdsa_secp256r1_sha256_test.json @@ -0,0 +1,4578 @@ +{ + "algorithm" : "ECDSA", + "generatorVersion" : "0.8r12", + "numberOfTests" : 387, + "header" : [ + "Test vectors of type EcdsaVerify are meant for the verification", + "of ASN encoded ECDSA signatures." + ], + "notes" : { + "BER" : "This is a signature with correct values for (r, s) but using some alternative BER encoding instead of DER encoding. Implementations should not accept such signatures to limit signature malleability.", + "EdgeCase" : "Edge case values such as r=1 and s=0 can lead to forgeries if the ECDSA implementation does not check boundaries and computes s^(-1)==0.", + "MissingZero" : "Some implementations of ECDSA and DSA incorrectly encode r and s by not including leading zeros in the ASN encoding of integers when necessary. Hence, some implementations (e.g. jdk) allow signatures with incorrect ASN encodings assuming that the signature is otherwise valid.", + "PointDuplication" : "Some implementations of ECDSA do not handle duplication and points at infinity correctly. This is a test vector that has been specially crafted to check for such an omission." + }, + "schema" : "ecdsa_verify_schema.json", + "testGroups" : [ + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "wx" : "2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838", + "wy" : "00c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKSexBRK64+3c/kZ4KBKLrSkDJpkZ\n9whgacjE32xzKDjHeHlk6qwA5ZIfsUmKYPRgZ2az2WhQAVWNGpdOc0FRPg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 1, + "comment" : "signature malleability", + "msg" : "313233343030", + "sig" : "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802204cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 2, + "comment" : "Legacy:ASN encoding of s misses leading 0", + "msg" : "313233343030", + "sig" : "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180220b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "acceptable", + "flags" : [ + "MissingZero" + ] + }, + { + "tcId" : 3, + "comment" : "valid", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 4, + "comment" : "long form encoding of length of sequence", + "msg" : "313233343030", + "sig" : "30814502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [ + "BER" + ] + }, + { + "tcId" : 5, + "comment" : "length of sequence contains leading 0", + "msg" : "313233343030", + "sig" : "3082004502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [ + "BER" + ] + }, + { + "tcId" : 6, + "comment" : "wrong length of sequence", + "msg" : "313233343030", + "sig" : "304602202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 7, + "comment" : "wrong length of sequence", + "msg" : "313233343030", + "sig" : "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 8, + "comment" : "uint32 overflow in length of sequence", + "msg" : "313233343030", + "sig" : "3085010000004502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 9, + "comment" : "uint64 overflow in length of sequence", + "msg" : "313233343030", + "sig" : "308901000000000000004502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 10, + "comment" : "length of sequence = 2**31 - 1", + "msg" : "313233343030", + "sig" : "30847fffffff02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 11, + "comment" : "length of sequence = 2**32 - 1", + "msg" : "313233343030", + "sig" : "3084ffffffff02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 12, + "comment" : "length of sequence = 2**40 - 1", + "msg" : "313233343030", + "sig" : "3085ffffffffff02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 13, + "comment" : "length of sequence = 2**64 - 1", + "msg" : "313233343030", + "sig" : "3088ffffffffffffffff02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 14, + "comment" : "incorrect length of sequence", + "msg" : "313233343030", + "sig" : "30ff02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 15, + "comment" : "indefinite length without termination", + "msg" : "313233343030", + "sig" : "308002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 16, + "comment" : "indefinite length without termination", + "msg" : "313233343030", + "sig" : "304502802ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 17, + "comment" : "indefinite length without termination", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18028000b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 18, + "comment" : "removing sequence", + "msg" : "313233343030", + "sig" : "", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 19, + "comment" : "lonely sequence tag", + "msg" : "313233343030", + "sig" : "30", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 20, + "comment" : "appending 0's to sequence", + "msg" : "313233343030", + "sig" : "304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 21, + "comment" : "prepending 0's to sequence", + "msg" : "313233343030", + "sig" : "3047000002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 22, + "comment" : "appending unused 0's to sequence", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 23, + "comment" : "appending null value to sequence", + "msg" : "313233343030", + "sig" : "304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0500", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 24, + "comment" : "including garbage", + "msg" : "313233343030", + "sig" : "304a498177304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 25, + "comment" : "including garbage", + "msg" : "313233343030", + "sig" : "30492500304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 26, + "comment" : "including garbage", + "msg" : "313233343030", + "sig" : "3047304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0004deadbeef", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 27, + "comment" : "including garbage", + "msg" : "313233343030", + "sig" : "304a222549817702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 28, + "comment" : "including garbage", + "msg" : "313233343030", + "sig" : "30492224250002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 29, + "comment" : "including garbage", + "msg" : "313233343030", + "sig" : "304d222202202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180004deadbeef022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 30, + "comment" : "including garbage", + "msg" : "313233343030", + "sig" : "304a02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e182226498177022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 31, + "comment" : "including garbage", + "msg" : "313233343030", + "sig" : "304902202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1822252500022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 32, + "comment" : "including garbage", + "msg" : "313233343030", + "sig" : "304d02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e182223022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0004deadbeef", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 33, + "comment" : "including undefined tags", + "msg" : "313233343030", + "sig" : "304daa00bb00cd00304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 34, + "comment" : "including undefined tags", + "msg" : "313233343030", + "sig" : "304baa02aabb304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 35, + "comment" : "including undefined tags", + "msg" : "313233343030", + "sig" : "304d2228aa00bb00cd0002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 36, + "comment" : "including undefined tags", + "msg" : "313233343030", + "sig" : "304b2226aa02aabb02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 37, + "comment" : "including undefined tags", + "msg" : "313233343030", + "sig" : "304d02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e182229aa00bb00cd00022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 38, + "comment" : "including undefined tags", + "msg" : "313233343030", + "sig" : "304b02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e182227aa02aabb022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 39, + "comment" : "truncated length of sequence", + "msg" : "313233343030", + "sig" : "3081", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 40, + "comment" : "using composition with indefinite length", + "msg" : "313233343030", + "sig" : "3080304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 41, + "comment" : "using composition with indefinite length", + "msg" : "313233343030", + "sig" : "3049228002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180000022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 42, + "comment" : "using composition with indefinite length", + "msg" : "313233343030", + "sig" : "304902202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e182280022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 43, + "comment" : "using composition with wrong tag", + "msg" : "313233343030", + "sig" : "3080314502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 44, + "comment" : "using composition with wrong tag", + "msg" : "313233343030", + "sig" : "3049228003202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180000022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 45, + "comment" : "using composition with wrong tag", + "msg" : "313233343030", + "sig" : "304902202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e182280032100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 46, + "comment" : "Replacing sequence with NULL", + "msg" : "313233343030", + "sig" : "0500", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 47, + "comment" : "changing tag value of sequence", + "msg" : "313233343030", + "sig" : "2e4502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 48, + "comment" : "changing tag value of sequence", + "msg" : "313233343030", + "sig" : "2f4502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 49, + "comment" : "changing tag value of sequence", + "msg" : "313233343030", + "sig" : "314502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 50, + "comment" : "changing tag value of sequence", + "msg" : "313233343030", + "sig" : "324502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 51, + "comment" : "changing tag value of sequence", + "msg" : "313233343030", + "sig" : "ff4502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 52, + "comment" : "dropping value of sequence", + "msg" : "313233343030", + "sig" : "3000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 53, + "comment" : "using composition for sequence", + "msg" : "313233343030", + "sig" : "30493001023044202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 54, + "comment" : "truncated sequence", + "msg" : "313233343030", + "sig" : "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 55, + "comment" : "truncated sequence", + "msg" : "313233343030", + "sig" : "3044202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 56, + "comment" : "indefinite length", + "msg" : "313233343030", + "sig" : "308002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000", + "result" : "invalid", + "flags" : [ + "BER" + ] + }, + { + "tcId" : 57, + "comment" : "indefinite length with truncated delimiter", + "msg" : "313233343030", + "sig" : "308002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db00", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 58, + "comment" : "indefinite length with additional element", + "msg" : "313233343030", + "sig" : "308002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db05000000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 59, + "comment" : "indefinite length with truncated element", + "msg" : "313233343030", + "sig" : "308002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db060811220000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 60, + "comment" : "indefinite length with garbage", + "msg" : "313233343030", + "sig" : "308002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000fe02beef", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 61, + "comment" : "indefinite length with nonempty EOC", + "msg" : "313233343030", + "sig" : "308002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0002beef", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 62, + "comment" : "prepend empty sequence", + "msg" : "313233343030", + "sig" : "3047300002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 63, + "comment" : "append empty sequence", + "msg" : "313233343030", + "sig" : "304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db3000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 64, + "comment" : "append garbage with high tag number", + "msg" : "313233343030", + "sig" : "304802202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847dbbf7f00", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 65, + "comment" : "sequence of sequence", + "msg" : "313233343030", + "sig" : "3047304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 66, + "comment" : "truncated sequence: removed last 1 elements", + "msg" : "313233343030", + "sig" : "302202202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 67, + "comment" : "repeating element in sequence", + "msg" : "313233343030", + "sig" : "306802202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 68, + "comment" : "long form encoding of length of integer", + "msg" : "313233343030", + "sig" : "30460281202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [ + "BER" + ] + }, + { + "tcId" : 69, + "comment" : "long form encoding of length of integer", + "msg" : "313233343030", + "sig" : "304602202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802812100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [ + "BER" + ] + }, + { + "tcId" : 70, + "comment" : "length of integer contains leading 0", + "msg" : "313233343030", + "sig" : "3047028200202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [ + "BER" + ] + }, + { + "tcId" : 71, + "comment" : "length of integer contains leading 0", + "msg" : "313233343030", + "sig" : "304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180282002100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [ + "BER" + ] + }, + { + "tcId" : 72, + "comment" : "wrong length of integer", + "msg" : "313233343030", + "sig" : "304502212ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 73, + "comment" : "wrong length of integer", + "msg" : "313233343030", + "sig" : "3045021f2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 74, + "comment" : "wrong length of integer", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022200b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 75, + "comment" : "wrong length of integer", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022000b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 76, + "comment" : "uint32 overflow in length of integer", + "msg" : "313233343030", + "sig" : "304a028501000000202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 77, + "comment" : "uint32 overflow in length of integer", + "msg" : "313233343030", + "sig" : "304a02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180285010000002100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 78, + "comment" : "uint64 overflow in length of integer", + "msg" : "313233343030", + "sig" : "304e02890100000000000000202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 79, + "comment" : "uint64 overflow in length of integer", + "msg" : "313233343030", + "sig" : "304e02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18028901000000000000002100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 80, + "comment" : "length of integer = 2**31 - 1", + "msg" : "313233343030", + "sig" : "304902847fffffff2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 81, + "comment" : "length of integer = 2**31 - 1", + "msg" : "313233343030", + "sig" : "304902202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802847fffffff00b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 82, + "comment" : "length of integer = 2**32 - 1", + "msg" : "313233343030", + "sig" : "30490284ffffffff2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 83, + "comment" : "length of integer = 2**32 - 1", + "msg" : "313233343030", + "sig" : "304902202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180284ffffffff00b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 84, + "comment" : "length of integer = 2**40 - 1", + "msg" : "313233343030", + "sig" : "304a0285ffffffffff2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 85, + "comment" : "length of integer = 2**40 - 1", + "msg" : "313233343030", + "sig" : "304a02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180285ffffffffff00b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 86, + "comment" : "length of integer = 2**64 - 1", + "msg" : "313233343030", + "sig" : "304d0288ffffffffffffffff2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 87, + "comment" : "length of integer = 2**64 - 1", + "msg" : "313233343030", + "sig" : "304d02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180288ffffffffffffffff00b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 88, + "comment" : "incorrect length of integer", + "msg" : "313233343030", + "sig" : "304502ff2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 89, + "comment" : "incorrect length of integer", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802ff00b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 90, + "comment" : "removing integer", + "msg" : "313233343030", + "sig" : "3023022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 91, + "comment" : "lonely integer tag", + "msg" : "313233343030", + "sig" : "302402022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 92, + "comment" : "lonely integer tag", + "msg" : "313233343030", + "sig" : "302302202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 93, + "comment" : "appending 0's to integer", + "msg" : "313233343030", + "sig" : "304702222ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180000022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 94, + "comment" : "appending 0's to integer", + "msg" : "313233343030", + "sig" : "304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022300b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 95, + "comment" : "prepending 0's to integer", + "msg" : "313233343030", + "sig" : "3047022200002ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [ + "BER" + ] + }, + { + "tcId" : 96, + "comment" : "prepending 0's to integer", + "msg" : "313233343030", + "sig" : "304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180223000000b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [ + "BER" + ] + }, + { + "tcId" : 97, + "comment" : "appending unused 0's to integer", + "msg" : "313233343030", + "sig" : "304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180000022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 98, + "comment" : "appending null value to integer", + "msg" : "313233343030", + "sig" : "304702222ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180500022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 99, + "comment" : "appending null value to integer", + "msg" : "313233343030", + "sig" : "304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022300b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0500", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 100, + "comment" : "truncated length of integer", + "msg" : "313233343030", + "sig" : "30250281022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 101, + "comment" : "truncated length of integer", + "msg" : "313233343030", + "sig" : "302402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180281", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 102, + "comment" : "Replacing integer with NULL", + "msg" : "313233343030", + "sig" : "30250500022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 103, + "comment" : "Replacing integer with NULL", + "msg" : "313233343030", + "sig" : "302402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180500", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 104, + "comment" : "changing tag value of integer", + "msg" : "313233343030", + "sig" : "304500202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 105, + "comment" : "changing tag value of integer", + "msg" : "313233343030", + "sig" : "304501202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 106, + "comment" : "changing tag value of integer", + "msg" : "313233343030", + "sig" : "304503202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 107, + "comment" : "changing tag value of integer", + "msg" : "313233343030", + "sig" : "304504202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 108, + "comment" : "changing tag value of integer", + "msg" : "313233343030", + "sig" : "3045ff202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 109, + "comment" : "changing tag value of integer", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18002100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 110, + "comment" : "changing tag value of integer", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18012100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 111, + "comment" : "changing tag value of integer", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18032100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 112, + "comment" : "changing tag value of integer", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18042100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 113, + "comment" : "changing tag value of integer", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18ff2100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 114, + "comment" : "dropping value of integer", + "msg" : "313233343030", + "sig" : "30250200022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 115, + "comment" : "dropping value of integer", + "msg" : "313233343030", + "sig" : "302402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180200", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 116, + "comment" : "using composition for integer", + "msg" : "313233343030", + "sig" : "3049222402012b021fa3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 117, + "comment" : "using composition for integer", + "msg" : "313233343030", + "sig" : "304902202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1822250201000220b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 118, + "comment" : "modify first byte of integer", + "msg" : "313233343030", + "sig" : "3045022029a3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 119, + "comment" : "modify first byte of integer", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022102b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 120, + "comment" : "modify last byte of integer", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e98022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 121, + "comment" : "modify last byte of integer", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b491568475b", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 122, + "comment" : "truncated integer", + "msg" : "313233343030", + "sig" : "3044021f2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 123, + "comment" : "truncated integer", + "msg" : "313233343030", + "sig" : "3044021fa3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 124, + "comment" : "truncated integer", + "msg" : "313233343030", + "sig" : "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022000b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 125, + "comment" : "leading ff in integer", + "msg" : "313233343030", + "sig" : "30460221ff2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 126, + "comment" : "leading ff in integer", + "msg" : "313233343030", + "sig" : "304602202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180222ff00b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 127, + "comment" : "replaced integer by infinity", + "msg" : "313233343030", + "sig" : "3026090180022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 128, + "comment" : "replaced integer by infinity", + "msg" : "313233343030", + "sig" : "302502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18090180", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 129, + "comment" : "replacing integer with zero", + "msg" : "313233343030", + "sig" : "3026020100022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 130, + "comment" : "replacing integer with zero", + "msg" : "313233343030", + "sig" : "302502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18020100", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 131, + "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", + "msg" : "313233343030", + "sig" : "30460221012ba3a8bd6b94d5ed80a6d9d1190a436ebccc0833490686deac8635bcb9bf5369022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 132, + "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", + "msg" : "313233343030", + "sig" : "30460221ff2ba3a8bf6b94d5eb80a6d9d1190a436f42fe12d7fad749d4c512a036c0f908c7022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 133, + "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", + "msg" : "313233343030", + "sig" : "30450220d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 134, + "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", + "msg" : "313233343030", + "sig" : "3046022100d45c5740946b2a147f59262ee6f5bc90bd01ed280528b62b3aed5fc93f06f739022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 135, + "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", + "msg" : "313233343030", + "sig" : "30460221fed45c5742946b2a127f59262ee6f5bc914333f7ccb6f979215379ca434640ac97022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 136, + "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", + "msg" : "313233343030", + "sig" : "30460221012ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 137, + "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", + "msg" : "313233343030", + "sig" : "3046022100d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 138, + "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022101b329f478a2bbd0a6c384ee1493b1f518276e0e4a5375928d6fcd160c11cb6d2c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 139, + "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", + "msg" : "313233343030", + "sig" : "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180220b329f47aa2bbd0a4c384ee1493b1f518ada018ef05465583885980861905228a", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 140, + "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180221ff4cd60b865d442f5a3c7b11eb6c4e0ae79578ec6353a20bf783ecb4b6ea97b825", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 141, + "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180221fe4cd60b875d442f593c7b11eb6c4e0ae7d891f1b5ac8a6d729032e9f3ee3492d4", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 142, + "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", + "msg" : "313233343030", + "sig" : "304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022101b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 143, + "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", + "msg" : "313233343030", + "sig" : "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802204cd60b865d442f5a3c7b11eb6c4e0ae79578ec6353a20bf783ecb4b6ea97b825", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 144, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3006020100020100", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 145, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3006020100020101", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 146, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "30060201000201ff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 147, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026020100022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 148, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026020100022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 149, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026020100022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 150, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026020100022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 151, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026020100022100ffffffff00000001000000000000000000000001000000000000000000000000", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 152, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3008020100090380fe01", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 153, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3006020100090142", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 154, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3006020101020100", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 155, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3006020101020101", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 156, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "30060201010201ff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 157, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026020101022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 158, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026020101022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 159, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026020101022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 160, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026020101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 161, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026020101022100ffffffff00000001000000000000000000000001000000000000000000000000", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 162, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3008020101090380fe01", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 163, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3006020101090142", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 164, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "30060201ff020100", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 165, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "30060201ff020101", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 166, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "30060201ff0201ff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 167, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "30260201ff022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 168, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "30260201ff022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 169, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "30260201ff022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 170, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "30260201ff022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 171, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "30260201ff022100ffffffff00000001000000000000000000000001000000000000000000000000", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 172, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "30080201ff090380fe01", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 173, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "30060201ff090142", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 174, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020100", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 175, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020101", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 176, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325510201ff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 177, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 178, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 179, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 180, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 181, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551022100ffffffff00000001000000000000000000000001000000000000000000000000", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 182, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3028022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551090380fe01", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 183, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551090142", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 184, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550020100", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 185, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550020101", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 186, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325500201ff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 187, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 188, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 189, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 190, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 191, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550022100ffffffff00000001000000000000000000000001000000000000000000000000", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 192, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3028022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550090380fe01", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 193, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550090142", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 194, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552020100", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 195, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552020101", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 196, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325520201ff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 197, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 198, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 199, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 200, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 201, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552022100ffffffff00000001000000000000000000000001000000000000000000000000", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 202, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3028022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552090380fe01", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 203, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552090142", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 204, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff020100", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 205, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff020101", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 206, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff0201ff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 207, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 208, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 209, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 210, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 211, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff022100ffffffff00000001000000000000000000000001000000000000000000000000", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 212, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3028022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff090380fe01", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 213, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff090142", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 214, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000001000000000000000000000001000000000000000000000000020100", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 215, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000001000000000000000000000001000000000000000000000000020101", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 216, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff000000010000000000000000000000010000000000000000000000000201ff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 217, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000001000000000000000000000001000000000000000000000000022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 218, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000001000000000000000000000001000000000000000000000000022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 219, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000001000000000000000000000001000000000000000000000000022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 220, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000001000000000000000000000001000000000000000000000000022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 221, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000001000000000000000000000001000000000000000000000000022100ffffffff00000001000000000000000000000001000000000000000000000000", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 222, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3028022100ffffffff00000001000000000000000000000001000000000000000000000000090380fe01", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 223, + "comment" : "Signature with special case values for r and s", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000001000000000000000000000001000000000000000000000000090142", + "result" : "invalid", + "flags" : [ + "EdgeCase" + ] + }, + { + "tcId" : 224, + "comment" : "Signature encoding contains wrong types.", + "msg" : "313233343030", + "sig" : "30060201010c0130", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 225, + "comment" : "Signature encoding contains wrong types.", + "msg" : "313233343030", + "sig" : "30050201010c00", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 226, + "comment" : "Signature encoding contains wrong types.", + "msg" : "313233343030", + "sig" : "30090c0225730c03732573", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 227, + "comment" : "Signature encoding contains wrong types.", + "msg" : "313233343030", + "sig" : "30080201013003020100", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 228, + "comment" : "Signature encoding contains wrong types.", + "msg" : "313233343030", + "sig" : "3003020101", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 229, + "comment" : "Signature encoding contains wrong types.", + "msg" : "313233343030", + "sig" : "3006020101010100", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 230, + "comment" : "Edge case for Shamir multiplication", + "msg" : "3639383139", + "sig" : "3044022064a1aab5000d0e804f3e2fc02bdee9be8ff312334e2ba16d11547c97711c898e02206af015971cc30be6d1a206d4e013e0997772a2f91d73286ffd683b9bb2cf4f1b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 231, + "comment" : "special case hash", + "msg" : "343236343739373234", + "sig" : "3044022016aea964a2f6506d6f78c81c91fc7e8bded7d397738448de1e19a0ec580bf2660220252cd762130c6667cfe8b7bc47d27d78391e8e80c578d1cd38c3ff033be928e9", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 232, + "comment" : "special case hash", + "msg" : "37313338363834383931", + "sig" : "30450221009cc98be2347d469bf476dfc26b9b733df2d26d6ef524af917c665baccb23c8820220093496459effe2d8d70727b82462f61d0ec1b7847929d10ea631dacb16b56c32", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 233, + "comment" : "special case hash", + "msg" : "3130333539333331363638", + "sig" : "3044022073b3c90ecd390028058164524dde892703dce3dea0d53fa8093999f07ab8aa4302202f67b0b8e20636695bb7d8bf0a651c802ed25a395387b5f4188c0c4075c88634", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 234, + "comment" : "special case hash", + "msg" : "33393439343031323135", + "sig" : "3046022100bfab3098252847b328fadf2f89b95c851a7f0eb390763378f37e90119d5ba3dd022100bdd64e234e832b1067c2d058ccb44d978195ccebb65c2aaf1e2da9b8b4987e3b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 235, + "comment" : "special case hash", + "msg" : "31333434323933303739", + "sig" : "30440220204a9784074b246d8bf8bf04a4ceb1c1f1c9aaab168b1596d17093c5cd21d2cd022051cce41670636783dc06a759c8847868a406c2506fe17975582fe648d1d88b52", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 236, + "comment" : "special case hash", + "msg" : "33373036323131373132", + "sig" : "3046022100ed66dc34f551ac82f63d4aa4f81fe2cb0031a91d1314f835027bca0f1ceeaa0302210099ca123aa09b13cd194a422e18d5fda167623c3f6e5d4d6abb8953d67c0c48c7", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 237, + "comment" : "special case hash", + "msg" : "333433363838373132", + "sig" : "30450220060b700bef665c68899d44f2356a578d126b062023ccc3c056bf0f60a237012b0221008d186c027832965f4fcc78a3366ca95dedbb410cbef3f26d6be5d581c11d3610", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 238, + "comment" : "special case hash", + "msg" : "31333531353330333730", + "sig" : "30460221009f6adfe8d5eb5b2c24d7aa7934b6cf29c93ea76cd313c9132bb0c8e38c96831d022100b26a9c9e40e55ee0890c944cf271756c906a33e66b5bd15e051593883b5e9902", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 239, + "comment" : "special case hash", + "msg" : "36353533323033313236", + "sig" : "3045022100a1af03ca91677b673ad2f33615e56174a1abf6da168cebfa8868f4ba273f16b7022020aa73ffe48afa6435cd258b173d0c2377d69022e7d098d75caf24c8c5e06b1c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 240, + "comment" : "special case hash", + "msg" : "31353634333436363033", + "sig" : "3045022100fdc70602766f8eed11a6c99a71c973d5659355507b843da6e327a28c11893db902203df5349688a085b137b1eacf456a9e9e0f6d15ec0078ca60a7f83f2b10d21350", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 241, + "comment" : "special case hash", + "msg" : "34343239353339313137", + "sig" : "3046022100b516a314f2fce530d6537f6a6c49966c23456f63c643cf8e0dc738f7b876e675022100d39ffd033c92b6d717dd536fbc5efdf1967c4bd80954479ba66b0120cd16fff2", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 242, + "comment" : "special case hash", + "msg" : "3130393533323631333531", + "sig" : "304402203b2cbf046eac45842ecb7984d475831582717bebb6492fd0a485c101e29ff0a802204c9b7b47a98b0f82de512bc9313aaf51701099cac5f76e68c8595fc1c1d99258", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 243, + "comment" : "special case hash", + "msg" : "35393837333530303431", + "sig" : "3044022030c87d35e636f540841f14af54e2f9edd79d0312cfa1ab656c3fb15bfde48dcf022047c15a5a82d24b75c85a692bd6ecafeb71409ede23efd08e0db9abf6340677ed", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 244, + "comment" : "special case hash", + "msg" : "33343633303036383738", + "sig" : "3044022038686ff0fda2cef6bc43b58cfe6647b9e2e8176d168dec3c68ff262113760f520220067ec3b651f422669601662167fa8717e976e2db5e6a4cf7c2ddabb3fde9d67d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 245, + "comment" : "special case hash", + "msg" : "39383137333230323837", + "sig" : "3044022044a3e23bf314f2b344fc25c7f2de8b6af3e17d27f5ee844b225985ab6e2775cf02202d48e223205e98041ddc87be532abed584f0411f5729500493c9cc3f4dd15e86", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 246, + "comment" : "special case hash", + "msg" : "33323232303431303436", + "sig" : "304402202ded5b7ec8e90e7bf11f967a3d95110c41b99db3b5aa8d330eb9d638781688e902207d5792c53628155e1bfc46fb1a67e3088de049c328ae1f44ec69238a009808f9", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 247, + "comment" : "special case hash", + "msg" : "36363636333037313034", + "sig" : "3046022100bdae7bcb580bf335efd3bc3d31870f923eaccafcd40ec2f605976f15137d8b8f022100f6dfa12f19e525270b0106eecfe257499f373a4fb318994f24838122ce7ec3c7", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 248, + "comment" : "special case hash", + "msg" : "31303335393531383938", + "sig" : "3045022050f9c4f0cd6940e162720957ffff513799209b78596956d21ece251c2401f1c6022100d7033a0a787d338e889defaaabb106b95a4355e411a59c32aa5167dfab244726", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 249, + "comment" : "special case hash", + "msg" : "31383436353937313935", + "sig" : "3045022100f612820687604fa01906066a378d67540982e29575d019aabe90924ead5c860d02203f9367702dd7dd4f75ea98afd20e328a1a99f4857b316525328230ce294b0fef", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 250, + "comment" : "special case hash", + "msg" : "33313336303436313839", + "sig" : "30460221009505e407657d6e8bc93db5da7aa6f5081f61980c1949f56b0f2f507da5782a7a022100c60d31904e3669738ffbeccab6c3656c08e0ed5cb92b3cfa5e7f71784f9c5021", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 251, + "comment" : "special case hash", + "msg" : "32363633373834323534", + "sig" : "3046022100bbd16fbbb656b6d0d83e6a7787cd691b08735aed371732723e1c68a40404517d0221009d8e35dba96028b7787d91315be675877d2d097be5e8ee34560e3e7fd25c0f00", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 252, + "comment" : "special case hash", + "msg" : "31363532313030353234", + "sig" : "304402202ec9760122db98fd06ea76848d35a6da442d2ceef7559a30cf57c61e92df327e02207ab271da90859479701fccf86e462ee3393fb6814c27b760c4963625c0a19878", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 253, + "comment" : "special case hash", + "msg" : "35373438303831363936", + "sig" : "3044022054e76b7683b6650baa6a7fc49b1c51eed9ba9dd463221f7a4f1005a89fe00c5902202ea076886c773eb937ec1cc8374b7915cfd11b1c1ae1166152f2f7806a31c8fd", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 254, + "comment" : "special case hash", + "msg" : "36333433393133343638", + "sig" : "304402205291deaf24659ffbbce6e3c26f6021097a74abdbb69be4fb10419c0c496c9466022065d6fcf336d27cc7cdb982bb4e4ecef5827f84742f29f10abf83469270a03dc3", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 255, + "comment" : "special case hash", + "msg" : "31353431313033353938", + "sig" : "30450220207a3241812d75d947419dc58efb05e8003b33fc17eb50f9d15166a88479f107022100cdee749f2e492b213ce80b32d0574f62f1c5d70793cf55e382d5caadf7592767", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 256, + "comment" : "special case hash", + "msg" : "3130343738353830313238", + "sig" : "304502206554e49f82a855204328ac94913bf01bbe84437a355a0a37c0dee3cf81aa7728022100aea00de2507ddaf5c94e1e126980d3df16250a2eaebc8be486effe7f22b4f929", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 257, + "comment" : "special case hash", + "msg" : "3130353336323835353638", + "sig" : "3046022100a54c5062648339d2bff06f71c88216c26c6e19b4d80a8c602990ac82707efdfc022100e99bbe7fcfafae3e69fd016777517aa01056317f467ad09aff09be73c9731b0d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 258, + "comment" : "special case hash", + "msg" : "393533393034313035", + "sig" : "3045022100975bd7157a8d363b309f1f444012b1a1d23096593133e71b4ca8b059cff37eaf02207faa7a28b1c822baa241793f2abc930bd4c69840fe090f2aacc46786bf919622", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 259, + "comment" : "special case hash", + "msg" : "393738383438303339", + "sig" : "304402205694a6f84b8f875c276afd2ebcfe4d61de9ec90305afb1357b95b3e0da43885e02200dffad9ffd0b757d8051dec02ebdf70d8ee2dc5c7870c0823b6ccc7c679cbaa4", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 260, + "comment" : "special case hash", + "msg" : "33363130363732343432", + "sig" : "3045022100a0c30e8026fdb2b4b4968a27d16a6d08f7098f1a98d21620d7454ba9790f1ba602205e470453a8a399f15baf463f9deceb53acc5ca64459149688bd2760c65424339", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 261, + "comment" : "special case hash", + "msg" : "31303534323430373035", + "sig" : "30440220614ea84acf736527dd73602cd4bb4eea1dfebebd5ad8aca52aa0228cf7b99a880220737cc85f5f2d2f60d1b8183f3ed490e4de14368e96a9482c2a4dd193195c902f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 262, + "comment" : "special case hash", + "msg" : "35313734343438313937", + "sig" : "3045022100bead6734ebe44b810d3fb2ea00b1732945377338febfd439a8d74dfbd0f942fa02206bb18eae36616a7d3cad35919fd21a8af4bbe7a10f73b3e036a46b103ef56e2a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 263, + "comment" : "special case hash", + "msg" : "31393637353631323531", + "sig" : "30440220499625479e161dacd4db9d9ce64854c98d922cbf212703e9654fae182df9bad2022042c177cf37b8193a0131108d97819edd9439936028864ac195b64fca76d9d693", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 264, + "comment" : "special case hash", + "msg" : "33343437323533333433", + "sig" : "3045022008f16b8093a8fb4d66a2c8065b541b3d31e3bfe694f6b89c50fb1aaa6ff6c9b20221009d6455e2d5d1779748573b611cb95d4a21f967410399b39b535ba3e5af81ca2e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 265, + "comment" : "special case hash", + "msg" : "333638323634333138", + "sig" : "3046022100be26231b6191658a19dd72ddb99ed8f8c579b6938d19bce8eed8dc2b338cb5f8022100e1d9a32ee56cffed37f0f22b2dcb57d5c943c14f79694a03b9c5e96952575c89", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 266, + "comment" : "special case hash", + "msg" : "33323631313938363038", + "sig" : "3045022015e76880898316b16204ac920a02d58045f36a229d4aa4f812638c455abe0443022100e74d357d3fcb5c8c5337bd6aba4178b455ca10e226e13f9638196506a1939123", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 267, + "comment" : "special case hash", + "msg" : "39363738373831303934", + "sig" : "30440220352ecb53f8df2c503a45f9846fc28d1d31e6307d3ddbffc1132315cc07f16dad02201348dfa9c482c558e1d05c5242ca1c39436726ecd28258b1899792887dd0a3c6", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 268, + "comment" : "special case hash", + "msg" : "34393538383233383233", + "sig" : "304402204a40801a7e606ba78a0da9882ab23c7677b8642349ed3d652c5bfa5f2a9558fb02203a49b64848d682ef7f605f2832f7384bdc24ed2925825bf8ea77dc5981725782", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 269, + "comment" : "special case hash", + "msg" : "383234363337383337", + "sig" : "3045022100eacc5e1a8304a74d2be412b078924b3bb3511bac855c05c9e5e9e44df3d61e9602207451cd8e18d6ed1885dd827714847f96ec4bb0ed4c36ce9808db8f714204f6d1", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 270, + "comment" : "special case hash", + "msg" : "3131303230383333373736", + "sig" : "304502202f7a5e9e5771d424f30f67fdab61e8ce4f8cd1214882adb65f7de94c31577052022100ac4e69808345809b44acb0b2bd889175fb75dd050c5a449ab9528f8f78daa10c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 271, + "comment" : "special case hash", + "msg" : "313333383731363438", + "sig" : "3045022100ffcda40f792ce4d93e7e0f0e95e1a2147dddd7f6487621c30a03d710b3300219022079938b55f8a17f7ed7ba9ade8f2065a1fa77618f0b67add8d58c422c2453a49a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 272, + "comment" : "special case hash", + "msg" : "333232313434313632", + "sig" : "304602210081f2359c4faba6b53d3e8c8c3fcc16a948350f7ab3a588b28c17603a431e39a8022100cd6f6a5cc3b55ead0ff695d06c6860b509e46d99fccefb9f7f9e101857f74300", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 273, + "comment" : "special case hash", + "msg" : "3130363836363535353436", + "sig" : "3045022100dfc8bf520445cbb8ee1596fb073ea283ea130251a6fdffa5c3f5f2aaf75ca8080220048e33efce147c9dd92823640e338e68bfd7d0dc7a4905b3a7ac711e577e90e7", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 274, + "comment" : "special case hash", + "msg" : "3632313535323436", + "sig" : "3046022100ad019f74c6941d20efda70b46c53db166503a0e393e932f688227688ba6a576202210093320eb7ca0710255346bdbb3102cdcf7964ef2e0988e712bc05efe16c199345", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 275, + "comment" : "special case hash", + "msg" : "37303330383138373734", + "sig" : "3046022100ac8096842e8add68c34e78ce11dd71e4b54316bd3ebf7fffdeb7bd5a3ebc1883022100f5ca2f4f23d674502d4caf85d187215d36e3ce9f0ce219709f21a3aac003b7a8", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 276, + "comment" : "special case hash", + "msg" : "35393234353233373434", + "sig" : "30440220677b2d3a59b18a5ff939b70ea002250889ddcd7b7b9d776854b4943693fb92f702206b4ba856ade7677bf30307b21f3ccda35d2f63aee81efd0bab6972cc0795db55", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 277, + "comment" : "special case hash", + "msg" : "31343935353836363231", + "sig" : "30450220479e1ded14bcaed0379ba8e1b73d3115d84d31d4b7c30e1f05e1fc0d5957cfb0022100918f79e35b3d89487cf634a4f05b2e0c30857ca879f97c771e877027355b2443", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 278, + "comment" : "special case hash", + "msg" : "34303035333134343036", + "sig" : "3044022043dfccd0edb9e280d9a58f01164d55c3d711e14b12ac5cf3b64840ead512a0a302201dbe33fa8ba84533cd5c4934365b3442ca1174899b78ef9a3199f49584389772", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 279, + "comment" : "special case hash", + "msg" : "33303936343537353132", + "sig" : "304402205b09ab637bd4caf0f4c7c7e4bca592fea20e9087c259d26a38bb4085f0bbff11022045b7eb467b6748af618e9d80d6fdcd6aa24964e5a13f885bca8101de08eb0d75", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 280, + "comment" : "special case hash", + "msg" : "32373834303235363230", + "sig" : "304502205e9b1c5a028070df5728c5c8af9b74e0667afa570a6cfa0114a5039ed15ee06f022100b1360907e2d9785ead362bb8d7bd661b6c29eeffd3c5037744edaeb9ad990c20", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 281, + "comment" : "special case hash", + "msg" : "32363138373837343138", + "sig" : "304502200671a0a85c2b72d54a2fb0990e34538b4890050f5a5712f6d1a7a5fb8578f32e022100db1846bab6b7361479ab9c3285ca41291808f27fd5bd4fdac720e5854713694c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 282, + "comment" : "special case hash", + "msg" : "31363432363235323632", + "sig" : "304402207673f8526748446477dbbb0590a45492c5d7d69859d301abbaedb35b2095103a02203dc70ddf9c6b524d886bed9e6af02e0e4dec0d417a414fed3807ef4422913d7c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 283, + "comment" : "special case hash", + "msg" : "36383234313839343336", + "sig" : "304402207f085441070ecd2bb21285089ebb1aa6450d1a06c36d3ff39dfd657a796d12b50220249712012029870a2459d18d47da9aa492a5e6cb4b2d8dafa9e4c5c54a2b9a8b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 284, + "comment" : "special case hash", + "msg" : "343834323435343235", + "sig" : "3046022100914c67fb61dd1e27c867398ea7322d5ab76df04bc5aa6683a8e0f30a5d287348022100fa07474031481dda4953e3ac1959ee8cea7e66ec412b38d6c96d28f6d37304ea", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "040ad99500288d466940031d72a9f5445a4d43784640855bf0a69874d2de5fe103c5011e6ef2c42dcd50d5d3d29f99ae6eba2c80c9244f4c5422f0979ff0c3ba5e", + "wx" : "0ad99500288d466940031d72a9f5445a4d43784640855bf0a69874d2de5fe103", + "wy" : "00c5011e6ef2c42dcd50d5d3d29f99ae6eba2c80c9244f4c5422f0979ff0c3ba5e" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200040ad99500288d466940031d72a9f5445a4d43784640855bf0a69874d2de5fe103c5011e6ef2c42dcd50d5d3d29f99ae6eba2c80c9244f4c5422f0979ff0c3ba5e", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECtmVACiNRmlAAx1yqfVEWk1DeEZA\nhVvwpph00t5f4QPFAR5u8sQtzVDV09Kfma5uuiyAySRPTFQi8Jef8MO6Xg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 285, + "comment" : "k*G has a large x-coordinate", + "msg" : "313233343030", + "sig" : "303502104319055358e8617b0c46353d039cdaab022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 286, + "comment" : "r too large", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000001000000000000000000000000fffffffffffffffffffffffc022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04ab05fd9d0de26b9ce6f4819652d9fc69193d0aa398f0fba8013e09c58220455419235271228c786759095d12b75af0692dd4103f19f6a8c32f49435a1e9b8d45", + "wx" : "00ab05fd9d0de26b9ce6f4819652d9fc69193d0aa398f0fba8013e09c582204554", + "wy" : "19235271228c786759095d12b75af0692dd4103f19f6a8c32f49435a1e9b8d45" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004ab05fd9d0de26b9ce6f4819652d9fc69193d0aa398f0fba8013e09c58220455419235271228c786759095d12b75af0692dd4103f19f6a8c32f49435a1e9b8d45", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqwX9nQ3ia5zm9IGWUtn8aRk9CqOY\n8PuoAT4JxYIgRVQZI1JxIox4Z1kJXRK3WvBpLdQQPxn2qMMvSUNaHpuNRQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 287, + "comment" : "r,s are large", + "msg" : "313233343030", + "sig" : "3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "0480984f39a1ff38a86a68aa4201b6be5dfbfecf876219710b07badf6fdd4c6c5611feb97390d9826e7a06dfb41871c940d74415ed3cac2089f1445019bb55ed95", + "wx" : "0080984f39a1ff38a86a68aa4201b6be5dfbfecf876219710b07badf6fdd4c6c56", + "wy" : "11feb97390d9826e7a06dfb41871c940d74415ed3cac2089f1445019bb55ed95" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000480984f39a1ff38a86a68aa4201b6be5dfbfecf876219710b07badf6fdd4c6c5611feb97390d9826e7a06dfb41871c940d74415ed3cac2089f1445019bb55ed95", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgJhPOaH/OKhqaKpCAba+Xfv+z4di\nGXELB7rfb91MbFYR/rlzkNmCbnoG37QYcclA10QV7TysIInxRFAZu1XtlQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 288, + "comment" : "r and s^-1 have a large Hamming weight", + "msg" : "313233343030", + "sig" : "304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022100909135bdb6799286170f5ead2de4f6511453fe50914f3df2de54a36383df8dd4", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "044201b4272944201c3294f5baa9a3232b6dd687495fcc19a70a95bc602b4f7c0595c37eba9ee8171c1bb5ac6feaf753bc36f463e3aef16629572c0c0a8fb0800e", + "wx" : "4201b4272944201c3294f5baa9a3232b6dd687495fcc19a70a95bc602b4f7c05", + "wy" : "0095c37eba9ee8171c1bb5ac6feaf753bc36f463e3aef16629572c0c0a8fb0800e" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200044201b4272944201c3294f5baa9a3232b6dd687495fcc19a70a95bc602b4f7c0595c37eba9ee8171c1bb5ac6feaf753bc36f463e3aef16629572c0c0a8fb0800e", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQgG0JylEIBwylPW6qaMjK23Wh0lf\nzBmnCpW8YCtPfAWVw366nugXHBu1rG/q91O8NvRj467xZilXLAwKj7CADg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 289, + "comment" : "r and s^-1 have a large Hamming weight", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022027b4577ca009376f71303fd5dd227dcef5deb773ad5f5a84360644669ca249a5", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04a71af64de5126a4a4e02b7922d66ce9415ce88a4c9d25514d91082c8725ac9575d47723c8fbe580bb369fec9c2665d8e30a435b9932645482e7c9f11e872296b", + "wx" : "00a71af64de5126a4a4e02b7922d66ce9415ce88a4c9d25514d91082c8725ac957", + "wy" : "5d47723c8fbe580bb369fec9c2665d8e30a435b9932645482e7c9f11e872296b" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004a71af64de5126a4a4e02b7922d66ce9415ce88a4c9d25514d91082c8725ac9575d47723c8fbe580bb369fec9c2665d8e30a435b9932645482e7c9f11e872296b", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpxr2TeUSakpOAreSLWbOlBXOiKTJ\n0lUU2RCCyHJayVddR3I8j75YC7Np/snCZl2OMKQ1uZMmRUgufJ8R6HIpaw==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 290, + "comment" : "small r and s", + "msg" : "313233343030", + "sig" : "3006020105020101", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "046627cec4f0731ea23fc2931f90ebe5b7572f597d20df08fc2b31ee8ef16b15726170ed77d8d0a14fc5c9c3c4c9be7f0d3ee18f709bb275eaf2073e258fe694a5", + "wx" : "6627cec4f0731ea23fc2931f90ebe5b7572f597d20df08fc2b31ee8ef16b1572", + "wy" : "6170ed77d8d0a14fc5c9c3c4c9be7f0d3ee18f709bb275eaf2073e258fe694a5" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200046627cec4f0731ea23fc2931f90ebe5b7572f597d20df08fc2b31ee8ef16b15726170ed77d8d0a14fc5c9c3c4c9be7f0d3ee18f709bb275eaf2073e258fe694a5", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZifOxPBzHqI/wpMfkOvlt1cvWX0g\n3wj8KzHujvFrFXJhcO132NChT8XJw8TJvn8NPuGPcJuyderyBz4lj+aUpQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 291, + "comment" : "small r and s", + "msg" : "313233343030", + "sig" : "3006020105020103", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "045a7c8825e85691cce1f5e7544c54e73f14afc010cb731343262ca7ec5a77f5bfef6edf62a4497c1bd7b147fb6c3d22af3c39bfce95f30e13a16d3d7b2812f813", + "wx" : "5a7c8825e85691cce1f5e7544c54e73f14afc010cb731343262ca7ec5a77f5bf", + "wy" : "00ef6edf62a4497c1bd7b147fb6c3d22af3c39bfce95f30e13a16d3d7b2812f813" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200045a7c8825e85691cce1f5e7544c54e73f14afc010cb731343262ca7ec5a77f5bfef6edf62a4497c1bd7b147fb6c3d22af3c39bfce95f30e13a16d3d7b2812f813", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWnyIJehWkczh9edUTFTnPxSvwBDL\ncxNDJiyn7Fp39b/vbt9ipEl8G9exR/tsPSKvPDm/zpXzDhOhbT17KBL4Ew==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 292, + "comment" : "small r and s", + "msg" : "313233343030", + "sig" : "3006020105020105", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04cbe0c29132cd738364fedd603152990c048e5e2fff996d883fa6caca7978c73770af6a8ce44cb41224b2603606f4c04d188e80bff7cc31ad5189d4ab0d70e8c1", + "wx" : "00cbe0c29132cd738364fedd603152990c048e5e2fff996d883fa6caca7978c737", + "wy" : "70af6a8ce44cb41224b2603606f4c04d188e80bff7cc31ad5189d4ab0d70e8c1" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004cbe0c29132cd738364fedd603152990c048e5e2fff996d883fa6caca7978c73770af6a8ce44cb41224b2603606f4c04d188e80bff7cc31ad5189d4ab0d70e8c1", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEy+DCkTLNc4Nk/t1gMVKZDASOXi//\nmW2IP6bKynl4xzdwr2qM5Ey0EiSyYDYG9MBNGI6Av/fMMa1RidSrDXDowQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 293, + "comment" : "small r and s", + "msg" : "313233343030", + "sig" : "3006020105020106", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 294, + "comment" : "r is larger than n", + "msg" : "313233343030", + "sig" : "3026022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632556020106", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "044be4178097002f0deab68f0d9a130e0ed33a6795d02a20796db83444b037e13920f13051e0eecdcfce4dacea0f50d1f247caa669f193c1b4075b51ae296d2d56", + "wx" : "4be4178097002f0deab68f0d9a130e0ed33a6795d02a20796db83444b037e139", + "wy" : "20f13051e0eecdcfce4dacea0f50d1f247caa669f193c1b4075b51ae296d2d56" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200044be4178097002f0deab68f0d9a130e0ed33a6795d02a20796db83444b037e13920f13051e0eecdcfce4dacea0f50d1f247caa669f193c1b4075b51ae296d2d56", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAES+QXgJcALw3qto8NmhMODtM6Z5XQ\nKiB5bbg0RLA34Tkg8TBR4O7Nz85NrOoPUNHyR8qmafGTwbQHW1GuKW0tVg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 295, + "comment" : "s is larger than n", + "msg" : "313233343030", + "sig" : "3026020105022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc75fbd8", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04d0f73792203716afd4be4329faa48d269f15313ebbba379d7783c97bf3e890d9971f4a3206605bec21782bf5e275c714417e8f566549e6bc68690d2363c89cc1", + "wx" : "00d0f73792203716afd4be4329faa48d269f15313ebbba379d7783c97bf3e890d9", + "wy" : "00971f4a3206605bec21782bf5e275c714417e8f566549e6bc68690d2363c89cc1" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004d0f73792203716afd4be4329faa48d269f15313ebbba379d7783c97bf3e890d9971f4a3206605bec21782bf5e275c714417e8f566549e6bc68690d2363c89cc1", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0Pc3kiA3Fq/UvkMp+qSNJp8VMT67\nujedd4PJe/PokNmXH0oyBmBb7CF4K/XidccUQX6PVmVJ5rxoaQ0jY8icwQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 296, + "comment" : "small r and s^-1", + "msg" : "313233343030", + "sig" : "3027020201000221008f1e3c7862c58b16bb76eddbb76eddbb516af4f63f2d74d76e0d28c9bb75ea88", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "044838b2be35a6276a80ef9e228140f9d9b96ce83b7a254f71ccdebbb8054ce05ffa9cbc123c919b19e00238198d04069043bd660a828814051fcb8aac738a6c6b", + "wx" : "4838b2be35a6276a80ef9e228140f9d9b96ce83b7a254f71ccdebbb8054ce05f", + "wy" : "00fa9cbc123c919b19e00238198d04069043bd660a828814051fcb8aac738a6c6b" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200044838b2be35a6276a80ef9e228140f9d9b96ce83b7a254f71ccdebbb8054ce05ffa9cbc123c919b19e00238198d04069043bd660a828814051fcb8aac738a6c6b", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESDiyvjWmJ2qA754igUD52bls6Dt6\nJU9xzN67uAVM4F/6nLwSPJGbGeACOBmNBAaQQ71mCoKIFAUfy4qsc4psaw==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 297, + "comment" : "smallish r and s^-1", + "msg" : "313233343030", + "sig" : "302c02072d9b4d347952d6022100ef3043e7329581dbb3974497710ab11505ee1c87ff907beebadd195a0ffe6d7a", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "047393983ca30a520bbc4783dc9960746aab444ef520c0a8e771119aa4e74b0f64e9d7be1ab01a0bf626e709863e6a486dbaf32793afccf774e2c6cd27b1857526", + "wx" : "7393983ca30a520bbc4783dc9960746aab444ef520c0a8e771119aa4e74b0f64", + "wy" : "00e9d7be1ab01a0bf626e709863e6a486dbaf32793afccf774e2c6cd27b1857526" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200047393983ca30a520bbc4783dc9960746aab444ef520c0a8e771119aa4e74b0f64e9d7be1ab01a0bf626e709863e6a486dbaf32793afccf774e2c6cd27b1857526", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEc5OYPKMKUgu8R4PcmWB0aqtETvUg\nwKjncRGapOdLD2Tp174asBoL9ibnCYY+akhtuvMnk6/M93Tixs0nsYV1Jg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 298, + "comment" : "100-bit r and small s^-1", + "msg" : "313233343030", + "sig" : "3032020d1033e67e37b32b445580bf4eff0221008b748b74000000008b748b748b748b7466e769ad4a16d3dcd87129b8e91d1b4d", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "045ac331a1103fe966697379f356a937f350588a05477e308851b8a502d5dfcdc5fe9993df4b57939b2b8da095bf6d794265204cfe03be995a02e65d408c871c0b", + "wx" : "5ac331a1103fe966697379f356a937f350588a05477e308851b8a502d5dfcdc5", + "wy" : "00fe9993df4b57939b2b8da095bf6d794265204cfe03be995a02e65d408c871c0b" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200045ac331a1103fe966697379f356a937f350588a05477e308851b8a502d5dfcdc5fe9993df4b57939b2b8da095bf6d794265204cfe03be995a02e65d408c871c0b", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWsMxoRA/6WZpc3nzVqk381BYigVH\nfjCIUbilAtXfzcX+mZPfS1eTmyuNoJW/bXlCZSBM/gO+mVoC5l1AjIccCw==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 299, + "comment" : "small r and 100 bit s^-1", + "msg" : "313233343030", + "sig" : "302702020100022100ef9f6ba4d97c09d03178fa20b4aaad83be3cf9cb824a879fec3270fc4b81ef5b", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "041d209be8de2de877095a399d3904c74cc458d926e27bb8e58e5eae5767c41509dd59e04c214f7b18dce351fc2a549893a6860e80163f38cc60a4f2c9d040d8c9", + "wx" : "1d209be8de2de877095a399d3904c74cc458d926e27bb8e58e5eae5767c41509", + "wy" : "00dd59e04c214f7b18dce351fc2a549893a6860e80163f38cc60a4f2c9d040d8c9" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200041d209be8de2de877095a399d3904c74cc458d926e27bb8e58e5eae5767c41509dd59e04c214f7b18dce351fc2a549893a6860e80163f38cc60a4f2c9d040d8c9", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHSCb6N4t6HcJWjmdOQTHTMRY2Sbi\ne7jljl6uV2fEFQndWeBMIU97GNzjUfwqVJiTpoYOgBY/OMxgpPLJ0EDYyQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 300, + "comment" : "100-bit r and s^-1", + "msg" : "313233343030", + "sig" : "3032020d062522bbd3ecbe7c39e93e7c25022100ef9f6ba4d97c09d03178fa20b4aaad83be3cf9cb824a879fec3270fc4b81ef5b", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04083539fbee44625e3acaafa2fcb41349392cef0633a1b8fabecee0c133b10e99915c1ebe7bf00df8535196770a58047ae2a402f26326bb7d41d4d7616337911e", + "wx" : "083539fbee44625e3acaafa2fcb41349392cef0633a1b8fabecee0c133b10e99", + "wy" : "00915c1ebe7bf00df8535196770a58047ae2a402f26326bb7d41d4d7616337911e" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004083539fbee44625e3acaafa2fcb41349392cef0633a1b8fabecee0c133b10e99915c1ebe7bf00df8535196770a58047ae2a402f26326bb7d41d4d7616337911e", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECDU5++5EYl46yq+i/LQTSTks7wYz\nobj6vs7gwTOxDpmRXB6+e/AN+FNRlncKWAR64qQC8mMmu31B1NdhYzeRHg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 301, + "comment" : "r and s^-1 are close to n", + "msg" : "313233343030", + "sig" : "3045022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6324d50220555555550000000055555555555555553ef7a8e48d07df81a693439654210c70", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "048aeb368a7027a4d64abdea37390c0c1d6a26f399e2d9734de1eb3d0e1937387405bd13834715e1dbae9b875cf07bd55e1b6691c7f7536aef3b19bf7a4adf576d", + "wx" : "008aeb368a7027a4d64abdea37390c0c1d6a26f399e2d9734de1eb3d0e19373874", + "wy" : "05bd13834715e1dbae9b875cf07bd55e1b6691c7f7536aef3b19bf7a4adf576d" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200048aeb368a7027a4d64abdea37390c0c1d6a26f399e2d9734de1eb3d0e1937387405bd13834715e1dbae9b875cf07bd55e1b6691c7f7536aef3b19bf7a4adf576d", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEius2inAnpNZKveo3OQwMHWom85ni\n2XNN4es9Dhk3OHQFvRODRxXh266bh1zwe9VeG2aRx/dTau87Gb96St9XbQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 302, + "comment" : "s == 1", + "msg" : "313233343030", + "sig" : "30250220555555550000000055555555555555553ef7a8e48d07df81a693439654210c70020101", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 303, + "comment" : "s == 0", + "msg" : "313233343030", + "sig" : "30250220555555550000000055555555555555553ef7a8e48d07df81a693439654210c70020100", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04b533d4695dd5b8c5e07757e55e6e516f7e2c88fa0239e23f60e8ec07dd70f2871b134ee58cc583278456863f33c3a85d881f7d4a39850143e29d4eaf009afe47", + "wx" : "00b533d4695dd5b8c5e07757e55e6e516f7e2c88fa0239e23f60e8ec07dd70f287", + "wy" : "1b134ee58cc583278456863f33c3a85d881f7d4a39850143e29d4eaf009afe47" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004b533d4695dd5b8c5e07757e55e6e516f7e2c88fa0239e23f60e8ec07dd70f2871b134ee58cc583278456863f33c3a85d881f7d4a39850143e29d4eaf009afe47", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEtTPUaV3VuMXgd1flXm5Rb34siPoC\nOeI/YOjsB91w8ocbE07ljMWDJ4RWhj8zw6hdiB99SjmFAUPinU6vAJr+Rw==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 304, + "comment" : "point at infinity during verify", + "msg" : "313233343030", + "sig" : "304402207fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a80220555555550000000055555555555555553ef7a8e48d07df81a693439654210c70", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04f50d371b91bfb1d7d14e1323523bc3aa8cbf2c57f9e284de628c8b4536787b86f94ad887ac94d527247cd2e7d0c8b1291c553c9730405380b14cbb209f5fa2dd", + "wx" : "00f50d371b91bfb1d7d14e1323523bc3aa8cbf2c57f9e284de628c8b4536787b86", + "wy" : "00f94ad887ac94d527247cd2e7d0c8b1291c553c9730405380b14cbb209f5fa2dd" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004f50d371b91bfb1d7d14e1323523bc3aa8cbf2c57f9e284de628c8b4536787b86f94ad887ac94d527247cd2e7d0c8b1291c553c9730405380b14cbb209f5fa2dd", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9Q03G5G/sdfRThMjUjvDqoy/LFf5\n4oTeYoyLRTZ4e4b5StiHrJTVJyR80ufQyLEpHFU8lzBAU4CxTLsgn1+i3Q==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 305, + "comment" : "edge case for signature malleability", + "msg" : "313233343030", + "sig" : "304402207fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a902207fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "0468ec6e298eafe16539156ce57a14b04a7047c221bafc3a582eaeb0d857c4d94697bed1af17850117fdb39b2324f220a5698ed16c426a27335bb385ac8ca6fb30", + "wx" : "68ec6e298eafe16539156ce57a14b04a7047c221bafc3a582eaeb0d857c4d946", + "wy" : "0097bed1af17850117fdb39b2324f220a5698ed16c426a27335bb385ac8ca6fb30" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000468ec6e298eafe16539156ce57a14b04a7047c221bafc3a582eaeb0d857c4d94697bed1af17850117fdb39b2324f220a5698ed16c426a27335bb385ac8ca6fb30", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEaOxuKY6v4WU5FWzlehSwSnBHwiG6\n/DpYLq6w2FfE2UaXvtGvF4UBF/2zmyMk8iClaY7RbEJqJzNbs4WsjKb7MA==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 306, + "comment" : "edge case for signature malleability", + "msg" : "313233343030", + "sig" : "304402207fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a902207fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "0469da0364734d2e530fece94019265fefb781a0f1b08f6c8897bdf6557927c8b866d2d3c7dcd518b23d726960f069ad71a933d86ef8abbcce8b20f71e2a847002", + "wx" : "69da0364734d2e530fece94019265fefb781a0f1b08f6c8897bdf6557927c8b8", + "wy" : "66d2d3c7dcd518b23d726960f069ad71a933d86ef8abbcce8b20f71e2a847002" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000469da0364734d2e530fece94019265fefb781a0f1b08f6c8897bdf6557927c8b866d2d3c7dcd518b23d726960f069ad71a933d86ef8abbcce8b20f71e2a847002", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEadoDZHNNLlMP7OlAGSZf77eBoPGw\nj2yIl732VXknyLhm0tPH3NUYsj1yaWDwaa1xqTPYbvirvM6LIPceKoRwAg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 307, + "comment" : "u1 == 1", + "msg" : "313233343030", + "sig" : "30450220555555550000000055555555555555553ef7a8e48d07df81a693439654210c70022100bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04d8adc00023a8edc02576e2b63e3e30621a471e2b2320620187bf067a1ac1ff3233e2b50ec09807accb36131fff95ed12a09a86b4ea9690aa32861576ba2362e1", + "wx" : "00d8adc00023a8edc02576e2b63e3e30621a471e2b2320620187bf067a1ac1ff32", + "wy" : "33e2b50ec09807accb36131fff95ed12a09a86b4ea9690aa32861576ba2362e1" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004d8adc00023a8edc02576e2b63e3e30621a471e2b2320620187bf067a1ac1ff3233e2b50ec09807accb36131fff95ed12a09a86b4ea9690aa32861576ba2362e1", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2K3AACOo7cAlduK2Pj4wYhpHHisj\nIGIBh78GehrB/zIz4rUOwJgHrMs2Ex//le0SoJqGtOqWkKoyhhV2uiNi4Q==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 308, + "comment" : "u1 == n - 1", + "msg" : "313233343030", + "sig" : "30440220555555550000000055555555555555553ef7a8e48d07df81a693439654210c70022044a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "043623ac973ced0a56fa6d882f03a7d5c7edca02cfc7b2401fab3690dbe75ab7858db06908e64b28613da7257e737f39793da8e713ba0643b92e9bb3252be7f8fe", + "wx" : "3623ac973ced0a56fa6d882f03a7d5c7edca02cfc7b2401fab3690dbe75ab785", + "wy" : "008db06908e64b28613da7257e737f39793da8e713ba0643b92e9bb3252be7f8fe" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200043623ac973ced0a56fa6d882f03a7d5c7edca02cfc7b2401fab3690dbe75ab7858db06908e64b28613da7257e737f39793da8e713ba0643b92e9bb3252be7f8fe", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENiOslzztClb6bYgvA6fVx+3KAs/H\nskAfqzaQ2+dat4WNsGkI5ksoYT2nJX5zfzl5PajnE7oGQ7kum7MlK+f4/g==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 309, + "comment" : "u2 == 1", + "msg" : "313233343030", + "sig" : "30440220555555550000000055555555555555553ef7a8e48d07df81a693439654210c700220555555550000000055555555555555553ef7a8e48d07df81a693439654210c70", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04cf04ea77e9622523d894b93ff52dc3027b31959503b6fa3890e5e04263f922f1e8528fb7c006b3983c8b8400e57b4ed71740c2f3975438821199bedeaecab2e9", + "wx" : "00cf04ea77e9622523d894b93ff52dc3027b31959503b6fa3890e5e04263f922f1", + "wy" : "00e8528fb7c006b3983c8b8400e57b4ed71740c2f3975438821199bedeaecab2e9" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004cf04ea77e9622523d894b93ff52dc3027b31959503b6fa3890e5e04263f922f1e8528fb7c006b3983c8b8400e57b4ed71740c2f3975438821199bedeaecab2e9", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzwTqd+liJSPYlLk/9S3DAnsxlZUD\ntvo4kOXgQmP5IvHoUo+3wAazmDyLhADle07XF0DC85dUOIIRmb7ersqy6Q==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 310, + "comment" : "u2 == n - 1", + "msg" : "313233343030", + "sig" : "30450220555555550000000055555555555555553ef7a8e48d07df81a693439654210c70022100aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04db7a2c8a1ab573e5929dc24077b508d7e683d49227996bda3e9f78dbeff773504f417f3bc9a88075c2e0aadd5a13311730cf7cc76a82f11a36eaf08a6c99a206", + "wx" : "00db7a2c8a1ab573e5929dc24077b508d7e683d49227996bda3e9f78dbeff77350", + "wy" : "4f417f3bc9a88075c2e0aadd5a13311730cf7cc76a82f11a36eaf08a6c99a206" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004db7a2c8a1ab573e5929dc24077b508d7e683d49227996bda3e9f78dbeff773504f417f3bc9a88075c2e0aadd5a13311730cf7cc76a82f11a36eaf08a6c99a206", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE23osihq1c+WSncJAd7UI1+aD1JIn\nmWvaPp942+/3c1BPQX87yaiAdcLgqt1aEzEXMM98x2qC8Ro26vCKbJmiBg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 311, + "comment" : "edge case for u1", + "msg" : "313233343030", + "sig" : "304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022100e91e1ba60fdedb76a46bcb51dc0b8b4b7e019f0a28721885fa5d3a8196623397", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04dead11c7a5b396862f21974dc4752fadeff994efe9bbd05ab413765ea80b6e1f1de3f0640e8ac6edcf89cff53c40e265bb94078a343736df07aa0318fc7fe1ff", + "wx" : "00dead11c7a5b396862f21974dc4752fadeff994efe9bbd05ab413765ea80b6e1f", + "wy" : "1de3f0640e8ac6edcf89cff53c40e265bb94078a343736df07aa0318fc7fe1ff" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004dead11c7a5b396862f21974dc4752fadeff994efe9bbd05ab413765ea80b6e1f1de3f0640e8ac6edcf89cff53c40e265bb94078a343736df07aa0318fc7fe1ff", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3q0Rx6WzloYvIZdNxHUvre/5lO/p\nu9BatBN2XqgLbh8d4/BkDorG7c+Jz/U8QOJlu5QHijQ3Nt8HqgMY/H/h/w==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 312, + "comment" : "edge case for u1", + "msg" : "313233343030", + "sig" : "304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022100fdea5843ffeb73af94313ba4831b53fe24f799e525b1e8e8c87b59b95b430ad9", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04d0bc472e0d7c81ebaed3a6ef96c18613bb1fea6f994326fbe80e00dfde67c7e9986c723ea4843d48389b946f64ad56c83ad70ff17ba85335667d1bb9fa619efd", + "wx" : "00d0bc472e0d7c81ebaed3a6ef96c18613bb1fea6f994326fbe80e00dfde67c7e9", + "wy" : "00986c723ea4843d48389b946f64ad56c83ad70ff17ba85335667d1bb9fa619efd" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004d0bc472e0d7c81ebaed3a6ef96c18613bb1fea6f994326fbe80e00dfde67c7e9986c723ea4843d48389b946f64ad56c83ad70ff17ba85335667d1bb9fa619efd", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0LxHLg18geuu06bvlsGGE7sf6m+Z\nQyb76A4A395nx+mYbHI+pIQ9SDiblG9krVbIOtcP8XuoUzVmfRu5+mGe/Q==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 313, + "comment" : "edge case for u1", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022003ffcabf2f1b4d2a65190db1680d62bb994e41c5251cd73b3c3dfc5e5bafc035", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04a0a44ca947d66a2acb736008b9c08d1ab2ad03776e02640f78495d458dd51c326337fe5cf8c4604b1f1c409dc2d872d4294a4762420df43a30a2392e40426add", + "wx" : "00a0a44ca947d66a2acb736008b9c08d1ab2ad03776e02640f78495d458dd51c32", + "wy" : "6337fe5cf8c4604b1f1c409dc2d872d4294a4762420df43a30a2392e40426add" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004a0a44ca947d66a2acb736008b9c08d1ab2ad03776e02640f78495d458dd51c326337fe5cf8c4604b1f1c409dc2d872d4294a4762420df43a30a2392e40426add", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoKRMqUfWairLc2AIucCNGrKtA3du\nAmQPeEldRY3VHDJjN/5c+MRgSx8cQJ3C2HLUKUpHYkIN9DowojkuQEJq3Q==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 314, + "comment" : "edge case for u1", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd02204dfbc401f971cd304b33dfdb17d0fed0fe4c1a88ae648e0d2847f74977534989", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04c9c2115290d008b45fb65fad0f602389298c25420b775019d42b62c3ce8a96b73877d25a8080dc02d987ca730f0405c2c9dbefac46f9e601cc3f06e9713973fd", + "wx" : "00c9c2115290d008b45fb65fad0f602389298c25420b775019d42b62c3ce8a96b7", + "wy" : "3877d25a8080dc02d987ca730f0405c2c9dbefac46f9e601cc3f06e9713973fd" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004c9c2115290d008b45fb65fad0f602389298c25420b775019d42b62c3ce8a96b73877d25a8080dc02d987ca730f0405c2c9dbefac46f9e601cc3f06e9713973fd", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEycIRUpDQCLRftl+tD2AjiSmMJUIL\nd1AZ1Ctiw86Klrc4d9JagIDcAtmHynMPBAXCydvvrEb55gHMPwbpcTlz/Q==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 315, + "comment" : "edge case for u1", + "msg" : "313233343030", + "sig" : "304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022100bc4024761cd2ffd43dfdb17d0fed112b988977055cd3a8e54971eba9cda5ca71", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "045eca1ef4c287dddc66b8bccf1b88e8a24c0018962f3c5e7efa83bc1a5ff6033e5e79c4cb2c245b8c45abdce8a8e4da758d92a607c32cd407ecaef22f1c934a71", + "wx" : "5eca1ef4c287dddc66b8bccf1b88e8a24c0018962f3c5e7efa83bc1a5ff6033e", + "wy" : "5e79c4cb2c245b8c45abdce8a8e4da758d92a607c32cd407ecaef22f1c934a71" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200045eca1ef4c287dddc66b8bccf1b88e8a24c0018962f3c5e7efa83bc1a5ff6033e5e79c4cb2c245b8c45abdce8a8e4da758d92a607c32cd407ecaef22f1c934a71", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXsoe9MKH3dxmuLzPG4jookwAGJYv\nPF5++oO8Gl/2Az5eecTLLCRbjEWr3Oio5Np1jZKmB8Ms1AfsrvIvHJNKcQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 316, + "comment" : "edge case for u1", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0220788048ed39a5ffa77bfb62fa1fda2257742bf35d128fb3459f2a0c909ee86f91", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "045caaa030e7fdf0e4936bc7ab5a96353e0a01e4130c3f8bf22d473e317029a47adeb6adc462f7058f2a20d371e9702254e9b201642005b3ceda926b42b178bef9", + "wx" : "5caaa030e7fdf0e4936bc7ab5a96353e0a01e4130c3f8bf22d473e317029a47a", + "wy" : "00deb6adc462f7058f2a20d371e9702254e9b201642005b3ceda926b42b178bef9" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200045caaa030e7fdf0e4936bc7ab5a96353e0a01e4130c3f8bf22d473e317029a47adeb6adc462f7058f2a20d371e9702254e9b201642005b3ceda926b42b178bef9", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXKqgMOf98OSTa8erWpY1PgoB5BMM\nP4vyLUc+MXAppHretq3EYvcFjyog03HpcCJU6bIBZCAFs87akmtCsXi++Q==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 317, + "comment" : "edge case for u1", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0220476d9131fd381bd917d0fed112bc9e0a5924b5ed5b11167edd8b23582b3cb15e", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04c2fd20bac06e555bb8ac0ce69eb1ea20f83a1fc3501c8a66469b1a31f619b0986237050779f52b615bd7b8d76a25fc95ca2ed32525c75f27ffc87ac397e6cbaf", + "wx" : "00c2fd20bac06e555bb8ac0ce69eb1ea20f83a1fc3501c8a66469b1a31f619b098", + "wy" : "6237050779f52b615bd7b8d76a25fc95ca2ed32525c75f27ffc87ac397e6cbaf" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004c2fd20bac06e555bb8ac0ce69eb1ea20f83a1fc3501c8a66469b1a31f619b0986237050779f52b615bd7b8d76a25fc95ca2ed32525c75f27ffc87ac397e6cbaf", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEwv0gusBuVVu4rAzmnrHqIPg6H8NQ\nHIpmRpsaMfYZsJhiNwUHefUrYVvXuNdqJfyVyi7TJSXHXyf/yHrDl+bLrw==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 318, + "comment" : "edge case for u1", + "msg" : "313233343030", + "sig" : "304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0221008374253e3e21bd154448d0a8f640fe46fafa8b19ce78d538f6cc0a19662d3601", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "043fd6a1ca7f77fb3b0bbe726c372010068426e11ea6ae78ce17bedae4bba86ced03ce5516406bf8cfaab8745eac1cd69018ad6f50b5461872ddfc56e0db3c8ff4", + "wx" : "3fd6a1ca7f77fb3b0bbe726c372010068426e11ea6ae78ce17bedae4bba86ced", + "wy" : "03ce5516406bf8cfaab8745eac1cd69018ad6f50b5461872ddfc56e0db3c8ff4" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200043fd6a1ca7f77fb3b0bbe726c372010068426e11ea6ae78ce17bedae4bba86ced03ce5516406bf8cfaab8745eac1cd69018ad6f50b5461872ddfc56e0db3c8ff4", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEP9ahyn93+zsLvnJsNyAQBoQm4R6m\nrnjOF77a5LuobO0DzlUWQGv4z6q4dF6sHNaQGK1vULVGGHLd/Fbg2zyP9A==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 319, + "comment" : "edge case for u1", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0220357cfd3be4d01d413c5b9ede36cba5452c11ee7fe14879e749ae6a2d897a52d6", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "049cb8e51e27a5ae3b624a60d6dc32734e4989db20e9bca3ede1edf7b086911114b4c104ab3c677e4b36d6556e8ad5f523410a19f2e277aa895fc57322b4427544", + "wx" : "009cb8e51e27a5ae3b624a60d6dc32734e4989db20e9bca3ede1edf7b086911114", + "wy" : "00b4c104ab3c677e4b36d6556e8ad5f523410a19f2e277aa895fc57322b4427544" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200049cb8e51e27a5ae3b624a60d6dc32734e4989db20e9bca3ede1edf7b086911114b4c104ab3c677e4b36d6556e8ad5f523410a19f2e277aa895fc57322b4427544", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEnLjlHielrjtiSmDW3DJzTkmJ2yDp\nvKPt4e33sIaRERS0wQSrPGd+SzbWVW6K1fUjQQoZ8uJ3qolfxXMitEJ1RA==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 320, + "comment" : "edge case for u1", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022029798c5c0ee287d4a5e8e6b799fd86b8df5225298e6ffc807cd2f2bc27a0a6d8", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04a3e52c156dcaf10502620b7955bc2b40bc78ef3d569e1223c262512d8f49602a4a2039f31c1097024ad3cc86e57321de032355463486164cf192944977df147f", + "wx" : "00a3e52c156dcaf10502620b7955bc2b40bc78ef3d569e1223c262512d8f49602a", + "wy" : "4a2039f31c1097024ad3cc86e57321de032355463486164cf192944977df147f" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004a3e52c156dcaf10502620b7955bc2b40bc78ef3d569e1223c262512d8f49602a4a2039f31c1097024ad3cc86e57321de032355463486164cf192944977df147f", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEo+UsFW3K8QUCYgt5VbwrQLx47z1W\nnhIjwmJRLY9JYCpKIDnzHBCXAkrTzIblcyHeAyNVRjSGFkzxkpRJd98Ufw==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 321, + "comment" : "edge case for u1", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd02200b70f22c781092452dca1a5711fa3a5a1f72add1bf52c2ff7cae4820b30078dd", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04f19b78928720d5bee8e670fb90010fb15c37bf91b58a5157c3f3c059b2655e88cf701ec962fb4a11dcf273f5dc357e58468560c7cfeb942d074abd4329260509", + "wx" : "00f19b78928720d5bee8e670fb90010fb15c37bf91b58a5157c3f3c059b2655e88", + "wy" : "00cf701ec962fb4a11dcf273f5dc357e58468560c7cfeb942d074abd4329260509" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004f19b78928720d5bee8e670fb90010fb15c37bf91b58a5157c3f3c059b2655e88cf701ec962fb4a11dcf273f5dc357e58468560c7cfeb942d074abd4329260509", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8Zt4kocg1b7o5nD7kAEPsVw3v5G1\nilFXw/PAWbJlXojPcB7JYvtKEdzyc/XcNX5YRoVgx8/rlC0HSr1DKSYFCQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 322, + "comment" : "edge case for u1", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022016e1e458f021248a5b9434ae23f474b43ee55ba37ea585fef95c90416600f1ba", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "0483a744459ecdfb01a5cf52b27a05bb7337482d242f235d7b4cb89345545c90a8c05d49337b9649813287de9ffe90355fd905df5f3c32945828121f37cc50de6e", + "wx" : "0083a744459ecdfb01a5cf52b27a05bb7337482d242f235d7b4cb89345545c90a8", + "wy" : "00c05d49337b9649813287de9ffe90355fd905df5f3c32945828121f37cc50de6e" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000483a744459ecdfb01a5cf52b27a05bb7337482d242f235d7b4cb89345545c90a8c05d49337b9649813287de9ffe90355fd905df5f3c32945828121f37cc50de6e", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEg6dERZ7N+wGlz1KyegW7czdILSQv\nI117TLiTRVRckKjAXUkze5ZJgTKH3p/+kDVf2QXfXzwylFgoEh83zFDebg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 323, + "comment" : "edge case for u1", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd02202252d6856831b6cf895e4f0535eeaf0e5e5809753df848fe760ad86219016a97", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04dd13c6b34c56982ddae124f039dfd23f4b19bbe88cee8e528ae51e5d6f3a21d7bfad4c2e6f263fe5eb59ca974d039fc0e4c3345692fb5320bdae4bd3b42a45ff", + "wx" : "00dd13c6b34c56982ddae124f039dfd23f4b19bbe88cee8e528ae51e5d6f3a21d7", + "wy" : "00bfad4c2e6f263fe5eb59ca974d039fc0e4c3345692fb5320bdae4bd3b42a45ff" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004dd13c6b34c56982ddae124f039dfd23f4b19bbe88cee8e528ae51e5d6f3a21d7bfad4c2e6f263fe5eb59ca974d039fc0e4c3345692fb5320bdae4bd3b42a45ff", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3RPGs0xWmC3a4STwOd/SP0sZu+iM\n7o5SiuUeXW86Ide/rUwubyY/5etZypdNA5/A5MM0VpL7UyC9rkvTtCpF/w==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 324, + "comment" : "edge case for u1", + "msg" : "313233343030", + "sig" : "304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd02210081ffe55f178da695b28c86d8b406b15dab1a9e39661a3ae017fbe390ac0972c3", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "0467e6f659cdde869a2f65f094e94e5b4dfad636bbf95192feeed01b0f3deb7460a37e0a51f258b7aeb51dfe592f5cfd5685bbe58712c8d9233c62886437c38ba0", + "wx" : "67e6f659cdde869a2f65f094e94e5b4dfad636bbf95192feeed01b0f3deb7460", + "wy" : "00a37e0a51f258b7aeb51dfe592f5cfd5685bbe58712c8d9233c62886437c38ba0" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000467e6f659cdde869a2f65f094e94e5b4dfad636bbf95192feeed01b0f3deb7460a37e0a51f258b7aeb51dfe592f5cfd5685bbe58712c8d9233c62886437c38ba0", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZ+b2Wc3ehpovZfCU6U5bTfrWNrv5\nUZL+7tAbDz3rdGCjfgpR8li3rrUd/lkvXP1WhbvlhxLI2SM8YohkN8OLoA==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 325, + "comment" : "edge case for u2", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd02207fffffffaaaaaaaaffffffffffffffffe9a2538f37b28a2c513dee40fecbb71a", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "042eb6412505aec05c6545f029932087e490d05511e8ec1f599617bb367f9ecaaf805f51efcc4803403f9b1ae0124890f06a43fedcddb31830f6669af292895cb0", + "wx" : "2eb6412505aec05c6545f029932087e490d05511e8ec1f599617bb367f9ecaaf", + "wy" : "00805f51efcc4803403f9b1ae0124890f06a43fedcddb31830f6669af292895cb0" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200042eb6412505aec05c6545f029932087e490d05511e8ec1f599617bb367f9ecaaf805f51efcc4803403f9b1ae0124890f06a43fedcddb31830f6669af292895cb0", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELrZBJQWuwFxlRfApkyCH5JDQVRHo\n7B9Zlhe7Nn+eyq+AX1HvzEgDQD+bGuASSJDwakP+3N2zGDD2ZprykolcsA==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 326, + "comment" : "edge case for u2", + "msg" : "313233343030", + "sig" : "304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022100b62f26b5f2a2b26f6de86d42ad8a13da3ab3cccd0459b201de009e526adf21f2", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "0484db645868eab35e3a9fd80e056e2e855435e3a6b68d75a50a854625fe0d7f356d2589ac655edc9a11ef3e075eddda9abf92e72171570ef7bf43a2ee39338cfe", + "wx" : "0084db645868eab35e3a9fd80e056e2e855435e3a6b68d75a50a854625fe0d7f35", + "wy" : "6d2589ac655edc9a11ef3e075eddda9abf92e72171570ef7bf43a2ee39338cfe" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000484db645868eab35e3a9fd80e056e2e855435e3a6b68d75a50a854625fe0d7f356d2589ac655edc9a11ef3e075eddda9abf92e72171570ef7bf43a2ee39338cfe", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhNtkWGjqs146n9gOBW4uhVQ146a2\njXWlCoVGJf4NfzVtJYmsZV7cmhHvPgde3dqav5LnIXFXDve/Q6LuOTOM/g==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 327, + "comment" : "edge case for u2", + "msg" : "313233343030", + "sig" : "304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022100bb1d9ac949dd748cd02bbbe749bd351cd57b38bb61403d700686aa7b4c90851e", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "0491b9e47c56278662d75c0983b22ca8ea6aa5059b7a2ff7637eb2975e386ad66349aa8ff283d0f77c18d6d11dc062165fd13c3c0310679c1408302a16854ecfbd", + "wx" : "0091b9e47c56278662d75c0983b22ca8ea6aa5059b7a2ff7637eb2975e386ad663", + "wy" : "49aa8ff283d0f77c18d6d11dc062165fd13c3c0310679c1408302a16854ecfbd" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000491b9e47c56278662d75c0983b22ca8ea6aa5059b7a2ff7637eb2975e386ad66349aa8ff283d0f77c18d6d11dc062165fd13c3c0310679c1408302a16854ecfbd", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkbnkfFYnhmLXXAmDsiyo6mqlBZt6\nL/djfrKXXjhq1mNJqo/yg9D3fBjW0R3AYhZf0Tw8AxBnnBQIMCoWhU7PvQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 328, + "comment" : "edge case for u2", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022066755a00638cdaec1c732513ca0234ece52545dac11f816e818f725b4f60aaf2", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04f3ec2f13caf04d0192b47fb4c5311fb6d4dc6b0a9e802e5327f7ec5ee8e4834df97e3e468b7d0db867d6ecfe81e2b0f9531df87efdb47c1338ac321fefe5a432", + "wx" : "00f3ec2f13caf04d0192b47fb4c5311fb6d4dc6b0a9e802e5327f7ec5ee8e4834d", + "wy" : "00f97e3e468b7d0db867d6ecfe81e2b0f9531df87efdb47c1338ac321fefe5a432" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004f3ec2f13caf04d0192b47fb4c5311fb6d4dc6b0a9e802e5327f7ec5ee8e4834df97e3e468b7d0db867d6ecfe81e2b0f9531df87efdb47c1338ac321fefe5a432", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8+wvE8rwTQGStH+0xTEfttTcawqe\ngC5TJ/fsXujkg035fj5Gi30NuGfW7P6B4rD5Ux34fv20fBM4rDIf7+WkMg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 329, + "comment" : "edge case for u2", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022055a00c9fcdaebb6032513ca0234ecfffe98ebe492fdf02e48ca48e982beb3669", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04d92b200aefcab6ac7dafd9acaf2fa10b3180235b8f46b4503e4693c670fccc885ef2f3aebf5b317475336256768f7c19efb7352d27e4cccadc85b6b8ab922c72", + "wx" : "00d92b200aefcab6ac7dafd9acaf2fa10b3180235b8f46b4503e4693c670fccc88", + "wy" : "5ef2f3aebf5b317475336256768f7c19efb7352d27e4cccadc85b6b8ab922c72" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004d92b200aefcab6ac7dafd9acaf2fa10b3180235b8f46b4503e4693c670fccc885ef2f3aebf5b317475336256768f7c19efb7352d27e4cccadc85b6b8ab922c72", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2SsgCu/Ktqx9r9msry+hCzGAI1uP\nRrRQPkaTxnD8zIhe8vOuv1sxdHUzYlZ2j3wZ77c1LSfkzMrchba4q5Iscg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 330, + "comment" : "edge case for u2", + "msg" : "313233343030", + "sig" : "304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022100ab40193f9b5d76c064a27940469d9fffd31d7c925fbe05c919491d3057d66cd2", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "040a88361eb92ecca2625b38e5f98bbabb96bf179b3d76fc48140a3bcd881523cde6bdf56033f84a5054035597375d90866aa2c96b86a41ccf6edebf47298ad489", + "wx" : "0a88361eb92ecca2625b38e5f98bbabb96bf179b3d76fc48140a3bcd881523cd", + "wy" : "00e6bdf56033f84a5054035597375d90866aa2c96b86a41ccf6edebf47298ad489" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200040a88361eb92ecca2625b38e5f98bbabb96bf179b3d76fc48140a3bcd881523cde6bdf56033f84a5054035597375d90866aa2c96b86a41ccf6edebf47298ad489", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECog2HrkuzKJiWzjl+Yu6u5a/F5s9\ndvxIFAo7zYgVI83mvfVgM/hKUFQDVZc3XZCGaqLJa4akHM9u3r9HKYrUiQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 331, + "comment" : "edge case for u2", + "msg" : "313233343030", + "sig" : "304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022100ca0234ebb5fdcb13ca0234ecffffffffcb0dadbbc7f549f8a26b4408d0dc8600", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04d0fb17ccd8fafe827e0c1afc5d8d80366e2b20e7f14a563a2ba50469d84375e868612569d39e2bb9f554355564646de99ac602cc6349cf8c1e236a7de7637d93", + "wx" : "00d0fb17ccd8fafe827e0c1afc5d8d80366e2b20e7f14a563a2ba50469d84375e8", + "wy" : "68612569d39e2bb9f554355564646de99ac602cc6349cf8c1e236a7de7637d93" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004d0fb17ccd8fafe827e0c1afc5d8d80366e2b20e7f14a563a2ba50469d84375e868612569d39e2bb9f554355564646de99ac602cc6349cf8c1e236a7de7637d93", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0PsXzNj6/oJ+DBr8XY2ANm4rIOfx\nSlY6K6UEadhDdehoYSVp054rufVUNVVkZG3pmsYCzGNJz4weI2p952N9kw==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 332, + "comment" : "edge case for u2", + "msg" : "313233343030", + "sig" : "304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022100bfffffff3ea3677e082b9310572620ae19933a9e65b285598711c77298815ad3", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04836f33bbc1dc0d3d3abbcef0d91f11e2ac4181076c9af0a22b1e4309d3edb2769ab443ff6f901e30c773867582997c2bec2b0cb8120d760236f3a95bbe881f75", + "wx" : "00836f33bbc1dc0d3d3abbcef0d91f11e2ac4181076c9af0a22b1e4309d3edb276", + "wy" : "009ab443ff6f901e30c773867582997c2bec2b0cb8120d760236f3a95bbe881f75" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004836f33bbc1dc0d3d3abbcef0d91f11e2ac4181076c9af0a22b1e4309d3edb2769ab443ff6f901e30c773867582997c2bec2b0cb8120d760236f3a95bbe881f75", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEg28zu8HcDT06u87w2R8R4qxBgQds\nmvCiKx5DCdPtsnaatEP/b5AeMMdzhnWCmXwr7CsMuBINdgI286lbvogfdQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 333, + "comment" : "edge case for u2", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0220266666663bbbbbbbe6666666666666665b37902e023fab7c8f055d86e5cc41f4", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "0492f99fbe973ed4a299719baee4b432741237034dec8d72ba5103cb33e55feeb8033dd0e91134c734174889f3ebcf1b7a1ac05767289280ee7a794cebd6e69697", + "wx" : "0092f99fbe973ed4a299719baee4b432741237034dec8d72ba5103cb33e55feeb8", + "wy" : "033dd0e91134c734174889f3ebcf1b7a1ac05767289280ee7a794cebd6e69697" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000492f99fbe973ed4a299719baee4b432741237034dec8d72ba5103cb33e55feeb8033dd0e91134c734174889f3ebcf1b7a1ac05767289280ee7a794cebd6e69697", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkvmfvpc+1KKZcZuu5LQydBI3A03s\njXK6UQPLM+Vf7rgDPdDpETTHNBdIifPrzxt6GsBXZyiSgO56eUzr1uaWlw==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 334, + "comment" : "edge case for u2", + "msg" : "313233343030", + "sig" : "304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022100bfffffff36db6db7a492492492492492146c573f4c6dfc8d08a443e258970b09", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04d35ba58da30197d378e618ec0fa7e2e2d12cffd73ebbb2049d130bba434af09eff83986e6875e41ea432b7585a49b3a6c77cbb3c47919f8e82874c794635c1d2", + "wx" : "00d35ba58da30197d378e618ec0fa7e2e2d12cffd73ebbb2049d130bba434af09e", + "wy" : "00ff83986e6875e41ea432b7585a49b3a6c77cbb3c47919f8e82874c794635c1d2" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004d35ba58da30197d378e618ec0fa7e2e2d12cffd73ebbb2049d130bba434af09eff83986e6875e41ea432b7585a49b3a6c77cbb3c47919f8e82874c794635c1d2", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE01uljaMBl9N45hjsD6fi4tEs/9c+\nu7IEnRMLukNK8J7/g5huaHXkHqQyt1haSbOmx3y7PEeRn46Ch0x5RjXB0g==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 335, + "comment" : "edge case for u2", + "msg" : "313233343030", + "sig" : "304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd022100bfffffff2aaaaaab7fffffffffffffffc815d0e60b3e596ecb1ad3a27cfd49c4", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "048651ce490f1b46d73f3ff475149be29136697334a519d7ddab0725c8d0793224e11c65bd8ca92dc8bc9ae82911f0b52751ce21dd9003ae60900bd825f590cc28", + "wx" : "008651ce490f1b46d73f3ff475149be29136697334a519d7ddab0725c8d0793224", + "wy" : "00e11c65bd8ca92dc8bc9ae82911f0b52751ce21dd9003ae60900bd825f590cc28" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200048651ce490f1b46d73f3ff475149be29136697334a519d7ddab0725c8d0793224e11c65bd8ca92dc8bc9ae82911f0b52751ce21dd9003ae60900bd825f590cc28", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhlHOSQ8bRtc/P/R1FJvikTZpczSl\nGdfdqwclyNB5MiThHGW9jKktyLya6CkR8LUnUc4h3ZADrmCQC9gl9ZDMKA==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 336, + "comment" : "edge case for u2", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd02207fffffff55555555ffffffffffffffffd344a71e6f651458a27bdc81fd976e37", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "046d8e1b12c831a0da8795650ff95f101ed921d9e2f72b15b1cdaca9826b9cfc6def6d63e2bc5c089570394a4bc9f892d5e6c7a6a637b20469a58c106ad486bf37", + "wx" : "6d8e1b12c831a0da8795650ff95f101ed921d9e2f72b15b1cdaca9826b9cfc6d", + "wy" : "00ef6d63e2bc5c089570394a4bc9f892d5e6c7a6a637b20469a58c106ad486bf37" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200046d8e1b12c831a0da8795650ff95f101ed921d9e2f72b15b1cdaca9826b9cfc6def6d63e2bc5c089570394a4bc9f892d5e6c7a6a637b20469a58c106ad486bf37", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbY4bEsgxoNqHlWUP+V8QHtkh2eL3\nKxWxzaypgmuc/G3vbWPivFwIlXA5SkvJ+JLV5sempjeyBGmljBBq1Ia/Nw==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 337, + "comment" : "edge case for u2", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd02203fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192aa", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "040ae580bae933b4ef2997cbdbb0922328ca9a410f627a0f7dff24cb4d920e15428911e7f8cc365a8a88eb81421a361ccc2b99e309d8dcd9a98ba83c3949d893e3", + "wx" : "0ae580bae933b4ef2997cbdbb0922328ca9a410f627a0f7dff24cb4d920e1542", + "wy" : "008911e7f8cc365a8a88eb81421a361ccc2b99e309d8dcd9a98ba83c3949d893e3" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200040ae580bae933b4ef2997cbdbb0922328ca9a410f627a0f7dff24cb4d920e15428911e7f8cc365a8a88eb81421a361ccc2b99e309d8dcd9a98ba83c3949d893e3", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECuWAuukztO8pl8vbsJIjKMqaQQ9i\neg99/yTLTZIOFUKJEef4zDZaiojrgUIaNhzMK5njCdjc2amLqDw5SdiT4w==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 338, + "comment" : "edge case for u2", + "msg" : "313233343030", + "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd02205d8ecd64a4eeba466815ddf3a4de9a8e6abd9c5db0a01eb80343553da648428f", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "045b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc46963838a40f2a36092e9004e92d8d940cf5638550ce672ce8b8d4e15eba5499249e9", + "wx" : "5b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc46963", + "wy" : "00838a40f2a36092e9004e92d8d940cf5638550ce672ce8b8d4e15eba5499249e9" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200045b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc46963838a40f2a36092e9004e92d8d940cf5638550ce672ce8b8d4e15eba5499249e9", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEW4Ev1SGq+mmDWoSczm+962mDtELS\nRE/nDhNMAn/EaWODikDyo2CS6QBOktjZQM9WOFUM5nLOi41OFeulSZJJ6Q==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 339, + "comment" : "point duplication during verification", + "msg" : "313233343030", + "sig" : "304502206f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569022100bb726660235793aa9957a61e76e00c2c435109cf9a15dd624d53f4301047856b", + "result" : "valid", + "flags" : [ + "PointDuplication" + ] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "045b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc469637c75bf0c5c9f6d17ffb16d2726bf30a9c7aaf31a8d317472b1ea145ab66db616", + "wx" : "5b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc46963", + "wy" : "7c75bf0c5c9f6d17ffb16d2726bf30a9c7aaf31a8d317472b1ea145ab66db616" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200045b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc469637c75bf0c5c9f6d17ffb16d2726bf30a9c7aaf31a8d317472b1ea145ab66db616", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEW4Ev1SGq+mmDWoSczm+962mDtELS\nRE/nDhNMAn/EaWN8db8MXJ9tF/+xbScmvzCpx6rzGo0xdHKx6hRatm22Fg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 340, + "comment" : "duplication bug", + "msg" : "313233343030", + "sig" : "304502206f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569022100bb726660235793aa9957a61e76e00c2c435109cf9a15dd624d53f4301047856b", + "result" : "invalid", + "flags" : [ + "PointDuplication" + ] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "046adda82b90261b0f319faa0d878665a6b6da497f09c903176222c34acfef72a647e6f50dcc40ad5d9b59f7602bb222fad71a41bf5e1f9df4959a364c62e488d9", + "wx" : "6adda82b90261b0f319faa0d878665a6b6da497f09c903176222c34acfef72a6", + "wy" : "47e6f50dcc40ad5d9b59f7602bb222fad71a41bf5e1f9df4959a364c62e488d9" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200046adda82b90261b0f319faa0d878665a6b6da497f09c903176222c34acfef72a647e6f50dcc40ad5d9b59f7602bb222fad71a41bf5e1f9df4959a364c62e488d9", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEat2oK5AmGw8xn6oNh4ZlprbaSX8J\nyQMXYiLDSs/vcqZH5vUNzECtXZtZ92ArsiL61xpBv14fnfSVmjZMYuSI2Q==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 341, + "comment" : "point with x-coordinate 0", + "msg" : "313233343030", + "sig" : "30250201010220555555550000000055555555555555553ef7a8e48d07df81a693439654210c70", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "042fca0d0a47914de77ed56e7eccc3276a601120c6df0069c825c8f6a01c9f382065f3450a1d17c6b24989a39beb1c7decfca8384fbdc294418e5d807b3c6ed7de", + "wx" : "2fca0d0a47914de77ed56e7eccc3276a601120c6df0069c825c8f6a01c9f3820", + "wy" : "65f3450a1d17c6b24989a39beb1c7decfca8384fbdc294418e5d807b3c6ed7de" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200042fca0d0a47914de77ed56e7eccc3276a601120c6df0069c825c8f6a01c9f382065f3450a1d17c6b24989a39beb1c7decfca8384fbdc294418e5d807b3c6ed7de", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEL8oNCkeRTed+1W5+zMMnamARIMbf\nAGnIJcj2oByfOCBl80UKHRfGskmJo5vrHH3s/Kg4T73ClEGOXYB7PG7X3g==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 342, + "comment" : "point with x-coordinate 0", + "msg" : "313233343030", + "sig" : "3045022101000000000000000000000000000000000000000000000000000000000000000002203333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aa9", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04dd86d3b5f4a13e8511083b78002081c53ff467f11ebd98a51a633db76665d25045d5c8200c89f2fa10d849349226d21d8dfaed6ff8d5cb3e1b7e17474ebc18f7", + "wx" : "00dd86d3b5f4a13e8511083b78002081c53ff467f11ebd98a51a633db76665d250", + "wy" : "45d5c8200c89f2fa10d849349226d21d8dfaed6ff8d5cb3e1b7e17474ebc18f7" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004dd86d3b5f4a13e8511083b78002081c53ff467f11ebd98a51a633db76665d25045d5c8200c89f2fa10d849349226d21d8dfaed6ff8d5cb3e1b7e17474ebc18f7", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3YbTtfShPoURCDt4ACCBxT/0Z/Ee\nvZilGmM9t2Zl0lBF1cggDIny+hDYSTSSJtIdjfrtb/jVyz4bfhdHTrwY9w==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 343, + "comment" : "comparison with point at infinity ", + "msg" : "313233343030", + "sig" : "30440220555555550000000055555555555555553ef7a8e48d07df81a693439654210c7002203333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aa9", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "044fea55b32cb32aca0c12c4cd0abfb4e64b0f5a516e578c016591a93f5a0fbcc5d7d3fd10b2be668c547b212f6bb14c88f0fecd38a8a4b2c785ed3be62ce4b280", + "wx" : "4fea55b32cb32aca0c12c4cd0abfb4e64b0f5a516e578c016591a93f5a0fbcc5", + "wy" : "00d7d3fd10b2be668c547b212f6bb14c88f0fecd38a8a4b2c785ed3be62ce4b280" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200044fea55b32cb32aca0c12c4cd0abfb4e64b0f5a516e578c016591a93f5a0fbcc5d7d3fd10b2be668c547b212f6bb14c88f0fecd38a8a4b2c785ed3be62ce4b280", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAET+pVsyyzKsoMEsTNCr+05ksPWlFu\nV4wBZZGpP1oPvMXX0/0Qsr5mjFR7IS9rsUyI8P7NOKiksseF7TvmLOSygA==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 344, + "comment" : "extreme value for k and edgecase s", + "msg" : "313233343030", + "sig" : "304402207cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc476699780220555555550000000055555555555555553ef7a8e48d07df81a693439654210c70", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e", + "wx" : "00c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107", + "wy" : "00bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExqdxUnAkIneSFwpvju5zW/Mrf5iv\nZp6tKZgC4y18MQe8O0teZauIe700NXKz5WGSYf46Bz4v/XhBL3JoZ9tYng==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 345, + "comment" : "extreme value for k and s^-1", + "msg" : "313233343030", + "sig" : "304502207cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978022100b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04851c2bbad08e54ec7a9af99f49f03644d6ec6d59b207fec98de85a7d15b956efcee9960283045075684b410be8d0f7494b91aa2379f60727319f10ddeb0fe9d6", + "wx" : "00851c2bbad08e54ec7a9af99f49f03644d6ec6d59b207fec98de85a7d15b956ef", + "wy" : "00cee9960283045075684b410be8d0f7494b91aa2379f60727319f10ddeb0fe9d6" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004851c2bbad08e54ec7a9af99f49f03644d6ec6d59b207fec98de85a7d15b956efcee9960283045075684b410be8d0f7494b91aa2379f60727319f10ddeb0fe9d6", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhRwrutCOVOx6mvmfSfA2RNbsbVmy\nB/7JjehafRW5Vu/O6ZYCgwRQdWhLQQvo0PdJS5GqI3n2BycxnxDd6w/p1g==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 346, + "comment" : "extreme value for k and s^-1", + "msg" : "313233343030", + "sig" : "304502207cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978022100cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04f6417c8a670584e388676949e53da7fc55911ff68318d1bf3061205acb19c48f8f2b743df34ad0f72674acb7505929784779cd9ac916c3669ead43026ab6d43f", + "wx" : "00f6417c8a670584e388676949e53da7fc55911ff68318d1bf3061205acb19c48f", + "wy" : "008f2b743df34ad0f72674acb7505929784779cd9ac916c3669ead43026ab6d43f" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004f6417c8a670584e388676949e53da7fc55911ff68318d1bf3061205acb19c48f8f2b743df34ad0f72674acb7505929784779cd9ac916c3669ead43026ab6d43f", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9kF8imcFhOOIZ2lJ5T2n/FWRH/aD\nGNG/MGEgWssZxI+PK3Q980rQ9yZ0rLdQWSl4R3nNmskWw2aerUMCarbUPw==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 347, + "comment" : "extreme value for k and s^-1", + "msg" : "313233343030", + "sig" : "304402207cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997802203333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaa", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04501421277be45a5eefec6c639930d636032565af420cf3373f557faa7f8a06438673d6cb6076e1cfcdc7dfe7384c8e5cac08d74501f2ae6e89cad195d0aa1371", + "wx" : "501421277be45a5eefec6c639930d636032565af420cf3373f557faa7f8a0643", + "wy" : "008673d6cb6076e1cfcdc7dfe7384c8e5cac08d74501f2ae6e89cad195d0aa1371" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004501421277be45a5eefec6c639930d636032565af420cf3373f557faa7f8a06438673d6cb6076e1cfcdc7dfe7384c8e5cac08d74501f2ae6e89cad195d0aa1371", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUBQhJ3vkWl7v7GxjmTDWNgMlZa9C\nDPM3P1V/qn+KBkOGc9bLYHbhz83H3+c4TI5crAjXRQHyrm6JytGV0KoTcQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 348, + "comment" : "extreme value for k and s^-1", + "msg" : "313233343030", + "sig" : "304402207cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978022049249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "040d935bf9ffc115a527735f729ca8a4ca23ee01a4894adf0e3415ac84e808bb343195a3762fea29ed38912bd9ea6c4fde70c3050893a4375850ce61d82eba33c5", + "wx" : "0d935bf9ffc115a527735f729ca8a4ca23ee01a4894adf0e3415ac84e808bb34", + "wy" : "3195a3762fea29ed38912bd9ea6c4fde70c3050893a4375850ce61d82eba33c5" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200040d935bf9ffc115a527735f729ca8a4ca23ee01a4894adf0e3415ac84e808bb343195a3762fea29ed38912bd9ea6c4fde70c3050893a4375850ce61d82eba33c5", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDZNb+f/BFaUnc19ynKikyiPuAaSJ\nSt8ONBWshOgIuzQxlaN2L+op7TiRK9nqbE/ecMMFCJOkN1hQzmHYLrozxQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 349, + "comment" : "extreme value for k", + "msg" : "313233343030", + "sig" : "304402207cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978022016a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "045e59f50708646be8a589355014308e60b668fb670196206c41e748e64e4dca215de37fee5c97bcaf7144d5b459982f52eeeafbdf03aacbafef38e213624a01de", + "wx" : "5e59f50708646be8a589355014308e60b668fb670196206c41e748e64e4dca21", + "wy" : "5de37fee5c97bcaf7144d5b459982f52eeeafbdf03aacbafef38e213624a01de" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200045e59f50708646be8a589355014308e60b668fb670196206c41e748e64e4dca215de37fee5c97bcaf7144d5b459982f52eeeafbdf03aacbafef38e213624a01de", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXln1Bwhka+iliTVQFDCOYLZo+2cB\nliBsQedI5k5NyiFd43/uXJe8r3FE1bRZmC9S7ur73wOqy6/vOOITYkoB3g==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 350, + "comment" : "extreme value for k and edgecase s", + "msg" : "313233343030", + "sig" : "304402206b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2960220555555550000000055555555555555553ef7a8e48d07df81a693439654210c70", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04169fb797325843faff2f7a5b5445da9e2fd6226f7ef90ef0bfe924104b02db8e7bbb8de662c7b9b1cf9b22f7a2e582bd46d581d68878efb2b861b131d8a1d667", + "wx" : "169fb797325843faff2f7a5b5445da9e2fd6226f7ef90ef0bfe924104b02db8e", + "wy" : "7bbb8de662c7b9b1cf9b22f7a2e582bd46d581d68878efb2b861b131d8a1d667" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004169fb797325843faff2f7a5b5445da9e2fd6226f7ef90ef0bfe924104b02db8e7bbb8de662c7b9b1cf9b22f7a2e582bd46d581d68878efb2b861b131d8a1d667", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFp+3lzJYQ/r/L3pbVEXani/WIm9+\n+Q7wv+kkEEsC2457u43mYse5sc+bIvei5YK9RtWB1oh477K4YbEx2KHWZw==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 351, + "comment" : "extreme value for k and s^-1", + "msg" : "313233343030", + "sig" : "304502206b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296022100b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04271cd89c000143096b62d4e9e4ca885aef2f7023d18affdaf8b7b548981487540a1c6e954e32108435b55fa385b0f76481a609b9149ccb4b02b2ca47fe8e4da5", + "wx" : "271cd89c000143096b62d4e9e4ca885aef2f7023d18affdaf8b7b54898148754", + "wy" : "0a1c6e954e32108435b55fa385b0f76481a609b9149ccb4b02b2ca47fe8e4da5" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004271cd89c000143096b62d4e9e4ca885aef2f7023d18affdaf8b7b548981487540a1c6e954e32108435b55fa385b0f76481a609b9149ccb4b02b2ca47fe8e4da5", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJxzYnAABQwlrYtTp5MqIWu8vcCPR\niv/a+Le1SJgUh1QKHG6VTjIQhDW1X6OFsPdkgaYJuRScy0sCsspH/o5NpQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 352, + "comment" : "extreme value for k and s^-1", + "msg" : "313233343030", + "sig" : "304502206b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296022100cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "043d0bc7ed8f09d2cb7ddb46ebc1ed799ab1563a9ab84bf524587a220afe499c12e22dc3b3c103824a4f378d96adb0a408abf19ce7d68aa6244f78cb216fa3f8df", + "wx" : "3d0bc7ed8f09d2cb7ddb46ebc1ed799ab1563a9ab84bf524587a220afe499c12", + "wy" : "00e22dc3b3c103824a4f378d96adb0a408abf19ce7d68aa6244f78cb216fa3f8df" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200043d0bc7ed8f09d2cb7ddb46ebc1ed799ab1563a9ab84bf524587a220afe499c12e22dc3b3c103824a4f378d96adb0a408abf19ce7d68aa6244f78cb216fa3f8df", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPQvH7Y8J0st920brwe15mrFWOpq4\nS/UkWHoiCv5JnBLiLcOzwQOCSk83jZatsKQIq/Gc59aKpiRPeMshb6P43w==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 353, + "comment" : "extreme value for k and s^-1", + "msg" : "313233343030", + "sig" : "304402206b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29602203333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaa", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04a6c885ade1a4c566f9bb010d066974abb281797fa701288c721bcbd23663a9b72e424b690957168d193a6096fc77a2b004a9c7d467e007e1f2058458f98af316", + "wx" : "00a6c885ade1a4c566f9bb010d066974abb281797fa701288c721bcbd23663a9b7", + "wy" : "2e424b690957168d193a6096fc77a2b004a9c7d467e007e1f2058458f98af316" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004a6c885ade1a4c566f9bb010d066974abb281797fa701288c721bcbd23663a9b72e424b690957168d193a6096fc77a2b004a9c7d467e007e1f2058458f98af316", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpsiFreGkxWb5uwENBml0q7KBeX+n\nASiMchvL0jZjqbcuQktpCVcWjRk6YJb8d6KwBKnH1GfgB+HyBYRY+YrzFg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 354, + "comment" : "extreme value for k and s^-1", + "msg" : "313233343030", + "sig" : "304402206b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296022049249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "048d3c2c2c3b765ba8289e6ac3812572a25bf75df62d87ab7330c3bdbad9ebfa5c4c6845442d66935b238578d43aec54f7caa1621d1af241d4632e0b780c423f5d", + "wx" : "008d3c2c2c3b765ba8289e6ac3812572a25bf75df62d87ab7330c3bdbad9ebfa5c", + "wy" : "4c6845442d66935b238578d43aec54f7caa1621d1af241d4632e0b780c423f5d" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200048d3c2c2c3b765ba8289e6ac3812572a25bf75df62d87ab7330c3bdbad9ebfa5c4c6845442d66935b238578d43aec54f7caa1621d1af241d4632e0b780c423f5d", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjTwsLDt2W6gonmrDgSVyolv3XfYt\nh6tzMMO9utnr+lxMaEVELWaTWyOFeNQ67FT3yqFiHRryQdRjLgt4DEI/XQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 355, + "comment" : "extreme value for k", + "msg" : "313233343030", + "sig" : "304402206b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296022016a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "wx" : "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", + "wy" : "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEaxfR8uEsQkf4vOblY6RA8ncDfYEt\n6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9Q==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 356, + "comment" : "testing point duplication", + "msg" : "313233343030", + "sig" : "3045022100bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230220249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 357, + "comment" : "testing point duplication", + "msg" : "313233343030", + "sig" : "3044022044a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e0220249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a", + "wx" : "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", + "wy" : "00b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEaxfR8uEsQkf4vOblY6RA8ncDfYEt\n6zOg9KE5RdiYwpawHL0cAeWAZXEYFLWD8GHp1DHMqZTOoTE0Sb+XyECuCg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 358, + "comment" : "testing point duplication", + "msg" : "313233343030", + "sig" : "3045022100bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca6050230220249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 359, + "comment" : "testing point duplication", + "msg" : "313233343030", + "sig" : "3044022044a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e0220249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "0404aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "wx" : "04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5", + "wy" : "0087d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000404aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEBKrsc2NXJvIT+4qeZNo7hjLkFJWp\nRNAEW1IuunJA+tWH2TFXmKqjpboBd1eHztBeqve04J/IHW0apUboNl1SXQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 360, + "comment" : "pseudorandom signature", + "msg" : "", + "sig" : "3045022100b292a619339f6e567a305c951c0dcbcc42d16e47f219f9e98e76e09d8770b34a02200177e60492c5a8242f76f07bfe3661bde59ec2a17ce5bd2dab2abebdf89a62e2", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 361, + "comment" : "pseudorandom signature", + "msg" : "4d7367", + "sig" : "30450220530bd6b0c9af2d69ba897f6b5fb59695cfbf33afe66dbadcf5b8d2a2a6538e23022100d85e489cb7a161fd55ededcedbf4cc0c0987e3e3f0f242cae934c72caa3f43e9", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 362, + "comment" : "pseudorandom signature", + "msg" : "313233343030", + "sig" : "3046022100a8ea150cb80125d7381c4c1f1da8e9de2711f9917060406a73d7904519e51388022100f3ab9fa68bd47973a73b2d40480c2ba50c22c9d76ec217257288293285449b86", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 363, + "comment" : "pseudorandom signature", + "msg" : "0000000000000000000000000000000000000000", + "sig" : "3045022100986e65933ef2ed4ee5aada139f52b70539aaf63f00a91f29c69178490d57fb7102203dafedfb8da6189d372308cbf1489bbbdabf0c0217d1c0ff0f701aaa7a694b9c", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "044f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", + "wx" : "4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000", + "wy" : "00ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200044f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETzN8z9Z3JqgF5PFgCuKEnfOAfsoR\nc4Ajn72BaQAAAADtneoSTMjDlkFkEemIww9CfrUEr0OjFGzV336mBmbWhQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 364, + "comment" : "x-coordinate of the public key has many trailing 0's", + "msg" : "4d657373616765", + "sig" : "3046022100d434e262a49eab7781e353a3565e482550dd0fd5defa013c7f29745eff3569f10221009b0c0a93f267fb6052fd8077be769c2b98953195d7bc10de844218305c6ba17a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 365, + "comment" : "x-coordinate of the public key has many trailing 0's", + "msg" : "4d657373616765", + "sig" : "304402200fe774355c04d060f76d79fd7a772e421463489221bf0a33add0be9b1979110b0220500dcba1c69a8fbd43fa4f57f743ce124ca8b91a1f325f3fac6181175df55737", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 366, + "comment" : "x-coordinate of the public key has many trailing 0's", + "msg" : "4d657373616765", + "sig" : "3045022100bb40bf217bed3fb3950c7d39f03d36dc8e3b2cd79693f125bfd06595ee1135e30220541bf3532351ebb032710bdb6a1bf1bfc89a1e291ac692b3fa4780745bb55677", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "043cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", + "wx" : "3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935", + "wy" : "0084fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200043cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPPA9YU2JOc/UmaB4c/rCgWGPBrj/\nh+gBXD9JcmUASTWE+hdNeRxyvyzjiAqJYN0qfHoTOKgvhanlnNvegAAAAA==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 367, + "comment" : "y-coordinate of the public key has many trailing 0's", + "msg" : "4d657373616765", + "sig" : "30440220664eb7ee6db84a34df3c86ea31389a5405badd5ca99231ff556d3e75a233e73a022059f3c752e52eca46137642490a51560ce0badc678754b8f72e51a2901426a1bd", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 368, + "comment" : "y-coordinate of the public key has many trailing 0's", + "msg" : "4d657373616765", + "sig" : "304502204cd0429bbabd2827009d6fcd843d4ce39c3e42e2d1631fd001985a79d1fd8b430221009638bf12dd682f60be7ef1d0e0d98f08b7bca77a1a2b869ae466189d2acdabe3", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 369, + "comment" : "y-coordinate of the public key has many trailing 0's", + "msg" : "4d657373616765", + "sig" : "3046022100e56c6ea2d1b017091c44d8b6cb62b9f460e3ce9aed5e5fd41e8added97c56c04022100a308ec31f281e955be20b457e463440b4fcf2b80258078207fc1378180f89b55", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "043cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", + "wx" : "3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935", + "wy" : "7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200043cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPPA9YU2JOc/UmaB4c/rCgWGPBrj/\nh+gBXD9JcmUASTV7BeixhuONQdMcd/V2nyLVg4XsyFfQelYaYyQhf////w==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 370, + "comment" : "y-coordinate of the public key has many trailing 1's", + "msg" : "4d657373616765", + "sig" : "304402201158a08d291500b4cabed3346d891eee57c176356a2624fb011f8fbbf34668300220228a8c486a736006e082325b85290c5bc91f378b75d487dda46798c18f285519", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 371, + "comment" : "y-coordinate of the public key has many trailing 1's", + "msg" : "4d657373616765", + "sig" : "3045022100b1db9289649f59410ea36b0c0fc8d6aa2687b29176939dd23e0dde56d309fa9d02203e1535e4280559015b0dbd987366dcf43a6d1af5c23c7d584e1c3f48a1251336", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 372, + "comment" : "y-coordinate of the public key has many trailing 1's", + "msg" : "4d657373616765", + "sig" : "3046022100b7b16e762286cb96446aa8d4e6e7578b0a341a79f2dd1a220ac6f0ca4e24ed86022100ddc60a700a139b04661c547d07bbb0721780146df799ccf55e55234ecb8f12bc", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "042829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", + "wx" : "2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff", + "wy" : "00a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200042829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKCnDH6ouQA40TtlLyj/NBUWVbrz+\nitD236X/jv////+gGq+vAA5SWFhVr6dnat4oQRMJkFLfV+frO9N+vrkiLg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 373, + "comment" : "x-coordinate of the public key has many trailing 1's", + "msg" : "4d657373616765", + "sig" : "3045022100d82a7c2717261187c8e00d8df963ff35d796edad36bc6e6bd1c91c670d9105b402203dcabddaf8fcaa61f4603e7cbac0f3c0351ecd5988efb23f680d07debd139929", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 374, + "comment" : "x-coordinate of the public key has many trailing 1's", + "msg" : "4d657373616765", + "sig" : "304402205eb9c8845de68eb13d5befe719f462d77787802baff30ce96a5cba063254af7802202c026ae9be2e2a5e7ca0ff9bbd92fb6e44972186228ee9a62b87ddbe2ef66fb5", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 375, + "comment" : "x-coordinate of the public key has many trailing 1's", + "msg" : "4d657373616765", + "sig" : "304602210096843dd03c22abd2f3b782b170239f90f277921becc117d0404a8e4e36230c28022100f2be378f526f74a543f67165976de9ed9a31214eb4d7e6db19e1ede123dd991d", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", + "wx" : "00fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5", + "wy" : "5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE////+UgIHmoEWN2PnnOPJmX/kFmt\naqwHCDGMTKmnpPVairy6LdqEdDEe5UFJuXPK4MD7iVV60L945lKaFmO9cw==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 376, + "comment" : "x-coordinate of the public key is large", + "msg" : "4d657373616765", + "sig" : "30440220766456dce1857c906f9996af729339464d27e9d98edc2d0e3b760297067421f60220402385ecadae0d8081dccaf5d19037ec4e55376eced699e93646bfbbf19d0b41", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 377, + "comment" : "x-coordinate of the public key is large", + "msg" : "4d657373616765", + "sig" : "3046022100c605c4b2edeab20419e6518a11b2dbc2b97ed8b07cced0b19c34f777de7b9fd9022100edf0f612c5f46e03c719647bc8af1b29b2cde2eda700fb1cff5e159d47326dba", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 378, + "comment" : "x-coordinate of the public key is large", + "msg" : "4d657373616765", + "sig" : "3046022100d48b68e6cabfe03cf6141c9ac54141f210e64485d9929ad7b732bfe3b7eb8a84022100feedae50c61bd00e19dc26f9b7e2265e4508c389109ad2f208f0772315b6c941", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "0400000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", + "wx" : "03fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e", + "wy" : "1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000400000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAAAAA/oV+WOUnV8DpvXH+G+eABXu\nsjrrv/EXOTe6dI4QmYcgcOjofFVfoTZZzKXX+tz8sAI+qIlUjKSK8rp+cQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 379, + "comment" : "x-coordinate of the public key is small", + "msg" : "4d657373616765", + "sig" : "3046022100b7c81457d4aeb6aa65957098569f0479710ad7f6595d5874c35a93d12a5dd4c7022100b7961a0b652878c2d568069a432ca18a1a9199f2ca574dad4b9e3a05c0a1cdb3", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 380, + "comment" : "x-coordinate of the public key is small", + "msg" : "4d657373616765", + "sig" : "304402206b01332ddb6edfa9a30a1321d5858e1ee3cf97e263e669f8de5e9652e76ff3f702205939545fced457309a6a04ace2bd0f70139c8f7d86b02cb1cc58f9e69e96cd5a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 381, + "comment" : "x-coordinate of the public key is small", + "msg" : "4d657373616765", + "sig" : "3046022100efdb884720eaeadc349f9fc356b6c0344101cd2fd8436b7d0e6a4fb93f106361022100f24bee6ad5dc05f7613975473aadf3aacba9e77de7d69b6ce48cb60d8113385d", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", + "wx" : "00bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015", + "wy" : "1352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvLspFMefBF6qbsu8YSgWs75dLWeW\ncH2BJen4UcGK8BUAAAAAE1K7Sg+i6kzOuatj3WhK3loRJ7zzAKaYpxk7wg==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 382, + "comment" : "y-coordinate of the public key is small", + "msg" : "4d657373616765", + "sig" : "3044022031230428405560dcb88fb5a646836aea9b23a23dd973dcbe8014c87b8b20eb0702200f9344d6e812ce166646747694a41b0aaf97374e19f3c5fb8bd7ae3d9bd0beff", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 383, + "comment" : "y-coordinate of the public key is small", + "msg" : "4d657373616765", + "sig" : "3046022100caa797da65b320ab0d5c470cda0b36b294359c7db9841d679174db34c4855743022100cf543a62f23e212745391aaf7505f345123d2685ee3b941d3de6d9b36242e5a0", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 384, + "comment" : "y-coordinate of the public key is small", + "msg" : "4d657373616765", + "sig" : "304502207e5f0ab5d900d3d3d7867657e5d6d36519bc54084536e7d21c336ed8001859450221009450c07f201faec94b82dfb322e5ac676688294aad35aa72e727ff0b19b646aa", + "result" : "valid", + "flags" : [] + } + ] + }, + { + "key" : { + "curve" : "secp256r1", + "keySize" : 256, + "type" : "EcPublicKey", + "uncompressed" : "04bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "wx" : "00bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015", + "wy" : "00fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d" + }, + "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", + "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvLspFMefBF6qbsu8YSgWs75dLWeW\ncH2BJen4UcGK8BX////+7K1EtvBdFbMxRlScIpe1IqXu2EMM/1lnWObEPQ==\n-----END PUBLIC KEY-----", + "sha" : "SHA-256", + "type" : "EcdsaVerify", + "tests" : [ + { + "tcId" : 385, + "comment" : "y-coordinate of the public key is large", + "msg" : "4d657373616765", + "sig" : "3046022100d7d70c581ae9e3f66dc6a480bf037ae23f8a1e4a2136fe4b03aa69f0ca25b35602210089c460f8a5a5c2bbba962c8a3ee833a413e85658e62a59e2af41d9127cc47224", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 386, + "comment" : "y-coordinate of the public key is large", + "msg" : "4d657373616765", + "sig" : "30440220341c1b9ff3c83dd5e0dfa0bf68bcdf4bb7aa20c625975e5eeee34bb396266b34022072b69f061b750fd5121b22b11366fad549c634e77765a017902a67099e0a4469", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 387, + "comment" : "y-coordinate of the public key is large", + "msg" : "4d657373616765", + "sig" : "3045022070bebe684cdcb5ca72a42f0d873879359bd1781a591809947628d313a3814f67022100aec03aca8f5587a4d535fa31027bbe9cc0e464b1c3577f4c2dcde6b2094798a9", + "result" : "valid", + "flags" : [] + } + ] + } + ] +} diff --git a/libraries/crypto/tests/wycheproof.rs b/libraries/crypto/tests/wycheproof.rs new file mode 100644 index 0000000..910a768 --- /dev/null +++ b/libraries/crypto/tests/wycheproof.rs @@ -0,0 +1,217 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crypto::ecdsa; +use serde::Deserialize; +use std::collections::HashMap; +use std::error::Error; +use std::fs::File; +use std::io::BufReader; +use std::path::Path; + +mod asn1; + +#[test] +fn wycheproof() { + let wycheproof = load_tests("tests/data/ecdsa_secp256r1_sha256_test.json").unwrap(); + wycheproof.type_check(); + assert!(wycheproof.run_tests()); +} + +fn load_tests>(path: P) -> Result> { + let file = File::open(path)?; + let wycheproof = serde_json::from_reader(BufReader::new(file))?; + Ok(wycheproof) +} + +#[derive(Deserialize)] +#[allow(non_snake_case)] +struct Wycheproof { + algorithm: String, + #[allow(dead_code)] + generatorVersion: String, + #[allow(dead_code)] + numberOfTests: u32, + #[allow(dead_code)] + header: Vec, + notes: HashMap, + schema: String, + testGroups: Vec, +} + +impl Wycheproof { + fn type_check(&self) { + assert_eq!(self.algorithm, "ECDSA"); + assert_eq!(self.schema, "ecdsa_verify_schema.json"); + for group in &self.testGroups { + group.type_check(); + } + } + + fn run_tests(&self) -> bool { + let mut result = true; + for group in &self.testGroups { + result &= group.run_tests(&self.notes); + } + result + } +} + +#[derive(Deserialize)] +#[allow(non_snake_case)] +struct TestGroup { + key: Key, + #[allow(dead_code)] + keyDer: String, + #[allow(dead_code)] + keyPem: String, + sha: String, + r#type: String, + tests: Vec, +} + +impl TestGroup { + fn type_check(&self) { + self.key.type_check(); + assert_eq!(self.sha, "SHA-256"); + assert_eq!(self.r#type, "EcdsaVerify"); + for test in &self.tests { + test.type_check(); + } + } + + fn run_tests(&self, notes: &HashMap) -> bool { + let key = self.key.get_key(); + let mut result = true; + for test in &self.tests { + result &= test.run_test(&key, notes); + } + result + } +} + +#[derive(Deserialize)] +#[allow(non_snake_case)] +struct Key { + curve: String, + keySize: u32, + r#type: String, + uncompressed: String, + #[allow(dead_code)] + wx: String, + #[allow(dead_code)] + wy: String, +} + +impl Key { + fn type_check(&self) { + assert_eq!(self.curve, "secp256r1"); + assert_eq!(self.keySize, 256); + assert_eq!(self.r#type, "EcPublicKey"); + assert_eq!(self.uncompressed.len(), 130); + } + + fn get_key(&self) -> Option { + let bytes = hex::decode(&self.uncompressed).unwrap(); + ecdsa::PubKey::from_bytes_uncompressed(&bytes) + } +} + +#[derive(Deserialize, Debug)] +#[allow(non_camel_case_types)] +enum TestResult { + valid, + invalid, + acceptable, +} + +#[derive(Deserialize)] +#[allow(non_snake_case)] +struct TestCase { + tcId: u32, + comment: String, + msg: String, + sig: String, + result: TestResult, + flags: Vec, +} + +impl TestCase { + fn type_check(&self) { + // Nothing to do. + } + + fn print(&self, notes: &HashMap, error_msg: &str) { + println!("Test case #{} => {}", self.tcId, error_msg); + println!(" {}", self.comment); + println!(" result = {:?}", self.result); + for f in &self.flags { + println!( + " flag {} = {}", + f, + notes.get(f).map_or("unknown flag", |x| &x) + ); + } + } + + fn run_test(&self, key: &Option, notes: &HashMap) -> bool { + match key { + None => { + let pass = match self.result { + TestResult::invalid | TestResult::acceptable => true, + TestResult::valid => false, + }; + if !pass { + self.print(notes, "Invalid public key"); + } + pass + } + Some(k) => { + let msg = hex::decode(&self.msg).unwrap(); + let sig = hex::decode(&self.sig).unwrap(); + match asn1::parse_signature(sig.as_slice()) { + Err(e) => { + let pass = match self.result { + TestResult::invalid | TestResult::acceptable => true, + TestResult::valid => false, + }; + if !pass { + self.print(notes, "Invalid ASN.1 encoding for the signature"); + println!(" {:?}", e); + } + pass + } + Ok(signature) => { + let verified = k.verify_vartime::(&msg, &signature); + let pass = match self.result { + TestResult::acceptable => true, + TestResult::valid => verified, + TestResult::invalid => !verified, + }; + if !pass { + self.print( + notes, + &format!( + "Expected {:?} result, but the signature verification was {}", + self.result, verified + ), + ); + } + pass + } + } + } + } + } +} diff --git a/nrf52840dk_layout.ld b/nrf52840dk_layout.ld new file mode 100644 index 0000000..218b6bb --- /dev/null +++ b/nrf52840dk_layout.ld @@ -0,0 +1,19 @@ +/* Layout for the nRF52840-DK and nRF52840 dongle, used by the + * app in this repository. + */ + +MEMORY { + /* The application region is 64 bytes (0x40) */ + FLASH (rx) : ORIGIN = 0x00040040, LENGTH = 0x000BFFC0 + SRAM (rwx) : ORIGIN = 0x20020000, LENGTH = 128K +} + +/* + * Any change to STACK_SIZE should be accompanied by a corresponding change to + * `elf2tab`'s `--stack` option + */ +STACK_SIZE = 16384; + +MPU_MIN_ALIGN = 8K; + +INCLUDE layout.ld diff --git a/patches/libtock-rs/01-panic_console.patch b/patches/libtock-rs/01-panic_console.patch new file mode 100644 index 0000000..dd8f31c --- /dev/null +++ b/patches/libtock-rs/01-panic_console.patch @@ -0,0 +1,81 @@ +diff --git a/Cargo.toml b/Cargo.toml +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -7,6 +7,9 @@ + + [dependencies] + linked_list_allocator = "0.6.4" ++ ++[features] ++panic_console = [] + + [dev-dependencies] + corepack = { version = "0.4.0", default-features = false, features = ["alloc"] } +diff --git a/src/lang_items.rs b/src/lang_items.rs +index ab2c945..deef73b 100644 +--- a/src/lang_items.rs ++++ b/src/lang_items.rs +@@ -18,10 +18,14 @@ + //! `rustc_main`. That's covered by the `_start` function in the root of this + //! crate. + ++#[cfg(feature = "panic_console")] ++use crate::console::Console; + use crate::led; + use crate::timer; + use crate::timer::Duration; + use core::alloc::Layout; ++#[cfg(feature = "panic_console")] ++use core::fmt::Write; + use core::panic::PanicInfo; + + #[lang = "start"] +@@ -42,11 +46,7 @@ + } + } + +-#[panic_handler] +-fn panic_handler(_info: &PanicInfo) -> ! { ++fn flash_all_leds() -> ! { +- // Signal a panic using the LowLevelDebug capsule (if available). +- super::debug::low_level_status_code(1); +- + // Flash all LEDs (if available). + loop { + for led in led::all() { +@@ -60,6 +59,34 @@ + } + } + ++#[cfg(feature = "panic_console")] ++#[panic_handler] ++fn panic_handler(info: &PanicInfo) -> ! { ++ // Signal a panic using the LowLevelDebug capsule (if available). ++ super::debug::low_level_status_code(1); ++ ++ let mut console = Console::new(); ++ writeln!(console, "{}", info).ok(); ++ // Force the kernel to report the panic cause, by reading an invalid address. ++ // The memory protection unit should be setup by the Tock kernel to prevent apps from accessing ++ // address zero. ++ unsafe { ++ core::ptr::read_volatile(0 as *const usize); ++ } ++ // We still flash the LEDs in case for some reason the previous line didn't cause a crash in ++ // the kernel. ++ flash_all_leds(); ++} ++ ++#[cfg(not(feature = "panic_console"))] ++#[panic_handler] ++fn panic_handler(_info: &PanicInfo) -> ! { ++ // Signal a panic using the LowLevelDebug capsule (if available). ++ super::debug::low_level_status_code(1); ++ ++ flash_all_leds(); ++} ++ + #[alloc_error_handler] + fn cycle_leds(_: Layout) -> ! { + loop { + diff --git a/patches/libtock-rs/02-timer.patch b/patches/libtock-rs/02-timer.patch new file mode 100644 index 0000000..7b8a5d9 --- /dev/null +++ b/patches/libtock-rs/02-timer.patch @@ -0,0 +1,72 @@ +diff --git a/src/timer.rs b/src/timer.rs +index ae60b07..2e7d544 100644 +--- a/src/timer.rs ++++ b/src/timer.rs +@@ -178,7 +178,7 @@ impl<'a> Timer<'a> { + } + } + +-#[derive(Copy, Clone, Debug)] ++#[derive(Copy, Clone, Debug, PartialEq)] + pub struct ClockFrequency { + hz: usize, + } +@@ -196,21 +196,53 @@ pub struct ClockValue { + } + + impl ClockValue { ++ pub const fn new(num_ticks: isize, clock_hz: usize) -> ClockValue { ++ ClockValue { ++ num_ticks, ++ clock_frequency: ClockFrequency { hz: clock_hz }, ++ } ++ } ++ + pub fn num_ticks(&self) -> isize { + self.num_ticks + } + ++ // Computes (value * factor) / divisor, even when value * factor >= isize::MAX. ++ fn scale_int(value: isize, factor: isize, divisor: isize) -> isize { ++ // As long as isize is not i64, this should be fine. If not, this is an alternative: ++ // factor * (value / divisor) + ((value % divisor) * factor) / divisor ++ ((value as i64 * factor as i64) / divisor as i64) as isize ++ } ++ + pub fn ms(&self) -> isize { +- if self.num_ticks.abs() < isize::MAX / 1000 { +- (1000 * self.num_ticks) / self.clock_frequency.hz() as isize +- } else { +- 1000 * (self.num_ticks / self.clock_frequency.hz() as isize) +- } ++ ClockValue::scale_int(self.num_ticks, 1000, self.clock_frequency.hz() as isize) + } + + pub fn ms_f64(&self) -> f64 { + 1000.0 * (self.num_ticks as f64) / (self.clock_frequency.hz() as f64) + } ++ ++ pub fn wrapping_add(self, duration: Duration) -> ClockValue { ++ // This is a precision preserving formula for scaling an isize. ++ let duration_ticks = ++ ClockValue::scale_int(duration.ms, self.clock_frequency.hz() as isize, 1000); ++ ClockValue { ++ num_ticks: self.num_ticks.wrapping_add(duration_ticks), ++ clock_frequency: self.clock_frequency, ++ } ++ } ++ ++ pub fn wrapping_sub(self, other: ClockValue) -> Option> { ++ if self.clock_frequency == other.clock_frequency { ++ let clock_duration = ClockValue { ++ num_ticks: self.num_ticks - other.num_ticks, ++ clock_frequency: self.clock_frequency, ++ }; ++ Some(Duration::from_ms(clock_duration.ms())) ++ } else { ++ None ++ } ++ } + } + + pub struct Alarm { diff --git a/patches/libtock-rs/03-public_syscalls.patch b/patches/libtock-rs/03-public_syscalls.patch new file mode 100644 index 0000000..109b6cb --- /dev/null +++ b/patches/libtock-rs/03-public_syscalls.patch @@ -0,0 +1,13 @@ +diff --git a/src/lib.rs b/src/lib.rs +index 1d4f26b..c1483e9 100644 +--- a/src/lib.rs ++++ b/src/lib.rs +@@ -42,7 +42,7 @@ pub mod syscalls; + + #[cfg(not(any(target_arch = "arm", target_arch = "riscv32")))] + #[path = "syscalls_mock.rs"] +-mod syscalls; ++pub mod syscalls; + + #[cfg(any(target_arch = "arm", target_arch = "riscv32"))] + #[global_allocator] diff --git a/patches/libtock-rs/04-bigger_heap.patch b/patches/libtock-rs/04-bigger_heap.patch new file mode 100644 index 0000000..098737d --- /dev/null +++ b/patches/libtock-rs/04-bigger_heap.patch @@ -0,0 +1,13 @@ +diff --git a/src/entry_point.rs b/src/entry_point.rs +index a24958c..e907e33 100644 +--- a/src/entry_point.rs ++++ b/src/entry_point.rs +@@ -348,7 +348,7 @@ pub unsafe extern "C" fn rust_start(app_start: usize, stacktop: usize, app_heap_ + // Heap size is set using `elf2tab` with `--app-heap` option, which is + // currently at 1024. If you change the `elf2tab` heap size, make sure to + // make the corresponding change here. +- const HEAP_SIZE: usize = 1024; ++ const HEAP_SIZE: usize = 90000; + + // we could have also bss_end for app_heap_start + let app_heap_start = app_heap_break; diff --git a/patches/tock/01-persistent-storage.patch b/patches/tock/01-persistent-storage.patch new file mode 100644 index 0000000..1a356a3 --- /dev/null +++ b/patches/tock/01-persistent-storage.patch @@ -0,0 +1,323 @@ +diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs +index ddac9dbd..7e2a3298 100644 +--- a/boards/nordic/nrf52dk_base/src/lib.rs ++++ b/boards/nordic/nrf52dk_base/src/lib.rs +@@ -105,6 +105,7 @@ pub struct Platform { + // The nRF52dk does not have the flash chip on it, so we make this optional. + nonvolatile_storage: + Option<&'static capsules::nonvolatile_storage_driver::NonvolatileStorage<'static>>, ++ nvmc: &'static nrf52::nvmc::SyscallDriver, + } + + impl kernel::Platform for Platform { +@@ -128,6 +129,7 @@ impl kernel::Platform for Platform { + capsules::nonvolatile_storage_driver::DRIVER_NUM => { + f(self.nonvolatile_storage.map_or(None, |nv| Some(nv))) + } ++ nrf52::nvmc::DRIVER_NUM => f(Some(self.nvmc)), + kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)), + _ => f(None), + } +@@ -408,6 +410,14 @@ pub unsafe fn setup_board( + None + }; + ++ let nvmc = static_init!( ++ nrf52::nvmc::SyscallDriver, ++ nrf52::nvmc::SyscallDriver::new( ++ &nrf52::nvmc::NVMC, ++ board_kernel.create_grant(&memory_allocation_capability) ++ ) ++ ); ++ + // Start all of the clocks. Low power operation will require a better + // approach than this. + nrf52::clock::CLOCK.low_stop(); +@@ -441,6 +451,7 @@ pub unsafe fn setup_board( + alarm: alarm, + nonvolatile_storage: nonvolatile_storage, + ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability), ++ nvmc: nvmc, + }; + + platform.pconsole.start(); +diff --git a/chips/nrf52/src/nvmc.rs b/chips/nrf52/src/nvmc.rs +index 5abd2d84..5a726fdb 100644 +--- a/chips/nrf52/src/nvmc.rs ++++ b/chips/nrf52/src/nvmc.rs +@@ -3,6 +3,7 @@ + //! Used in order read and write to internal flash. + + use core::cell::Cell; ++use core::convert::TryFrom; + use core::ops::{Index, IndexMut}; + use kernel::common::cells::OptionalCell; + use kernel::common::cells::TakeCell; +@@ -11,7 +12,7 @@ use kernel::common::deferred_call::DeferredCall; + use kernel::common::registers::{register_bitfields, ReadOnly, ReadWrite}; + use kernel::common::StaticRef; + use kernel::hil; +-use kernel::ReturnCode; ++use kernel::{AppId, AppSlice, Callback, Driver, Grant, ReturnCode, Shared}; + + use crate::deferred_call_tasks::DeferredCallTask; + +@@ -141,7 +142,13 @@ register_bitfields! [u32, + static DEFERRED_CALL: DeferredCall = + unsafe { DeferredCall::new(DeferredCallTask::Nvmc) }; + ++type WORD = u32; ++const WORD_SIZE: usize = core::mem::size_of::(); + const PAGE_SIZE: usize = 4096; ++const MAX_WORD_WRITES: usize = 2; ++const MAX_PAGE_ERASES: usize = 10000; ++const WORD_MASK: usize = WORD_SIZE - 1; ++const PAGE_MASK: usize = PAGE_SIZE - 1; + + /// This is a wrapper around a u8 array that is sized to a single page for the + /// nrf. Users of this module must pass an object of this type to use the +@@ -215,6 +222,11 @@ impl Nvmc { + } + } + ++ pub fn configure_readonly(&self) { ++ let regs = &*self.registers; ++ regs.config.write(Configuration::WEN::Ren); ++ } ++ + /// Configure the NVMC to allow writes to flash. + pub fn configure_writeable(&self) { + let regs = &*self.registers; +@@ -230,7 +242,7 @@ impl Nvmc { + let regs = &*self.registers; + regs.config.write(Configuration::WEN::Een); + while !self.is_ready() {} +- regs.erasepage.write(ErasePage::ERASEPAGE.val(0x10001000)); ++ regs.eraseuicr.write(EraseUicr::ERASEUICR::ERASE); + while !self.is_ready() {} + } + +@@ -314,7 +326,7 @@ impl Nvmc { + // Put the NVMC in write mode. + regs.config.write(Configuration::WEN::Wen); + +- for i in (0..data.len()).step_by(4) { ++ for i in (0..data.len()).step_by(WORD_SIZE) { + let word: u32 = (data[i + 0] as u32) << 0 + | (data[i + 1] as u32) << 8 + | (data[i + 2] as u32) << 16 +@@ -374,3 +386,178 @@ impl hil::flash::Flash for Nvmc { + self.erase_page(page_number) + } + } ++ ++/// Provides access to the writeable flash regions of the application. ++/// ++/// The purpose of this driver is to provide low-level access to the embedded flash of nRF52 boards ++/// to allow applications to implement flash-aware (like wear-leveling) data-structures. The driver ++/// only permits applications to operate on their writeable flash regions. The API is blocking since ++/// the CPU is halted during write and erase operations. ++/// ++/// Supported boards: ++/// - nRF52840 (tested) ++/// - nRF52833 ++/// - nRF52811 ++/// - nRF52810 ++/// ++/// The maximum number of writes for the nRF52832 board is not per word but per block (512 bytes) ++/// and as such doesn't exactly fit this API. However, it could be safely supported by returning ++/// either 1 for the maximum number of word writes (i.e. the flash can only be written once before ++/// being erased) or 8 for the word size (i.e. the write granularity is doubled). In both cases, ++/// only 128 writes per block are permitted while the flash supports 181. ++/// ++/// # Syscalls ++/// ++/// - COMMAND(0): Check the driver. ++/// - COMMAND(1, 0): Get the word size (always 4). ++/// - COMMAND(1, 1): Get the page size (always 4096). ++/// - COMMAND(1, 2): Get the maximum number of word writes between page erasures (always 2). ++/// - COMMAND(1, 3): Get the maximum number page erasures in the lifetime of the flash (always ++/// 10000). ++/// - COMMAND(2, ptr): Write the allow slice to the flash region starting at `ptr`. ++/// - `ptr` must be word-aligned. ++/// - The allow slice length must be word aligned. ++/// - The region starting at `ptr` of the same length as the allow slice must be in a writeable ++/// flash region. ++/// - COMMAND(3, ptr): Erase a page. ++/// - `ptr` must be page-aligned. ++/// - The page starting at `ptr` must be in a writeable flash region. ++/// - ALLOW(0): The allow slice for COMMAND(2). ++pub struct SyscallDriver { ++ nvmc: &'static Nvmc, ++ apps: Grant, ++} ++ ++pub const DRIVER_NUM: usize = 0x50003; ++ ++#[derive(Default)] ++pub struct App { ++ /// The allow slice for COMMAND(2). ++ slice: Option>, ++} ++ ++impl SyscallDriver { ++ pub fn new(nvmc: &'static Nvmc, apps: Grant) -> SyscallDriver { ++ SyscallDriver { nvmc, apps } ++ } ++} ++ ++fn is_write_needed(old: u32, new: u32) -> bool { ++ // No need to write if it would not modify the current value. ++ old & new != old ++} ++ ++impl SyscallDriver { ++ /// Writes a word-aligned slice at a word-aligned address. ++ /// ++ /// Words are written only if necessary, i.e. if writing the new value would change the current ++ /// value. This can be used to simplify recovery operations (e.g. if power is lost during a ++ /// write operation). The application doesn't need to check which prefix has already been ++ /// written and may repeat the complete write that was interrupted. ++ /// ++ /// # Safety ++ /// ++ /// The words in this range must have been written less than `MAX_WORD_WRITES` since their last ++ /// page erasure. ++ /// ++ /// # Errors ++ /// ++ /// Fails with `EINVAL` if any of the following conditions does not hold: ++ /// - `ptr` must be word-aligned. ++ /// - `slice.len()` must be word-aligned. ++ /// - The slice starting at `ptr` of length `slice.len()` must fit in a writeable flash region. ++ fn write_slice(&self, appid: AppId, ptr: usize, slice: &[u8]) -> ReturnCode { ++ if !appid.in_writeable_flash_region(ptr, slice.len()) { ++ return ReturnCode::EINVAL; ++ } ++ if ptr & WORD_MASK != 0 || slice.len() & WORD_MASK != 0 { ++ return ReturnCode::EINVAL; ++ } ++ self.nvmc.configure_writeable(); ++ for (i, chunk) in slice.chunks(WORD_SIZE).enumerate() { ++ // `unwrap` cannot fail because `slice.len()` is word-aligned (see above). ++ let val = WORD::from_ne_bytes(<[u8; WORD_SIZE]>::try_from(chunk).unwrap()); ++ let loc = unsafe { &*(ptr as *const VolatileCell).add(i) }; ++ if is_write_needed(loc.get(), val) { ++ loc.set(val); ++ } ++ } ++ while !self.nvmc.is_ready() {} ++ self.nvmc.configure_readonly(); ++ ReturnCode::SUCCESS ++ } ++ ++ /// Erases a page at a page-aligned address. ++ /// ++ /// # Errors ++ /// ++ /// Fails with `EINVAL` if any of the following conditions does not hold: ++ /// - `ptr` must be page-aligned. ++ /// - The slice starting at `ptr` of length `PAGE_SIZE` must fit in a writeable flash region. ++ fn erase_page(&self, appid: AppId, ptr: usize) -> ReturnCode { ++ if !appid.in_writeable_flash_region(ptr, PAGE_SIZE) { ++ return ReturnCode::EINVAL; ++ } ++ if ptr & PAGE_MASK != 0 { ++ return ReturnCode::EINVAL; ++ } ++ self.nvmc.erase_page_helper(ptr / PAGE_SIZE); ++ self.nvmc.configure_readonly(); ++ ReturnCode::SUCCESS ++ } ++} ++ ++impl Driver for SyscallDriver { ++ fn subscribe(&self, _: usize, _: Option, _: AppId) -> ReturnCode { ++ ReturnCode::ENOSUPPORT ++ } ++ ++ fn command(&self, cmd: usize, arg: usize, _: usize, appid: AppId) -> ReturnCode { ++ match (cmd, arg) { ++ (0, _) => ReturnCode::SUCCESS, ++ ++ (1, 0) => ReturnCode::SuccessWithValue { value: WORD_SIZE }, ++ (1, 1) => ReturnCode::SuccessWithValue { value: PAGE_SIZE }, ++ (1, 2) => ReturnCode::SuccessWithValue { ++ value: MAX_WORD_WRITES, ++ }, ++ (1, 3) => ReturnCode::SuccessWithValue { ++ value: MAX_PAGE_ERASES, ++ }, ++ (1, _) => ReturnCode::EINVAL, ++ ++ (2, ptr) => self ++ .apps ++ .enter(appid, |app, _| { ++ let slice = match app.slice.take() { ++ None => return ReturnCode::EINVAL, ++ Some(slice) => slice, ++ }; ++ self.write_slice(appid, ptr, slice.as_ref()) ++ }) ++ .unwrap_or_else(|err| err.into()), ++ ++ (3, ptr) => self.erase_page(appid, ptr), ++ ++ _ => ReturnCode::ENOSUPPORT, ++ } ++ } ++ ++ fn allow( ++ &self, ++ appid: AppId, ++ allow_num: usize, ++ slice: Option>, ++ ) -> ReturnCode { ++ match allow_num { ++ 0 => self ++ .apps ++ .enter(appid, |app, _| { ++ app.slice = slice; ++ ReturnCode::SUCCESS ++ }) ++ .unwrap_or_else(|err| err.into()), ++ _ => ReturnCode::ENOSUPPORT, ++ } ++ } ++} +diff --git a/kernel/src/callback.rs b/kernel/src/callback.rs +index 95b25cc0..a7d8bc5c 100644 +--- a/kernel/src/callback.rs ++++ b/kernel/src/callback.rs +@@ -50,6 +50,31 @@ impl AppId { + (start, end) + }) + } ++ ++ pub fn in_writeable_flash_region(&self, ptr: usize, len: usize) -> bool { ++ self.kernel.process_map_or(false, self.idx, |process| { ++ let ptr = match ptr.checked_sub(process.flash_start() as usize) { ++ None => return false, ++ Some(ptr) => ptr, ++ }; ++ (0..process.number_writeable_flash_regions()).any(|i| { ++ let (region_ptr, region_len) = process.get_writeable_flash_region(i); ++ let region_ptr = region_ptr as usize; ++ let region_len = region_len as usize; ++ // We want to check the 2 following inequalities: ++ // (1) `region_ptr <= ptr` ++ // (2) `ptr + len <= region_ptr + region_len` ++ // However, the second one may overflow written as is. We introduce a third ++ // inequality to solve this issue: ++ // (3) `len <= region_len` ++ // Using this third inequality, we can rewrite the second one as: ++ // (4) `ptr - region_ptr <= region_len - len` ++ // This fourth inequality is equivalent to the second one but doesn't overflow when ++ // the first and third inequalities hold. ++ region_ptr <= ptr && len <= region_len && ptr - region_ptr <= region_len - len ++ }) ++ }) ++ } + } + + /// Type to uniquely identify a callback subscription across all drivers. diff --git a/patches/tock/02-usb.patch b/patches/tock/02-usb.patch new file mode 100644 index 0000000..0ba33d8 --- /dev/null +++ b/patches/tock/02-usb.patch @@ -0,0 +1,1009 @@ +diff --git a/boards/nordic/nrf52840_dongle/src/main.rs b/boards/nordic/nrf52840_dongle/src/main.rs +index 5a9da538..75043d13 100644 +--- a/boards/nordic/nrf52840_dongle/src/main.rs ++++ b/boards/nordic/nrf52840_dongle/src/main.rs +@@ -140,6 +140,7 @@ pub unsafe fn reset_handler() { + FAULT_RESPONSE, + nrf52840::uicr::Regulator0Output::V3_0, + false, ++ &Some(&nrf52840::usbd::USBD), + chip, + ); + } +diff --git a/boards/nordic/nrf52840dk/src/main.rs b/boards/nordic/nrf52840dk/src/main.rs +index 0b19ea3f..bd71dfbe 100644 +--- a/boards/nordic/nrf52840dk/src/main.rs ++++ b/boards/nordic/nrf52840dk/src/main.rs +@@ -252,6 +252,7 @@ pub unsafe fn reset_handler() { + FAULT_RESPONSE, + nrf52840::uicr::Regulator0Output::DEFAULT, + false, ++ &Some(&nrf52840::usbd::USBD), + chip, + ); + } +diff --git a/boards/nordic/nrf52dk/src/main.rs b/boards/nordic/nrf52dk/src/main.rs +index b49518ff..39f996c4 100644 +--- a/boards/nordic/nrf52dk/src/main.rs ++++ b/boards/nordic/nrf52dk/src/main.rs +@@ -209,6 +209,7 @@ pub unsafe fn reset_handler() { + FAULT_RESPONSE, + nrf52832::uicr::Regulator0Output::DEFAULT, + false, ++ &None, + chip, + ); + } +diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs +index 7e2a3298..d391e455 100644 +--- a/boards/nordic/nrf52dk_base/src/lib.rs ++++ b/boards/nordic/nrf52dk_base/src/lib.rs +@@ -102,6 +102,13 @@ pub struct Platform { + 'static, + capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc<'static>>, + >, ++ usb: Option< ++ &'static capsules::usb::usb_ctap::CtapUsbSyscallDriver< ++ 'static, ++ 'static, ++ nrf52::usbd::Usbd<'static>, ++ >, ++ >, + // The nRF52dk does not have the flash chip on it, so we make this optional. + nonvolatile_storage: + Option<&'static capsules::nonvolatile_storage_driver::NonvolatileStorage<'static>>, +@@ -130,6 +137,9 @@ impl kernel::Platform for Platform { + f(self.nonvolatile_storage.map_or(None, |nv| Some(nv))) + } + nrf52::nvmc::DRIVER_NUM => f(Some(self.nvmc)), ++ capsules::usb::usb_ctap::DRIVER_NUM => { ++ f(self.usb.map(|ctap| ctap as &dyn kernel::Driver)) ++ } + kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)), + _ => f(None), + } +@@ -157,6 +167,7 @@ pub unsafe fn setup_board( + app_fault_response: kernel::procs::FaultResponse, + reg_vout: Regulator0Output, + nfc_as_gpios: bool, ++ usb: &Option<&'static nrf52::usbd::Usbd<'static>>, + chip: &'static nrf52::chip::NRF52, + ) { + // Make non-volatile memory writable and activate the reset button +@@ -418,6 +429,44 @@ pub unsafe fn setup_board( + ) + ); + ++ // Configure USB controller if supported ++ let usb_driver: Option< ++ &'static capsules::usb::usb_ctap::CtapUsbSyscallDriver< ++ 'static, ++ 'static, ++ nrf52::usbd::Usbd<'static>, ++ >, ++ > = usb.map(|driver| { ++ let usb_ctap = static_init!( ++ capsules::usb::usbc_ctap_hid::ClientCtapHID< ++ 'static, ++ 'static, ++ nrf52::usbd::Usbd<'static>, ++ >, ++ capsules::usb::usbc_ctap_hid::ClientCtapHID::new(driver) ++ ); ++ driver.set_client(usb_ctap); ++ ++ // Enable power events to be sent to USB controller ++ nrf52::power::POWER.set_usb_client(driver); ++ nrf52::power::POWER.enable_interrupts(); ++ ++ // Configure the USB userspace driver ++ let usb_driver = static_init!( ++ capsules::usb::usb_ctap::CtapUsbSyscallDriver< ++ 'static, ++ 'static, ++ nrf52::usbd::Usbd<'static>, ++ >, ++ capsules::usb::usb_ctap::CtapUsbSyscallDriver::new( ++ usb_ctap, ++ board_kernel.create_grant(&memory_allocation_capability) ++ ) ++ ); ++ usb_ctap.set_client(usb_driver); ++ usb_driver as &'static _ ++ }); ++ + // Start all of the clocks. Low power operation will require a better + // approach than this. + nrf52::clock::CLOCK.low_stop(); +@@ -449,6 +498,7 @@ pub unsafe fn setup_board( + rng: rng, + temp: temp, + alarm: alarm, ++ usb: usb_driver, + nonvolatile_storage: nonvolatile_storage, + ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability), + nvmc: nvmc, +diff --git a/capsules/src/driver.rs b/capsules/src/driver.rs +index 9305e6a7..40466f44 100644 +--- a/capsules/src/driver.rs ++++ b/capsules/src/driver.rs +@@ -24,6 +24,7 @@ pub enum NUM { + Spi = 0x20001, + UsbUser = 0x20005, + I2cMasterSlave = 0x20006, ++ UsbCtap = 0x20009, + + // Radio + BleAdvertising = 0x30000, +diff --git a/capsules/src/usb/mod.rs b/capsules/src/usb/mod.rs +index e5c8d6ad..7af3da2e 100644 +--- a/capsules/src/usb/mod.rs ++++ b/capsules/src/usb/mod.rs +@@ -1,4 +1,6 @@ + pub mod descriptors; ++pub mod usb_ctap; + pub mod usb_user; + pub mod usbc_client; + pub mod usbc_client_ctrl; ++pub mod usbc_ctap_hid; +diff --git a/capsules/src/usb/usb_ctap.rs b/capsules/src/usb/usb_ctap.rs +new file mode 100644 +index 00000000..da3d16d8 +--- /dev/null ++++ b/capsules/src/usb/usb_ctap.rs +@@ -0,0 +1,355 @@ ++use super::usbc_ctap_hid::ClientCtapHID; ++use kernel::hil; ++use kernel::hil::usb::Client; ++use kernel::{AppId, AppSlice, Callback, Driver, Grant, ReturnCode, Shared}; ++ ++/// Syscall number ++use crate::driver; ++pub const DRIVER_NUM: usize = driver::NUM::UsbCtap as usize; ++ ++pub const CTAP_CMD_CHECK: usize = 0; ++pub const CTAP_CMD_CONNECT: usize = 1; ++pub const CTAP_CMD_TRANSMIT: usize = 2; ++pub const CTAP_CMD_RECEIVE: usize = 3; ++pub const CTAP_CMD_TRANSMIT_OR_RECEIVE: usize = 4; ++pub const CTAP_CMD_CANCEL: usize = 5; ++ ++pub const CTAP_ALLOW_TRANSMIT: usize = 1; ++pub const CTAP_ALLOW_RECEIVE: usize = 2; ++pub const CTAP_ALLOW_TRANSMIT_OR_RECEIVE: usize = 3; ++ ++pub const CTAP_SUBSCRIBE_TRANSMIT: usize = 1; ++pub const CTAP_SUBSCRIBE_RECEIVE: usize = 2; ++pub const CTAP_SUBSCRIBE_TRANSMIT_OR_RECEIVE: usize = 3; ++ ++pub const CTAP_CALLBACK_TRANSMITED: usize = 1; ++pub const CTAP_CALLBACK_RECEIVED: usize = 2; ++ ++#[derive(Clone, Copy, PartialEq, Eq)] ++enum Side { ++ Transmit, ++ Receive, ++ TransmitOrReceive, ++} ++ ++impl Side { ++ fn can_transmit(&self) -> bool { ++ match self { ++ Side::Transmit | Side::TransmitOrReceive => true, ++ Side::Receive => false, ++ } ++ } ++ ++ fn can_receive(&self) -> bool { ++ match self { ++ Side::Receive | Side::TransmitOrReceive => true, ++ Side::Transmit => false, ++ } ++ } ++} ++ ++#[derive(Default)] ++pub struct App { ++ // Only one app can be connected to this driver, to avoid needing to route packets among apps. ++ // This field tracks this status. ++ connected: bool, ++ // Currently enabled transaction side. Subscribing to a callback or allowing a buffer ++ // automatically sets the corresponding side. Clearing both the callback and the buffer resets ++ // the side to None. ++ side: Option, ++ callback: Option, ++ buffer: Option>, ++ // Whether the app is waiting for the kernel signaling a packet transfer. ++ waiting: bool, ++} ++ ++impl App { ++ fn check_side(&mut self) { ++ if self.callback.is_none() && self.buffer.is_none() && !self.waiting { ++ self.side = None; ++ } ++ } ++ ++ fn set_side(&mut self, side: Side) -> bool { ++ match self.side { ++ None => { ++ self.side = Some(side); ++ true ++ } ++ Some(app_side) => side == app_side, ++ } ++ } ++ ++ fn is_ready_for_command(&self, side: Side) -> bool { ++ self.buffer.is_some() && self.callback.is_some() && self.side == Some(side) ++ } ++} ++ ++pub trait CtapUsbClient { ++ // Whether this client is ready to receive a packet. This must be checked before calling ++ // packet_received(). ++ fn can_receive_packet(&self) -> bool; ++ ++ // Signal to the client that a packet has been received. ++ fn packet_received(&self, packet: &[u8; 64]); ++ ++ // Signal to the client that a packet has been transmitted. ++ fn packet_transmitted(&self); ++} ++ ++pub struct CtapUsbSyscallDriver<'a, 'b, C: 'a> { ++ usb_client: &'a ClientCtapHID<'a, 'b, C>, ++ apps: Grant, ++} ++ ++impl<'a, 'b, C: hil::usb::UsbController<'a>> CtapUsbSyscallDriver<'a, 'b, C> { ++ pub fn new(usb_client: &'a ClientCtapHID<'a, 'b, C>, apps: Grant) -> Self { ++ CtapUsbSyscallDriver { usb_client, apps } ++ } ++} ++ ++impl<'a, 'b, C: hil::usb::UsbController<'a>> CtapUsbClient for CtapUsbSyscallDriver<'a, 'b, C> { ++ fn can_receive_packet(&self) -> bool { ++ let mut result = false; ++ for app in self.apps.iter() { ++ app.enter(|app, _| { ++ if app.connected { ++ result = app.waiting ++ && app.side.map_or(false, |side| side.can_receive()) ++ && app.buffer.is_some(); ++ } ++ }); ++ } ++ result ++ } ++ ++ fn packet_received(&self, packet: &[u8; 64]) { ++ for app in self.apps.iter() { ++ app.enter(|app, _| { ++ if app.connected && app.waiting && app.side.map_or(false, |side| side.can_receive()) ++ { ++ if let Some(buf) = &mut app.buffer { ++ // Copy the packet to the app's allowed buffer. ++ buf.as_mut().copy_from_slice(packet); ++ app.waiting = false; ++ // Signal to the app that a packet is ready. ++ app.callback ++ .map(|mut cb| cb.schedule(CTAP_CALLBACK_RECEIVED, 0, 0)); ++ } ++ } ++ }); ++ } ++ } ++ ++ fn packet_transmitted(&self) { ++ for app in self.apps.iter() { ++ app.enter(|app, _| { ++ if app.connected ++ && app.waiting ++ && app.side.map_or(false, |side| side.can_transmit()) ++ { ++ app.waiting = false; ++ // Signal to the app that the packet was sent. ++ app.callback ++ .map(|mut cb| cb.schedule(CTAP_CALLBACK_TRANSMITED, 0, 0)); ++ } ++ }); ++ } ++ } ++} ++ ++impl<'a, 'b, C: hil::usb::UsbController<'a>> Driver for CtapUsbSyscallDriver<'a, 'b, C> { ++ fn allow( ++ &self, ++ appid: AppId, ++ allow_num: usize, ++ slice: Option>, ++ ) -> ReturnCode { ++ let side = match allow_num { ++ CTAP_ALLOW_TRANSMIT => Side::Transmit, ++ CTAP_ALLOW_RECEIVE => Side::Receive, ++ CTAP_ALLOW_TRANSMIT_OR_RECEIVE => Side::TransmitOrReceive, ++ _ => return ReturnCode::ENOSUPPORT, ++ }; ++ self.apps ++ .enter(appid, |app, _| { ++ if !app.connected { ++ ReturnCode::ERESERVE ++ } else { ++ if let Some(buf) = &slice { ++ if buf.len() != 64 { ++ return ReturnCode::EINVAL; ++ } ++ } ++ if !app.set_side(side) { ++ return ReturnCode::EALREADY; ++ } ++ app.buffer = slice; ++ app.check_side(); ++ ReturnCode::SUCCESS ++ } ++ }) ++ .unwrap_or_else(|err| err.into()) ++ } ++ ++ fn subscribe( ++ &self, ++ subscribe_num: usize, ++ callback: Option, ++ appid: AppId, ++ ) -> ReturnCode { ++ let side = match subscribe_num { ++ CTAP_SUBSCRIBE_TRANSMIT => Side::Transmit, ++ CTAP_SUBSCRIBE_RECEIVE => Side::Receive, ++ CTAP_SUBSCRIBE_TRANSMIT_OR_RECEIVE => Side::TransmitOrReceive, ++ _ => return ReturnCode::ENOSUPPORT, ++ }; ++ self.apps ++ .enter(appid, |app, _| { ++ if !app.connected { ++ ReturnCode::ERESERVE ++ } else { ++ if !app.set_side(side) { ++ return ReturnCode::EALREADY; ++ } ++ app.callback = callback; ++ app.check_side(); ++ ReturnCode::SUCCESS ++ } ++ }) ++ .unwrap_or_else(|err| err.into()) ++ } ++ ++ fn command(&self, cmd_num: usize, _arg1: usize, _arg2: usize, appid: AppId) -> ReturnCode { ++ match cmd_num { ++ CTAP_CMD_CHECK => ReturnCode::SUCCESS, ++ CTAP_CMD_CONNECT => { ++ // First, check if any app is already connected to this driver. ++ let mut busy = false; ++ for app in self.apps.iter() { ++ app.enter(|app, _| { ++ busy |= app.connected; ++ }); ++ } ++ ++ self.apps ++ .enter(appid, |app, _| { ++ if app.connected { ++ ReturnCode::EALREADY ++ } else if busy { ++ ReturnCode::EBUSY ++ } else { ++ self.usb_client.enable(); ++ self.usb_client.attach(); ++ app.connected = true; ++ ReturnCode::SUCCESS ++ } ++ }) ++ .unwrap_or_else(|err| err.into()) ++ } ++ CTAP_CMD_TRANSMIT => self ++ .apps ++ .enter(appid, |app, _| { ++ if !app.connected { ++ ReturnCode::ERESERVE ++ } else { ++ if app.is_ready_for_command(Side::Transmit) { ++ if app.waiting { ++ ReturnCode::EALREADY ++ } else if self ++ .usb_client ++ .transmit_packet(app.buffer.as_ref().unwrap().as_ref()) ++ { ++ app.waiting = true; ++ ReturnCode::SUCCESS ++ } else { ++ ReturnCode::EBUSY ++ } ++ } else { ++ ReturnCode::EINVAL ++ } ++ } ++ }) ++ .unwrap_or_else(|err| err.into()), ++ CTAP_CMD_RECEIVE => self ++ .apps ++ .enter(appid, |app, _| { ++ if !app.connected { ++ ReturnCode::ERESERVE ++ } else { ++ if app.is_ready_for_command(Side::Receive) { ++ if app.waiting { ++ ReturnCode::EALREADY ++ } else { ++ app.waiting = true; ++ self.usb_client.receive_packet(); ++ ReturnCode::SUCCESS ++ } ++ } else { ++ ReturnCode::EINVAL ++ } ++ } ++ }) ++ .unwrap_or_else(|err| err.into()), ++ CTAP_CMD_TRANSMIT_OR_RECEIVE => self ++ .apps ++ .enter(appid, |app, _| { ++ if !app.connected { ++ ReturnCode::ERESERVE ++ } else { ++ if app.is_ready_for_command(Side::TransmitOrReceive) { ++ if app.waiting { ++ ReturnCode::EALREADY ++ } else { ++ // Indicates to the driver that we can receive any pending packet. ++ app.waiting = true; ++ self.usb_client.receive_packet(); ++ ++ if !app.waiting { ++ // The call to receive_packet() collected a pending packet. ++ ReturnCode::SUCCESS ++ } else { ++ // Indicates to the driver that we have a packet to send. ++ if self ++ .usb_client ++ .transmit_packet(app.buffer.as_ref().unwrap().as_ref()) ++ { ++ ReturnCode::SUCCESS ++ } else { ++ ReturnCode::EBUSY ++ } ++ } ++ } ++ } else { ++ ReturnCode::EINVAL ++ } ++ } ++ }) ++ .unwrap_or_else(|err| err.into()), ++ CTAP_CMD_CANCEL => self ++ .apps ++ .enter(appid, |app, _| { ++ if !app.connected { ++ ReturnCode::ERESERVE ++ } else { ++ if app.waiting { ++ // FIXME: if cancellation failed, the app should still wait. But that ++ // doesn't work yet. ++ app.waiting = false; ++ if self.usb_client.cancel_transaction() { ++ ReturnCode::SUCCESS ++ } else { ++ // Cannot cancel now because the transaction is already in process. ++ // The app should wait for the callback instead. ++ ReturnCode::EBUSY ++ } ++ } else { ++ ReturnCode::EALREADY ++ } ++ } ++ }) ++ .unwrap_or_else(|err| err.into()), ++ _ => ReturnCode::ENOSUPPORT, ++ } ++ } ++} +diff --git a/capsules/src/usb/usbc_ctap_hid.rs b/capsules/src/usb/usbc_ctap_hid.rs +new file mode 100644 +index 00000000..fdf7263a +--- /dev/null ++++ b/capsules/src/usb/usbc_ctap_hid.rs +@@ -0,0 +1,352 @@ ++//! A USB HID client of the USB hardware interface ++ ++use super::descriptors::Buffer64; ++use super::descriptors::ConfigurationDescriptor; ++use super::descriptors::DescriptorType; ++use super::descriptors::DeviceDescriptor; ++use super::descriptors::EndpointAddress; ++use super::descriptors::EndpointDescriptor; ++use super::descriptors::HIDCountryCode; ++use super::descriptors::HIDDescriptor; ++use super::descriptors::HIDSubordinateDescriptor; ++use super::descriptors::InterfaceDescriptor; ++use super::descriptors::ReportDescriptor; ++use super::descriptors::TransferDirection; ++use super::usb_ctap::CtapUsbClient; ++use super::usbc_client_ctrl::ClientCtrl; ++use core::cell::Cell; ++use kernel::common::cells::OptionalCell; ++use kernel::debug; ++use kernel::hil; ++use kernel::hil::usb::TransferType; ++ ++const VENDOR_ID: u16 = 0x1915; // Nordic Semiconductor ++const PRODUCT_ID: u16 = 0x521f; // nRF52840 Dongle (PCA10059) ++ ++static LANGUAGES: &'static [u16; 1] = &[ ++ 0x0409, // English (United States) ++]; ++ ++static STRINGS: &'static [&'static str] = &[ ++ // Manufacturer ++ "Nordic Semiconductor ASA", ++ // Product ++ "OpenSK", ++ // Serial number ++ "v0.1", ++]; ++ ++static ENDPOINTS: &'static [EndpointDescriptor] = &[ ++ EndpointDescriptor { ++ endpoint_address: EndpointAddress::new_const(1, TransferDirection::HostToDevice), ++ transfer_type: TransferType::Interrupt, ++ max_packet_size: 64, ++ interval: 5, ++ }, ++ EndpointDescriptor { ++ endpoint_address: EndpointAddress::new_const(1, TransferDirection::DeviceToHost), ++ transfer_type: TransferType::Interrupt, ++ max_packet_size: 64, ++ interval: 5, ++ }, ++]; ++ ++static CTAP_REPORT_DESCRIPTOR: &'static [u8] = &[ ++ 0x06, 0xD0, 0xF1, // HID_UsagePage ( FIDO_USAGE_PAGE ), ++ 0x09, 0x01, // HID_Usage ( FIDO_USAGE_CTAPHID ), ++ 0xA1, 0x01, // HID_Collection ( HID_Application ), ++ 0x09, 0x20, // HID_Usage ( FIDO_USAGE_DATA_IN ), ++ 0x15, 0x00, // HID_LogicalMin ( 0 ), ++ 0x26, 0xFF, 0x00, // HID_LogicalMaxS ( 0xff ), ++ 0x75, 0x08, // HID_ReportSize ( 8 ), ++ 0x95, 0x40, // HID_ReportCount ( HID_INPUT_REPORT_BYTES ), ++ 0x81, 0x02, // HID_Input ( HID_Data | HID_Absolute | HID_Variable ), ++ 0x09, 0x21, // HID_Usage ( FIDO_USAGE_DATA_OUT ), ++ 0x15, 0x00, // HID_LogicalMin ( 0 ), ++ 0x26, 0xFF, 0x00, // HID_LogicalMaxS ( 0xff ), ++ 0x75, 0x08, // HID_ReportSize ( 8 ), ++ 0x95, 0x40, // HID_ReportCount ( HID_OUTPUT_REPORT_BYTES ), ++ 0x91, 0x02, // HID_Output ( HID_Data | HID_Absolute | HID_Variable ), ++ 0xC0, // HID_EndCollection ++]; ++ ++static CTAP_REPORT: ReportDescriptor<'static> = ReportDescriptor { ++ desc: CTAP_REPORT_DESCRIPTOR, ++}; ++ ++static HID_SUB_DESCRIPTORS: &'static [HIDSubordinateDescriptor] = &[HIDSubordinateDescriptor { ++ typ: DescriptorType::Report, ++ len: CTAP_REPORT_DESCRIPTOR.len() as u16, ++}]; ++ ++static HID: HIDDescriptor<'static> = HIDDescriptor { ++ hid_class: 0x0110, ++ country_code: HIDCountryCode::NotSupported, ++ sub_descriptors: HID_SUB_DESCRIPTORS, ++}; ++ ++pub struct ClientCtapHID<'a, 'b, C: 'a> { ++ client_ctrl: ClientCtrl<'a, 'static, C>, ++ ++ // A 64-byte buffer for the endpoint ++ buffer: Buffer64, ++ ++ // Interaction with the client ++ client: OptionalCell<&'b dyn CtapUsbClient>, ++ tx_packet: OptionalCell<[u8; 64]>, ++ pending_in: Cell, ++ pending_out: Cell, ++ delayed_out: Cell, ++} ++ ++impl<'a, 'b, C: hil::usb::UsbController<'a>> ClientCtapHID<'a, 'b, C> { ++ pub fn new(controller: &'a C) -> Self { ++ ClientCtapHID { ++ client_ctrl: ClientCtrl::new( ++ controller, ++ DeviceDescriptor { ++ // TODO: set this field at the board level. ++ max_packet_size_ep0: 64, ++ vendor_id: VENDOR_ID, ++ product_id: PRODUCT_ID, ++ manufacturer_string: 1, ++ product_string: 2, ++ serial_number_string: 3, ++ ..Default::default() ++ }, ++ ConfigurationDescriptor { ++ // Must be non-zero, otherwise dmesg prints the following error: ++ // [...] usb 2-3: config 0 descriptor?? ++ configuration_value: 1, ++ ..Default::default() ++ }, ++ // Interface declared in the FIDO2 specification, section 8.1.8.1 ++ InterfaceDescriptor { ++ interface_class: 0x03, // HID ++ interface_subclass: 0x00, ++ interface_protocol: 0x00, ++ ..Default::default() ++ }, ++ ENDPOINTS, ++ Some(&HID), ++ Some(&CTAP_REPORT), ++ LANGUAGES, ++ STRINGS, ++ ), ++ buffer: Default::default(), ++ client: OptionalCell::empty(), ++ tx_packet: OptionalCell::empty(), ++ pending_in: Cell::new(false), ++ pending_out: Cell::new(false), ++ delayed_out: Cell::new(false), ++ } ++ } ++ ++ pub fn set_client(&'a self, client: &'b dyn CtapUsbClient) { ++ self.client.set(client); ++ } ++ ++ pub fn transmit_packet(&'a self, packet: &[u8]) -> bool { ++ if self.pending_in.get() { ++ // The previous packet has not yet been transmitted, reject the new one. ++ false ++ } else { ++ self.pending_in.set(true); ++ let mut buf: [u8; 64] = [0; 64]; ++ buf.copy_from_slice(packet); ++ self.tx_packet.set(buf); ++ // Alert the controller that we now have data to send on the Interrupt IN endpoint. ++ self.controller().endpoint_resume_in(1); ++ true ++ } ++ } ++ ++ pub fn receive_packet(&'a self) -> bool { ++ if self.pending_out.get() { ++ // The previous packet has not yet been received, reject the new one. ++ false ++ } else { ++ self.pending_out.set(true); ++ // In case we reported Delay before, send the pending packet back to the client. ++ // Otherwise, there's nothing to do, the controller will send us a packet_out when a ++ // packet arrives. ++ if self.delayed_out.take() { ++ if self.send_packet_to_client() { ++ // If that succeeds, alert the controller that we can now ++ // receive data on the Interrupt OUT endpoint. ++ self.controller().endpoint_resume_out(1); ++ } ++ } ++ true ++ } ++ } ++ ++ // Send an OUT packet available in the controller back to the client. ++ // This returns false if the client is not ready to receive a packet, and true if the client ++ // successfully accepted the packet. ++ fn send_packet_to_client(&'a self) -> bool { ++ // Copy the packet into a buffer to send to the client. ++ let mut buf: [u8; 64] = [0; 64]; ++ for (i, x) in self.buffer.buf.iter().enumerate() { ++ buf[i] = x.get(); ++ } ++ ++ assert!(!self.delayed_out.get()); ++ ++ // Notify the client ++ if self ++ .client ++ .map_or(false, |client| client.can_receive_packet()) ++ { ++ assert!(self.pending_out.take()); ++ ++ // Clear any pending packet on the transmitting side. ++ // It's up to the client to handle the received packet and decide if this packet ++ // should be re-transmitted or not. ++ self.cancel_in_transaction(); ++ ++ self.client.map(|client| client.packet_received(&buf)); ++ true ++ } else { ++ // Cannot receive now, indicate a delay to the controller. ++ self.delayed_out.set(true); ++ false ++ } ++ } ++ ++ pub fn cancel_transaction(&'a self) -> bool { ++ self.cancel_in_transaction() | self.cancel_out_transaction() ++ } ++ ++ fn cancel_in_transaction(&'a self) -> bool { ++ self.tx_packet.take(); ++ let result = self.pending_in.take(); ++ if result { ++ self.controller().endpoint_cancel_in(1); ++ } ++ result ++ } ++ ++ fn cancel_out_transaction(&'a self) -> bool { ++ self.pending_out.take() ++ } ++ ++ #[inline] ++ fn controller(&'a self) -> &'a C { ++ self.client_ctrl.controller() ++ } ++} ++ ++impl<'a, 'b, C: hil::usb::UsbController<'a>> hil::usb::Client<'a> for ClientCtapHID<'a, 'b, C> { ++ fn enable(&'a self) { ++ // Set up the default control endpoint ++ self.client_ctrl.enable(); ++ ++ // Set up the interrupt in-out endpoint ++ self.controller().endpoint_set_buffer(1, &self.buffer.buf); ++ self.controller() ++ .endpoint_in_out_enable(TransferType::Interrupt, 1); ++ } ++ ++ fn attach(&'a self) { ++ self.client_ctrl.attach(); ++ } ++ ++ fn bus_reset(&'a self) { ++ // Should the client initiate reconfiguration here? ++ // For now, the hardware layer does it. ++ ++ debug!("Bus reset"); ++ } ++ ++ /// Handle a Control Setup transaction ++ fn ctrl_setup(&'a self, endpoint: usize) -> hil::usb::CtrlSetupResult { ++ self.client_ctrl.ctrl_setup(endpoint) ++ } ++ ++ /// Handle a Control In transaction ++ fn ctrl_in(&'a self, endpoint: usize) -> hil::usb::CtrlInResult { ++ self.client_ctrl.ctrl_in(endpoint) ++ } ++ ++ /// Handle a Control Out transaction ++ fn ctrl_out(&'a self, endpoint: usize, packet_bytes: u32) -> hil::usb::CtrlOutResult { ++ self.client_ctrl.ctrl_out(endpoint, packet_bytes) ++ } ++ ++ fn ctrl_status(&'a self, endpoint: usize) { ++ self.client_ctrl.ctrl_status(endpoint) ++ } ++ ++ /// Handle the completion of a Control transfer ++ fn ctrl_status_complete(&'a self, endpoint: usize) { ++ self.client_ctrl.ctrl_status_complete(endpoint) ++ } ++ ++ /// Handle a Bulk/Interrupt IN transaction ++ fn packet_in(&'a self, transfer_type: TransferType, endpoint: usize) -> hil::usb::InResult { ++ match transfer_type { ++ TransferType::Bulk => hil::usb::InResult::Error, ++ TransferType::Interrupt => { ++ if endpoint != 1 { ++ return hil::usb::InResult::Error; ++ } ++ ++ if let Some(packet) = self.tx_packet.take() { ++ let buf = &self.buffer.buf; ++ for i in 0..64 { ++ buf[i].set(packet[i]); ++ } ++ ++ hil::usb::InResult::Packet(64) ++ } else { ++ // Nothing to send ++ hil::usb::InResult::Delay ++ } ++ } ++ TransferType::Control | TransferType::Isochronous => unreachable!(), ++ } ++ } ++ ++ /// Handle a Bulk/Interrupt OUT transaction ++ fn packet_out( ++ &'a self, ++ transfer_type: TransferType, ++ endpoint: usize, ++ packet_bytes: u32, ++ ) -> hil::usb::OutResult { ++ match transfer_type { ++ TransferType::Bulk => hil::usb::OutResult::Error, ++ TransferType::Interrupt => { ++ if endpoint != 1 { ++ return hil::usb::OutResult::Error; ++ } ++ ++ if packet_bytes != 64 { ++ // Cannot process this packet ++ hil::usb::OutResult::Error ++ } else { ++ if self.send_packet_to_client() { ++ hil::usb::OutResult::Ok ++ } else { ++ hil::usb::OutResult::Delay ++ } ++ } ++ } ++ TransferType::Control | TransferType::Isochronous => unreachable!(), ++ } ++ } ++ ++ fn packet_transmitted(&'a self, endpoint: usize) { ++ if endpoint != 1 { ++ panic!("Unexpected transmission on ep {}", endpoint); ++ } ++ ++ if self.tx_packet.is_some() { ++ panic!("Unexpected tx_packet while a packet was being transmitted."); ++ } ++ self.pending_in.set(false); ++ // Notify the client ++ self.client.map(|client| client.packet_transmitted()); ++ } ++} +diff --git a/chips/nrf52/src/usbd.rs b/chips/nrf52/src/usbd.rs +index 8ddb5895..8c1992cc 100644 +--- a/chips/nrf52/src/usbd.rs ++++ b/chips/nrf52/src/usbd.rs +@@ -1499,7 +1499,23 @@ impl<'a> Usbd<'a> { + if epdatastatus.is_set(status_epin(endpoint)) { + let (transfer_type, direction, state) = + self.descriptors[endpoint].state.get().bulk_state(); +- assert_eq!(state, BulkState::InData); ++ match state { ++ BulkState::InData => { ++ // Totally expected state. Nothing to do. ++ } ++ BulkState::Init => { ++ internal_warn!( ++ "Received a stale epdata IN in an unexpected state: {:?}", ++ state ++ ); ++ } ++ BulkState::OutDelay ++ | BulkState::OutData ++ | BulkState::OutDma ++ | BulkState::InDma => { ++ internal_err!("Unexpected state: {:?}", state); ++ } ++ } + self.descriptors[endpoint].state.set(EndpointState::Bulk( + transfer_type, + direction, +@@ -1677,7 +1693,7 @@ impl<'a> Usbd<'a> { + } + + fn transmit_in(&self, endpoint: usize) { +- debug_info!("transmit_in({})", endpoint); ++ debug_events!("transmit_in({})", endpoint); + let regs = &*self.registers; + + self.client.map(|client| { +@@ -1717,7 +1733,7 @@ impl<'a> Usbd<'a> { + } + + fn transmit_out(&self, endpoint: usize) { +- debug_info!("transmit_out({})", endpoint); ++ debug_events!("transmit_out({})", endpoint); + + let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state(); + // Starting the DMA can only happen in the OutData state, i.e. after an EPDATA event. +@@ -1882,11 +1898,13 @@ impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { + } + + fn endpoint_resume_in(&self, endpoint: usize) { ++ debug_events!("endpoint_resume_in({})", endpoint); ++ + let (_, direction, _) = self.descriptors[endpoint].state.get().bulk_state(); + assert!(direction.has_in()); + + if self.dma_pending.get() { +- debug_info!("requesting resume_in[{}]", endpoint); ++ debug_events!("requesting resume_in[{}]", endpoint); + // A DMA is already pending. Schedule the resume for later. + self.descriptors[endpoint].request_transmit_in.set(true); + } else { +@@ -1896,6 +1914,8 @@ impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { + } + + fn endpoint_resume_out(&self, endpoint: usize) { ++ debug_events!("endpoint_resume_out({})", endpoint); ++ + let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state(); + assert!(direction.has_out()); + +@@ -1914,7 +1934,7 @@ impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { + // happened in the meantime. This pending transaction will now + // continue in transmit_out(). + if self.dma_pending.get() { +- debug_info!("requesting resume_out[{}]", endpoint); ++ debug_events!("requesting resume_out[{}]", endpoint); + // A DMA is already pending. Schedule the resume for later. + self.descriptors[endpoint].request_transmit_out.set(true); + } else { +@@ -1927,6 +1947,20 @@ impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { + } + } + } ++ ++ fn endpoint_cancel_in(&self, endpoint: usize) { ++ debug_events!("endpoint_cancel_in({})", endpoint); ++ ++ let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state(); ++ assert!(direction.has_in()); ++ assert_eq!(state, BulkState::InData); ++ ++ self.descriptors[endpoint].state.set(EndpointState::Bulk( ++ transfer_type, ++ direction, ++ BulkState::Init, ++ )); ++ } + } + + fn status_epin(ep: usize) -> Field { +diff --git a/chips/nrf52840/src/lib.rs b/chips/nrf52840/src/lib.rs +index 0c281276..7e9f7d1e 100644 +--- a/chips/nrf52840/src/lib.rs ++++ b/chips/nrf52840/src/lib.rs +@@ -2,7 +2,7 @@ + + pub use nrf52::{ + adc, aes, ble_radio, clock, constants, crt1, ficr, i2c, ieee802154_radio, init, nvmc, pinmux, +- ppi, pwm, rtc, spi, temperature, timer, trng, uart, uicr, ++ ppi, pwm, rtc, spi, temperature, timer, trng, uart, uicr, usbd, + }; + pub mod chip; + pub mod gpio; +diff --git a/chips/sam4l/src/usbc/mod.rs b/chips/sam4l/src/usbc/mod.rs +index 35f3bb7c..28a0b9f9 100644 +--- a/chips/sam4l/src/usbc/mod.rs ++++ b/chips/sam4l/src/usbc/mod.rs +@@ -1547,6 +1547,10 @@ impl hil::usb::UsbController<'a> for Usbc<'a> { + requests.resume_out = true; + self.requests[endpoint].set(requests); + } ++ ++ fn endpoint_cancel_in(&self, _endpoint: usize) { ++ unimplemented!() ++ } + } + + /// Static state to manage the USBC +diff --git a/kernel/src/hil/usb.rs b/kernel/src/hil/usb.rs +index 846f5e93..64610fa5 100644 +--- a/kernel/src/hil/usb.rs ++++ b/kernel/src/hil/usb.rs +@@ -27,6 +27,8 @@ pub trait UsbController<'a> { + fn endpoint_resume_in(&self, endpoint: usize); + + fn endpoint_resume_out(&self, endpoint: usize); ++ ++ fn endpoint_cancel_in(&self, endpoint: usize); + } + + #[derive(Clone, Copy, Debug)] diff --git a/patches/tock/03-app-memory.patch b/patches/tock/03-app-memory.patch new file mode 100644 index 0000000..355375c --- /dev/null +++ b/patches/tock/03-app-memory.patch @@ -0,0 +1,13 @@ +diff --git a/boards/nordic/nrf52840dk/src/main.rs b/boards/nordic/nrf52840dk/src/main.rs +index bd71dfbe..e8247905 100644 +--- a/boards/nordic/nrf52840dk/src/main.rs ++++ b/boards/nordic/nrf52840dk/src/main.rs +@@ -113,7 +113,7 @@ const FAULT_RESPONSE: kernel::procs::FaultResponse = kernel::procs::FaultRespons + const NUM_PROCS: usize = 8; + + #[link_section = ".app_memory"] +-static mut APP_MEMORY: [u8; 245760] = [0; 245760]; ++static mut APP_MEMORY: [u8; 0x3A000] = [0; 0x3A000]; + + static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; NUM_PROCS] = + [None, None, None, None, None, None, None, None]; diff --git a/patches/tock/04-rtt.patch b/patches/tock/04-rtt.patch new file mode 100644 index 0000000..70bb382 --- /dev/null +++ b/patches/tock/04-rtt.patch @@ -0,0 +1,522 @@ +diff --git a/boards/acd52832/src/main.rs b/boards/acd52832/src/main.rs +index c844ccaf..d60bbc00 100644 +--- a/boards/acd52832/src/main.rs ++++ b/boards/acd52832/src/main.rs +@@ -304,23 +304,26 @@ pub unsafe fn reset_handler() { + ); + + // RTT communication channel ++ let name = b"Terminal\0"; ++ let up_buffer_name = name; ++ let down_buffer_name = name; ++ let up_buffer = static_init!([u8; 1024], [0; 1024]); ++ let down_buffer = static_init!([u8; 32], [0; 32]); ++ + let rtt_memory = static_init!( + capsules::segger_rtt::SeggerRttMemory, +- capsules::segger_rtt::SeggerRttMemory::new( +- b"Terminal\0", +- &mut capsules::segger_rtt::UP_BUFFER, +- b"Terminal\0", +- &mut capsules::segger_rtt::DOWN_BUFFER ++ capsules::segger_rtt::SeggerRttMemory::new_raw( ++ up_buffer_name, ++ up_buffer.as_ptr(), ++ up_buffer.len(), ++ down_buffer_name, ++ down_buffer.as_ptr(), ++ down_buffer.len() + ) + ); + let rtt = static_init!( + capsules::segger_rtt::SeggerRtt>, +- capsules::segger_rtt::SeggerRtt::new( +- virtual_alarm_rtt, +- rtt_memory, +- &mut capsules::segger_rtt::UP_BUFFER, +- &mut capsules::segger_rtt::DOWN_BUFFER +- ) ++ capsules::segger_rtt::SeggerRtt::new(virtual_alarm_rtt, rtt_memory, up_buffer, down_buffer) + ); + hil::time::Alarm::set_client(virtual_alarm_rtt, rtt); + +diff --git a/boards/nordic/nrf52840_dongle/src/main.rs b/boards/nordic/nrf52840_dongle/src/main.rs +index 31d0b392..5a9da538 100644 +--- a/boards/nordic/nrf52840_dongle/src/main.rs ++++ b/boards/nordic/nrf52840_dongle/src/main.rs +@@ -11,7 +11,7 @@ use kernel::component::Component; + #[allow(unused_imports)] + use kernel::{debug, debug_gpio, debug_verbose, static_init}; + use nrf52840::gpio::Pin; +-use nrf52dk_base::{SpiPins, UartPins}; ++use nrf52dk_base::{SpiPins, UartChannel, UartPins}; + + // The nRF52840 Dongle LEDs + const LED1_PIN: Pin = Pin::P0_06; +@@ -130,7 +130,7 @@ pub unsafe fn reset_handler() { + LED2_G_PIN, + LED2_B_PIN, + led, +- &UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD), ++ UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD)), + &SpiPins::new(SPI_MOSI, SPI_MISO, SPI_CLK), + &None, + button, +diff --git a/boards/nordic/nrf52840dk/Cargo.toml b/boards/nordic/nrf52840dk/Cargo.toml +index 171c497f..9d16f679 100644 +--- a/boards/nordic/nrf52840dk/Cargo.toml ++++ b/boards/nordic/nrf52840dk/Cargo.toml +@@ -17,6 +17,10 @@ lto = true + opt-level = "z" + debug = true + ++[features] ++usb_debugging = [] ++default = ["usb_debugging"] ++ + [dependencies] + components = { path = "../../components" } + cortexm4 = { path = "../../../arch/cortex-m4" } +diff --git a/boards/nordic/nrf52840dk/src/io.rs b/boards/nordic/nrf52840dk/src/io.rs +index 4c4f3bf3..608fa9ca 100644 +--- a/boards/nordic/nrf52840dk/src/io.rs ++++ b/boards/nordic/nrf52840dk/src/io.rs +@@ -1,19 +1,46 @@ + use core::fmt::Write; + use core::panic::PanicInfo; + use cortexm4; ++#[cfg(feature = "usb_debugging")] ++use kernel::common::cells::TakeCell; + use kernel::debug; + use kernel::debug::IoWrite; + use kernel::hil::led; ++#[cfg(not(feature = "usb_debugging"))] + use kernel::hil::uart::{self, Configure}; + use nrf52840::gpio::Pin; + + use crate::PROCESSES; + + struct Writer { ++ #[cfg(not(feature = "usb_debugging"))] + initialized: bool, ++ #[cfg(feature = "usb_debugging")] ++ rtt_memory: TakeCell<'static, capsules::segger_rtt::SeggerRttMemory<'static>>, + } + ++#[cfg(not(feature = "usb_debugging"))] + static mut WRITER: Writer = Writer { initialized: false }; ++#[cfg(feature = "usb_debugging")] ++static mut WRITER: Writer = Writer { ++ rtt_memory: TakeCell::empty(), ++}; ++ ++#[cfg(feature = "usb_debugging")] ++fn wait() { ++ let mut x = 0; ++ for i in 0..5000 { ++ unsafe { core::ptr::write_volatile(&mut x as *mut _, i) }; ++ } ++} ++ ++/// Set the RTT memory buffer used to output panic messages. ++#[cfg(feature = "usb_debugging")] ++pub unsafe fn set_rtt_memory( ++ rtt_memory: &'static mut capsules::segger_rtt::SeggerRttMemory<'static>, ++) { ++ WRITER.rtt_memory.replace(rtt_memory); ++} + + impl Write for Writer { + fn write_str(&mut self, s: &str) -> ::core::fmt::Result { +@@ -23,6 +50,7 @@ impl Write for Writer { + } + + impl IoWrite for Writer { ++ #[cfg(not(feature = "usb_debugging"))] + fn write(&mut self, buf: &[u8]) { + let uart = unsafe { &mut nrf52840::uart::UARTE0 }; + if !self.initialized { +@@ -42,6 +70,30 @@ impl IoWrite for Writer { + while !uart.tx_ready() {} + } + } ++ ++ #[cfg(feature = "usb_debugging")] ++ fn write(&mut self, buf: &[u8]) { ++ // TODO: initialize if needed. ++ self.rtt_memory.map(|rtt_memory| { ++ let up_buffer = &mut rtt_memory.up_buffer; ++ let buffer_len = up_buffer.length.get(); ++ let buffer = unsafe { ++ core::slice::from_raw_parts_mut( ++ up_buffer.buffer.get() as *mut u8, ++ buffer_len as usize, ++ ) ++ }; ++ ++ let mut write_position = up_buffer.write_position.get(); ++ ++ for &c in buf { ++ buffer[write_position as usize] = c; ++ write_position = (write_position + 1) % buffer_len; ++ up_buffer.write_position.set(write_position); ++ wait(); ++ } ++ }); ++ } + } + + #[cfg(not(test))] +diff --git a/boards/nordic/nrf52840dk/src/main.rs b/boards/nordic/nrf52840dk/src/main.rs +index 57c42436..0b19ea3f 100644 +--- a/boards/nordic/nrf52840dk/src/main.rs ++++ b/boards/nordic/nrf52840dk/src/main.rs +@@ -68,7 +68,9 @@ use kernel::component::Component; + #[allow(unused_imports)] + use kernel::{debug, debug_gpio, debug_verbose, static_init}; + use nrf52840::gpio::Pin; +-use nrf52dk_base::{SpiMX25R6435FPins, SpiPins, UartPins}; ++#[cfg(not(feature = "usb_debugging"))] ++use nrf52dk_base::UartPins; ++use nrf52dk_base::{SpiMX25R6435FPins, SpiPins, UartChannel}; + + // The nRF52840DK LEDs (see back of board) + const LED1_PIN: Pin = Pin::P0_13; +@@ -83,9 +85,13 @@ const BUTTON3_PIN: Pin = Pin::P0_24; + const BUTTON4_PIN: Pin = Pin::P0_25; + const BUTTON_RST_PIN: Pin = Pin::P0_18; + ++#[cfg(not(feature = "usb_debugging"))] + const UART_RTS: Pin = Pin::P0_05; ++#[cfg(not(feature = "usb_debugging"))] + const UART_TXD: Pin = Pin::P0_06; ++#[cfg(not(feature = "usb_debugging"))] + const UART_CTS: Pin = Pin::P0_07; ++#[cfg(not(feature = "usb_debugging"))] + const UART_RXD: Pin = Pin::P0_08; + + const SPI_MOSI: Pin = Pin::P0_20; +@@ -123,6 +129,37 @@ pub unsafe fn reset_handler() { + // Loads relocations and clears BSS + nrf52840::init(); + ++ // Initialize Segger RTT as early as possible so that any panic beyond this point can use the ++ // RTT memory object. ++ #[cfg(feature = "usb_debugging")] ++ let (up_buffer, down_buffer, rtt_memory) = { ++ let name = b"Terminal\0"; ++ let up_buffer_name = name; ++ let down_buffer_name = name; ++ let up_buffer = static_init!([u8; 1024], [0; 1024]); ++ let down_buffer = static_init!([u8; 32], [0; 32]); ++ ++ let rtt_memory = static_init!( ++ capsules::segger_rtt::SeggerRttMemory, ++ capsules::segger_rtt::SeggerRttMemory::new_raw( ++ up_buffer_name, ++ up_buffer.as_ptr(), ++ up_buffer.len(), ++ down_buffer_name, ++ down_buffer.as_ptr(), ++ down_buffer.len() ++ ) ++ ); ++ ++ (up_buffer, down_buffer, rtt_memory) ++ }; ++ ++ // XXX: This is inherently unsafe as it aliases the mutable reference to rtt_memory. This ++ // aliases reference is only used inside a panic handler, which should be OK, but maybe we ++ // should use a const reference to rtt_memory and leverage interior mutability instead. ++ #[cfg(feature = "usb_debugging")] ++ self::io::set_rtt_memory(&mut *(rtt_memory as *mut _)); ++ + let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&PROCESSES)); + let gpio = components::gpio::GpioComponent::new(board_kernel).finalize( + components::gpio_component_helper!( +@@ -198,7 +235,10 @@ pub unsafe fn reset_handler() { + LED2_PIN, + LED3_PIN, + led, +- &UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD), ++ #[cfg(feature = "usb_debugging")] ++ UartChannel::Rtt(up_buffer, down_buffer, rtt_memory), ++ #[cfg(not(feature = "usb_debugging"))] ++ UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD)), + &SpiPins::new(SPI_MOSI, SPI_MISO, SPI_CLK), + &Some(SpiMX25R6435FPins::new( + SPI_MX25R6435F_CHIP_SELECT, +diff --git a/boards/nordic/nrf52dk/src/main.rs b/boards/nordic/nrf52dk/src/main.rs +index 693f1e18..b49518ff 100644 +--- a/boards/nordic/nrf52dk/src/main.rs ++++ b/boards/nordic/nrf52dk/src/main.rs +@@ -68,7 +68,7 @@ use kernel::component::Component; + #[allow(unused_imports)] + use kernel::{debug, debug_gpio, debug_verbose, static_init}; + use nrf52832::gpio::Pin; +-use nrf52dk_base::{SpiPins, UartPins}; ++use nrf52dk_base::{SpiPins, UartChannel, UartPins}; + + // The nRF52 DK LEDs (see back of board) + const LED1_PIN: Pin = Pin::P0_17; +@@ -199,7 +199,7 @@ pub unsafe fn reset_handler() { + LED2_PIN, + LED3_PIN, + led, +- &UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD), ++ UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD)), + &SpiPins::new(SPI_MOSI, SPI_MISO, SPI_CLK), + &None, + button, +diff --git a/boards/nordic/nrf52dk_base/src/lib.rs b/boards/nordic/nrf52dk_base/src/lib.rs +index 17be93a4..ddac9dbd 100644 +--- a/boards/nordic/nrf52dk_base/src/lib.rs ++++ b/boards/nordic/nrf52dk_base/src/lib.rs +@@ -70,6 +70,15 @@ impl UartPins { + } + } + ++pub enum UartChannel<'a> { ++ Pins(UartPins), ++ Rtt( ++ &'a mut [u8], ++ &'a mut [u8], ++ &'a mut capsules::segger_rtt::SeggerRttMemory<'a>, ++ ), ++} ++ + /// Supported drivers by the platform + pub struct Platform { + ble_radio: &'static capsules::ble_advertising_driver::BLE< +@@ -136,7 +145,7 @@ pub unsafe fn setup_board( + debug_pin2_index: Pin, + debug_pin3_index: Pin, + led: &'static capsules::led::LED<'static>, +- uart_pins: &UartPins, ++ uart_channel: UartChannel<'static>, + spi_pins: &SpiPins, + mx25r6435f: &Option, + button: &'static capsules::button::Button<'static>, +@@ -232,6 +241,38 @@ pub unsafe fn setup_board( + let alarm = components::alarm::AlarmDriverComponent::new(board_kernel, mux_alarm) + .finalize(components::alarm_component_helper!(nrf52::rtc::Rtc)); + ++ let channel: &dyn kernel::hil::uart::Uart = match uart_channel { ++ UartChannel::Pins(uart_pins) => { ++ nrf52::uart::UARTE0.initialize( ++ nrf52::pinmux::Pinmux::new(uart_pins.txd as u32), ++ nrf52::pinmux::Pinmux::new(uart_pins.rxd as u32), ++ Some(nrf52::pinmux::Pinmux::new(uart_pins.cts as u32)), ++ Some(nrf52::pinmux::Pinmux::new(uart_pins.rts as u32)), ++ ); ++ &nrf52::uart::UARTE0 ++ } ++ UartChannel::Rtt(up_buffer, down_buffer, rtt_memory) => { ++ // Virtual alarm for the Segger RTT communication channel ++ let virtual_alarm_rtt = static_init!( ++ capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc>, ++ capsules::virtual_alarm::VirtualMuxAlarm::new(mux_alarm) ++ ); ++ ++ // RTT communication channel ++ let rtt = static_init!( ++ capsules::segger_rtt::SeggerRtt>, ++ capsules::segger_rtt::SeggerRtt::new( ++ virtual_alarm_rtt, ++ rtt_memory, ++ up_buffer, ++ down_buffer ++ ) ++ ); ++ hil::time::Alarm::set_client(virtual_alarm_rtt, rtt); ++ rtt ++ } ++ }; ++ + let dynamic_deferred_call_clients = + static_init!([DynamicDeferredCallClientState; 2], Default::default()); + let dynamic_deferred_caller = static_init!( +@@ -241,19 +282,10 @@ pub unsafe fn setup_board( + DynamicDeferredCall::set_global_instance(dynamic_deferred_caller); + + // Create a shared UART channel for the console and for kernel debug. +- let uart_mux = components::console::UartMuxComponent::new( +- &nrf52::uart::UARTE0, +- 115200, +- dynamic_deferred_caller, +- ) +- .finalize(()); +- +- nrf52::uart::UARTE0.initialize( +- nrf52::pinmux::Pinmux::new(uart_pins.txd as u32), +- nrf52::pinmux::Pinmux::new(uart_pins.rxd as u32), +- Some(nrf52::pinmux::Pinmux::new(uart_pins.cts as u32)), +- Some(nrf52::pinmux::Pinmux::new(uart_pins.rts as u32)), +- ); ++ let uart_mux = ++ components::console::UartMuxComponent::new(channel, 115200, dynamic_deferred_caller) ++ .finalize(()); ++ + let pconsole = + components::process_console::ProcessConsoleComponent::new(board_kernel, uart_mux) + .finalize(()); +diff --git a/capsules/src/segger_rtt.rs b/capsules/src/segger_rtt.rs +index 1bf93fc1..33103c57 100644 +--- a/capsules/src/segger_rtt.rs ++++ b/capsules/src/segger_rtt.rs +@@ -91,67 +91,69 @@ + //! ``` + + use core::cell::Cell; +-use kernel::common::cells::{OptionalCell, TakeCell}; ++use core::marker::PhantomData; ++use kernel::common::cells::{OptionalCell, TakeCell, VolatileCell}; + use kernel::hil; + use kernel::hil::time::Frequency; + use kernel::hil::uart; + use kernel::ReturnCode; + +-/// Buffer for transmitting to the host. +-pub static mut UP_BUFFER: [u8; 1024] = [0; 1024]; +- +-/// Buffer for receiving messages from the host. +-pub static mut DOWN_BUFFER: [u8; 32] = [0; 32]; +- + /// This structure is defined by the segger RTT protocol. It must exist in + /// memory in exactly this form so that the segger JTAG tool can find it in the + /// chip's memory and read and write messages to the appropriate buffers. + #[repr(C)] +-pub struct SeggerRttMemory { +- id: [u8; 16], +- number_up_buffers: u32, +- number_down_buffers: u32, +- up_buffer: SeggerRttBuffer, +- down_buffer: SeggerRttBuffer, ++pub struct SeggerRttMemory<'a> { ++ id: VolatileCell<[u8; 16]>, ++ number_up_buffers: VolatileCell, ++ number_down_buffers: VolatileCell, ++ pub up_buffer: SeggerRttBuffer<'a>, ++ down_buffer: SeggerRttBuffer<'a>, + } + + #[repr(C)] +-pub struct SeggerRttBuffer { +- name: *const u8, // Pointer to the name of this channel. Must be a 4 byte thin pointer. +- buffer: *const u8, // Pointer to the buffer for this channel. +- length: u32, +- write_position: u32, +- read_position: u32, +- flags: u32, ++pub struct SeggerRttBuffer<'a> { ++ name: VolatileCell<*const u8>, // Pointer to the name of this channel. Must be a 4 byte thin pointer. ++ pub buffer: VolatileCell<*const u8>, // Pointer to the buffer for this channel. ++ pub length: VolatileCell, ++ pub write_position: VolatileCell, ++ read_position: VolatileCell, ++ flags: VolatileCell, ++ _lifetime: PhantomData<&'a [u8]>, + } + +-impl SeggerRttMemory { +- pub fn new( ++impl SeggerRttMemory<'a> { ++ pub fn new_raw( + up_buffer_name: &'a [u8], +- up_buffer: &'static mut [u8], +- down_buffer_name: &'static [u8], +- down_buffer: &'static mut [u8], +- ) -> SeggerRttMemory { ++ up_buffer_ptr: *const u8, ++ up_buffer_len: usize, ++ down_buffer_name: &'a [u8], ++ down_buffer_ptr: *const u8, ++ down_buffer_len: usize, ++ ) -> SeggerRttMemory<'a> { + SeggerRttMemory { ++ // TODO: only write this ID when the object is fully initialized, to avoid having ++ // these bytes elsewhere in (flash) memory. + // Must be "SEGGER RTT". +- id: *b"SEGGER RTT\0\0\0\0\0\0", +- number_up_buffers: 1, +- number_down_buffers: 1, ++ id: VolatileCell::new(*b"SEGGER RTT\0\0\0\0\0\0"), ++ number_up_buffers: VolatileCell::new(1), ++ number_down_buffers: VolatileCell::new(1), + up_buffer: SeggerRttBuffer { +- name: up_buffer_name.as_ptr(), +- buffer: up_buffer.as_ptr(), +- length: 1024, +- write_position: 0, +- read_position: 0, +- flags: 0, ++ name: VolatileCell::new(up_buffer_name.as_ptr()), ++ buffer: VolatileCell::new(up_buffer_ptr), ++ length: VolatileCell::new(up_buffer_len as u32), ++ write_position: VolatileCell::new(0), ++ read_position: VolatileCell::new(0), ++ flags: VolatileCell::new(0), ++ _lifetime: PhantomData, + }, + down_buffer: SeggerRttBuffer { +- name: down_buffer_name.as_ptr(), +- buffer: down_buffer.as_ptr(), +- length: 32, +- write_position: 0, +- read_position: 0, +- flags: 0, ++ name: VolatileCell::new(down_buffer_name.as_ptr()), ++ buffer: VolatileCell::new(down_buffer_ptr), ++ length: VolatileCell::new(down_buffer_len as u32), ++ write_position: VolatileCell::new(0), ++ read_position: VolatileCell::new(0), ++ flags: VolatileCell::new(0), ++ _lifetime: PhantomData, + }, + } + } +@@ -159,9 +161,9 @@ impl SeggerRttMemory { + + pub struct SeggerRtt<'a, A: hil::time::Alarm<'a>> { + alarm: &'a A, // Dummy alarm so we can get a callback. +- config: TakeCell<'a, SeggerRttMemory>, +- up_buffer: TakeCell<'static, [u8]>, +- _down_buffer: TakeCell<'static, [u8]>, ++ config: TakeCell<'a, SeggerRttMemory<'a>>, ++ up_buffer: TakeCell<'a, [u8]>, ++ _down_buffer: TakeCell<'a, [u8]>, + client: OptionalCell<&'a dyn uart::TransmitClient>, + client_buffer: TakeCell<'static, [u8]>, + tx_len: Cell, +@@ -170,9 +172,9 @@ pub struct SeggerRtt<'a, A: hil::time::Alarm<'a>> { + impl<'a, A: hil::time::Alarm<'a>> SeggerRtt<'a, A> { + pub fn new( + alarm: &'a A, +- config: &'a mut SeggerRttMemory, +- up_buffer: &'static mut [u8], +- down_buffer: &'static mut [u8], ++ config: &'a mut SeggerRttMemory<'a>, ++ up_buffer: &'a mut [u8], ++ down_buffer: &'a mut [u8], + ) -> SeggerRtt<'a, A> { + SeggerRtt { + alarm: alarm, +@@ -205,15 +207,15 @@ impl<'a, A: hil::time::Alarm<'a>> uart::Transmit<'a> for SeggerRtt<'a, A> { + // Copy the incoming data into the buffer. Once we increment + // the `write_position` the RTT listener will go ahead and read + // the message from us. +- let mut index = config.up_buffer.write_position as usize; +- let buffer_len = config.up_buffer.length as usize; ++ let mut index = config.up_buffer.write_position.get() as usize; ++ let buffer_len = config.up_buffer.length.get() as usize; + + for i in 0..tx_len { + buffer[(i + index) % buffer_len] = tx_data[i]; + } + + index = (index + tx_len) % buffer_len; +- config.up_buffer.write_position = index as u32; ++ config.up_buffer.write_position.set(index as u32); + self.tx_len.set(tx_len); + // Save the client buffer so we can pass it back with the callback. + self.client_buffer.replace(tx_data); diff --git a/reset.sh b/reset.sh new file mode 100755 index 0000000..8067c4a --- /dev/null +++ b/reset.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +echo "$(tput bold)This script will restore the repository to a clean state$(tput sgr0)" +echo "$(tput bold)Any pending change will be lost.$(tput sgr0)" +echo "" + +accept='' +while + case "$accept" in + [Yy]) + # Start echoeing the commands to the screen + set -x + # Reset the submodules + git submodule foreach 'git reset --hard && git clean -fxd' + # Reset also the main repository + git reset --hard && git clean -fxd + + set +x + echo "DONE." + # And break the loop + false + ;; + + [Nn]) + echo "Nothing was done. Repository was left untouched." + # Don't do anything but break the while loop to exit + false + ;; + + *) + # Continue looping + true + ;; + esac +do + echo "$(tput bold)Are you sure you want to continue? [y/n]$(tput sgr0)" + read -s -n 1 accept +done diff --git a/rules.d/55-opensk.rules b/rules.d/55-opensk.rules new file mode 100644 index 0000000..b1c8c60 --- /dev/null +++ b/rules.d/55-opensk.rules @@ -0,0 +1 @@ +SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="1915", ATTRS{idProduct}=="521f", ATTRS{product}=="OpenSK", MODE="0660", GROUP="logindev", TAG+="uaccess" diff --git a/run_desktop_tests.sh b/run_desktop_tests.sh new file mode 100755 index 0000000..11786e7 --- /dev/null +++ b/run_desktop_tests.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eu + +# Ensure we have the key_material.rs file before running the tests +if [ ! -f src/ctap/key_material.rs ] +then + echo "$(tput bold)ERROR:$(tput sgr0) Cannot find src/ctap/key_material.rs file." + echo "Please make sure that you have run the following script: ./setup.sh" + exit 2 +fi + +set -x + +echo "Checking formatting..." +cargo fmt --all -- --check +cd libraries/cbor +cargo fmt --all -- --check +cd ../.. +cd libraries/crypto +cargo fmt --all -- --check +cd ../.. + +echo "Checking that CTAP2 builds properly..." +cargo check --release --target=thumbv7em-none-eabi +cargo check --release --target=thumbv7em-none-eabi --features with_ctap1 +cargo check --release --target=thumbv7em-none-eabi --features debug_ctap +cargo check --release --target=thumbv7em-none-eabi --features debug_ctap,with_ctap1 + +echo "Checking that examples build properly..." +cargo check --release --target=thumbv7em-none-eabi --examples + +echo "Checking that CTAP2 builds and links properly (1 set of features)..." +cargo build --release --target=thumbv7em-none-eabi --features with_ctap1 + +echo "Running unit tests on the desktop (release mode)..." +cd libraries/cbor +cargo test --release --features std +cd ../.. +cd libraries/crypto +RUSTFLAGS='-C target-feature=+aes' cargo test --release --features std,derive_debug +cd ../.. +cargo test --release --features std + +echo "Running unit tests on the desktop (debug mode)..." +cd libraries/cbor +cargo test --features std +cd ../.. +cd libraries/crypto +RUSTFLAGS='-C target-feature=+aes' cargo test --features std,derive_debug +cd ../.. +cargo test --features std + +echo "Running unit tests on the desktop (release mode + CTAP1)..." +cargo test --release --features std,with_ctap1 + +echo "Running unit tests on the desktop (debug mode + CTAP1)..." +cargo test --features std,with_ctap1 + diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 0000000..20d9cda --- /dev/null +++ b/rust-toolchain @@ -0,0 +1 @@ +nightly-2020-01-16 diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..d3da3dd --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,3 @@ +use_field_init_shorthand = true +use_try_shorthand = true +edition = "2018" \ No newline at end of file diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..2b45be3 --- /dev/null +++ b/setup.sh @@ -0,0 +1,49 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Ensure the submodules are pulled and up-to-date +git submodule update --init + +done_text="$(tput bold)DONE.$(tput sgr0)" + +# Apply patches to kernel. Do that in a sub-shell +( + cd third_party/tock/ && \ + for p in ../../patches/tock/[0-9][0-9]-*.patch + do + echo -n '[-] Applying patch "'$(basename $p)'"... ' + git apply "$p" && echo $done_text + done +) + +# Now apply patches to libtock-rs. Do that in a sub-shell +( + cd third_party/libtock-rs/ && \ + for p in ../../patches/libtock-rs/[0-9][0-9]-*.patch + do + echo -n '[-] Applying patch "'$(basename $p)'"... ' + git apply "$p" && echo $done_text + done +) + +# Ensure we have certificates, keys, etc. so that the tests can run +source tools/gen_key_materials.sh +generate_crypto_materials N + +rustup install $(head -n 1 rust-toolchain) +pip3 install --user --upgrade tockloader +rustup target add thumbv7em-none-eabi + +# Install dependency to create applications. +cargo install elf2tab diff --git a/src/ctap/command.rs b/src/ctap/command.rs new file mode 100644 index 0000000..129c671 --- /dev/null +++ b/src/ctap/command.rs @@ -0,0 +1,483 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::data_formats::{ + ok_or_missing, read_array, read_byte_string, read_integer, read_map, read_text_string, + read_unsigned, ClientPinSubCommand, CoseKey, Extensions, GetAssertionOptions, + MakeCredentialOptions, PublicKeyCredentialDescriptor, PublicKeyCredentialRpEntity, + PublicKeyCredentialType, PublicKeyCredentialUserEntity, +}; +use super::status_code::Ctap2StatusCode; +use alloc::string::String; +use alloc::vec::Vec; +use core::convert::TryFrom; + +// CTAP specification (version 20190130) section 6.1 +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +pub enum Command { + AuthenticatorMakeCredential(AuthenticatorMakeCredentialParameters), + AuthenticatorGetAssertion(AuthenticatorGetAssertionParameters), + AuthenticatorGetInfo, + AuthenticatorClientPin(AuthenticatorClientPinParameters), + AuthenticatorReset, + AuthenticatorGetNextAssertion, + // TODO(kaczmarczyck) implement FIDO 2.1 commands (see below consts) +} + +impl From for Ctap2StatusCode { + fn from(_: cbor::reader::DecoderError) -> Self { + Ctap2StatusCode::CTAP2_ERR_INVALID_CBOR + } +} + +// TODO: Remove this `allow(dead_code)` once the constants are used. +#[allow(dead_code)] +impl Command { + const AUTHENTICATOR_MAKE_CREDENTIAL: u8 = 0x01; + const AUTHENTICATOR_GET_ASSERTION: u8 = 0x02; + const AUTHENTICATOR_GET_INFO: u8 = 0x04; + const AUTHENTICATOR_CLIENT_PIN: u8 = 0x06; + const AUTHENTICATOR_RESET: u8 = 0x07; + // TODO(kaczmarczyck) use or remove those constants + const AUTHENTICATOR_GET_NEXT_ASSERTION: u8 = 0x08; + const AUTHENTICATOR_BIO_ENROLLMENT: u8 = 0x09; + const AUTHENTICATOR_CREDENTIAL_MANAGEMENT: u8 = 0xA0; + const AUTHENTICATOR_SELECTION: u8 = 0xB0; + const AUTHENTICATOR_CONFIG: u8 = 0xC0; + const AUTHENTICATOR_VENDOR_FIRST: u8 = 0x40; + const AUTHENTICATOR_VENDOR_LAST: u8 = 0xBF; + + pub fn deserialize(bytes: &[u8]) -> Result { + if bytes.is_empty() { + // The error to return is not specified, missing parameter seems to fit best. + return Err(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER); + } + + let command_value = bytes[0]; + match command_value { + Command::AUTHENTICATOR_MAKE_CREDENTIAL => { + let decoded_cbor = cbor::read(&bytes[1..])?; + Ok(Command::AuthenticatorMakeCredential( + AuthenticatorMakeCredentialParameters::try_from(decoded_cbor)?, + )) + } + Command::AUTHENTICATOR_GET_ASSERTION => { + let decoded_cbor = cbor::read(&bytes[1..])?; + Ok(Command::AuthenticatorGetAssertion( + AuthenticatorGetAssertionParameters::try_from(decoded_cbor)?, + )) + } + Command::AUTHENTICATOR_GET_INFO => { + // Parameters are ignored. + Ok(Command::AuthenticatorGetInfo) + } + Command::AUTHENTICATOR_CLIENT_PIN => { + let decoded_cbor = cbor::read(&bytes[1..])?; + Ok(Command::AuthenticatorClientPin( + AuthenticatorClientPinParameters::try_from(decoded_cbor)?, + )) + } + Command::AUTHENTICATOR_RESET => { + // Parameters are ignored. + Ok(Command::AuthenticatorReset) + } + Command::AUTHENTICATOR_GET_NEXT_ASSERTION => { + // Parameters are ignored. + Ok(Command::AuthenticatorGetNextAssertion) + } + _ => Err(Ctap2StatusCode::CTAP1_ERR_INVALID_COMMAND), + } + } +} + +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +pub struct AuthenticatorMakeCredentialParameters { + pub client_data_hash: Vec, + pub rp: PublicKeyCredentialRpEntity, + pub user: PublicKeyCredentialUserEntity, + pub pub_key_cred_params: Vec<(PublicKeyCredentialType, i64)>, + pub exclude_list: Option>, + pub extensions: Option, + // Even though options are optional, we can use the default if not present. + pub options: MakeCredentialOptions, + pub pin_uv_auth_param: Option>, + pub pin_uv_auth_protocol: Option, +} + +impl TryFrom for AuthenticatorMakeCredentialParameters { + type Error = Ctap2StatusCode; + + fn try_from(cbor_value: cbor::Value) -> Result { + let param_map = read_map(&cbor_value)?; + + let client_data_hash = read_byte_string(ok_or_missing(param_map.get(&cbor_unsigned!(1)))?)?; + + let rp = PublicKeyCredentialRpEntity::try_from(ok_or_missing( + param_map.get(&cbor_unsigned!(2)), + )?)?; + + let user = PublicKeyCredentialUserEntity::try_from(ok_or_missing( + param_map.get(&cbor_unsigned!(3)), + )?)?; + + let cred_param_vec = read_array(ok_or_missing(param_map.get(&cbor_unsigned!(4)))?)?; + let mut pub_key_cred_params = vec![]; + for cred_param_map_value in cred_param_vec { + let cred_param_map = read_map(cred_param_map_value)?; + let cred_type = PublicKeyCredentialType::try_from(ok_or_missing( + cred_param_map.get(&cbor_text!("type")), + )?)?; + let alg = read_integer(ok_or_missing(cred_param_map.get(&cbor_text!("alg")))?)?; + pub_key_cred_params.push((cred_type, alg)); + } + + let exclude_list = match param_map.get(&cbor_unsigned!(5)) { + Some(entry) => { + let exclude_list_vec = read_array(entry)?; + let mut exclude_list = vec![]; + for exclude_list_value in exclude_list_vec { + exclude_list.push(PublicKeyCredentialDescriptor::try_from(exclude_list_value)?); + } + Some(exclude_list) + } + None => None, + }; + + let extensions = param_map + .get(&cbor_unsigned!(6)) + .map(Extensions::try_from) + .transpose()?; + + let options = match param_map.get(&cbor_unsigned!(7)) { + Some(entry) => MakeCredentialOptions::try_from(entry)?, + None => MakeCredentialOptions { + rk: false, + uv: false, + }, + }; + + let pin_uv_auth_param = param_map + .get(&cbor_unsigned!(8)) + .map(read_byte_string) + .transpose()?; + + let pin_uv_auth_protocol = param_map + .get(&cbor_unsigned!(9)) + .map(read_unsigned) + .transpose()?; + + Ok(AuthenticatorMakeCredentialParameters { + client_data_hash, + rp, + user, + pub_key_cred_params, + exclude_list, + extensions, + options, + pin_uv_auth_param, + pin_uv_auth_protocol, + }) + } +} + +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +pub struct AuthenticatorGetAssertionParameters { + pub rp_id: String, + pub client_data_hash: Vec, + pub allow_list: Option>, + pub extensions: Option, + // Even though options are optional, we can use the default if not present. + pub options: GetAssertionOptions, + pub pin_uv_auth_param: Option>, + pub pin_uv_auth_protocol: Option, +} + +impl TryFrom for AuthenticatorGetAssertionParameters { + type Error = Ctap2StatusCode; + + fn try_from(cbor_value: cbor::Value) -> Result { + let param_map = read_map(&cbor_value)?; + + let rp_id = read_text_string(ok_or_missing(param_map.get(&cbor_unsigned!(1)))?)?; + + let client_data_hash = read_byte_string(ok_or_missing(param_map.get(&cbor_unsigned!(2)))?)?; + + let allow_list = match param_map.get(&cbor_unsigned!(3)) { + Some(entry) => { + let allow_list_vec = read_array(entry)?; + let mut allow_list = vec![]; + for allow_list_value in allow_list_vec { + allow_list.push(PublicKeyCredentialDescriptor::try_from(allow_list_value)?); + } + Some(allow_list) + } + None => None, + }; + + let extensions = param_map + .get(&cbor_unsigned!(4)) + .map(Extensions::try_from) + .transpose()?; + + let options = match param_map.get(&cbor_unsigned!(5)) { + Some(entry) => GetAssertionOptions::try_from(entry)?, + None => GetAssertionOptions { + up: true, + uv: false, + }, + }; + + let pin_uv_auth_param = param_map + .get(&cbor_unsigned!(6)) + .map(read_byte_string) + .transpose()?; + + let pin_uv_auth_protocol = param_map + .get(&cbor_unsigned!(7)) + .map(read_unsigned) + .transpose()?; + + Ok(AuthenticatorGetAssertionParameters { + rp_id, + client_data_hash, + allow_list, + extensions, + options, + pin_uv_auth_param, + pin_uv_auth_protocol, + }) + } +} + +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +pub struct AuthenticatorClientPinParameters { + pub pin_protocol: u64, + pub sub_command: ClientPinSubCommand, + pub key_agreement: Option, + pub pin_auth: Option>, + pub new_pin_enc: Option>, + pub pin_hash_enc: Option>, +} + +impl TryFrom for AuthenticatorClientPinParameters { + type Error = Ctap2StatusCode; + + fn try_from(cbor_value: cbor::Value) -> Result { + let param_map = read_map(&cbor_value)?; + + let pin_protocol = read_unsigned(ok_or_missing(param_map.get(&cbor_unsigned!(1)))?)?; + + let sub_command = + ClientPinSubCommand::try_from(ok_or_missing(param_map.get(&cbor_unsigned!(2)))?)?; + + let key_agreement = param_map + .get(&cbor_unsigned!(3)) + .map(read_map) + .transpose()? + .map(|x| CoseKey(x.clone())); + + let pin_auth = param_map + .get(&cbor_unsigned!(4)) + .map(read_byte_string) + .transpose()?; + + let new_pin_enc = param_map + .get(&cbor_unsigned!(5)) + .map(read_byte_string) + .transpose()?; + + let pin_hash_enc = param_map + .get(&cbor_unsigned!(6)) + .map(read_byte_string) + .transpose()?; + + Ok(AuthenticatorClientPinParameters { + pin_protocol, + sub_command, + key_agreement, + pin_auth, + new_pin_enc, + pin_hash_enc, + }) + } +} + +#[cfg(test)] +mod test { + use super::super::data_formats::{ + AuthenticatorTransport, PublicKeyCredentialRpEntity, PublicKeyCredentialUserEntity, + }; + use super::*; + use alloc::collections::BTreeMap; + + #[test] + fn test_from_cbor_make_credential_parameters() { + let cbor_value = cbor_map! { + 1 => vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F], + 2 => cbor_map! { + "id" => "example.com", + "name" => "Example", + "icon" => "example.com/icon.png", + }, + 3 => cbor_map! { + "id" => vec![0x1D, 0x1D, 0x1D, 0x1D], + "name" => "foo", + "displayName" => "bar", + "icon" => "example.com/foo/icon.png", + }, + 4 => cbor_array![ cbor_map! { + "type" => "public-key", + "alg" => -7 + } ], + 5 => cbor_array![], + 8 => vec![0x12, 0x34], + 9 => 1, + }; + let returned_make_credential_parameters = + AuthenticatorMakeCredentialParameters::try_from(cbor_value).unwrap(); + + let client_data_hash = vec![ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, + ]; + let rp = PublicKeyCredentialRpEntity { + rp_id: "example.com".to_string(), + rp_name: Some("Example".to_string()), + rp_icon: Some("example.com/icon.png".to_string()), + }; + let user = PublicKeyCredentialUserEntity { + user_id: vec![0x1D, 0x1D, 0x1D, 0x1D], + user_name: Some("foo".to_string()), + user_display_name: Some("bar".to_string()), + user_icon: Some("example.com/foo/icon.png".to_string()), + }; + let pub_key_cred_param = (PublicKeyCredentialType::PublicKey, -7); + let options = MakeCredentialOptions { + rk: false, + uv: false, + }; + let expected_make_credential_parameters = AuthenticatorMakeCredentialParameters { + client_data_hash, + rp, + user, + pub_key_cred_params: vec![pub_key_cred_param], + exclude_list: Some(vec![]), + extensions: None, + options, + pin_uv_auth_param: Some(vec![0x12, 0x34]), + pin_uv_auth_protocol: Some(1), + }; + + assert_eq!( + returned_make_credential_parameters, + expected_make_credential_parameters + ); + } + + #[test] + fn test_from_cbor_get_assertion_parameters() { + let cbor_value = cbor_map! { + 1 => "example.com", + 2 => vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F], + 3 => cbor_array![ cbor_map! { + "type" => "public-key", + "id" => vec![0x2D, 0x2D, 0x2D, 0x2D], + "transports" => cbor_array!["usb"], + } ], + 6 => vec![0x12, 0x34], + 7 => 1, + }; + let returned_get_assertion_parameters = + AuthenticatorGetAssertionParameters::try_from(cbor_value).unwrap(); + + let rp_id = "example.com".to_string(); + let client_data_hash = vec![ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, + ]; + let pub_key_cred_descriptor = PublicKeyCredentialDescriptor { + key_type: PublicKeyCredentialType::PublicKey, + key_id: vec![0x2D, 0x2D, 0x2D, 0x2D], + transports: Some(vec![AuthenticatorTransport::Usb]), + }; + let options = GetAssertionOptions { + up: true, + uv: false, + }; + let expected_get_assertion_parameters = AuthenticatorGetAssertionParameters { + rp_id, + client_data_hash, + allow_list: Some(vec![pub_key_cred_descriptor]), + extensions: None, + options, + pin_uv_auth_param: Some(vec![0x12, 0x34]), + pin_uv_auth_protocol: Some(1), + }; + + assert_eq!( + returned_get_assertion_parameters, + expected_get_assertion_parameters + ); + } + + #[test] + fn test_from_cbor_client_pin_parameters() { + let cbor_value = cbor_map! { + 1 => 1, + 2 => ClientPinSubCommand::GetPinRetries, + 3 => cbor_map!{}, + 4 => vec! [0xBB], + 5 => vec! [0xCC], + 6 => vec! [0xDD], + }; + let returned_pin_protocol_parameters = + AuthenticatorClientPinParameters::try_from(cbor_value).unwrap(); + + let expected_pin_protocol_parameters = AuthenticatorClientPinParameters { + pin_protocol: 1, + sub_command: ClientPinSubCommand::GetPinRetries, + key_agreement: Some(CoseKey(BTreeMap::new())), + pin_auth: Some(vec![0xBB]), + new_pin_enc: Some(vec![0xCC]), + pin_hash_enc: Some(vec![0xDD]), + }; + + assert_eq!( + returned_pin_protocol_parameters, + expected_pin_protocol_parameters + ); + } + + #[test] + fn test_deserialize_get_info() { + let cbor_bytes = [Command::AUTHENTICATOR_GET_INFO]; + let command = Command::deserialize(&cbor_bytes); + assert_eq!(command, Ok(Command::AuthenticatorGetInfo)); + } + + #[test] + fn test_deserialize_reset() { + // Adding some random bytes to see if they are ignored. + let cbor_bytes = [Command::AUTHENTICATOR_RESET, 0xAB, 0xCD, 0xEF]; + let command = Command::deserialize(&cbor_bytes); + assert_eq!(command, Ok(Command::AuthenticatorReset)); + } + + #[test] + fn test_deserialize_get_next_assertion() { + let cbor_bytes = [Command::AUTHENTICATOR_GET_NEXT_ASSERTION]; + let command = Command::deserialize(&cbor_bytes); + assert_eq!(command, Ok(Command::AuthenticatorGetNextAssertion)); + } +} diff --git a/src/ctap/ctap1.rs b/src/ctap/ctap1.rs new file mode 100644 index 0000000..f3a9ce3 --- /dev/null +++ b/src/ctap/ctap1.rs @@ -0,0 +1,675 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::hid::ChannelID; +use super::key_material::{ATTESTATION_CERTIFICATE, ATTESTATION_PRIVATE_KEY}; +use super::status_code::Ctap2StatusCode; +use super::CtapState; +use crate::timer::ClockValue; +use alloc::vec::Vec; +use core::convert::Into; +use core::convert::TryFrom; +use crypto::rng256::Rng256; + +// The specification referenced in this file is at: +// https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-raw-message-formats-v1.2-ps-20170411.pdf + +// status codes specification (version 20170411) section 3.3 +#[allow(non_camel_case_types)] +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +pub enum Ctap1StatusCode { + SW_NO_ERROR = 0x9000, + SW_CONDITIONS_NOT_SATISFIED = 0x6985, + SW_WRONG_DATA = 0x6A80, + SW_WRONG_LENGTH = 0x6700, + SW_CLA_NOT_SUPPORTED = 0x6E00, + SW_INS_NOT_SUPPORTED = 0x6D00, + SW_VENDOR_KEY_HANDLE_TOO_LONG = 0xF000, +} + +impl TryFrom for Ctap1StatusCode { + type Error = (); + + fn try_from(value: u16) -> Result { + match value { + 0x9000 => Ok(Ctap1StatusCode::SW_NO_ERROR), + 0x6985 => Ok(Ctap1StatusCode::SW_CONDITIONS_NOT_SATISFIED), + 0x6A80 => Ok(Ctap1StatusCode::SW_WRONG_DATA), + 0x6700 => Ok(Ctap1StatusCode::SW_WRONG_LENGTH), + 0x6E00 => Ok(Ctap1StatusCode::SW_CLA_NOT_SUPPORTED), + 0x6D00 => Ok(Ctap1StatusCode::SW_INS_NOT_SUPPORTED), + 0xF000 => Ok(Ctap1StatusCode::SW_VENDOR_KEY_HANDLE_TOO_LONG), + _ => Err(()), + } + } +} + +impl Into for Ctap1StatusCode { + fn into(self) -> u16 { + self as u16 + } +} + +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Clone, Debug))] +#[derive(PartialEq)] +pub enum Ctap1Flags { + CheckOnly = 0x07, + EnforceUpAndSign = 0x03, + DontEnforceUpAndSign = 0x08, +} + +impl TryFrom for Ctap1Flags { + type Error = Ctap1StatusCode; + + fn try_from(value: u8) -> Result { + match value { + 0x07 => Ok(Ctap1Flags::CheckOnly), + 0x03 => Ok(Ctap1Flags::EnforceUpAndSign), + 0x08 => Ok(Ctap1Flags::DontEnforceUpAndSign), + _ => Err(Ctap1StatusCode::SW_WRONG_DATA), + } + } +} + +impl Into for Ctap1Flags { + fn into(self) -> u8 { + self as u8 + } +} + +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +// TODO: remove #allow when https://github.com/rust-lang/rust/issues/64362 is fixed +enum U2fCommand { + #[allow(dead_code)] + Register { + challenge: [u8; 32], + application: [u8; 32], + }, + #[allow(dead_code)] + Authenticate { + challenge: [u8; 32], + application: [u8; 32], + key_handle: Vec, + flags: Ctap1Flags, + }, + Version, + #[allow(dead_code)] + VendorSpecific { + payload: Vec, + }, +} + +impl TryFrom<&[u8]> for U2fCommand { + type Error = Ctap1StatusCode; + + fn try_from(message: &[u8]) -> Result { + if message.len() < Ctap1Command::APDU_HEADER_LEN as usize { + return Err(Ctap1StatusCode::SW_WRONG_DATA); + } + + let (apdu, payload) = message.split_at(Ctap1Command::APDU_HEADER_LEN as usize); + + // ISO7816 APDU Header format. Each cell is 1 byte. Note that the CTAP flavor always + // encodes the length on 3 bytes and doesn't use the field "Le" (Length Expected). + // We keep the 2 byte of "Le" for the packet length in mind, but always ignore its value. + // Lc is using big-endian encoding + // +-----+-----+----+----+-----+-----+-----+ + // | CLA | INS | P1 | P2 | Lc1 | Lc2 | Lc3 | + // +-----+-----+----+----+-----+-----+-----+ + if apdu[0] != Ctap1Command::CTAP1_CLA { + return Err(Ctap1StatusCode::SW_CLA_NOT_SUPPORTED); + } + + let lc = (((apdu[4] as u32) << 16) | ((apdu[5] as u32) << 8) | (apdu[6] as u32)) as usize; + + // Since there is always request data, the expected length is either omitted or + // encoded in 2 bytes. + if lc != payload.len() && lc + 2 != payload.len() { + return Err(Ctap1StatusCode::SW_WRONG_LENGTH); + } + + match apdu[1] { + // U2F raw message format specification, Section 4.1 + // +-----------------+-------------------+ + // + Challenge (32B) | Application (32B) | + // +-----------------+-------------------+ + Ctap1Command::U2F_REGISTER => { + if lc != 64 { + return Err(Ctap1StatusCode::SW_WRONG_LENGTH); + } + Ok(Self::Register { + challenge: *array_ref!(payload, 0, 32), + application: *array_ref!(payload, 32, 32), + }) + } + + // U2F raw message format specification, Section 5.1 + // +-----------------+-------------------+---------------------+------------+ + // + Challenge (32B) | Application (32B) | key handle len (1B) | key handle | + // +-----------------+-------------------+---------------------+------------+ + Ctap1Command::U2F_AUTHENTICATE => { + if lc < 65 { + return Err(Ctap1StatusCode::SW_WRONG_LENGTH); + } + let handle_length = payload[64] as usize; + if lc != 65 + handle_length { + return Err(Ctap1StatusCode::SW_WRONG_LENGTH); + } + let flag = Ctap1Flags::try_from(apdu[2])?; + Ok(Self::Authenticate { + challenge: *array_ref!(payload, 0, 32), + application: *array_ref!(payload, 32, 32), + key_handle: payload[65..lc].to_vec(), + flags: flag, + }) + } + + // U2F raw message format specification, Section 6.1 + Ctap1Command::U2F_VERSION => { + if lc != 0 { + return Err(Ctap1StatusCode::SW_WRONG_LENGTH); + } + Ok(Self::Version) + } + + // For Vendor specific command. + Ctap1Command::VENDOR_SPECIFIC_FIRST..=Ctap1Command::VENDOR_SPECIFIC_LAST => { + Ok(Self::VendorSpecific { + payload: payload.to_vec(), + }) + } + + _ => Err(Ctap1StatusCode::SW_INS_NOT_SUPPORTED), + } + } +} + +pub struct Ctap1Command {} + +impl Ctap1Command { + const APDU_HEADER_LEN: u32 = 7; // CLA + INS + P1 + P2 + LC1-3 + + const CTAP1_CLA: u8 = 0; + // This byte is used in Register, but only serves backwards compatibility. + const LEGACY_BYTE: u8 = 0x05; + // This byte is hardcoded into the specification of Authenticate. + const USER_PRESENCE_INDICATOR_BYTE: u8 = 0x01; + + // CTAP1/U2F commands + // U2F raw message format specification 1.2 (version 20170411) + const U2F_REGISTER: u8 = 0x01; + const U2F_AUTHENTICATE: u8 = 0x02; + const U2F_VERSION: u8 = 0x03; + const VENDOR_SPECIFIC_FIRST: u8 = 0x40; + const VENDOR_SPECIFIC_LAST: u8 = 0xBF; + + pub fn process_command( + message: &[u8], + ctap_state: &mut CtapState, + clock_value: ClockValue, + ) -> Result, Ctap1StatusCode> + where + R: Rng256, + CheckUserPresence: Fn(ChannelID) -> Result<(), Ctap2StatusCode>, + { + let command = U2fCommand::try_from(message)?; + match command { + U2fCommand::Register { + challenge, + application, + } => { + if !ctap_state.u2f_up_state.consume_up(clock_value) { + return Err(Ctap1StatusCode::SW_CONDITIONS_NOT_SATISFIED); + } + Ctap1Command::process_register(challenge, application, ctap_state) + } + + U2fCommand::Authenticate { + challenge, + application, + key_handle, + flags, + } => { + // The order is important due to side effects of checking user presence. + if flags == Ctap1Flags::EnforceUpAndSign + && !ctap_state.u2f_up_state.consume_up(clock_value) + { + return Err(Ctap1StatusCode::SW_CONDITIONS_NOT_SATISFIED); + } + Ctap1Command::process_authenticate( + challenge, + application, + key_handle, + flags, + ctap_state, + ) + } + + // U2F raw message format specification (version 20170411) section 6.3 + U2fCommand::Version => Ok(Vec::::from(super::U2F_VERSION_STRING)), + + // TODO: should we return an error instead such as SW_INS_NOT_SUPPORTED? + U2fCommand::VendorSpecific { .. } => Err(Ctap1StatusCode::SW_NO_ERROR), + } + } + + // U2F raw message format specification (version 20170411) section 4.3 + // In case of success we need to send back the following reply + // (excluding ISO7816 success code) + // +------+--------------------+---------------------+------------+------------+------+ + // + 0x05 | User pub key (65B) | key handle len (1B) | key handle | X.509 Cert | Sign | + // +------+--------------------+---------------------+------------+------------+------+ + // + // Where Sign is an ECDSA signature over the following structure: + // +------+-------------------+-----------------+------------+--------------------+ + // + 0x00 | application (32B) | challenge (32B) | key handle | User pub key (65B) | + // +------+-------------------+-----------------+------------+--------------------+ + fn process_register( + challenge: [u8; 32], + application: [u8; 32], + ctap_state: &mut CtapState, + ) -> Result, Ctap1StatusCode> + where + R: Rng256, + CheckUserPresence: Fn(ChannelID) -> Result<(), Ctap2StatusCode>, + { + let sk = crypto::ecdsa::SecKey::gensk(ctap_state.rng); + let pk = sk.genpk(); + let key_handle = ctap_state.encrypt_key_handle(sk, &application); + if key_handle.len() > 0xFF { + // This is just being defensive with unreachable code. + return Err(Ctap1StatusCode::SW_VENDOR_KEY_HANDLE_TOO_LONG); + } + + let mut response = + Vec::with_capacity(105 + key_handle.len() + ATTESTATION_CERTIFICATE.len()); + response.push(Ctap1Command::LEGACY_BYTE); + let user_pk = pk.to_uncompressed(); + response.extend_from_slice(&user_pk); + response.push(key_handle.len() as u8); + response.extend(key_handle.clone()); + response.extend_from_slice(&ATTESTATION_CERTIFICATE); + + // The first byte is reserved. + let mut signature_data = Vec::with_capacity(66 + key_handle.len()); + signature_data.push(0x00); + signature_data.extend(&application); + signature_data.extend(&challenge); + signature_data.extend(key_handle); + signature_data.extend_from_slice(&user_pk); + + let attestation_key = crypto::ecdsa::SecKey::from_bytes(&ATTESTATION_PRIVATE_KEY).unwrap(); + let signature = attestation_key.sign_rfc6979::(&signature_data); + + response.extend(signature.to_asn1_der()); + Ok(response) + } + + // U2F raw message format specification (version 20170411) section 5.4 + // In case of success we need to send back the following reply + // (excluding ISO7816 success code) + // +---------+--------------+-----------+ + // + UP (1B) | Counter (4B) | Signature | + // +---------+--------------+-----------+ + // UP only has 2 defined values: + // - 0x00: user presence was not verified + // - 0x01: user presence was verified + // + // Where Signature is an ECDSA signature over the following structure: + // +-------------------+---------+--------------+-----------------+ + // + application (32B) | UP (1B) | Counter (4B) | challenge (32B) | + // +-------------------+---------+--------------+-----------------+ + fn process_authenticate( + challenge: [u8; 32], + application: [u8; 32], + key_handle: Vec, + flags: Ctap1Flags, + ctap_state: &mut CtapState, + ) -> Result, Ctap1StatusCode> + where + R: Rng256, + CheckUserPresence: Fn(ChannelID) -> Result<(), Ctap2StatusCode>, + { + let credential_source = ctap_state.decrypt_credential_source(key_handle, &application); + if let Some(credential_source) = credential_source { + if flags == Ctap1Flags::CheckOnly { + return Err(Ctap1StatusCode::SW_CONDITIONS_NOT_SATISFIED); + } + ctap_state.increment_global_signature_counter(); + let mut signature_data = ctap_state + .generate_auth_data(&application, Ctap1Command::USER_PRESENCE_INDICATOR_BYTE); + signature_data.extend(&challenge); + let signature = credential_source + .private_key + .sign_rfc6979::(&signature_data); + + let mut response = signature_data[application.len()..application.len() + 5].to_vec(); + response.extend(signature.to_asn1_der()); + Ok(response) + } else { + Err(Ctap1StatusCode::SW_WRONG_DATA) + } + } +} + +#[cfg(test)] +mod test { + use super::super::{ENCRYPTED_CREDENTIAL_ID_SIZE, USE_SIGNATURE_COUNTER}; + use super::*; + use crypto::rng256::ThreadRng256; + use crypto::Hash256; + + const CLOCK_FREQUENCY_HZ: usize = 32768; + const START_CLOCK_VALUE: ClockValue = ClockValue::new(0, CLOCK_FREQUENCY_HZ); + const TIMEOUT_CLOCK_VALUE: ClockValue = ClockValue::new( + (30001 * CLOCK_FREQUENCY_HZ as isize) / 1000, + CLOCK_FREQUENCY_HZ, + ); + + fn create_register_message(application: &[u8; 32]) -> Vec { + let mut message = vec![ + Ctap1Command::CTAP1_CLA, + Ctap1Command::U2F_REGISTER, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + ]; + let challenge = [0x0C; 32]; + message.extend(&challenge); + message.extend(application); + message + } + + fn create_authenticate_message( + application: &[u8; 32], + flags: Ctap1Flags, + key_handle: &Vec, + ) -> Vec { + let mut message = vec![ + Ctap1Command::CTAP1_CLA, + Ctap1Command::U2F_AUTHENTICATE, + flags.into(), + 0x00, + 0x00, + 0x00, + 65 + ENCRYPTED_CREDENTIAL_ID_SIZE as u8, + ]; + let challenge = [0x0C; 32]; + message.extend(&challenge); + message.extend(application); + message.push(ENCRYPTED_CREDENTIAL_ID_SIZE as u8); + message.extend(key_handle); + message + } + + #[test] + fn test_process_register() { + let mut rng = ThreadRng256 {}; + let dummy_user_presence = |_| panic!("Unexpected user presence check in CTAP1"); + let mut ctap_state = CtapState::new(&mut rng, dummy_user_presence); + + let application = [0x0A; 32]; + let message = create_register_message(&application); + ctap_state.u2f_up_state.consume_up(START_CLOCK_VALUE); + ctap_state.u2f_up_state.grant_up(START_CLOCK_VALUE); + let response = + Ctap1Command::process_command(&message, &mut ctap_state, START_CLOCK_VALUE).unwrap(); + + assert_eq!(response[0], Ctap1Command::LEGACY_BYTE); + assert_eq!(response[66], ENCRYPTED_CREDENTIAL_ID_SIZE as u8); + assert!(ctap_state + .decrypt_credential_source( + response[67..67 + ENCRYPTED_CREDENTIAL_ID_SIZE].to_vec(), + &application + ) + .is_some()); + const CERT_START: usize = 67 + ENCRYPTED_CREDENTIAL_ID_SIZE; + assert_eq!( + &response[CERT_START..CERT_START + ATTESTATION_CERTIFICATE.len()], + &ATTESTATION_CERTIFICATE[..] + ); + } + + #[test] + fn test_process_register_bad_message() { + let mut rng = ThreadRng256 {}; + let dummy_user_presence = |_| panic!("Unexpected user presence check in CTAP1"); + let mut ctap_state = CtapState::new(&mut rng, dummy_user_presence); + + let application = [0x0A; 32]; + let message = create_register_message(&application); + let response = Ctap1Command::process_command( + &message[..message.len() - 1], + &mut ctap_state, + START_CLOCK_VALUE, + ); + + assert_eq!(response, Err(Ctap1StatusCode::SW_WRONG_LENGTH)); + } + + #[test] + fn test_process_register_without_up() { + let application = [0x0A; 32]; + let message = create_register_message(&application); + + let mut rng = ThreadRng256 {}; + let dummy_user_presence = |_| panic!("Unexpected user presence check in CTAP1"); + let mut ctap_state = CtapState::new(&mut rng, dummy_user_presence); + + ctap_state.u2f_up_state.consume_up(START_CLOCK_VALUE); + ctap_state.u2f_up_state.grant_up(START_CLOCK_VALUE); + let response = + Ctap1Command::process_command(&message, &mut ctap_state, TIMEOUT_CLOCK_VALUE); + assert_eq!(response, Err(Ctap1StatusCode::SW_CONDITIONS_NOT_SATISFIED)); + } + + #[test] + fn test_process_authenticate_check_only() { + let mut rng = ThreadRng256 {}; + let dummy_user_presence = |_| panic!("Unexpected user presence check in CTAP1"); + let sk = crypto::ecdsa::SecKey::gensk(&mut rng); + let mut ctap_state = CtapState::new(&mut rng, dummy_user_presence); + + let rp_id = "example.com"; + let application = crypto::sha256::Sha256::hash(rp_id.as_bytes()); + let key_handle = ctap_state.encrypt_key_handle(sk, &application); + let message = create_authenticate_message(&application, Ctap1Flags::CheckOnly, &key_handle); + + let response = Ctap1Command::process_command(&message, &mut ctap_state, START_CLOCK_VALUE); + assert_eq!(response, Err(Ctap1StatusCode::SW_CONDITIONS_NOT_SATISFIED)); + } + + #[test] + fn test_process_authenticate_check_only_wrong_rp() { + let mut rng = ThreadRng256 {}; + let dummy_user_presence = |_| panic!("Unexpected user presence check in CTAP1"); + let sk = crypto::ecdsa::SecKey::gensk(&mut rng); + let mut ctap_state = CtapState::new(&mut rng, dummy_user_presence); + + let rp_id = "example.com"; + let application = crypto::sha256::Sha256::hash(rp_id.as_bytes()); + let key_handle = ctap_state.encrypt_key_handle(sk, &application); + let application = [0x55; 32]; + let message = create_authenticate_message(&application, Ctap1Flags::CheckOnly, &key_handle); + + let response = Ctap1Command::process_command(&message, &mut ctap_state, START_CLOCK_VALUE); + assert_eq!(response, Err(Ctap1StatusCode::SW_WRONG_DATA)); + } + + #[test] + fn test_process_authenticate_check_only_wrong_length() { + let mut rng = ThreadRng256 {}; + let dummy_user_presence = |_| panic!("Unexpected user presence check in CTAP1"); + let sk = crypto::ecdsa::SecKey::gensk(&mut rng); + let mut ctap_state = CtapState::new(&mut rng, dummy_user_presence); + + let rp_id = "example.com"; + let application = crypto::sha256::Sha256::hash(rp_id.as_bytes()); + let key_handle = ctap_state.encrypt_key_handle(sk, &application); + let mut message = + create_authenticate_message(&application, Ctap1Flags::CheckOnly, &key_handle); + + message.push(0x00); + let response = Ctap1Command::process_command(&message, &mut ctap_state, START_CLOCK_VALUE); + assert_eq!(response, Err(Ctap1StatusCode::SW_WRONG_LENGTH)); + + // Two extra zeros are okay, they could encode the expected response length. + message.push(0x00); + message.push(0x00); + let response = Ctap1Command::process_command(&message, &mut ctap_state, START_CLOCK_VALUE); + assert_eq!(response, Err(Ctap1StatusCode::SW_WRONG_LENGTH)); + } + + #[test] + fn test_process_authenticate_check_only_wrong_cla() { + let mut rng = ThreadRng256 {}; + let dummy_user_presence = |_| panic!("Unexpected user presence check in CTAP1"); + let sk = crypto::ecdsa::SecKey::gensk(&mut rng); + let mut ctap_state = CtapState::new(&mut rng, dummy_user_presence); + + let rp_id = "example.com"; + let application = crypto::sha256::Sha256::hash(rp_id.as_bytes()); + let key_handle = ctap_state.encrypt_key_handle(sk, &application); + let mut message = + create_authenticate_message(&application, Ctap1Flags::CheckOnly, &key_handle); + message[0] = 0xEE; + + let response = Ctap1Command::process_command(&message, &mut ctap_state, START_CLOCK_VALUE); + assert_eq!(response, Err(Ctap1StatusCode::SW_CLA_NOT_SUPPORTED)); + } + + #[test] + fn test_process_authenticate_check_only_wrong_ins() { + let mut rng = ThreadRng256 {}; + let dummy_user_presence = |_| panic!("Unexpected user presence check in CTAP1"); + let sk = crypto::ecdsa::SecKey::gensk(&mut rng); + let mut ctap_state = CtapState::new(&mut rng, dummy_user_presence); + + let rp_id = "example.com"; + let application = crypto::sha256::Sha256::hash(rp_id.as_bytes()); + let key_handle = ctap_state.encrypt_key_handle(sk, &application); + let mut message = + create_authenticate_message(&application, Ctap1Flags::CheckOnly, &key_handle); + message[1] = 0xEE; + + let response = Ctap1Command::process_command(&message, &mut ctap_state, START_CLOCK_VALUE); + assert_eq!(response, Err(Ctap1StatusCode::SW_INS_NOT_SUPPORTED)); + } + + #[test] + fn test_process_authenticate_check_only_wrong_flags() { + let mut rng = ThreadRng256 {}; + let dummy_user_presence = |_| panic!("Unexpected user presence check in CTAP1"); + let sk = crypto::ecdsa::SecKey::gensk(&mut rng); + let mut ctap_state = CtapState::new(&mut rng, dummy_user_presence); + + let rp_id = "example.com"; + let application = crypto::sha256::Sha256::hash(rp_id.as_bytes()); + let key_handle = ctap_state.encrypt_key_handle(sk, &application); + let mut message = + create_authenticate_message(&application, Ctap1Flags::CheckOnly, &key_handle); + message[2] = 0xEE; + + let response = Ctap1Command::process_command(&message, &mut ctap_state, START_CLOCK_VALUE); + assert_eq!(response, Err(Ctap1StatusCode::SW_WRONG_DATA)); + } + + #[test] + fn test_process_authenticate_enforce() { + let mut rng = ThreadRng256 {}; + let dummy_user_presence = |_| panic!("Unexpected user presence check in CTAP1"); + let sk = crypto::ecdsa::SecKey::gensk(&mut rng); + let mut ctap_state = CtapState::new(&mut rng, dummy_user_presence); + + let rp_id = "example.com"; + let application = crypto::sha256::Sha256::hash(rp_id.as_bytes()); + let key_handle = ctap_state.encrypt_key_handle(sk, &application); + let message = + create_authenticate_message(&application, Ctap1Flags::EnforceUpAndSign, &key_handle); + + ctap_state.u2f_up_state.consume_up(START_CLOCK_VALUE); + ctap_state.u2f_up_state.grant_up(START_CLOCK_VALUE); + let response = + Ctap1Command::process_command(&message, &mut ctap_state, START_CLOCK_VALUE).unwrap(); + assert_eq!(response[0], 0x01); + if USE_SIGNATURE_COUNTER { + assert_eq!(response[1..5], [0x00, 0x00, 0x00, 0x01]); + } else { + assert_eq!(response[1..5], [0x00, 0x00, 0x00, 0x00]); + } + } + + #[test] + fn test_process_authenticate_dont_enforce() { + let mut rng = ThreadRng256 {}; + let dummy_user_presence = |_| panic!("Unexpected user presence check in CTAP1"); + let sk = crypto::ecdsa::SecKey::gensk(&mut rng); + let mut ctap_state = CtapState::new(&mut rng, dummy_user_presence); + + let rp_id = "example.com"; + let application = crypto::sha256::Sha256::hash(rp_id.as_bytes()); + let key_handle = ctap_state.encrypt_key_handle(sk, &application); + let message = create_authenticate_message( + &application, + Ctap1Flags::DontEnforceUpAndSign, + &key_handle, + ); + + let response = + Ctap1Command::process_command(&message, &mut ctap_state, TIMEOUT_CLOCK_VALUE).unwrap(); + assert_eq!(response[0], 0x01); + if USE_SIGNATURE_COUNTER { + assert_eq!(response[1..5], [0x00, 0x00, 0x00, 0x01]); + } else { + assert_eq!(response[1..5], [0x00, 0x00, 0x00, 0x00]); + } + } + + #[test] + fn test_process_authenticate_bad_key_handle() { + let application = [0x0A; 32]; + let key_handle = vec![0x00; ENCRYPTED_CREDENTIAL_ID_SIZE]; + let message = + create_authenticate_message(&application, Ctap1Flags::EnforceUpAndSign, &key_handle); + + let mut rng = ThreadRng256 {}; + let dummy_user_presence = |_| panic!("Unexpected user presence check in CTAP1"); + let mut ctap_state = CtapState::new(&mut rng, dummy_user_presence); + + ctap_state.u2f_up_state.consume_up(START_CLOCK_VALUE); + ctap_state.u2f_up_state.grant_up(START_CLOCK_VALUE); + let response = Ctap1Command::process_command(&message, &mut ctap_state, START_CLOCK_VALUE); + assert_eq!(response, Err(Ctap1StatusCode::SW_WRONG_DATA)); + } + + #[test] + fn test_process_authenticate_without_up() { + let application = [0x0A; 32]; + let key_handle = vec![0x00; ENCRYPTED_CREDENTIAL_ID_SIZE]; + let message = + create_authenticate_message(&application, Ctap1Flags::EnforceUpAndSign, &key_handle); + + let mut rng = ThreadRng256 {}; + let dummy_user_presence = |_| panic!("Unexpected user presence check in CTAP1"); + let mut ctap_state = CtapState::new(&mut rng, dummy_user_presence); + + ctap_state.u2f_up_state.consume_up(START_CLOCK_VALUE); + ctap_state.u2f_up_state.grant_up(START_CLOCK_VALUE); + let response = + Ctap1Command::process_command(&message, &mut ctap_state, TIMEOUT_CLOCK_VALUE); + assert_eq!(response, Err(Ctap1StatusCode::SW_CONDITIONS_NOT_SATISFIED)); + } +} diff --git a/src/ctap/data_formats.rs b/src/ctap/data_formats.rs new file mode 100644 index 0000000..eae2948 --- /dev/null +++ b/src/ctap/data_formats.rs @@ -0,0 +1,1020 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::status_code::Ctap2StatusCode; +use alloc::collections::BTreeMap; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::convert::TryFrom; +use crypto::{ecdh, ecdsa}; + +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +pub struct PublicKeyCredentialRpEntity { + pub rp_id: String, + pub rp_name: Option, + pub rp_icon: Option, +} + +impl TryFrom<&cbor::Value> for PublicKeyCredentialRpEntity { + type Error = Ctap2StatusCode; + + fn try_from(cbor_value: &cbor::Value) -> Result { + let rp_map = read_map(cbor_value)?; + let rp_id = read_text_string(ok_or_missing(rp_map.get(&cbor_text!("id")))?)?; + let rp_name = rp_map + .get(&cbor_text!("name")) + .map(read_text_string) + .transpose()?; + let rp_icon = rp_map + .get(&cbor_text!("icon")) + .map(read_text_string) + .transpose()?; + Ok(Self { + rp_id, + rp_name, + rp_icon, + }) + } +} + +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +pub struct PublicKeyCredentialUserEntity { + pub user_id: Vec, + pub user_name: Option, + pub user_display_name: Option, + pub user_icon: Option, +} + +impl TryFrom<&cbor::Value> for PublicKeyCredentialUserEntity { + type Error = Ctap2StatusCode; + + fn try_from(cbor_value: &cbor::Value) -> Result { + let user_map = read_map(cbor_value)?; + let user_id = read_byte_string(ok_or_missing(user_map.get(&cbor_text!("id")))?)?; + let user_name = user_map + .get(&cbor_text!("name")) + .map(read_text_string) + .transpose()?; + let user_display_name = user_map + .get(&cbor_text!("displayName")) + .map(read_text_string) + .transpose()?; + let user_icon = user_map + .get(&cbor_text!("icon")) + .map(read_text_string) + .transpose()?; + Ok(Self { + user_id, + user_name, + user_display_name, + user_icon, + }) + } +} + +impl From for cbor::Value { + fn from(entity: PublicKeyCredentialUserEntity) -> Self { + cbor_map_options! { + "id" => entity.user_id, + "name" => entity.user_name, + "displayName" => entity.user_display_name, + "icon" => entity.user_icon, + } + } +} + +#[derive(Clone, PartialEq)] +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug))] +pub enum PublicKeyCredentialType { + PublicKey, +} + +impl From for cbor::Value { + fn from(cred_type: PublicKeyCredentialType) -> Self { + match cred_type { + PublicKeyCredentialType::PublicKey => "public-key", + } + .into() + } +} + +impl TryFrom<&cbor::Value> for PublicKeyCredentialType { + type Error = Ctap2StatusCode; + + fn try_from(cbor_value: &cbor::Value) -> Result { + let cred_type_string = read_text_string(cbor_value)?; + match &cred_type_string[..] { + "public-key" => Ok(PublicKeyCredentialType::PublicKey), + _ => Err(Ctap2StatusCode::CTAP2_ERR_UNSUPPORTED_ALGORITHM), + } + } +} + +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +pub enum AuthenticatorTransport { + Usb, + Nfc, + Ble, + Internal, +} + +impl From for cbor::Value { + fn from(transport: AuthenticatorTransport) -> Self { + match transport { + AuthenticatorTransport::Usb => "usb", + AuthenticatorTransport::Nfc => "nfc", + AuthenticatorTransport::Ble => "ble", + AuthenticatorTransport::Internal => "internal", + } + .into() + } +} + +impl TryFrom<&cbor::Value> for AuthenticatorTransport { + type Error = Ctap2StatusCode; + + fn try_from(cbor_value: &cbor::Value) -> Result { + let transport_string = read_text_string(cbor_value)?; + match &transport_string[..] { + "usb" => Ok(AuthenticatorTransport::Usb), + "nfc" => Ok(AuthenticatorTransport::Nfc), + "ble" => Ok(AuthenticatorTransport::Ble), + "internal" => Ok(AuthenticatorTransport::Internal), + _ => Err(Ctap2StatusCode::CTAP2_ERR_CBOR_UNEXPECTED_TYPE), + } + } +} + +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +pub struct PublicKeyCredentialDescriptor { + pub key_type: PublicKeyCredentialType, + pub key_id: Vec, + pub transports: Option>, +} + +impl TryFrom<&cbor::Value> for PublicKeyCredentialDescriptor { + type Error = Ctap2StatusCode; + + fn try_from(cbor_value: &cbor::Value) -> Result { + let cred_desc_map = read_map(cbor_value)?; + let key_type = PublicKeyCredentialType::try_from(ok_or_missing( + cred_desc_map.get(&cbor_text!("type")), + )?)?; + let key_id = read_byte_string(ok_or_missing(cred_desc_map.get(&cbor_text!("id")))?)?; + let transports = match cred_desc_map.get(&cbor_text!("transports")) { + Some(exclude_entry) => { + let transport_vec = read_array(exclude_entry)?; + let mut transports = vec![]; + for transport_value in transport_vec { + transports.push(AuthenticatorTransport::try_from(transport_value)?); + } + Some(transports) + } + None => None, + }; + Ok(Self { + key_type, + key_id, + transports, + }) + } +} + +impl From for cbor::Value { + fn from(desc: PublicKeyCredentialDescriptor) -> Self { + cbor_map_options! { + "type" => desc.key_type, + "id" => desc.key_id, + "transports" => desc.transports.map(|vec| cbor_array_vec!(vec)), + } + } +} + +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +pub struct Extensions(BTreeMap); + +impl TryFrom<&cbor::Value> for Extensions { + type Error = Ctap2StatusCode; + + fn try_from(cbor_value: &cbor::Value) -> Result { + let mut extensions = BTreeMap::new(); + for (extension_key, extension_value) in read_map(cbor_value)? { + if let cbor::KeyType::TextString(extension_key_string) = extension_key { + extensions.insert(extension_key_string.to_string(), extension_value.clone()); + } else { + return Err(Ctap2StatusCode::CTAP2_ERR_CBOR_UNEXPECTED_TYPE); + } + } + Ok(Extensions(extensions)) + } +} + +// Even though options are optional, we can use the default if not present. +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +pub struct MakeCredentialOptions { + pub rk: bool, + pub uv: bool, +} + +impl TryFrom<&cbor::Value> for MakeCredentialOptions { + type Error = Ctap2StatusCode; + + fn try_from(cbor_value: &cbor::Value) -> Result { + let options_map = read_map(cbor_value)?; + let rk = match options_map.get(&cbor_text!("rk")) { + Some(options_entry) => read_bool(options_entry)?, + None => false, + }; + if let Some(options_entry) = options_map.get(&cbor_text!("up")) { + if !read_bool(options_entry)? { + return Err(Ctap2StatusCode::CTAP2_ERR_INVALID_OPTION); + } + } + let uv = match options_map.get(&cbor_text!("uv")) { + Some(options_entry) => read_bool(options_entry)?, + None => false, + }; + Ok(Self { rk, uv }) + } +} + +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +pub struct GetAssertionOptions { + pub up: bool, + pub uv: bool, +} + +impl TryFrom<&cbor::Value> for GetAssertionOptions { + type Error = Ctap2StatusCode; + + fn try_from(cbor_value: &cbor::Value) -> Result { + let options_map = read_map(cbor_value)?; + if let Some(options_entry) = options_map.get(&cbor_text!("rk")) { + // This is only for returning the correct status code. + read_bool(options_entry)?; + return Err(Ctap2StatusCode::CTAP2_ERR_INVALID_OPTION); + } + let up = match options_map.get(&cbor_text!("up")) { + Some(options_entry) => read_bool(options_entry)?, + None => true, + }; + let uv = match options_map.get(&cbor_text!("uv")) { + Some(options_entry) => read_bool(options_entry)?, + None => false, + }; + Ok(Self { up, uv }) + } +} + +#[cfg_attr(test, derive(PartialEq))] +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug))] +pub struct PackedAttestationStatement { + pub alg: i64, + pub sig: Vec, + pub x5c: Option>>, + pub ecdaa_key_id: Option>, +} + +impl From for cbor::Value { + fn from(att_stmt: PackedAttestationStatement) -> Self { + cbor_map_options! { + "alg" => att_stmt.alg, + "sig" => att_stmt.sig, + "x5c" => att_stmt.x5c.map(|x| cbor_array_vec!(x)), + "ecdaaKeyId" => att_stmt.ecdaa_key_id, + } + } +} + +#[cfg_attr(test, derive(PartialEq))] +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug))] +pub enum SignatureAlgorithm { + ES256 = ecdsa::PubKey::ES256_ALGORITHM as isize, +} + +#[derive(Clone)] +#[cfg_attr(test, derive(PartialEq))] +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug))] +pub struct PublicKeyCredentialSource { + // TODO function to convert to / from Vec + pub key_type: PublicKeyCredentialType, + pub credential_id: Vec, + pub private_key: ecdsa::SecKey, // TODO(kaczmarczyck) open for other algorithms + pub rp_id: String, + pub user_handle: Vec, // not optional, but nullable + pub other_ui: Option, +} + +impl From for cbor::Value { + fn from(credential: PublicKeyCredentialSource) -> cbor::Value { + let mut private_key = [0u8; 32]; + credential.private_key.to_bytes(&mut private_key); + let other_ui = match credential.other_ui { + None => cbor_null!(), + Some(other_ui) => cbor_text!(other_ui), + }; + cbor_array! { + credential.credential_id, + private_key, + credential.rp_id, + credential.user_handle, + other_ui, + } + } +} + +impl TryFrom for PublicKeyCredentialSource { + type Error = Ctap2StatusCode; + + fn try_from(cbor_value: cbor::Value) -> Result { + use cbor::{SimpleValue, Value}; + + let fields = read_array(&cbor_value)?; + if fields.len() != 5 { + return Err(Ctap2StatusCode::CTAP2_ERR_INVALID_CBOR); + } + let credential_id = read_byte_string(&fields[0])?; + let private_key = read_byte_string(&fields[1])?; + if private_key.len() != 32 { + return Err(Ctap2StatusCode::CTAP2_ERR_INVALID_CBOR); + } + let private_key = ecdsa::SecKey::from_bytes(array_ref!(private_key, 0, 32)) + .ok_or(Ctap2StatusCode::CTAP2_ERR_INVALID_CBOR)?; + let rp_id = read_text_string(&fields[2])?; + let user_handle = read_byte_string(&fields[3])?; + let other_ui = match &fields[4] { + Value::Simple(SimpleValue::NullValue) => None, + cbor_value => Some(read_text_string(cbor_value)?), + }; + Ok(PublicKeyCredentialSource { + key_type: PublicKeyCredentialType::PublicKey, + credential_id, + private_key, + rp_id, + user_handle, + other_ui, + }) + } +} + +// TODO(kaczmarczyck) we could decide to split this data type up +// It depends on the algorithm though, I think. +// So before creating a mess, this is my workaround. +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +pub struct CoseKey(pub BTreeMap); + +// This is the algorithm specifier that is supposed to be used in a COSE key +// map. The CTAP specification says -25 which represents ECDH-ES + HKDF-256 +// here: https://www.iana.org/assignments/cose/cose.xhtml#algorithms +// In fact, this is just used for compatibility with older specification versions. +const ECDH_ALGORITHM: i64 = -25; +const EC2_KEY_TYPE: i64 = 2; +const P_256_CURVE: i64 = 1; + +impl From for CoseKey { + fn from(pk: ecdh::PubKey) -> Self { + let mut x_bytes = [0; ecdh::NBYTES]; + let mut y_bytes = [0; ecdh::NBYTES]; + pk.to_coordinates(&mut x_bytes, &mut y_bytes); + let x_byte_cbor: cbor::Value = cbor_bytes_lit!(&x_bytes); + let y_byte_cbor: cbor::Value = cbor_bytes_lit!(&y_bytes); + // TODO(kaczmarczyck) do not write optional parameters, spec is unclear + let cose_cbor_value = cbor_map_options! { + 1 => EC2_KEY_TYPE, + 3 => ECDH_ALGORITHM, + -1 => P_256_CURVE, + -2 => x_byte_cbor, + -3 => y_byte_cbor, + }; + if let cbor::Value::Map(cose_map) = cose_cbor_value { + CoseKey(cose_map) + } else { + unreachable!(); + } + } +} + +impl TryFrom for ecdh::PubKey { + type Error = Ctap2StatusCode; + + fn try_from(cose_key: CoseKey) -> Result { + let key_type = read_integer(ok_or_missing(cose_key.0.get(&cbor_int!(1)))?)?; + if key_type != EC2_KEY_TYPE { + return Err(Ctap2StatusCode::CTAP2_ERR_UNSUPPORTED_ALGORITHM); + } + let algorithm = read_integer(ok_or_missing(cose_key.0.get(&cbor_int!(3)))?)?; + if algorithm != ECDH_ALGORITHM { + return Err(Ctap2StatusCode::CTAP2_ERR_UNSUPPORTED_ALGORITHM); + } + let curve = read_integer(ok_or_missing(cose_key.0.get(&cbor_int!(-1)))?)?; + if curve != P_256_CURVE { + return Err(Ctap2StatusCode::CTAP2_ERR_UNSUPPORTED_ALGORITHM); + } + let x_bytes = read_byte_string(ok_or_missing(cose_key.0.get(&cbor_int!(-2)))?)?; + if x_bytes.len() != ecdh::NBYTES { + return Err(Ctap2StatusCode::CTAP1_ERR_INVALID_PARAMETER); + } + let y_bytes = read_byte_string(ok_or_missing(cose_key.0.get(&cbor_int!(-3)))?)?; + if y_bytes.len() != ecdh::NBYTES { + return Err(Ctap2StatusCode::CTAP1_ERR_INVALID_PARAMETER); + } + let x_array_ref = array_ref![x_bytes.as_slice(), 0, ecdh::NBYTES]; + let y_array_ref = array_ref![y_bytes.as_slice(), 0, ecdh::NBYTES]; + ecdh::PubKey::from_coordinates(x_array_ref, y_array_ref) + .ok_or(Ctap2StatusCode::CTAP1_ERR_INVALID_PARAMETER) + } +} + +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))] +pub enum ClientPinSubCommand { + GetPinRetries, + GetKeyAgreement, + SetPin, + ChangePin, + GetPinUvAuthTokenUsingPin, + GetPinUvAuthTokenUsingUv, + GetUvRetries, +} + +impl From for cbor::Value { + fn from(subcommand: ClientPinSubCommand) -> Self { + match subcommand { + ClientPinSubCommand::GetPinRetries => 0x01, + ClientPinSubCommand::GetKeyAgreement => 0x02, + ClientPinSubCommand::SetPin => 0x03, + ClientPinSubCommand::ChangePin => 0x04, + ClientPinSubCommand::GetPinUvAuthTokenUsingPin => 0x05, + ClientPinSubCommand::GetPinUvAuthTokenUsingUv => 0x06, + ClientPinSubCommand::GetUvRetries => 0x07, + } + .into() + } +} + +impl TryFrom<&cbor::Value> for ClientPinSubCommand { + type Error = Ctap2StatusCode; + + fn try_from(cbor_value: &cbor::Value) -> Result { + let subcommand_int = read_unsigned(cbor_value)?; + match subcommand_int { + 0x01 => Ok(ClientPinSubCommand::GetPinRetries), + 0x02 => Ok(ClientPinSubCommand::GetKeyAgreement), + 0x03 => Ok(ClientPinSubCommand::SetPin), + 0x04 => Ok(ClientPinSubCommand::ChangePin), + 0x05 => Ok(ClientPinSubCommand::GetPinUvAuthTokenUsingPin), + 0x06 => Ok(ClientPinSubCommand::GetPinUvAuthTokenUsingUv), + 0x07 => Ok(ClientPinSubCommand::GetUvRetries), + // TODO(kaczmarczyck) what is the correct status code for this error? + _ => Err(Ctap2StatusCode::CTAP1_ERR_INVALID_PARAMETER), + } + } +} + +pub(super) fn read_unsigned(cbor_value: &cbor::Value) -> Result { + match cbor_value { + cbor::Value::KeyValue(cbor::KeyType::Unsigned(unsigned)) => Ok(*unsigned), + _ => Err(Ctap2StatusCode::CTAP2_ERR_CBOR_UNEXPECTED_TYPE), + } +} + +pub(super) fn read_integer(cbor_value: &cbor::Value) -> Result { + match cbor_value { + cbor::Value::KeyValue(cbor::KeyType::Unsigned(unsigned)) => { + if *unsigned <= core::i64::MAX as u64 { + Ok(*unsigned as i64) + } else { + Err(Ctap2StatusCode::CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + } + } + cbor::Value::KeyValue(cbor::KeyType::Negative(signed)) => Ok(*signed), + _ => Err(Ctap2StatusCode::CTAP2_ERR_CBOR_UNEXPECTED_TYPE), + } +} + +pub fn read_byte_string(cbor_value: &cbor::Value) -> Result, Ctap2StatusCode> { + match cbor_value { + cbor::Value::KeyValue(cbor::KeyType::ByteString(byte_string)) => Ok(byte_string.to_vec()), + _ => Err(Ctap2StatusCode::CTAP2_ERR_CBOR_UNEXPECTED_TYPE), + } +} + +pub(super) fn read_text_string(cbor_value: &cbor::Value) -> Result { + match cbor_value { + cbor::Value::KeyValue(cbor::KeyType::TextString(text_string)) => { + Ok(text_string.to_string()) + } + _ => Err(Ctap2StatusCode::CTAP2_ERR_CBOR_UNEXPECTED_TYPE), + } +} + +pub(super) fn read_array(cbor_value: &cbor::Value) -> Result<&Vec, Ctap2StatusCode> { + match cbor_value { + cbor::Value::Array(array) => Ok(array), + _ => Err(Ctap2StatusCode::CTAP2_ERR_CBOR_UNEXPECTED_TYPE), + } +} + +pub(super) fn read_map( + cbor_value: &cbor::Value, +) -> Result<&BTreeMap, Ctap2StatusCode> { + match cbor_value { + cbor::Value::Map(map) => Ok(map), + _ => Err(Ctap2StatusCode::CTAP2_ERR_CBOR_UNEXPECTED_TYPE), + } +} + +pub(super) fn read_bool(cbor_value: &cbor::Value) -> Result { + match cbor_value { + cbor::Value::Simple(cbor::SimpleValue::FalseValue) => Ok(false), + cbor::Value::Simple(cbor::SimpleValue::TrueValue) => Ok(true), + _ => Err(Ctap2StatusCode::CTAP2_ERR_CBOR_UNEXPECTED_TYPE), + } +} + +pub(super) fn ok_or_missing( + value_option: Option<&cbor::Value>, +) -> Result<&cbor::Value, Ctap2StatusCode> { + value_option.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER) +} + +#[cfg(test)] +mod test { + use self::Ctap2StatusCode::CTAP2_ERR_CBOR_UNEXPECTED_TYPE; + use super::*; + use alloc::collections::BTreeMap; + + #[test] + fn test_read_unsigned() { + assert_eq!(read_unsigned(&cbor_int!(123)), Ok(123)); + assert_eq!( + read_unsigned(&cbor_bool!(true)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_unsigned(&cbor_text!("foo")), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_unsigned(&cbor_bytes_lit!(b"bar")), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_unsigned(&cbor_array![]), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_unsigned(&cbor_map! {}), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + } + + #[test] + fn test_read_unsigned_limits() { + assert_eq!( + read_unsigned(&cbor_unsigned!(std::u64::MAX)), + Ok(std::u64::MAX) + ); + assert_eq!( + read_unsigned(&cbor_unsigned!((std::i64::MAX as u64) + 1)), + Ok((std::i64::MAX as u64) + 1) + ); + assert_eq!( + read_unsigned(&cbor_int!(std::i64::MAX)), + Ok(std::i64::MAX as u64) + ); + assert_eq!(read_unsigned(&cbor_int!(123)), Ok(123)); + assert_eq!(read_unsigned(&cbor_int!(1)), Ok(1)); + assert_eq!(read_unsigned(&cbor_int!(0)), Ok(0)); + assert_eq!( + read_unsigned(&cbor_int!(-1)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_unsigned(&cbor_int!(-123)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_unsigned(&cbor_int!(std::i64::MIN)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + } + + #[test] + fn test_read_integer() { + assert_eq!(read_integer(&cbor_int!(123)), Ok(123)); + assert_eq!(read_integer(&cbor_int!(-123)), Ok(-123)); + assert_eq!( + read_integer(&cbor_bool!(true)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_integer(&cbor_text!("foo")), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_integer(&cbor_bytes_lit!(b"bar")), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_integer(&cbor_array![]), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_integer(&cbor_map! {}), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + } + + #[test] + fn test_read_integer_limits() { + assert_eq!( + read_integer(&cbor_unsigned!(std::u64::MAX)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_integer(&cbor_unsigned!((std::i64::MAX as u64) + 1)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!(read_integer(&cbor_int!(std::i64::MAX)), Ok(std::i64::MAX)); + assert_eq!(read_integer(&cbor_int!(123)), Ok(123)); + assert_eq!(read_integer(&cbor_int!(1)), Ok(1)); + assert_eq!(read_integer(&cbor_int!(0)), Ok(0)); + assert_eq!(read_integer(&cbor_int!(-1)), Ok(-1)); + assert_eq!(read_integer(&cbor_int!(-123)), Ok(-123)); + assert_eq!(read_integer(&cbor_int!(std::i64::MIN)), Ok(std::i64::MIN)); + } + + #[test] + fn test_read_byte_string() { + assert_eq!( + read_byte_string(&cbor_int!(123)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_byte_string(&cbor_bool!(true)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_byte_string(&cbor_text!("foo")), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!(read_byte_string(&cbor_bytes_lit!(b"")), Ok(Vec::new())); + assert_eq!( + read_byte_string(&cbor_bytes_lit!(b"bar")), + Ok(b"bar".to_vec()) + ); + assert_eq!( + read_byte_string(&cbor_array![]), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_byte_string(&cbor_map! {}), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + } + + #[test] + fn test_read_text_string() { + assert_eq!( + read_text_string(&cbor_int!(123)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_text_string(&cbor_bool!(true)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!(read_text_string(&cbor_text!("")), Ok(String::new())); + assert_eq!( + read_text_string(&cbor_text!("foo")), + Ok(String::from("foo")) + ); + assert_eq!( + read_text_string(&cbor_bytes_lit!(b"bar")), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_text_string(&cbor_array![]), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_text_string(&cbor_map! {}), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + } + + #[test] + fn test_read_array() { + assert_eq!( + read_array(&cbor_int!(123)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_array(&cbor_bool!(true)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_array(&cbor_text!("foo")), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_array(&cbor_bytes_lit!(b"bar")), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!(read_array(&cbor_array![]), Ok(&Vec::new())); + assert_eq!( + read_array(&cbor_array![ + 123, + cbor_null!(), + "foo", + cbor_array![], + cbor_map! {}, + ]), + Ok(&vec![ + cbor_int!(123), + cbor_null!(), + cbor_text!("foo"), + cbor_array![], + cbor_map! {}, + ]) + ); + assert_eq!( + read_array(&cbor_map! {}), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + } + + #[test] + fn test_read_map() { + assert_eq!( + read_map(&cbor_int!(123)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_map(&cbor_bool!(true)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_map(&cbor_text!("foo")), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_map(&cbor_bytes_lit!(b"bar")), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_map(&cbor_array![]), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!(read_map(&cbor_map! {}), Ok(&BTreeMap::new())); + assert_eq!( + read_map(&cbor_map! { + 1 => cbor_false!(), + "foo" => b"bar", + b"bin" => -42, + }), + Ok(&[ + (cbor_unsigned!(1), cbor_false!()), + (cbor_text!("foo"), cbor_bytes_lit!(b"bar")), + (cbor_bytes_lit!(b"bin"), cbor_int!(-42)), + ] + .iter() + .cloned() + .collect::>()) + ); + } + + #[test] + fn test_read_bool() { + assert_eq!( + read_bool(&cbor_int!(123)), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!(read_bool(&cbor_bool!(true)), Ok(true)); + assert_eq!(read_bool(&cbor_bool!(false)), Ok(false)); + assert_eq!( + read_bool(&cbor_text!("foo")), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_bool(&cbor_bytes_lit!(b"bar")), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_bool(&cbor_array![]), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + assert_eq!( + read_bool(&cbor_map! {}), + Err(CTAP2_ERR_CBOR_UNEXPECTED_TYPE) + ); + } + + #[test] + fn test_from_public_key_credential_rp_entity() { + let cbor_rp_entity = cbor_map! { + "id" => "example.com", + "name" => "Example", + "icon" => "example.com/icon.png", + }; + let rp_entity = PublicKeyCredentialRpEntity::try_from(&cbor_rp_entity); + let expected_rp_entity = PublicKeyCredentialRpEntity { + rp_id: "example.com".to_string(), + rp_name: Some("Example".to_string()), + rp_icon: Some("example.com/icon.png".to_string()), + }; + assert_eq!(rp_entity, Ok(expected_rp_entity)); + } + + #[test] + fn test_from_into_public_key_credential_user_entity() { + let cbor_user_entity = cbor_map! { + "id" => vec![0x1D, 0x1D, 0x1D, 0x1D], + "name" => "foo", + "displayName" => "bar", + "icon" => "example.com/foo/icon.png", + }; + let user_entity = PublicKeyCredentialUserEntity::try_from(&cbor_user_entity); + let expected_user_entity = PublicKeyCredentialUserEntity { + user_id: vec![0x1D, 0x1D, 0x1D, 0x1D], + user_name: Some("foo".to_string()), + user_display_name: Some("bar".to_string()), + user_icon: Some("example.com/foo/icon.png".to_string()), + }; + assert_eq!(user_entity, Ok(expected_user_entity)); + let created_cbor: cbor::Value = user_entity.unwrap().into(); + assert_eq!(created_cbor, cbor_user_entity); + } + + #[test] + fn test_from_into_public_key_credential_type() { + let cbor_credential_type = cbor_text!("public-key"); + let credential_type = PublicKeyCredentialType::try_from(&cbor_credential_type); + let expected_credential_type = PublicKeyCredentialType::PublicKey; + assert_eq!(credential_type, Ok(expected_credential_type)); + let created_cbor: cbor::Value = credential_type.unwrap().into(); + assert_eq!(created_cbor, cbor_credential_type); + } + + #[test] + fn test_from_into_authenticator_transport() { + let cbor_authenticator_transport = cbor_text!("usb"); + let authenticator_transport = + AuthenticatorTransport::try_from(&cbor_authenticator_transport); + let expected_authenticator_transport = AuthenticatorTransport::Usb; + assert_eq!( + authenticator_transport, + Ok(expected_authenticator_transport) + ); + let created_cbor: cbor::Value = authenticator_transport.unwrap().into(); + assert_eq!(created_cbor, cbor_authenticator_transport); + } + + #[test] + fn test_from_into_public_key_credential_descriptor() { + let cbor_credential_descriptor = cbor_map! { + "type" => "public-key", + "id" => vec![0x2D, 0x2D, 0x2D, 0x2D], + "transports" => cbor_array!["usb"], + }; + let credential_descriptor = + PublicKeyCredentialDescriptor::try_from(&cbor_credential_descriptor); + let expected_credential_descriptor = PublicKeyCredentialDescriptor { + key_type: PublicKeyCredentialType::PublicKey, + key_id: vec![0x2D, 0x2D, 0x2D, 0x2D], + transports: Some(vec![AuthenticatorTransport::Usb]), + }; + assert_eq!(credential_descriptor, Ok(expected_credential_descriptor)); + let created_cbor: cbor::Value = credential_descriptor.unwrap().into(); + assert_eq!(created_cbor, cbor_credential_descriptor); + } + + #[test] + fn test_from_extensions() { + let cbor_extensions = cbor_map! { + "the_answer" => 42, + }; + let extensions = Extensions::try_from(&cbor_extensions); + let mut expected_extensions = Extensions(BTreeMap::new()); + expected_extensions + .0 + .insert("the_answer".to_string(), cbor_int!(42)); + assert_eq!(extensions, Ok(expected_extensions)); + } + + #[test] + fn test_from_make_credential_options() { + let cbor_make_options = cbor_map! { + "rk" => true, + "uv" => false, + }; + let make_options = MakeCredentialOptions::try_from(&cbor_make_options); + let expected_make_options = MakeCredentialOptions { + rk: true, + uv: false, + }; + assert_eq!(make_options, Ok(expected_make_options)); + } + + #[test] + fn test_from_get_assertion_options() { + let cbor_get_assertion = cbor_map! { + "up" => true, + "uv" => false, + }; + let get_assertion = GetAssertionOptions::try_from(&cbor_get_assertion); + let expected_get_assertion = GetAssertionOptions { + up: true, + uv: false, + }; + assert_eq!(get_assertion, Ok(expected_get_assertion)); + } + + #[test] + fn test_into_packed_attestation_statement() { + let certificate: cbor::values::KeyType = cbor_bytes![vec![0x5C, 0x5C, 0x5C, 0x5C]]; + let cbor_packed_attestation_statement = cbor_map! { + "alg" => 1, + "sig" => vec![0x55, 0x55, 0x55, 0x55], + "x5c" => cbor_array_vec![vec![certificate]], + "ecdaaKeyId" => vec![0xEC, 0xDA, 0x1D], + }; + let packed_attestation_statement = PackedAttestationStatement { + alg: 1, + sig: vec![0x55, 0x55, 0x55, 0x55], + x5c: Some(vec![vec![0x5C, 0x5C, 0x5C, 0x5C]]), + ecdaa_key_id: Some(vec![0xEC, 0xDA, 0x1D]), + }; + let created_cbor: cbor::Value = packed_attestation_statement.into(); + assert_eq!(created_cbor, cbor_packed_attestation_statement); + } + + #[test] + fn test_from_into_cose_key() { + use crypto::rng256::ThreadRng256; + + let mut rng = ThreadRng256 {}; + let sk = crypto::ecdh::SecKey::gensk(&mut rng); + let pk = sk.genpk(); + let cose_key = CoseKey::from(pk.clone()); + let created_pk = ecdh::PubKey::try_from(cose_key); + assert_eq!(created_pk, Ok(pk)); + } + + #[test] + fn test_from_into_client_pin_sub_command() { + let cbor_sub_command = cbor_int!(0x01); + let sub_command = ClientPinSubCommand::try_from(&cbor_sub_command); + let expected_sub_command = ClientPinSubCommand::GetPinRetries; + assert_eq!(sub_command, Ok(expected_sub_command)); + let created_cbor: cbor::Value = sub_command.unwrap().into(); + assert_eq!(created_cbor, cbor_sub_command); + } + + #[test] + fn test_credential_source_cbor_round_trip() { + use crypto::rng256::{Rng256, ThreadRng256}; + + let mut rng = ThreadRng256 {}; + let credential = PublicKeyCredentialSource { + key_type: PublicKeyCredentialType::PublicKey, + credential_id: rng.gen_uniform_u8x32().to_vec(), + private_key: crypto::ecdsa::SecKey::gensk(&mut rng), + rp_id: "example.com".to_string(), + user_handle: b"foo".to_vec(), + other_ui: None, + }; + + assert_eq!( + PublicKeyCredentialSource::try_from(cbor::Value::from(credential.clone())), + Ok(credential.clone()) + ); + + let credential = PublicKeyCredentialSource { + other_ui: Some("other".to_string()), + ..credential + }; + + assert_eq!( + PublicKeyCredentialSource::try_from(cbor::Value::from(credential.clone())), + Ok(credential) + ); + } + + #[test] + fn test_credential_source_invalid_cbor() { + assert!(PublicKeyCredentialSource::try_from(cbor_false!()).is_err()); + assert!(PublicKeyCredentialSource::try_from(cbor_array!(false)).is_err()); + assert!(PublicKeyCredentialSource::try_from(cbor_array!(b"foo".to_vec())).is_err()); + } +} diff --git a/src/ctap/hid/mod.rs b/src/ctap/hid/mod.rs new file mode 100644 index 0000000..53e0ad6 --- /dev/null +++ b/src/ctap/hid/mod.rs @@ -0,0 +1,596 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +mod receive; +mod send; + +use self::receive::MessageAssembler; +use self::send::HidPacketIterator; +#[cfg(feature = "with_ctap1")] +use super::ctap1; +use super::status_code::Ctap2StatusCode; +use super::timed_permission::TimedPermission; +use super::CtapState; +use crate::timer::{ClockValue, Duration, Timestamp}; +use alloc::vec::Vec; +#[cfg(feature = "debug_ctap")] +use core::fmt::Write; +use crypto::rng256::Rng256; +#[cfg(feature = "debug_ctap")] +use libtock::console::Console; + +// CTAP specification (version 20190130) section 8.1 +// TODO: Channel allocation, section 8.1.3? +// TODO: Transaction timeout, section 8.1.5.2 + +pub type HidPacket = [u8; 64]; +pub type ChannelID = [u8; 4]; + +pub enum ProcessedPacket<'a> { + InitPacket { + cmd: u8, + len: usize, + data: &'a [u8; 57], + }, + ContinuationPacket { + seq: u8, + data: &'a [u8; 59], + }, +} + +// An assembled CTAPHID command. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Message { + // Channel ID. + pub cid: ChannelID, + // Command. + pub cmd: u8, + // Bytes of the message. + pub payload: Vec, +} + +pub struct CtapHid { + assembler: MessageAssembler, + // The specification (version 20190130) only requires unique CIDs ; the allocation algorithm is + // vendor specific. + // We allocate them incrementally, that is all `cid` such that 1 <= cid <= allocated_cids are + // allocated. + // In packets, the ids are then encoded with the native endianness (with the + // u32::to/from_ne_bytes methods). + allocated_cids: usize, + pub wink_permission: TimedPermission, +} + +#[allow(dead_code)] +pub enum KeepaliveStatus { + Processing, + UpNeeded, +} + +#[allow(dead_code)] +// TODO(kaczmarczyck) disable the warning in the end +impl CtapHid { + // CTAP specification (version 20190130) section 8.1.3 + const CHANNEL_RESERVED: ChannelID = [0, 0, 0, 0]; + const CHANNEL_BROADCAST: ChannelID = [0xFF, 0xFF, 0xFF, 0xFF]; + const TYPE_INIT_BIT: u8 = 0x80; + const PACKET_TYPE_MASK: u8 = 0x80; + + // CTAP specification (version 20190130) section 8.1.9 + const COMMAND_PING: u8 = 0x01; + const COMMAND_MSG: u8 = 0x03; + const COMMAND_INIT: u8 = 0x06; + const COMMAND_CBOR: u8 = 0x10; + pub const COMMAND_CANCEL: u8 = 0x11; + const COMMAND_KEEPALIVE: u8 = 0x3B; + const COMMAND_ERROR: u8 = 0x3F; + // TODO: optional lock command + const COMMAND_LOCK: u8 = 0x04; + const COMMAND_WINK: u8 = 0x08; + const COMMAND_VENDOR_FIRST: u8 = 0x40; + const COMMAND_VENDOR_LAST: u8 = 0x7F; + + // CTAP specification (version 20190130) section 8.1.9.1.6 + const ERR_INVALID_CMD: u8 = 0x01; + const ERR_INVALID_PAR: u8 = 0x02; + const ERR_INVALID_LEN: u8 = 0x03; + const ERR_INVALID_SEQ: u8 = 0x04; + const ERR_MSG_TIMEOUT: u8 = 0x05; + const ERR_CHANNEL_BUSY: u8 = 0x06; + const ERR_LOCK_REQUIRED: u8 = 0x0A; + const ERR_INVALID_CHANNEL: u8 = 0x0B; + const ERR_OTHER: u8 = 0x7F; + + // CTAP specification (version 20190130) section 8.1.9.1.3 + const PROTOCOL_VERSION: u8 = 2; + + // The device version number is vendor-defined. For now we define them to be zero. + // TODO: Update with device version? + const DEVICE_VERSION_MAJOR: u8 = 0; + const DEVICE_VERSION_MINOR: u8 = 0; + const DEVICE_VERSION_BUILD: u8 = 0; + + const CAPABILITY_WINK: u8 = 0x01; + const CAPABILITY_CBOR: u8 = 0x04; + const CAPABILITY_NMSG: u8 = 0x08; + // Capabilitites currently supported by this device. + #[cfg(feature = "with_ctap1")] + const CAPABILITIES: u8 = CtapHid::CAPABILITY_WINK | CtapHid::CAPABILITY_CBOR; + #[cfg(not(feature = "with_ctap1"))] + const CAPABILITIES: u8 = + CtapHid::CAPABILITY_WINK | CtapHid::CAPABILITY_CBOR | CtapHid::CAPABILITY_NMSG; + + // TODO: Is this timeout duration specified? + const TIMEOUT_DURATION: Duration = Duration::from_ms(100); + const WINK_TIMEOUT_DURATION: Duration = Duration::from_ms(5000); + + pub fn new() -> CtapHid { + CtapHid { + assembler: MessageAssembler::new(), + allocated_cids: 0, + wink_permission: TimedPermission::waiting(), + } + } + + // Process an incoming USB HID packet, and optionally returns a list of outgoing packets to + // send as a reply. + pub fn process_hid_packet( + &mut self, + packet: &HidPacket, + clock_value: ClockValue, + ctap_state: &mut CtapState, + ) -> HidPacketIterator + where + R: Rng256, + CheckUserPresence: Fn(ChannelID) -> Result<(), Ctap2StatusCode>, + { + // TODO: Send COMMAND_KEEPALIVE every 100ms? + match self + .assembler + .parse_packet(packet, Timestamp::::from_clock_value(clock_value)) + { + Ok(Some(message)) => { + #[cfg(feature = "debug_ctap")] + writeln!(&mut Console::new(), "Received message: {:02x?}", message).unwrap(); + + let cid = message.cid; + if !self.has_valid_channel(&message) { + #[cfg(feature = "debug_ctap")] + writeln!(&mut Console::new(), "Invalid channel: {:02x?}", cid).unwrap(); + return CtapHid::error_message(cid, CtapHid::ERR_INVALID_CHANNEL); + } + // If another command arrives, stop winking to prevent accidential button touches. + self.wink_permission = TimedPermission::waiting(); + + match message.cmd { + // CTAP specification (version 20190130) section 8.1.9.1.1 + CtapHid::COMMAND_MSG => { + // If we don't have CTAP1 backward compatibilty, this command in invalid. + #[cfg(not(feature = "with_ctap1"))] + return CtapHid::error_message(cid, CtapHid::ERR_INVALID_CMD); + + #[cfg(feature = "with_ctap1")] + match ctap1::Ctap1Command::process_command( + &message.payload, + ctap_state, + clock_value, + ) { + Ok(payload) => CtapHid::ctap1_success_message(cid, &payload), + Err(ctap1_status_code) => { + CtapHid::ctap1_error_message(cid, ctap1_status_code) + } + } + } + // CTAP specification (version 20190130) section 8.1.9.1.2 + CtapHid::COMMAND_CBOR => { + // CTAP specification (version 20190130) section 8.1.5.1 + // Each transaction is atomic, so we process the command directly here and + // don't handle any other packet in the meantime. + // TODO: Send keep-alive packets in the meantime. + let response = ctap_state.process_command(&message.payload, cid); + if let Some(iterator) = CtapHid::split_message(Message { + cid, + cmd: CtapHid::COMMAND_CBOR, + payload: response, + }) { + iterator + } else { + // Handle the case of a payload > 7609 bytes. + // Although this shouldn't happen if the FIDO2 commands are implemented + // correctly, we reply with a vendor specific code instead of silently + // ignoring the error. + // + // The error payload that we send instead is 1 <= 7609 bytes, so it is + // safe to unwrap() the result. + CtapHid::split_message(Message { + cid, + cmd: CtapHid::COMMAND_CBOR, + payload: vec![ + Ctap2StatusCode::CTAP2_ERR_VENDOR_RESPONSE_TOO_LONG as u8, + ], + }) + .unwrap() + } + } + // CTAP specification (version 20190130) section 8.1.9.1.3 + CtapHid::COMMAND_INIT => { + if cid == CtapHid::CHANNEL_BROADCAST { + if message.payload.len() != 8 { + return CtapHid::error_message(cid, CtapHid::ERR_INVALID_LEN); + } + + // TODO: Prevent allocating 2^32 channels. + self.allocated_cids += 1; + let allocated_cid = (self.allocated_cids as u32).to_ne_bytes(); + + let mut payload = vec![0; 17]; + payload[..8].copy_from_slice(&message.payload); + payload[8..12].copy_from_slice(&allocated_cid); + payload[12] = CtapHid::PROTOCOL_VERSION; + payload[13] = CtapHid::DEVICE_VERSION_MAJOR; + payload[14] = CtapHid::DEVICE_VERSION_MINOR; + payload[15] = CtapHid::DEVICE_VERSION_BUILD; + payload[16] = CtapHid::CAPABILITIES; + + // This unwrap is safe because the payload length is 17 <= 7609 bytes. + CtapHid::split_message(Message { + cid, + cmd: CtapHid::COMMAND_INIT, + payload, + }) + .unwrap() + } else { + // Sync the channel and discard the current transaction. + // TODO: The specification (version 20190130) wording isn't clear about + // the payload format in this case. + // + // This unwrap is safe because the payload length is 0 <= 7609 bytes. + CtapHid::split_message(Message { + cid, + cmd: CtapHid::COMMAND_INIT, + payload: vec![], + }) + .unwrap() + } + } + // CTAP specification (version 20190130) section 8.1.9.1.4 + CtapHid::COMMAND_PING => { + // Pong the same message. + // This unwrap is safe because if we could parse the incoming message, it's + // payload length must be <= 7609 bytes. + CtapHid::split_message(message).unwrap() + } + // CTAP specification (version 20190130) section 8.1.9.1.5 + CtapHid::COMMAND_CANCEL => { + // Authenticators MUST NOT reply to this message. + // CANCEL is handled during user presence checks in main. + HidPacketIterator::none() + } + // Optional commands + // CTAP specification (version 20190130) section 8.1.9.2.1 + CtapHid::COMMAND_WINK => { + if !message.payload.is_empty() { + return CtapHid::error_message(cid, CtapHid::ERR_INVALID_LEN); + } + self.wink_permission = + TimedPermission::granted(clock_value, CtapHid::WINK_TIMEOUT_DURATION); + CtapHid::split_message(Message { + cid, + cmd: CtapHid::COMMAND_WINK, + payload: vec![], + }) + .unwrap() + } + // CTAP specification (version 20190130) section 8.1.9.2.2 + // TODO: implement LOCK + _ => { + // Unknown or unsupported command. + CtapHid::error_message(cid, CtapHid::ERR_INVALID_CMD) + } + } + } + Ok(None) => { + // Waiting for more packets to assemble the message, nothing to send for now. + HidPacketIterator::none() + } + Err((cid, error)) => { + if !self.is_allocated_channel(cid) { + CtapHid::error_message(cid, CtapHid::ERR_INVALID_CHANNEL) + } else { + match error { + receive::Error::UnexpectedChannel => { + CtapHid::error_message(cid, CtapHid::ERR_CHANNEL_BUSY) + } + receive::Error::UnexpectedInit => { + // TODO: Should we send another error code in this case? + // Technically, we were expecting a sequence number and got another + // byte, although the command/seqnum bit has higher-level semantics + // than sequence numbers. + CtapHid::error_message(cid, CtapHid::ERR_INVALID_SEQ) + } + receive::Error::UnexpectedContinuation => { + // CTAP specification (version 20190130) section 8.1.5.4 + // Spurious continuation packets will be ignored. + HidPacketIterator::none() + } + receive::Error::UnexpectedSeq => { + CtapHid::error_message(cid, CtapHid::ERR_INVALID_SEQ) + } + receive::Error::Timeout => { + CtapHid::error_message(cid, CtapHid::ERR_MSG_TIMEOUT) + } + } + } + } + } + } + + fn has_valid_channel(&self, message: &Message) -> bool { + match message.cid { + // Only INIT commands use the broadcast channel. + CtapHid::CHANNEL_BROADCAST => message.cmd == CtapHid::COMMAND_INIT, + // Check that the channel is allocated. + _ => self.is_allocated_channel(message.cid), + } + } + + fn is_allocated_channel(&self, cid: ChannelID) -> bool { + cid != CtapHid::CHANNEL_RESERVED && u32::from_ne_bytes(cid) as usize <= self.allocated_cids + } + + fn error_message(cid: ChannelID, error_code: u8) -> HidPacketIterator { + // This unwrap is safe because the payload length is 1 <= 7609 bytes. + CtapHid::split_message(Message { + cid, + cmd: CtapHid::COMMAND_ERROR, + payload: vec![error_code], + }) + .unwrap() + } + + pub fn process_single_packet(packet: &HidPacket) -> (&ChannelID, ProcessedPacket) { + let (cid, rest) = array_refs![packet, 4, 60]; + if rest[0] & CtapHid::PACKET_TYPE_MASK != 0 { + let cmd = rest[0] & !CtapHid::PACKET_TYPE_MASK; + let len = (rest[1] as usize) << 8 | (rest[2] as usize); + ( + cid, + ProcessedPacket::InitPacket { + cmd, + len, + data: array_ref!(rest, 3, 57), + }, + ) + } else { + ( + cid, + ProcessedPacket::ContinuationPacket { + seq: rest[0], + data: array_ref!(rest, 1, 59), + }, + ) + } + } + + fn split_message(message: Message) -> Option { + #[cfg(feature = "debug_ctap")] + writeln!(&mut Console::new(), "Sending message: {:02x?}", message).unwrap(); + HidPacketIterator::new(message) + } + + pub fn keepalive(cid: ChannelID, status: KeepaliveStatus) -> HidPacketIterator { + let status_code = match status { + KeepaliveStatus::Processing => 1, + KeepaliveStatus::UpNeeded => 2, + }; + // This unwrap is safe because the payload length is 1 <= 7609 bytes. + CtapHid::split_message(Message { + cid, + cmd: CtapHid::COMMAND_KEEPALIVE, + payload: vec![status_code], + }) + .unwrap() + } + + #[cfg(feature = "with_ctap1")] + fn ctap1_error_message( + cid: ChannelID, + error_code: ctap1::Ctap1StatusCode, + ) -> HidPacketIterator { + // This unwrap is safe because the payload length is 2 <= 7609 bytes + let code: u16 = error_code.into(); + CtapHid::split_message(Message { + cid, + cmd: CtapHid::COMMAND_MSG, + payload: code.to_be_bytes().to_vec(), + }) + .unwrap() + } + + #[cfg(feature = "with_ctap1")] + fn ctap1_success_message(cid: ChannelID, payload: &[u8]) -> HidPacketIterator { + let mut response = payload.to_vec(); + let code: u16 = ctap1::Ctap1StatusCode::SW_NO_ERROR.into(); + response.extend_from_slice(&code.to_be_bytes()); + CtapHid::split_message(Message { + cid, + cmd: CtapHid::COMMAND_MSG, + payload: response, + }) + .unwrap() + } +} + +#[cfg(test)] +mod test { + use super::*; + use crypto::rng256::ThreadRng256; + + const CLOCK_FREQUENCY_HZ: usize = 32768; + // Except for tests for timeouts (done in ctap1.rs), transactions are time independant. + const DUMMY_CLOCK_VALUE: ClockValue = ClockValue::new(0, CLOCK_FREQUENCY_HZ); + const DUMMY_TIMESTAMP: Timestamp = Timestamp::from_ms(0); + + fn process_messages( + ctap_hid: &mut CtapHid, + ctap_state: &mut CtapState, + request: Vec, + ) -> Option> + where + CheckUserPresence: Fn(ChannelID) -> Result<(), Ctap2StatusCode>, + { + let mut result = Vec::new(); + let mut assembler_reply = MessageAssembler::new(); + for msg_request in request { + for pkt_request in HidPacketIterator::new(msg_request).unwrap() { + for pkt_reply in + ctap_hid.process_hid_packet(&pkt_request, DUMMY_CLOCK_VALUE, ctap_state) + { + match assembler_reply.parse_packet(&pkt_reply, DUMMY_TIMESTAMP) { + Ok(Some(message)) => result.push(message), + Ok(None) => (), + Err(_) => return None, + } + } + } + } + Some(result) + } + + fn cid_from_init( + ctap_hid: &mut CtapHid, + ctap_state: &mut CtapState, + ) -> ChannelID + where + CheckUserPresence: Fn(ChannelID) -> Result<(), Ctap2StatusCode>, + { + let nonce = vec![0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]; + let reply = process_messages( + ctap_hid, + ctap_state, + vec![Message { + cid: CtapHid::CHANNEL_BROADCAST, + cmd: CtapHid::COMMAND_INIT, + payload: nonce.clone(), + }], + ); + + let mut cid_in_payload: ChannelID = Default::default(); + if let Some(messages) = reply { + assert_eq!(messages.len(), 1); + assert!(messages[0].payload.len() >= 12); + assert_eq!(nonce, &messages[0].payload[..8]); + cid_in_payload.copy_from_slice(&messages[0].payload[8..12]); + } else { + panic!("The init process was not successful to generate a valid channel ID.") + } + cid_in_payload + } + + #[test] + fn test_split_assemble() { + for payload_len in 0..7609 { + let message = Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0x00, + payload: vec![0xFF; payload_len], + }; + + let mut messages = Vec::new(); + let mut assembler = MessageAssembler::new(); + for packet in HidPacketIterator::new(message.clone()).unwrap() { + match assembler.parse_packet(&packet, DUMMY_TIMESTAMP) { + Ok(Some(msg)) => messages.push(msg), + Ok(None) => (), + Err(_) => panic!("Couldn't assemble packet: {:02x?}", &packet as &[u8]), + } + } + + assert_eq!(messages, vec![message]); + } + } + + #[test] + fn test_command_init() { + let mut rng = ThreadRng256 {}; + let user_immediately_present = |_| Ok(()); + let mut ctap_state = CtapState::new(&mut rng, user_immediately_present); + let mut ctap_hid = CtapHid::new(); + + let reply = process_messages( + &mut ctap_hid, + &mut ctap_state, + vec![Message { + cid: CtapHid::CHANNEL_BROADCAST, + cmd: CtapHid::COMMAND_INIT, + payload: vec![0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0], + }], + ); + + assert_eq!( + reply, + Some(vec![Message { + cid: CtapHid::CHANNEL_BROADCAST, + cmd: CtapHid::COMMAND_INIT, + payload: vec![ + 0x12, // Nonce + 0x34, + 0x56, + 0x78, + 0x9A, + 0xBC, + 0xDE, + 0xF0, + 0x01, // Allocated CID + 0x00, + 0x00, + 0x00, + 0x02, // Protocol version + 0x00, // Device version + 0x00, + 0x00, + CtapHid::CAPABILITIES + ] + }]) + ); + } + + #[test] + fn test_command_ping() { + let mut rng = ThreadRng256 {}; + let user_immediately_present = |_| Ok(()); + let mut ctap_state = CtapState::new(&mut rng, user_immediately_present); + let mut ctap_hid = CtapHid::new(); + let cid = cid_from_init(&mut ctap_hid, &mut ctap_state); + + let reply = process_messages( + &mut ctap_hid, + &mut ctap_state, + vec![Message { + cid, + cmd: CtapHid::COMMAND_PING, + payload: vec![0x99, 0x99], + }], + ); + + assert_eq!( + reply, + Some(vec![Message { + cid, + cmd: CtapHid::COMMAND_PING, + payload: vec![0x99, 0x99] + }]) + ); + } +} diff --git a/src/ctap/hid/receive.rs b/src/ctap/hid/receive.rs new file mode 100644 index 0000000..ae2e707 --- /dev/null +++ b/src/ctap/hid/receive.rs @@ -0,0 +1,590 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::{ChannelID, CtapHid, HidPacket, Message, ProcessedPacket}; +use crate::timer::Timestamp; +use alloc::vec::Vec; +use core::mem::swap; + +// A structure to assemble CTAPHID commands from a series of incoming USB HID packets. +pub struct MessageAssembler { + // Whether this is waiting to receive an initialization packet. + idle: bool, + // Current channel ID. + cid: ChannelID, + // Timestamp of the last packet received on the current channel. + last_timestamp: Timestamp, + // Current command. + cmd: u8, + // Sequence number expected for the next packet. + seq: u8, + // Number of bytes left to fill the current message. + remaining_payload_len: usize, + // Buffer for the current payload. + payload: Vec, +} + +#[derive(PartialEq, Debug)] +pub enum Error { + // Expected a continuation packet on a specific channel, got a packet on another channel. + UnexpectedChannel, + // Expected a continuation packet, got an init packet. + UnexpectedInit, + // Expected an init packet, got a continuation packet. + UnexpectedContinuation, + // Expected a continuation packet with a specific sequence number, got another sequence number. + UnexpectedSeq, + // This packet arrived after a timeout. + Timeout, +} + +impl MessageAssembler { + pub fn new() -> MessageAssembler { + MessageAssembler { + idle: true, + cid: [0, 0, 0, 0], + last_timestamp: Timestamp::from_ms(0), + cmd: 0, + seq: 0, + remaining_payload_len: 0, + payload: Vec::new(), + } + } + + // Resets the message assembler to the idle state. + // The caller can reset the assembler for example due to a timeout. + pub fn reset(&mut self) { + self.idle = true; + self.cid = [0, 0, 0, 0]; + self.last_timestamp = Timestamp::from_ms(0); + self.cmd = 0; + self.seq = 0; + self.remaining_payload_len = 0; + self.payload.clear(); + } + + // Returns: + // - An Ok() result if the packet was parsed correctly. This contains either Some(Vec) if a + // full message was assembled after this packet, or None if more packets are needed to fill the + // message. + // - An Err() result if there was a parsing error. + // TODO: Implement timeouts. For example, have the caller pass us a timestamp of when this + // packet was received. + pub fn parse_packet( + &mut self, + packet: &HidPacket, + timestamp: Timestamp, + ) -> Result, (ChannelID, Error)> { + // TODO: Support non-full-speed devices (i.e. packet len != 64)? This isn't recommended by + // section 8.8.1 + let (cid, processed_packet) = CtapHid::process_single_packet(&packet); + + if !self.idle && timestamp - self.last_timestamp >= CtapHid::TIMEOUT_DURATION { + // The current channel timed out. + // Save the channel ID and reset the state. + let current_cid = self.cid; + self.reset(); + + // If the packet is from the timed-out channel, send back a timeout error. + // Otherwise, proceed with processing the packet. + if *cid == current_cid { + return Err((*cid, Error::Timeout)); + } + } + + if self.idle { + // Expecting an initialization packet. + match processed_packet { + ProcessedPacket::InitPacket { cmd, len, data } => { + Ok(self.accept_init_packet(*cid, cmd, len, data, timestamp)) + } + ProcessedPacket::ContinuationPacket { .. } => { + // CTAP specification (version 20190130) section 8.1.5.4 + // Spurious continuation packets will be ignored. + Err((*cid, Error::UnexpectedContinuation)) + } + } + } else { + // Expecting a continuation packet from the current channel. + + // CTAP specification (version 20190130) section 8.1.5.1 + // Reject packets from other channels. + if *cid != self.cid { + return Err((*cid, Error::UnexpectedChannel)); + } + + match processed_packet { + // Unexpected initialization packet. + ProcessedPacket::InitPacket { cmd, len, data } => { + self.reset(); + if cmd == CtapHid::COMMAND_INIT { + Ok(self.accept_init_packet(*cid, cmd, len, data, timestamp)) + } else { + Err((*cid, Error::UnexpectedInit)) + } + } + ProcessedPacket::ContinuationPacket { seq, data } => { + if seq != self.seq { + // Reject packets with the wrong sequence number. + self.reset(); + Err((*cid, Error::UnexpectedSeq)) + } else { + // Update the last timestamp. + self.last_timestamp = timestamp; + // Increment the sequence number for the next packet. + self.seq += 1; + Ok(self.append_payload(data)) + } + } + } + } + } + + fn accept_init_packet( + &mut self, + cid: ChannelID, + cmd: u8, + len: usize, + data: &[u8], + timestamp: Timestamp, + ) -> Option { + // TODO: Should invalid commands/payload lengths be rejected early, i.e. as soon as the + // initialization packet is received, or should we build a message and then catch the + // error? + // The specification (version 20190130) isn't clear on this point. + self.cid = cid; + self.last_timestamp = timestamp; + self.cmd = cmd; + self.seq = 0; + self.remaining_payload_len = len; + self.append_payload(data) + } + + fn append_payload(&mut self, data: &[u8]) -> Option { + if data.len() < self.remaining_payload_len { + self.payload.extend_from_slice(data); + self.idle = false; + self.remaining_payload_len -= data.len(); + None + } else { + self.payload + .extend_from_slice(&data[..self.remaining_payload_len]); + self.idle = true; + let mut payload = Vec::new(); + swap(&mut self.payload, &mut payload); + Some(Message { + cid: self.cid, + cmd: self.cmd, + payload, + }) + } + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::timer::Duration; + + // Except for tests that exercise timeouts, all packets are synchronized at the same dummy + // timestamp. + const DUMMY_TIMESTAMP: Timestamp = Timestamp::from_ms(0); + + fn byte_extend(bytes: &[u8], padding: u8) -> HidPacket { + let len = bytes.len(); + assert!(len <= 64); + let mut result = [0; 64]; + result[..len].copy_from_slice(bytes); + for byte in result[len..].iter_mut() { + *byte = padding; + } + result + } + + fn zero_extend(bytes: &[u8]) -> HidPacket { + byte_extend(bytes, 0) + } + + #[test] + fn test_empty_payload() { + let mut assembler = MessageAssembler::new(); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x80]), + DUMMY_TIMESTAMP + ), + Ok(Some(Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0x00, + payload: vec![] + })) + ); + } + + #[test] + fn test_one_packet() { + let mut assembler = MessageAssembler::new(); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x80, 0x00, 0x10]), + DUMMY_TIMESTAMP + ), + Ok(Some(Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0x00, + payload: vec![0x00; 0x10] + })) + ); + } + + #[test] + fn test_nonzero_padding() { + // CTAP specification (version 20190130) section 8.1.4 + // It is written that "Unused bytes SHOULD be set to zero", so we test that non-zero + // padding is accepted as well. + let mut assembler = MessageAssembler::new(); + assert_eq!( + assembler.parse_packet( + &byte_extend(&[0x12, 0x34, 0x56, 0x78, 0x80, 0x00, 0x10], 0xFF), + DUMMY_TIMESTAMP + ), + Ok(Some(Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0x00, + payload: vec![0xFF; 0x10] + })) + ); + } + + #[test] + fn test_two_packets() { + let mut assembler = MessageAssembler::new(); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x81, 0x00, 0x40]), + DUMMY_TIMESTAMP + ), + Ok(None) + ); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x00]), + DUMMY_TIMESTAMP + ), + Ok(Some(Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0x01, + payload: vec![0x00; 0x40] + })) + ); + } + + #[test] + fn test_three_packets() { + let mut assembler = MessageAssembler::new(); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x81, 0x00, 0x80]), + DUMMY_TIMESTAMP + ), + Ok(None) + ); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x00]), + DUMMY_TIMESTAMP + ), + Ok(None) + ); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x01]), + DUMMY_TIMESTAMP + ), + Ok(Some(Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0x01, + payload: vec![0x00; 0x80] + })) + ); + } + + #[test] + fn test_max_packets() { + let mut assembler = MessageAssembler::new(); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x81, 0x1D, 0xB9]), + DUMMY_TIMESTAMP + ), + Ok(None) + ); + for seq in 0..0x7F { + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, seq]), + DUMMY_TIMESTAMP + ), + Ok(None) + ); + } + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x7F]), + DUMMY_TIMESTAMP + ), + Ok(Some(Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0x01, + payload: vec![0x00; 0x1DB9] + })) + ); + } + + #[test] + fn test_multiple_messages() { + // Check that after yielding a message, the assembler is ready to process new messages. + let mut assembler = MessageAssembler::new(); + for i in 0..10 { + // Introduce some variability in the messages. + let cmd = 2 * i; + let byte = 3 * i; + + assert_eq!( + assembler.parse_packet( + &byte_extend(&[0x12, 0x34, 0x56, 0x78, 0x80 | cmd, 0x00, 0x80], byte), + DUMMY_TIMESTAMP + ), + Ok(None) + ); + assert_eq!( + assembler.parse_packet( + &byte_extend(&[0x12, 0x34, 0x56, 0x78, 0x00], byte), + DUMMY_TIMESTAMP + ), + Ok(None) + ); + assert_eq!( + assembler.parse_packet( + &byte_extend(&[0x12, 0x34, 0x56, 0x78, 0x01], byte), + DUMMY_TIMESTAMP + ), + Ok(Some(Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd, + payload: vec![byte; 0x80] + })) + ); + } + } + + #[test] + fn test_channel_switch() { + // Check that the assembler can process messages from multiple channels, sequentially. + let mut assembler = MessageAssembler::new(); + for i in 0..10 { + // Introduce some variability in the messages. + let cid = 0x78 + i; + let cmd = 2 * i; + let byte = 3 * i; + + assert_eq!( + assembler.parse_packet( + &byte_extend(&[0x12, 0x34, 0x56, cid, 0x80 | cmd, 0x00, 0x80], byte), + DUMMY_TIMESTAMP + ), + Ok(None) + ); + assert_eq!( + assembler.parse_packet( + &byte_extend(&[0x12, 0x34, 0x56, cid, 0x00], byte), + DUMMY_TIMESTAMP + ), + Ok(None) + ); + assert_eq!( + assembler.parse_packet( + &byte_extend(&[0x12, 0x34, 0x56, cid, 0x01], byte), + DUMMY_TIMESTAMP + ), + Ok(Some(Message { + cid: [0x12, 0x34, 0x56, cid], + cmd, + payload: vec![byte; 0x80] + })) + ); + } + } + + #[test] + fn test_unexpected_channel() { + let mut assembler = MessageAssembler::new(); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x81, 0x00, 0x40]), + DUMMY_TIMESTAMP + ), + Ok(None) + ); + + // Check that many sorts of packets on another channel are ignored. + for cmd in 0..=0xFF { + for byte in 0..=0xFF { + assert_eq!( + assembler.parse_packet( + &byte_extend(&[0x12, 0x34, 0x56, 0x9A, cmd, 0x00], byte), + DUMMY_TIMESTAMP + ), + Err(([0x12, 0x34, 0x56, 0x9A], Error::UnexpectedChannel)) + ); + } + } + + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x00]), + DUMMY_TIMESTAMP + ), + Ok(Some(Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0x01, + payload: vec![0x00; 0x40] + })) + ); + } + + #[test] + fn test_spurious_continuation_packets() { + // CTAP specification (version 20190130) section 8.1.5.4 + // Spurious continuation packets appearing without a prior initialization packet will be + // ignored. + let mut assembler = MessageAssembler::new(); + for i in 0..0x80 { + // Some legit packet. + let byte = 2 * i; + assert_eq!( + assembler.parse_packet( + &byte_extend(&[0x12, 0x34, 0x56, 0x78, 0x80, 0x00, 0x10], byte), + DUMMY_TIMESTAMP + ), + Ok(Some(Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0x00, + payload: vec![byte; 0x10] + })) + ); + + // Spurious continuation packet. + let seq = i; + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, seq]), + DUMMY_TIMESTAMP + ), + Err(([0x12, 0x34, 0x56, 0x78], Error::UnexpectedContinuation)) + ); + } + } + + #[test] + fn test_unexpected_init() { + let mut assembler = MessageAssembler::new(); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x81, 0x00, 0x40]), + DUMMY_TIMESTAMP + ), + Ok(None) + ); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x80]), + DUMMY_TIMESTAMP + ), + Err(([0x12, 0x34, 0x56, 0x78], Error::UnexpectedInit)) + ); + } + + #[test] + fn test_unexpected_seq() { + let mut assembler = MessageAssembler::new(); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x81, 0x00, 0x40]), + DUMMY_TIMESTAMP + ), + Ok(None) + ); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x01]), + DUMMY_TIMESTAMP + ), + Err(([0x12, 0x34, 0x56, 0x78], Error::UnexpectedSeq)) + ); + } + + #[test] + fn test_timed_out_packet() { + let mut assembler = MessageAssembler::new(); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x81, 0x00, 0x40]), + DUMMY_TIMESTAMP + ), + Ok(None) + ); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x00]), + DUMMY_TIMESTAMP + CtapHid::TIMEOUT_DURATION + ), + Err(([0x12, 0x34, 0x56, 0x78], Error::Timeout)) + ); + } + + #[test] + fn test_just_in_time_packets() { + let mut timestamp = DUMMY_TIMESTAMP; + // Delay between each packet is just below the threshold. + let delay = CtapHid::TIMEOUT_DURATION - Duration::from_ms(1); + + let mut assembler = MessageAssembler::new(); + assert_eq!( + assembler.parse_packet( + &zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x81, 0x1D, 0xB9]), + timestamp + ), + Ok(None) + ); + for seq in 0..0x7F { + timestamp += delay; + assert_eq!( + assembler.parse_packet(&zero_extend(&[0x12, 0x34, 0x56, 0x78, seq]), timestamp), + Ok(None) + ); + } + timestamp += delay; + assert_eq!( + assembler.parse_packet(&zero_extend(&[0x12, 0x34, 0x56, 0x78, 0x7F]), timestamp), + Ok(Some(Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0x01, + payload: vec![0x00; 0x1DB9] + })) + ); + } + + // TODO: more tests +} diff --git a/src/ctap/hid/send.rs b/src/ctap/hid/send.rs new file mode 100644 index 0000000..434d633 --- /dev/null +++ b/src/ctap/hid/send.rs @@ -0,0 +1,296 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::{CtapHid, HidPacket, Message}; + +pub struct HidPacketIterator(Option); + +impl HidPacketIterator { + pub fn new(message: Message) -> Option { + let splitter = MessageSplitter::new(message); + if splitter.is_some() { + Some(HidPacketIterator(splitter)) + } else { + None + } + } + + pub fn none() -> HidPacketIterator { + HidPacketIterator(None) + } +} + +impl Iterator for HidPacketIterator { + type Item = HidPacket; + + fn next(&mut self) -> Option { + match &mut self.0 { + Some(splitter) => splitter.next(), + None => None, + } + } +} + +pub struct MessageSplitter { + message: Message, + packet: HidPacket, + seq: Option, + i: usize, +} + +impl MessageSplitter { + // Try to split this message into an iterator of HID packets. This fails if the message is too + // long to fit into a sequence of HID packets (which is limited to 7609 bytes). + pub fn new(message: Message) -> Option { + if message.payload.len() > 7609 { + None + } else { + // Cache the CID, as it is constant for all packets in this message. + let mut packet = [0; 64]; + packet[..4].copy_from_slice(&message.cid); + + Some(MessageSplitter { + message, + packet, + seq: None, + i: 0, + }) + } + } + + // Copy as many bytes as possible from data to dst, and return how many bytes are copied. + // Contrary to copy_from_slice, this doesn't require slices of the same length. + // All unused bytes in dst are set to zero, as if the data was padded with zeros to match. + fn consume_data(dst: &mut [u8], data: &[u8]) -> usize { + let dst_len = dst.len(); + let data_len = data.len(); + + if data_len <= dst_len { + // data fits in dst, copy all the bytes. + dst[..data_len].copy_from_slice(data); + for byte in dst[data_len..].iter_mut() { + *byte = 0; + } + data_len + } else { + // Fill all of dst. + dst.copy_from_slice(&data[..dst_len]); + dst_len + } + } +} + +impl Iterator for MessageSplitter { + type Item = HidPacket; + + fn next(&mut self) -> Option { + let payload_len = self.message.payload.len(); + match self.seq { + None => { + // First, send an initialization packet. + self.packet[4] = self.message.cmd | CtapHid::TYPE_INIT_BIT; + self.packet[5] = (payload_len >> 8) as u8; + self.packet[6] = payload_len as u8; + + self.seq = Some(0); + self.i = + MessageSplitter::consume_data(&mut self.packet[7..], &self.message.payload); + Some(self.packet) + } + Some(seq) => { + // Send the next continuation packet, if any. + if self.i < payload_len { + self.packet[4] = seq; + self.seq = Some(seq + 1); + self.i += MessageSplitter::consume_data( + &mut self.packet[5..], + &self.message.payload[self.i..], + ); + Some(self.packet) + } else { + None + } + } + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + fn assert_packet_output_equality(message: Message, expected_packets: Vec) { + let packets: Vec = HidPacketIterator::new(message).unwrap().collect(); + assert_eq!(packets.len(), expected_packets.len()); + for (packet, expected_packet) in packets.iter().zip(expected_packets.iter()) { + assert_eq!(packet as &[u8], expected_packet as &[u8]); + } + } + + #[test] + fn test_hid_packet_iterator_single_packet() { + let message = Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0x4C, + payload: vec![0xAA, 0xBB], + }; + let expected_packets: Vec = vec![[ + 0x12, 0x34, 0x56, 0x78, 0xCC, 0x00, 0x02, 0xAA, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]]; + assert_packet_output_equality(message, expected_packets); + } + + #[test] + fn test_hid_packet_iterator_big_single_packet() { + let message = Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0x4C, + payload: vec![0xAA; 64 - 7], + }; + let expected_packets: Vec = vec![[ + 0x12, 0x34, 0x56, 0x78, 0xCC, 0x00, 0x39, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + ]]; + assert_packet_output_equality(message, expected_packets); + } + + #[test] + fn test_hid_packet_iterator_two_packets() { + let message = Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0x4C, + payload: vec![0xAA; 64 - 7 + 1], + }; + let expected_packets: Vec = vec![ + [ + 0x12, 0x34, 0x56, 0x78, 0xCC, 0x00, 0x3A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + ], + [ + 0x12, 0x34, 0x56, 0x78, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ], + ]; + assert_packet_output_equality(message, expected_packets); + } + + #[test] + fn test_hid_packet_iterator_two_full_packets() { + let mut payload = vec![0xAA; 64 - 7]; + payload.extend(vec![0xBB; 64 - 5]); + let message = Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0x4C, + payload, + }; + let expected_packets: Vec = vec![ + [ + 0x12, 0x34, 0x56, 0x78, 0xCC, 0x00, 0x74, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + ], + [ + 0x12, 0x34, 0x56, 0x78, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, + 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, + 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, + 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, + 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, + ], + ]; + assert_packet_output_equality(message, expected_packets); + } + + #[test] + fn test_hid_packet_iterator_max_packets() { + let mut payload = vec![0xFF; 64 - 7]; + for i in 0..128 { + payload.extend(vec![i + 1; 64 - 5]); + } + + // Sanity check for the length of the payload. + assert_eq!((64 - 7) + 128 * (64 - 5), 0x1db9); + assert_eq!(7609, 0x1db9); + assert_eq!(payload.len(), 0x1db9); + + let message = Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0xAB, + payload, + }; + + let mut expected_packets = Vec::new(); + expected_packets.push([ + 0x12, 0x34, 0x56, 0x78, 0xAB, 0x1D, 0xB9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + ]); + for i in 0..128 { + let mut packet: HidPacket = [0; 64]; + packet[0] = 0x12; + packet[1] = 0x34; + packet[2] = 0x56; + packet[3] = 0x78; + packet[4] = i; + for byte in packet.iter_mut().skip(5) { + *byte = i + 1; + } + expected_packets.push(packet); + } + + assert_packet_output_equality(message, expected_packets); + } + + #[test] + fn test_hid_packet_iterator_payload_one_too_large() { + let payload = vec![0xFF; (64 - 7) + 128 * (64 - 5) + 1]; + assert_eq!(payload.len(), 0x1dba); + let message = Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0xAB, + payload, + }; + assert!(HidPacketIterator::new(message).is_none()); + } + + #[test] + fn test_hid_packet_iterator_payload_way_too_large() { + // Check that overflow of u16 doesn't bypass the size limit. + let payload = vec![0xFF; 0x10000]; + let message = Message { + cid: [0x12, 0x34, 0x56, 0x78], + cmd: 0xAB, + payload, + }; + assert!(HidPacketIterator::new(message).is_none()); + } + + // TODO(kaczmarczyck) implement and test limits (maximum bytes and packets) +} diff --git a/src/ctap/mod.rs b/src/ctap/mod.rs new file mode 100644 index 0000000..26740d5 --- /dev/null +++ b/src/ctap/mod.rs @@ -0,0 +1,1297 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod command; +#[cfg(feature = "with_ctap1")] +mod ctap1; +pub mod data_formats; +pub mod hid; +mod key_material; +pub mod response; +pub mod status_code; +mod storage; +mod timed_permission; + +use self::command::{ + AuthenticatorClientPinParameters, AuthenticatorGetAssertionParameters, + AuthenticatorMakeCredentialParameters, Command, +}; +use self::data_formats::{ + ClientPinSubCommand, CoseKey, PackedAttestationStatement, PublicKeyCredentialDescriptor, + PublicKeyCredentialSource, PublicKeyCredentialType, PublicKeyCredentialUserEntity, + SignatureAlgorithm, +}; +use self::hid::ChannelID; +use self::key_material::{AAGUID, ATTESTATION_CERTIFICATE, ATTESTATION_PRIVATE_KEY}; +use self::response::{ + AuthenticatorClientPinResponse, AuthenticatorGetAssertionResponse, + AuthenticatorGetInfoResponse, AuthenticatorMakeCredentialResponse, ResponseData, +}; +use self::status_code::Ctap2StatusCode; +use self::storage::PersistentStore; +#[cfg(feature = "with_ctap1")] +use self::timed_permission::U2fUserPresenceState; +use alloc::collections::BTreeMap; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use byteorder::{BigEndian, ByteOrder}; +use core::convert::TryInto; +#[cfg(feature = "debug_ctap")] +use core::fmt::Write; +use crypto::cbc::{cbc_decrypt, cbc_encrypt}; +use crypto::hmac::{hmac_256, verify_hmac_256, verify_hmac_256_first_128bits}; +use crypto::rng256::Rng256; +use crypto::sha256::Sha256; +use crypto::Hash256; +#[cfg(feature = "debug_ctap")] +use libtock::console::Console; +use libtock::timer::{Duration, Timestamp}; +use subtle::ConstantTimeEq; + +// This flag enables or disables basic attestation for FIDO2. U2F is unaffected by +// this setting. The basic attestation uses the signing key from key_material.rs +// as a batch key. Turn it on if you want attestation. In this case, be aware that +// it is your responsibility to generate your own key material and keep it secret. +const USE_BATCH_ATTESTATION: bool = false; +// The signature counter is currently implemented as a global counter, if you set +// this flag to true. The spec strongly suggests to have per-credential-counters, +// but it means you can't have an infinite amount of credentials anymore. Also, +// since this is the only piece of information that needs writing often, we might +// need a flash storage friendly way to implement this feature. The implemented +// solution is a compromise to be compatible with U2F and not wasting storage. +const USE_SIGNATURE_COUNTER: bool = true; +// Those constants have to be multiples of 16, the AES block size. +const PIN_AUTH_LENGTH: usize = 16; +const PIN_TOKEN_LENGTH: usize = 32; +const PIN_PADDED_LENGTH: usize = 64; +// Our credential ID consists of +// - 16 byte initialization vector for AES-256, +// - 32 byte ECDSA private key for the credential, +// - 32 byte relying party ID hashed with SHA256, +// - 32 byte HMAC-SHA256 over everything else. +pub const ENCRYPTED_CREDENTIAL_ID_SIZE: usize = 112; +const UP_FLAG: u8 = 0x01; +const UV_FLAG: u8 = 0x04; +const AT_FLAG: u8 = 0x40; + +pub const TOUCH_TIMEOUT_MS: isize = 30000; +#[cfg(feature = "with_ctap1")] +const U2F_UP_PROMPT_TIMEOUT: Duration = Duration::from_ms(10000); +const RESET_TIMEOUT_MS: isize = 10000; + +pub const FIDO2_VERSION_STRING: &str = "FIDO_2_0"; +#[cfg(feature = "with_ctap1")] +pub const U2F_VERSION_STRING: &str = "U2F_V2"; + +fn check_pin_auth(hmac_key: &[u8], hmac_contents: &[u8], pin_auth: &[u8]) -> bool { + if pin_auth.len() != PIN_AUTH_LENGTH { + return false; + } + verify_hmac_256_first_128bits::( + hmac_key, + hmac_contents, + array_ref![pin_auth, 0, PIN_AUTH_LENGTH], + ) +} + +// This function is adapted from https://doc.rust-lang.org/nightly/src/core/str/mod.rs.html#2110 +// (as of 2020-01-20) and truncates to "max" bytes, not breaking the encoding. +// We change the return value, since we don't need the bool. +fn truncate_to_char_boundary(s: &str, mut max: usize) -> &str { + if max >= s.len() { + s + } else { + while !s.is_char_boundary(max) { + max -= 1; + } + &s[..max] + } +} + +// This struct currently holds all state, not only the persistent memory. The persistent members are +// in the persistent store field. +pub struct CtapState<'a, R: Rng256, CheckUserPresence: Fn(ChannelID) -> Result<(), Ctap2StatusCode>> +{ + rng: &'a mut R, + // A function to check user presence, ultimately returning true if user presence was detected, + // false otherwise. + check_user_presence: CheckUserPresence, + persistent_store: PersistentStore, + key_agreement_key: crypto::ecdh::SecKey, + pin_uv_auth_token: [u8; PIN_TOKEN_LENGTH], + consecutive_pin_mismatches: u64, + // This variable will be irreversibly set to false RESET_TIMEOUT_MS milliseconds after boot. + accepts_reset: bool, + #[cfg(feature = "with_ctap1")] + pub u2f_up_state: U2fUserPresenceState, +} + +impl<'a, R, CheckUserPresence> CtapState<'a, R, CheckUserPresence> +where + R: Rng256, + CheckUserPresence: Fn(ChannelID) -> Result<(), Ctap2StatusCode>, +{ + pub const PIN_PROTOCOL_VERSION: u64 = 1; + + pub fn new( + rng: &'a mut R, + check_user_presence: CheckUserPresence, + ) -> CtapState<'a, R, CheckUserPresence> { + let key_agreement_key = crypto::ecdh::SecKey::gensk(rng); + let pin_uv_auth_token = rng.gen_uniform_u8x32(); + let persistent_store = PersistentStore::new(rng); + CtapState { + rng, + check_user_presence, + persistent_store, + key_agreement_key, + pin_uv_auth_token, + consecutive_pin_mismatches: 0, + accepts_reset: true, + #[cfg(feature = "with_ctap1")] + u2f_up_state: U2fUserPresenceState::new( + U2F_UP_PROMPT_TIMEOUT, + Duration::from_ms(TOUCH_TIMEOUT_MS), + ), + } + } + + pub fn check_disable_reset(&mut self, timestamp: Timestamp) { + if timestamp - Timestamp::::from_ms(0) > Duration::from_ms(RESET_TIMEOUT_MS) { + self.accepts_reset = false; + } + } + + pub fn increment_global_signature_counter(&mut self) { + if USE_SIGNATURE_COUNTER { + self.persistent_store.incr_global_signature_counter(); + } + } + + // Encrypts the private key and relying party ID hash into a credential ID. Other + // information, such as a user name, are not stored, because encrypted credential IDs + // are used for credentials stored server-side. Also, we want the key handle to be + // compatible with U2F. + pub fn encrypt_key_handle( + &mut self, + private_key: crypto::ecdsa::SecKey, + application: &[u8; 32], + ) -> Vec { + let master_keys = self.persistent_store.master_keys(); + let aes_enc_key = crypto::aes256::EncryptionKey::new(master_keys.encryption); + let mut sk_bytes = [0; 32]; + private_key.to_bytes(&mut sk_bytes); + let mut iv = [0; 16]; + iv.copy_from_slice(&self.rng.gen_uniform_u8x32()[..16]); + + let mut blocks = [[0u8; 16]; 4]; + blocks[0].copy_from_slice(&sk_bytes[..16]); + blocks[1].copy_from_slice(&sk_bytes[16..]); + blocks[2].copy_from_slice(&application[..16]); + blocks[3].copy_from_slice(&application[16..]); + cbc_encrypt(&aes_enc_key, iv, &mut blocks); + + let mut encrypted_id = Vec::with_capacity(ENCRYPTED_CREDENTIAL_ID_SIZE); + encrypted_id.extend(&iv); + for b in &blocks { + encrypted_id.extend(b); + } + let id_hmac = hmac_256::(master_keys.hmac, &encrypted_id[..]); + encrypted_id.extend(&id_hmac); + encrypted_id + } + + // Decrypts a credential ID and writes the private key into a PublicKeyCredentialSource. + // None is returned if the HMAC test fails or the relying party does not match the + // decrypted relying party ID hash. + pub fn decrypt_credential_source( + &self, + credential_id: Vec, + rp_id_hash: &[u8], + ) -> Option { + if credential_id.len() != ENCRYPTED_CREDENTIAL_ID_SIZE { + return None; + } + let master_keys = self.persistent_store.master_keys(); + let payload_size = ENCRYPTED_CREDENTIAL_ID_SIZE - 32; + if !verify_hmac_256::( + master_keys.hmac, + &credential_id[..payload_size], + array_ref![credential_id, payload_size, 32], + ) { + return None; + } + let aes_enc_key = crypto::aes256::EncryptionKey::new(master_keys.encryption); + let aes_dec_key = crypto::aes256::DecryptionKey::new(&aes_enc_key); + let mut iv = [0; 16]; + iv.copy_from_slice(&credential_id[..16]); + let mut blocks = [[0u8; 16]; 4]; + for i in 0..4 { + blocks[i].copy_from_slice(&credential_id[16 * (i + 1)..16 * (i + 2)]); + } + + cbc_decrypt(&aes_dec_key, iv, &mut blocks); + let mut decrypted_sk = [0; 32]; + let mut decrypted_rp_id_hash = [0; 32]; + decrypted_sk[..16].clone_from_slice(&blocks[0]); + decrypted_sk[16..].clone_from_slice(&blocks[1]); + decrypted_rp_id_hash[..16].clone_from_slice(&blocks[2]); + decrypted_rp_id_hash[16..].clone_from_slice(&blocks[3]); + + if rp_id_hash != decrypted_rp_id_hash { + return None; + } + + let sk_option = crypto::ecdsa::SecKey::from_bytes(&decrypted_sk); + sk_option.map(|sk| PublicKeyCredentialSource { + key_type: PublicKeyCredentialType::PublicKey, + credential_id, + private_key: sk, + rp_id: String::from(""), + user_handle: vec![], + other_ui: None, + }) + } + + pub fn process_command(&mut self, command_cbor: &[u8], cid: ChannelID) -> Vec { + let cmd = Command::deserialize(command_cbor); + #[cfg(feature = "debug_ctap")] + writeln!(&mut Console::new(), "Received command: {:#?}", cmd).unwrap(); + match cmd { + Ok(command) => { + // Correct behavior between CTAP1 and CTAP2 isn't defined yet. Just a guess. + #[cfg(feature = "with_ctap1")] + { + self.u2f_up_state = U2fUserPresenceState::new( + U2F_UP_PROMPT_TIMEOUT, + Duration::from_ms(TOUCH_TIMEOUT_MS), + ); + } + let response = match command { + Command::AuthenticatorMakeCredential(params) => { + self.process_make_credential(params, cid) + } + Command::AuthenticatorGetAssertion(params) => { + self.process_get_assertion(params, cid) + } + Command::AuthenticatorGetInfo => self.process_get_info(), + Command::AuthenticatorClientPin(params) => self.process_client_pin(params), + Command::AuthenticatorReset => self.process_reset(cid), + // TODO(kaczmarczyck) implement GetNextAssertion and FIDO 2.1 commands + _ => unimplemented!(), + }; + #[cfg(feature = "debug_ctap")] + writeln!(&mut Console::new(), "Sending response: {:#?}", response).unwrap(); + match response { + Ok(response_data) => { + let mut response_vec = vec![0x00]; + if let Some(value) = response_data.into() { + if !cbor::write(value, &mut response_vec) { + response_vec = vec![ + Ctap2StatusCode::CTAP2_ERR_VENDOR_RESPONSE_CANNOT_WRITE_CBOR + as u8, + ]; + } + } + response_vec + } + Err(error_code) => vec![error_code as u8], + } + } + Err(error_code) => vec![error_code as u8], + } + } + + fn process_make_credential( + &mut self, + make_credential_params: AuthenticatorMakeCredentialParameters, + cid: ChannelID, + ) -> Result { + let AuthenticatorMakeCredentialParameters { + client_data_hash, + rp, + user, + pub_key_cred_params, + exclude_list, + options, + pin_uv_auth_param, + pin_uv_auth_protocol, + .. + } = make_credential_params; + + if let Some(auth_param) = &pin_uv_auth_param { + // This case was added in FIDO 2.1. + if auth_param.is_empty() { + if self.persistent_store.pin_hash().is_none() { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_NOT_SET); + } else { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_INVALID); + } + } + + match pin_uv_auth_protocol { + Some(protocol) => { + if protocol != CtapState::::PIN_PROTOCOL_VERSION { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID); + } + } + None => return Err(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER), + } + } + + let has_es_256 = pub_key_cred_params + .iter() + .any(|(credential_type, algorithm)| { + // Even though there is only one type now, checking seems safer in + // case of extension so you can't forget to update here. + *credential_type == PublicKeyCredentialType::PublicKey + && *algorithm == SignatureAlgorithm::ES256 as i64 + }); + if !has_es_256 { + return Err(Ctap2StatusCode::CTAP2_ERR_UNSUPPORTED_ALGORITHM); + } + + let rp_id = rp.rp_id; + if let Some(exclude_list) = exclude_list { + for cred_desc in exclude_list { + if self + .persistent_store + .find_credential(&rp_id, &cred_desc.key_id) + .is_some() + { + // Perform this check, so bad actors can't brute force exclude_list + // without user interaction. Discard the user presence check's outcome. + let _ = (self.check_user_presence)(cid); + return Err(Ctap2StatusCode::CTAP2_ERR_CREDENTIAL_EXCLUDED); + } + } + } + + // MakeCredential always requires user presence. + // User verification depends on the PIN auth inputs, which are checked here. + let flags = match pin_uv_auth_param { + Some(pin_auth) => { + if self.persistent_store.pin_hash().is_none() { + // Specification is unclear, could be CTAP2_ERR_INVALID_OPTION. + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_NOT_SET); + } + if !check_pin_auth(&self.pin_uv_auth_token, &client_data_hash, &pin_auth) { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID); + } + UP_FLAG | UV_FLAG | AT_FLAG + } + None => { + if self.persistent_store.pin_hash().is_some() { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_REQUIRED); + } + if options.uv { + return Err(Ctap2StatusCode::CTAP2_ERR_INVALID_OPTION); + } + UP_FLAG | AT_FLAG + } + }; + + (self.check_user_presence)(cid)?; + + let sk = crypto::ecdsa::SecKey::gensk(self.rng); + let pk = sk.genpk(); + + let rp_id_hash = Sha256::hash(rp_id.as_bytes()); + let credential_id = if options.rk { + let random_id = self.rng.gen_uniform_u8x32().to_vec(); + let credential_source = PublicKeyCredentialSource { + key_type: PublicKeyCredentialType::PublicKey, + credential_id: random_id.clone(), + private_key: sk.clone(), + rp_id, + user_handle: user.user_id, + // This input is user provided, so we crop it to 64 byte for storage. + // The UTF8 encoding is always preserved, so the string might end up shorter. + other_ui: user + .user_display_name + .map(|s| truncate_to_char_boundary(&s, 64).to_string()), + }; + self.persistent_store.store_credential(credential_source)?; + random_id + } else { + self.encrypt_key_handle(sk.clone(), &rp_id_hash) + }; + + let mut auth_data = self.generate_auth_data(&rp_id_hash, flags); + auth_data.extend(&AAGUID); + // The length is fixed to 0x20 or 0x70 and fits one byte. + if credential_id.len() > 0xFF { + return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_RESPONSE_TOO_LONG); + } + auth_data.extend(vec![0x00, credential_id.len() as u8]); + auth_data.extend(&credential_id); + let cose_key = match pk.to_cose_key() { + Some(cose_key) => cose_key, + None => return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_RESPONSE_CANNOT_WRITE_CBOR), + }; + auth_data.extend(cose_key); + + let mut signature_data = auth_data.clone(); + signature_data.extend(client_data_hash); + let (signature, x5c) = if USE_BATCH_ATTESTATION { + let attestation_key = + crypto::ecdsa::SecKey::from_bytes(&ATTESTATION_PRIVATE_KEY).unwrap(); + ( + attestation_key.sign_rfc6979::(&signature_data), + Some(vec![ATTESTATION_CERTIFICATE.to_vec()]), + ) + } else { + ( + sk.sign_rfc6979::(&signature_data), + None, + ) + }; + let attestation_statement = PackedAttestationStatement { + alg: SignatureAlgorithm::ES256 as i64, + sig: signature.to_asn1_der(), + x5c, + ecdaa_key_id: None, + }; + Ok(ResponseData::AuthenticatorMakeCredential( + AuthenticatorMakeCredentialResponse { + fmt: String::from("packed"), + auth_data, + att_stmt: attestation_statement, + }, + )) + } + + fn process_get_assertion( + &mut self, + get_assertion_params: AuthenticatorGetAssertionParameters, + cid: ChannelID, + ) -> Result { + let AuthenticatorGetAssertionParameters { + rp_id, + client_data_hash, + allow_list, + options, + pin_uv_auth_param, + pin_uv_auth_protocol, + .. + } = get_assertion_params; + + if let Some(auth_param) = &pin_uv_auth_param { + // This case was added in FIDO 2.1. + if auth_param.is_empty() { + if self.persistent_store.pin_hash().is_none() { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_NOT_SET); + } else { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_INVALID); + } + } + + match pin_uv_auth_protocol { + Some(protocol) => { + if protocol != CtapState::::PIN_PROTOCOL_VERSION { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID); + } + } + None => return Err(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER), + } + } + + // This case was added in FIDO 2.1. + if pin_uv_auth_param == Some(vec![]) { + if self.persistent_store.pin_hash().is_none() { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_NOT_SET); + } else { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_INVALID); + } + } + + if pin_uv_auth_param.is_some() { + match pin_uv_auth_protocol { + Some(protocol) => { + if protocol != CtapState::::PIN_PROTOCOL_VERSION { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID); + } + } + None => return Err(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER), + } + } + + // The user verification bit depends on the existance of PIN auth, whereas + // user presence is requested as an option. + let mut flags = match pin_uv_auth_param { + Some(pin_auth) => { + if self.persistent_store.pin_hash().is_none() { + // Specification is unclear, could be CTAP2_ERR_UNSUPPORTED_OPTION. + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_NOT_SET); + } + if !check_pin_auth(&self.pin_uv_auth_token, &client_data_hash, &pin_auth) { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID); + } + UV_FLAG + } + None => { + if options.uv { + // The specification (inconsistently) wants CTAP2_ERR_UNSUPPORTED_OPTION. + return Err(Ctap2StatusCode::CTAP2_ERR_INVALID_OPTION); + } + 0x00 + } + }; + if options.up { + flags |= UP_FLAG; + } + + let rp_id_hash = Sha256::hash(rp_id.as_bytes()); + let mut decrypted_credential = None; + let credentials = if let Some(allow_list) = allow_list { + let mut found_credentials = vec![]; + for allowed_credential in allow_list { + match self + .persistent_store + .find_credential(&rp_id, &allowed_credential.key_id) + { + Some(credential) => found_credentials.push(credential), + None => { + if decrypted_credential.is_none() { + decrypted_credential = self + .decrypt_credential_source(allowed_credential.key_id, &rp_id_hash); + } + } + } + } + found_credentials + } else { + // TODO(kaczmarczyck) use GetNextAssertion + self.persistent_store.filter_credential(&rp_id) + }; + + let credential = if let Some(credential) = credentials.first() { + credential + } else { + decrypted_credential + .as_ref() + .ok_or(Ctap2StatusCode::CTAP2_ERR_NO_CREDENTIALS)? + }; + + if options.up { + (self.check_user_presence)(cid)?; + } + + self.increment_global_signature_counter(); + + let auth_data = self.generate_auth_data(&rp_id_hash, flags); + let mut signature_data = auth_data.clone(); + signature_data.extend(client_data_hash); + let signature = credential + .private_key + .sign_rfc6979::(&signature_data); + + let cred_desc = PublicKeyCredentialDescriptor { + key_type: PublicKeyCredentialType::PublicKey, + key_id: credential.credential_id.clone(), + transports: None, // You can set USB as a hint here. + }; + let user = if flags & UV_FLAG != 0 { + Some(PublicKeyCredentialUserEntity { + user_id: credential.user_handle.clone(), + user_name: None, + user_display_name: credential.other_ui.clone(), + user_icon: None, + }) + } else { + None + }; + Ok(ResponseData::AuthenticatorGetAssertion( + AuthenticatorGetAssertionResponse { + credential: Some(cred_desc), + auth_data, + signature: signature.to_asn1_der(), + user, + number_of_credentials: None, + }, + )) + } + + fn process_get_info(&self) -> Result { + let mut options_map = BTreeMap::new(); + // TODO(kaczmarczyck) add FIDO 2.1 options + options_map.insert(String::from("rk"), true); + options_map.insert(String::from("up"), true); + options_map.insert( + String::from("clientPin"), + self.persistent_store.pin_hash().is_some(), + ); + Ok(ResponseData::AuthenticatorGetInfo( + AuthenticatorGetInfoResponse { + versions: vec![ + #[cfg(feature = "with_ctap1")] + String::from(U2F_VERSION_STRING), + String::from(FIDO2_VERSION_STRING), + ], + extensions: Some(vec![]), + aaguid: AAGUID, + options: Some(options_map), + max_msg_size: Some(1024), + pin_protocols: Some(vec![ + CtapState::::PIN_PROTOCOL_VERSION, + ]), + }, + )) + } + + fn check_and_store_new_pin( + &mut self, + aes_dec_key: &crypto::aes256::DecryptionKey, + new_pin_enc: Vec, + ) -> bool { + if new_pin_enc.len() != PIN_PADDED_LENGTH { + return false; + } + let iv = [0; 16]; + // Assuming PIN_PADDED_LENGTH % block_size == 0 here. + let mut blocks = [[0u8; 16]; PIN_PADDED_LENGTH / 16]; + for i in 0..PIN_PADDED_LENGTH / 16 { + blocks[i].copy_from_slice(&new_pin_enc[i * 16..(i + 1) * 16]); + } + cbc_decrypt(aes_dec_key, iv, &mut blocks); + let mut pin = vec![]; + 'pin_block_loop: for block in blocks.iter().take(PIN_PADDED_LENGTH / 16) { + for cur_char in block.iter() { + if *cur_char != 0 { + pin.push(*cur_char); + } else { + break 'pin_block_loop; + } + } + } + if pin.len() < 4 || pin.len() == PIN_PADDED_LENGTH { + return false; + } + let mut pin_hash = [0; 16]; + pin_hash.copy_from_slice(&Sha256::hash(&pin[..])[..16]); + self.persistent_store.set_pin_hash(&pin_hash); + true + } + + fn check_pin_hash_enc( + &mut self, + aes_dec_key: &crypto::aes256::DecryptionKey, + pin_hash_enc: Vec, + ) -> Result<(), Ctap2StatusCode> { + match self.persistent_store.pin_hash() { + Some(pin_hash) => { + if self.consecutive_pin_mismatches >= 3 { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_BLOCKED); + } + // We need to copy the pin hash, because decrementing the pin retries below may + // invalidate the reference (if the page containing the pin hash is compacted). + let pin_hash = pin_hash.to_vec(); + self.persistent_store.decr_pin_retries(); + if pin_hash_enc.len() != PIN_AUTH_LENGTH { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_INVALID); + } + + let iv = [0; 16]; + let mut blocks = [[0u8; 16]; 1]; + blocks[0].copy_from_slice(&pin_hash_enc[0..PIN_AUTH_LENGTH]); + cbc_decrypt(aes_dec_key, iv, &mut blocks); + + let pin_comparison = array_ref![pin_hash, 0, PIN_AUTH_LENGTH].ct_eq(&blocks[0]); + if !bool::from(pin_comparison) { + self.key_agreement_key = crypto::ecdh::SecKey::gensk(self.rng); + if self.persistent_store.pin_retries() == 0 { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_BLOCKED); + } + self.consecutive_pin_mismatches += 1; + if self.consecutive_pin_mismatches >= 3 { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_BLOCKED); + } + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_INVALID); + } + } + // This status code is not explicitly mentioned in the specification. + None => return Err(Ctap2StatusCode::CTAP2_ERR_PIN_REQUIRED), + } + self.persistent_store.reset_pin_retries(); + self.consecutive_pin_mismatches = 0; + Ok(()) + } + + fn process_get_pin_retries(&self) -> Result { + Ok(AuthenticatorClientPinResponse { + key_agreement: None, + pin_token: None, + retries: Some(self.persistent_store.pin_retries() as u64), + }) + } + + fn process_get_key_agreement(&self) -> Result { + let pk = self.key_agreement_key.genpk(); + Ok(AuthenticatorClientPinResponse { + key_agreement: Some(CoseKey::from(pk)), + pin_token: None, + retries: None, + }) + } + + fn process_set_pin( + &mut self, + key_agreement: CoseKey, + pin_auth: Vec, + new_pin_enc: Vec, + ) -> Result<(), Ctap2StatusCode> { + if self.persistent_store.pin_hash().is_some() { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID); + } + let pk: crypto::ecdh::PubKey = CoseKey::try_into(key_agreement)?; + let shared_secret = self.key_agreement_key.exchange_x_sha256(&pk); + + if !check_pin_auth(&shared_secret, &new_pin_enc, &pin_auth) { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID); + } + + let aes_enc_key = crypto::aes256::EncryptionKey::new(&shared_secret); + let aes_dec_key = crypto::aes256::DecryptionKey::new(&aes_enc_key); + if !self.check_and_store_new_pin(&aes_dec_key, new_pin_enc) { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_POLICY_VIOLATION); + } + self.persistent_store.reset_pin_retries(); + Ok(()) + } + + fn process_change_pin( + &mut self, + key_agreement: CoseKey, + pin_auth: Vec, + new_pin_enc: Vec, + pin_hash_enc: Vec, + ) -> Result<(), Ctap2StatusCode> { + if self.persistent_store.pin_retries() == 0 { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_BLOCKED); + } + let pk: crypto::ecdh::PubKey = CoseKey::try_into(key_agreement)?; + let shared_secret = self.key_agreement_key.exchange_x_sha256(&pk); + + let mut auth_param_data = new_pin_enc.clone(); + auth_param_data.extend(&pin_hash_enc); + if !check_pin_auth(&shared_secret, &auth_param_data, &pin_auth) { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID); + } + + let aes_enc_key = crypto::aes256::EncryptionKey::new(&shared_secret); + let aes_dec_key = crypto::aes256::DecryptionKey::new(&aes_enc_key); + self.check_pin_hash_enc(&aes_dec_key, pin_hash_enc)?; + + if !self.check_and_store_new_pin(&aes_dec_key, new_pin_enc) { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_POLICY_VIOLATION); + } + self.pin_uv_auth_token = self.rng.gen_uniform_u8x32(); + Ok(()) + } + + fn process_get_pin_uv_auth_token_using_pin( + &mut self, + key_agreement: CoseKey, + pin_hash_enc: Vec, + ) -> Result { + if self.persistent_store.pin_retries() == 0 { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_BLOCKED); + } + let pk: crypto::ecdh::PubKey = CoseKey::try_into(key_agreement)?; + let shared_secret = self.key_agreement_key.exchange_x_sha256(&pk); + + let aes_enc_key = crypto::aes256::EncryptionKey::new(&shared_secret); + let aes_dec_key = crypto::aes256::DecryptionKey::new(&aes_enc_key); + self.check_pin_hash_enc(&aes_dec_key, pin_hash_enc)?; + + // Assuming PIN_TOKEN_LENGTH % block_size == 0 here. + let iv = [0; 16]; + let mut blocks = [[0u8; 16]; PIN_TOKEN_LENGTH / 16]; + for (i, item) in blocks.iter_mut().take(PIN_TOKEN_LENGTH / 16).enumerate() { + item.copy_from_slice(&self.pin_uv_auth_token[i * 16..(i + 1) * 16]); + } + cbc_encrypt(&aes_enc_key, iv, &mut blocks); + let mut pin_token = vec![]; + for item in blocks.iter().take(PIN_TOKEN_LENGTH / 16) { + pin_token.extend(item); + } + + Ok(AuthenticatorClientPinResponse { + key_agreement: None, + pin_token: Some(pin_token), + retries: None, + }) + } + + fn process_get_pin_uv_auth_token_using_uv( + &self, + _: CoseKey, + ) -> Result { + Ok(AuthenticatorClientPinResponse { + // User verifications is only supported through PIN currently. + key_agreement: None, + pin_token: Some(vec![]), + retries: None, + }) + } + + fn process_get_uv_retries(&self) -> Result { + // User verifications is only supported through PIN currently. + Ok(AuthenticatorClientPinResponse { + key_agreement: None, + pin_token: None, + retries: Some(0), + }) + } + + fn process_client_pin( + &mut self, + client_pin_params: AuthenticatorClientPinParameters, + ) -> Result { + let AuthenticatorClientPinParameters { + pin_protocol, + sub_command, + key_agreement, + pin_auth, + new_pin_enc, + pin_hash_enc, + } = client_pin_params; + + if pin_protocol != 1 { + return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID); + } + + let response = match sub_command { + ClientPinSubCommand::GetPinRetries => Some(self.process_get_pin_retries()?), + ClientPinSubCommand::GetKeyAgreement => Some(self.process_get_key_agreement()?), + ClientPinSubCommand::SetPin => { + self.process_set_pin( + key_agreement.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?, + pin_auth.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?, + new_pin_enc.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?, + )?; + None + } + ClientPinSubCommand::ChangePin => { + self.process_change_pin( + key_agreement.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?, + pin_auth.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?, + new_pin_enc.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?, + pin_hash_enc.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?, + )?; + None + } + ClientPinSubCommand::GetPinUvAuthTokenUsingPin => { + Some(self.process_get_pin_uv_auth_token_using_pin( + key_agreement.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?, + pin_hash_enc.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?, + )?) + } + ClientPinSubCommand::GetPinUvAuthTokenUsingUv => { + Some(self.process_get_pin_uv_auth_token_using_uv( + key_agreement.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?, + )?) + } + ClientPinSubCommand::GetUvRetries => Some(self.process_get_uv_retries()?), + }; + Ok(ResponseData::AuthenticatorClientPin(response)) + } + + fn process_reset(&mut self, cid: ChannelID) -> Result { + // Resets are only possible in the first 10 seconds after booting. + if !self.accepts_reset { + return Err(Ctap2StatusCode::CTAP2_ERR_NOT_ALLOWED); + } + (self.check_user_presence)(cid)?; + + self.persistent_store.reset(self.rng); + self.key_agreement_key = crypto::ecdh::SecKey::gensk(self.rng); + self.pin_uv_auth_token = self.rng.gen_uniform_u8x32(); + self.consecutive_pin_mismatches = 0; + #[cfg(feature = "with_ctap1")] + { + self.u2f_up_state = U2fUserPresenceState::new( + U2F_UP_PROMPT_TIMEOUT, + Duration::from_ms(TOUCH_TIMEOUT_MS), + ); + } + Ok(ResponseData::AuthenticatorReset) + } + + pub fn generate_auth_data(&self, rp_id_hash: &[u8], flag_byte: u8) -> Vec { + let mut auth_data = vec![]; + auth_data.extend(rp_id_hash); + auth_data.push(flag_byte); + // The global counter is only increased if USE_SIGNATURE_COUNTER is true. + // It uses a big-endian representation. + let mut signature_counter = [0u8; 4]; + BigEndian::write_u32( + &mut signature_counter, + self.persistent_store.global_signature_counter(), + ); + auth_data.extend(&signature_counter); + auth_data + } +} + +#[cfg(test)] +mod test { + use super::data_formats::{ + GetAssertionOptions, MakeCredentialOptions, PublicKeyCredentialRpEntity, + PublicKeyCredentialUserEntity, + }; + use super::*; + use crypto::rng256::ThreadRng256; + + // The keep-alive logic in the processing of some commands needs a channel ID to send + // keep-alive packets to. + // In tests where we define a dummy user-presence check that immediately returns, the channel + // ID is irrelevant, so we pass this (dummy but valid) value. + const DUMMY_CHANNEL_ID: ChannelID = [0x12, 0x34, 0x56, 0x78]; + + #[test] + fn test_get_info() { + let mut rng = ThreadRng256 {}; + let user_immediately_present = |_| Ok(()); + let mut ctap_state = CtapState::new(&mut rng, user_immediately_present); + let info_reponse = ctap_state.process_command(&[0x04], DUMMY_CHANNEL_ID); + + let mut expected_response = vec![0x00, 0xA6, 0x01]; + // The difference here is a longer array of supported versions. + #[cfg(not(feature = "with_ctap1"))] + expected_response.extend(&[ + 0x81, 0x68, 0x46, 0x49, 0x44, 0x4F, 0x5F, 0x32, 0x5F, 0x30, 0x02, 0x80, 0x03, 0x50, + ]); + #[cfg(feature = "with_ctap1")] + expected_response.extend(&[ + 0x82, 0x66, 0x55, 0x32, 0x46, 0x5F, 0x56, 0x32, 0x68, 0x46, 0x49, 0x44, 0x4F, 0x5F, + 0x32, 0x5F, 0x30, 0x02, 0x80, 0x03, 0x50, + ]); + expected_response.extend(&AAGUID); + expected_response.extend(&[ + 0x04, 0xA3, 0x62, 0x72, 0x6B, 0xF5, 0x62, 0x75, 0x70, 0xF5, 0x69, 0x63, 0x6C, 0x69, + 0x65, 0x6E, 0x74, 0x50, 0x69, 0x6E, 0xF4, 0x05, 0x19, 0x04, 0x00, 0x06, 0x81, 0x01, + ]); + + assert_eq!(info_reponse, expected_response); + } + + fn create_minimal_make_credential_parameters() -> AuthenticatorMakeCredentialParameters { + let client_data_hash = vec![0xCD]; + let rp = PublicKeyCredentialRpEntity { + rp_id: String::from("example.com"), + rp_name: None, + rp_icon: None, + }; + let user = PublicKeyCredentialUserEntity { + user_id: vec![0xFA, 0xB1, 0xA2], + user_name: None, + user_display_name: None, + user_icon: None, + }; + let pub_key_cred_params = vec![( + PublicKeyCredentialType::PublicKey, + SignatureAlgorithm::ES256 as i64, + )]; + let options = MakeCredentialOptions { + rk: true, + uv: false, + }; + AuthenticatorMakeCredentialParameters { + client_data_hash, + rp, + user, + pub_key_cred_params, + exclude_list: None, + extensions: None, + options, + pin_uv_auth_param: None, + pin_uv_auth_protocol: None, + } + } + + #[test] + fn test_residential_process_make_credential() { + let mut rng = ThreadRng256 {}; + let user_immediately_present = |_| Ok(()); + let mut ctap_state = CtapState::new(&mut rng, user_immediately_present); + + let make_credential_params = create_minimal_make_credential_parameters(); + let make_credential_response = + ctap_state.process_make_credential(make_credential_params, DUMMY_CHANNEL_ID); + + match make_credential_response.unwrap() { + ResponseData::AuthenticatorMakeCredential(make_credential_response) => { + let AuthenticatorMakeCredentialResponse { + fmt, + auth_data, + att_stmt, + } = make_credential_response; + // The expected response is split to only assert the non-random parts. + assert_eq!(fmt, "packed"); + let mut expected_auth_data = vec![ + 0xA3, 0x79, 0xA6, 0xF6, 0xEE, 0xAF, 0xB9, 0xA5, 0x5E, 0x37, 0x8C, 0x11, 0x80, + 0x34, 0xE2, 0x75, 0x1E, 0x68, 0x2F, 0xAB, 0x9F, 0x2D, 0x30, 0xAB, 0x13, 0xD2, + 0x12, 0x55, 0x86, 0xCE, 0x19, 0x47, 0x41, 0x00, 0x00, 0x00, 0x00, + ]; + expected_auth_data.extend(&AAGUID); + expected_auth_data.extend(&[0x00, 0x20]); + assert_eq!( + auth_data[0..expected_auth_data.len()], + expected_auth_data[..] + ); + assert_eq!(att_stmt.alg, SignatureAlgorithm::ES256 as i64); + } + _ => panic!("Invalid response type"), + } + } + + #[test] + fn test_non_residential_process_make_credential() { + let mut rng = ThreadRng256 {}; + let user_immediately_present = |_| Ok(()); + let mut ctap_state = CtapState::new(&mut rng, user_immediately_present); + + let mut make_credential_params = create_minimal_make_credential_parameters(); + make_credential_params.options.rk = false; + let make_credential_response = + ctap_state.process_make_credential(make_credential_params, DUMMY_CHANNEL_ID); + + match make_credential_response.unwrap() { + ResponseData::AuthenticatorMakeCredential(make_credential_response) => { + let AuthenticatorMakeCredentialResponse { + fmt, + auth_data, + att_stmt, + } = make_credential_response; + // The expected response is split to only assert the non-random parts. + assert_eq!(fmt, "packed"); + let mut expected_auth_data = vec![ + 0xA3, 0x79, 0xA6, 0xF6, 0xEE, 0xAF, 0xB9, 0xA5, 0x5E, 0x37, 0x8C, 0x11, 0x80, + 0x34, 0xE2, 0x75, 0x1E, 0x68, 0x2F, 0xAB, 0x9F, 0x2D, 0x30, 0xAB, 0x13, 0xD2, + 0x12, 0x55, 0x86, 0xCE, 0x19, 0x47, 0x41, 0x00, 0x00, 0x00, 0x00, + ]; + expected_auth_data.extend(&AAGUID); + expected_auth_data.extend(&[0x00, ENCRYPTED_CREDENTIAL_ID_SIZE as u8]); + assert_eq!( + auth_data[0..expected_auth_data.len()], + expected_auth_data[..] + ); + assert_eq!(att_stmt.alg, SignatureAlgorithm::ES256 as i64); + } + _ => panic!("Invalid response type"), + } + } + + #[test] + fn test_process_make_credential_unsupported_algorithm() { + let mut rng = ThreadRng256 {}; + let user_immediately_present = |_| Ok(()); + let mut ctap_state = CtapState::new(&mut rng, user_immediately_present); + + let pub_key_cred_params = vec![( + PublicKeyCredentialType::PublicKey, + SignatureAlgorithm::ES256 as i64 + 1, // any different number works + )]; + let mut make_credential_params = create_minimal_make_credential_parameters(); + make_credential_params.pub_key_cred_params = pub_key_cred_params; + let make_credential_response = + ctap_state.process_make_credential(make_credential_params, DUMMY_CHANNEL_ID); + + assert_eq!( + make_credential_response, + Err(Ctap2StatusCode::CTAP2_ERR_UNSUPPORTED_ALGORITHM) + ); + } + + #[test] + fn test_process_make_credential_credential_excluded() { + let mut rng = ThreadRng256 {}; + let excluded_private_key = crypto::ecdsa::SecKey::gensk(&mut rng); + let user_immediately_present = |_| Ok(()); + let mut ctap_state = CtapState::new(&mut rng, user_immediately_present); + + let excluded_credential_id = vec![0x01, 0x23, 0x45, 0x67]; + let excluded_credential_source = PublicKeyCredentialSource { + key_type: PublicKeyCredentialType::PublicKey, + credential_id: excluded_credential_id.clone(), + private_key: excluded_private_key, + rp_id: String::from("example.com"), + user_handle: vec![], + other_ui: None, + }; + assert!(ctap_state + .persistent_store + .store_credential(excluded_credential_source) + .is_ok()); + + let excluded_credential_descriptor = PublicKeyCredentialDescriptor { + key_type: PublicKeyCredentialType::PublicKey, + key_id: excluded_credential_id, + transports: None, + }; + let exclude_list = Some(vec![excluded_credential_descriptor]); + let mut make_credential_params = create_minimal_make_credential_parameters(); + make_credential_params.exclude_list = exclude_list; + let make_credential_response = + ctap_state.process_make_credential(make_credential_params, DUMMY_CHANNEL_ID); + + assert_eq!( + make_credential_response, + Err(Ctap2StatusCode::CTAP2_ERR_CREDENTIAL_EXCLUDED) + ); + } + + #[test] + fn test_process_make_credential_cancelled() { + let mut rng = ThreadRng256 {}; + let user_presence_always_cancel = |_| Err(Ctap2StatusCode::CTAP2_ERR_KEEPALIVE_CANCEL); + let mut ctap_state = CtapState::new(&mut rng, user_presence_always_cancel); + + let make_credential_params = create_minimal_make_credential_parameters(); + let make_credential_response = + ctap_state.process_make_credential(make_credential_params, DUMMY_CHANNEL_ID); + + assert_eq!( + make_credential_response, + Err(Ctap2StatusCode::CTAP2_ERR_KEEPALIVE_CANCEL) + ); + } + + #[test] + fn test_residential_process_get_assertion() { + let mut rng = ThreadRng256 {}; + let user_immediately_present = |_| Ok(()); + let mut ctap_state = CtapState::new(&mut rng, user_immediately_present); + + let make_credential_params = create_minimal_make_credential_parameters(); + assert!(ctap_state + .process_make_credential(make_credential_params, DUMMY_CHANNEL_ID) + .is_ok()); + + let get_assertion_params = AuthenticatorGetAssertionParameters { + rp_id: String::from("example.com"), + client_data_hash: vec![0xCD], + allow_list: None, + extensions: None, + options: GetAssertionOptions { + up: false, + uv: false, + }, + pin_uv_auth_param: None, + pin_uv_auth_protocol: None, + }; + let get_assertion_response = + ctap_state.process_get_assertion(get_assertion_params, DUMMY_CHANNEL_ID); + + match get_assertion_response.unwrap() { + ResponseData::AuthenticatorGetAssertion(get_assertion_response) => { + let AuthenticatorGetAssertionResponse { + auth_data, + user, + number_of_credentials, + .. + } = get_assertion_response; + let expected_auth_data = vec![ + 0xA3, 0x79, 0xA6, 0xF6, 0xEE, 0xAF, 0xB9, 0xA5, 0x5E, 0x37, 0x8C, 0x11, 0x80, + 0x34, 0xE2, 0x75, 0x1E, 0x68, 0x2F, 0xAB, 0x9F, 0x2D, 0x30, 0xAB, 0x13, 0xD2, + 0x12, 0x55, 0x86, 0xCE, 0x19, 0x47, 0x00, 0x00, 0x00, 0x00, 0x01, + ]; + assert_eq!(auth_data, expected_auth_data); + assert!(user.is_none()); + assert!(number_of_credentials.is_none()); + } + _ => panic!("Invalid response type"), + } + } + + #[test] + fn test_process_reset() { + let mut rng = ThreadRng256 {}; + let user_immediately_present = |_| Ok(()); + let private_key = crypto::ecdsa::SecKey::gensk(&mut rng); + let mut ctap_state = CtapState::new(&mut rng, user_immediately_present); + + let credential_id = vec![0x01, 0x23, 0x45, 0x67]; + let credential_source = PublicKeyCredentialSource { + key_type: PublicKeyCredentialType::PublicKey, + credential_id, + private_key, + rp_id: String::from("example.com"), + user_handle: vec![], + other_ui: None, + }; + assert!(ctap_state + .persistent_store + .store_credential(credential_source) + .is_ok()); + assert!(ctap_state.persistent_store.count_credentials() > 0); + + let reset_reponse = ctap_state.process_command(&[0x07], DUMMY_CHANNEL_ID); + let expected_response = vec![0x00]; + assert_eq!(reset_reponse, expected_response); + assert!(ctap_state.persistent_store.count_credentials() == 0); + } + + #[test] + fn test_process_reset_cancelled() { + let mut rng = ThreadRng256 {}; + let user_presence_always_cancel = |_| Err(Ctap2StatusCode::CTAP2_ERR_KEEPALIVE_CANCEL); + let mut ctap_state = CtapState::new(&mut rng, user_presence_always_cancel); + + let reset_reponse = ctap_state.process_reset(DUMMY_CHANNEL_ID); + + assert_eq!( + reset_reponse, + Err(Ctap2StatusCode::CTAP2_ERR_KEEPALIVE_CANCEL) + ); + } + + #[test] + fn test_encrypt_decrypt_credential() { + let mut rng = ThreadRng256 {}; + let user_immediately_present = |_| Ok(()); + let private_key = crypto::ecdsa::SecKey::gensk(&mut rng); + let mut ctap_state = CtapState::new(&mut rng, user_immediately_present); + + // Usually, the relying party ID or its hash is provided by the client. + // We are not testing the correctness of our SHA256 here, only if it is checked. + let rp_id_hash = [0x55; 32]; + let encrypted_id = ctap_state.encrypt_key_handle(private_key.clone(), &rp_id_hash); + let decrypted_source = ctap_state + .decrypt_credential_source(encrypted_id, &rp_id_hash) + .unwrap(); + + assert_eq!(private_key, decrypted_source.private_key); + } + + #[test] + fn test_encrypt_decrypt_bad_hmac() { + let mut rng = ThreadRng256 {}; + let user_immediately_present = |_| Ok(()); + let private_key = crypto::ecdsa::SecKey::gensk(&mut rng); + let mut ctap_state = CtapState::new(&mut rng, user_immediately_present); + + // Same as above. + let rp_id_hash = [0x55; 32]; + let encrypted_id = ctap_state.encrypt_key_handle(private_key, &rp_id_hash); + for i in 0..encrypted_id.len() { + let mut modified_id = encrypted_id.clone(); + modified_id[i] ^= 0x01; + assert!(ctap_state + .decrypt_credential_source(modified_id, &rp_id_hash) + .is_none()); + } + } +} diff --git a/src/ctap/response.rs b/src/ctap/response.rs new file mode 100644 index 0000000..4b8a089 --- /dev/null +++ b/src/ctap/response.rs @@ -0,0 +1,267 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::data_formats::{ + CoseKey, PackedAttestationStatement, PublicKeyCredentialDescriptor, + PublicKeyCredentialUserEntity, +}; +use alloc::collections::BTreeMap; +use alloc::string::String; +use alloc::vec::Vec; + +#[cfg_attr(test, derive(PartialEq))] +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug))] +pub enum ResponseData { + AuthenticatorMakeCredential(AuthenticatorMakeCredentialResponse), + AuthenticatorGetAssertion(AuthenticatorGetAssertionResponse), + AuthenticatorGetNextAssertion(AuthenticatorGetAssertionResponse), + AuthenticatorGetInfo(AuthenticatorGetInfoResponse), + AuthenticatorClientPin(Option), + AuthenticatorReset, +} + +impl From for Option { + fn from(response: ResponseData) -> Self { + match response { + ResponseData::AuthenticatorMakeCredential(data) => Some(data.into()), + ResponseData::AuthenticatorGetAssertion(data) => Some(data.into()), + ResponseData::AuthenticatorGetNextAssertion(data) => Some(data.into()), + ResponseData::AuthenticatorGetInfo(data) => Some(data.into()), + ResponseData::AuthenticatorClientPin(Some(data)) => Some(data.into()), + ResponseData::AuthenticatorClientPin(None) => None, + ResponseData::AuthenticatorReset => None, + } + } +} + +#[cfg_attr(test, derive(PartialEq))] +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug))] +pub struct AuthenticatorMakeCredentialResponse { + pub fmt: String, + pub auth_data: Vec, + pub att_stmt: PackedAttestationStatement, +} + +impl From for cbor::Value { + fn from(make_credential_response: AuthenticatorMakeCredentialResponse) -> Self { + let AuthenticatorMakeCredentialResponse { + fmt, + auth_data, + att_stmt, + } = make_credential_response; + + cbor_map_options! { + 1 => fmt, + 2 => auth_data, + 3 => att_stmt, + } + } +} + +#[cfg_attr(test, derive(PartialEq))] +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug))] +pub struct AuthenticatorGetAssertionResponse { + pub credential: Option, + pub auth_data: Vec, + pub signature: Vec, + pub user: Option, + pub number_of_credentials: Option, +} + +impl From for cbor::Value { + fn from(get_assertion_response: AuthenticatorGetAssertionResponse) -> Self { + let AuthenticatorGetAssertionResponse { + credential, + auth_data, + signature, + user, + number_of_credentials, + } = get_assertion_response; + + cbor_map_options! { + 1 => credential, + 2 => auth_data, + 3 => signature, + 4 => user, + 5 => number_of_credentials, + } + } +} + +#[cfg_attr(test, derive(PartialEq))] +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug))] +pub struct AuthenticatorGetInfoResponse { + // TODO(kaczmarczyck) add fields from 2.1 + pub versions: Vec, + pub extensions: Option>, + pub aaguid: [u8; 16], + pub options: Option>, + pub max_msg_size: Option, + pub pin_protocols: Option>, +} + +impl From for cbor::Value { + fn from(get_info_response: AuthenticatorGetInfoResponse) -> Self { + let AuthenticatorGetInfoResponse { + versions, + extensions, + aaguid, + options, + max_msg_size, + pin_protocols, + } = get_info_response; + + let options_cbor: Option = options.map(|options| { + let option_map: BTreeMap<_, _> = options + .into_iter() + .map(|(key, value)| (cbor_text!(key), cbor_bool!(value))) + .collect(); + cbor_map_btree!(option_map) + }); + + cbor_map_options! { + 1 => cbor_array_vec!(versions), + 2 => extensions.map(|vec| cbor_array_vec!(vec)), + 3 => &aaguid, + 4 => options_cbor, + 5 => max_msg_size, + 6 => pin_protocols.map(|vec| cbor_array_vec!(vec)), + } + } +} + +#[cfg_attr(test, derive(PartialEq))] +#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug))] +pub struct AuthenticatorClientPinResponse { + pub key_agreement: Option, + pub pin_token: Option>, + pub retries: Option, +} + +impl From for cbor::Value { + fn from(client_pin_response: AuthenticatorClientPinResponse) -> Self { + let AuthenticatorClientPinResponse { + key_agreement, + pin_token, + retries, + } = client_pin_response; + + cbor_map_options! { + 1 => key_agreement.map(|cose_key| cbor_map_btree!(cose_key.0)), + 2 => pin_token, + 3 => retries, + } + } +} + +#[cfg(test)] +mod test { + use super::super::data_formats::PackedAttestationStatement; + use super::*; + + #[test] + fn test_make_credential_into_cbor() { + let certificate: cbor::values::KeyType = cbor_bytes![vec![0x5C, 0x5C, 0x5C, 0x5C]]; + let att_stmt = PackedAttestationStatement { + alg: 1, + sig: vec![0x55, 0x55, 0x55, 0x55], + x5c: Some(vec![vec![0x5C, 0x5C, 0x5C, 0x5C]]), + ecdaa_key_id: Some(vec![0xEC, 0xDA, 0x1D]), + }; + let cbor_packed_attestation_statement = cbor_map! { + "alg" => 1, + "sig" => vec![0x55, 0x55, 0x55, 0x55], + "x5c" => cbor_array_vec![vec![certificate]], + "ecdaaKeyId" => vec![0xEC, 0xDA, 0x1D], + }; + + let make_credential_response = AuthenticatorMakeCredentialResponse { + fmt: "packed".to_string(), + auth_data: vec![0xAD], + att_stmt, + }; + let response_cbor: Option = + ResponseData::AuthenticatorMakeCredential(make_credential_response).into(); + let expected_cbor = cbor_map_options! { + 1 => "packed", + 2 => vec![0xAD], + 3 => cbor_packed_attestation_statement, + }; + assert_eq!(response_cbor, Some(expected_cbor)); + } + + #[test] + fn test_get_assertion_into_cbor() { + let get_assertion_response = AuthenticatorGetAssertionResponse { + credential: None, + auth_data: vec![0xAD], + signature: vec![0x51], + user: None, + number_of_credentials: None, + }; + let response_cbor: Option = + ResponseData::AuthenticatorGetAssertion(get_assertion_response).into(); + let expected_cbor = cbor_map_options! { + 2 => vec![0xAD], + 3 => vec![0x51], + }; + assert_eq!(response_cbor, Some(expected_cbor)); + } + + #[test] + fn test_get_info_into_cbor() { + let get_info_response = AuthenticatorGetInfoResponse { + versions: vec!["FIDO_2_0".to_string()], + extensions: None, + aaguid: [0x00; 16], + options: None, + max_msg_size: None, + pin_protocols: None, + }; + let response_cbor: Option = + ResponseData::AuthenticatorGetInfo(get_info_response).into(); + let expected_cbor = cbor_map_options! { + 1 => cbor_array_vec![vec!["FIDO_2_0"]], + 3 => vec![0x00; 16], + }; + assert_eq!(response_cbor, Some(expected_cbor)); + } + + #[test] + fn test_used_client_pin_into_cbor() { + let client_pin_response = AuthenticatorClientPinResponse { + key_agreement: None, + pin_token: Some(vec![70]), + retries: None, + }; + let response_cbor: Option = + ResponseData::AuthenticatorClientPin(Some(client_pin_response)).into(); + let expected_cbor = cbor_map_options! { + 2 => vec![70], + }; + assert_eq!(response_cbor, Some(expected_cbor)); + } + + #[test] + fn test_empty_client_pin_into_cbor() { + let response_cbor: Option = ResponseData::AuthenticatorClientPin(None).into(); + assert_eq!(response_cbor, None); + } + + #[test] + fn test_reset_into_cbor() { + let response_cbor: Option = ResponseData::AuthenticatorReset.into(); + assert_eq!(response_cbor, None); + } +} diff --git a/src/ctap/status_code.rs b/src/ctap/status_code.rs new file mode 100644 index 0000000..1e0c2bf --- /dev/null +++ b/src/ctap/status_code.rs @@ -0,0 +1,71 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// CTAP specification (version 20190130) section 6.3 +// For now, only the CTAP2 codes are here, the CTAP1 are not included. +#[allow(non_camel_case_types)] +#[allow(dead_code)] +#[derive(Debug, PartialEq)] +pub enum Ctap2StatusCode { + CTAP2_OK = 0x00, + CTAP1_ERR_INVALID_COMMAND = 0x01, + CTAP1_ERR_INVALID_PARAMETER = 0x02, + CTAP1_ERR_INVALID_LENGTH = 0x03, + CTAP1_ERR_INVALID_SEQ = 0x04, + CTAP1_ERR_TIMEOUT = 0x05, + CTAP1_ERR_CHANNEL_BUSY = 0x06, + CTAP1_ERR_LOCK_REQUIRED = 0x0A, + CTAP1_ERR_INVALID_CHANNEL = 0x0B, + CTAP2_ERR_CBOR_UNEXPECTED_TYPE = 0x11, + CTAP2_ERR_INVALID_CBOR = 0x12, + CTAP2_ERR_MISSING_PARAMETER = 0x14, + CTAP2_ERR_LIMIT_EXCEEDED = 0x15, + CTAP2_ERR_UNSUPPORTED_EXTENSION = 0x16, + CTAP2_ERR_CREDENTIAL_EXCLUDED = 0x19, + CTAP2_ERR_PROCESSING = 0x21, + CTAP2_ERR_INVALID_CREDENTIAL = 0x22, + CTAP2_ERR_USER_ACTION_PENDING = 0x23, + CTAP2_ERR_OPERATION_PENDING = 0x24, + CTAP2_ERR_NO_OPERATIONS = 0x25, + CTAP2_ERR_UNSUPPORTED_ALGORITHM = 0x26, + CTAP2_ERR_OPERATION_DENIED = 0x27, + CTAP2_ERR_KEY_STORE_FULL = 0x28, + CTAP2_ERR_NO_OPERATION_PENDING = 0x2A, + CTAP2_ERR_UNSUPPORTED_OPTION = 0x2B, + CTAP2_ERR_INVALID_OPTION = 0x2C, + CTAP2_ERR_KEEPALIVE_CANCEL = 0x2D, + CTAP2_ERR_NO_CREDENTIALS = 0x2E, + CTAP2_ERR_USER_ACTION_TIMEOUT = 0x2F, + CTAP2_ERR_NOT_ALLOWED = 0x30, + CTAP2_ERR_PIN_INVALID = 0x31, + CTAP2_ERR_PIN_BLOCKED = 0x32, + CTAP2_ERR_PIN_AUTH_INVALID = 0x33, + CTAP2_ERR_PIN_AUTH_BLOCKED = 0x34, + CTAP2_ERR_PIN_NOT_SET = 0x35, + CTAP2_ERR_PIN_REQUIRED = 0x36, + CTAP2_ERR_PIN_POLICY_VIOLATION = 0x37, + CTAP2_ERR_PIN_TOKEN_EXPIRED = 0x38, + CTAP2_ERR_REQUEST_TOO_LARGE = 0x39, + CTAP2_ERR_ACTION_TIMEOUT = 0x3A, + CTAP2_ERR_UP_REQUIRED = 0x3B, + CTAP2_ERR_UV_BLOCKED = 0x3C, + CTAP1_ERR_OTHER = 0x7F, + CTAP2_ERR_SPEC_LAST = 0xDF, + CTAP2_ERR_EXTENSION_FIRST = 0xE0, + CTAP2_ERR_EXTENSION_LAST = 0xEF, + // CTAP2_ERR_VENDOR_FIRST = 0xF0, + CTAP2_ERR_VENDOR_RESPONSE_TOO_LONG = 0xF0, + CTAP2_ERR_VENDOR_RESPONSE_CANNOT_WRITE_CBOR = 0xF1, + CTAP2_ERR_VENDOR_LAST = 0xFF, +} diff --git a/src/ctap/storage.rs b/src/ctap/storage.rs new file mode 100644 index 0000000..e693a13 --- /dev/null +++ b/src/ctap/storage.rs @@ -0,0 +1,682 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::crypto::rng256::Rng256; +use crate::ctap::data_formats::PublicKeyCredentialSource; +use crate::ctap::status_code::Ctap2StatusCode; +use crate::ctap::PIN_AUTH_LENGTH; +use alloc::string::String; +use alloc::vec::Vec; +use core::convert::TryInto; +use ctap2::embedded_flash::{self, StoreConfig, StoreEntry, StoreError, StoreIndex}; + +#[cfg(test)] +type Storage = embedded_flash::BufferStorage; +#[cfg(not(test))] +type Storage = embedded_flash::SyscallStorage; + +// Those constants may be modified before compilation to tune the behavior of the key. +// +// The number of pages should be at least 2 and at most what the flash can hold. There should be no +// reason to put a small number here, except that the latency of flash operations depends on the +// number of pages. This will improve in the future. Currently, using 20 pages gives 65ms per +// operation. The rule of thumb is 3.5ms per additional page. +// +// Limiting the number of residential keys permits to ensure a minimum number of counter increments. +// Let: +// - P the number of pages (NUM_PAGES) +// - K the maximum number of residential keys (MAX_SUPPORTED_RESIDENTIAL_KEYS) +// - S the maximum size of a residential key (about 500) +// - C the number of erase cycles (10000) +// - I the minimum number of counter increments +// +// We have: I = ((P - 1) * 4092 - K * S) / 12 * C +// +// With P=20 and K=150, we have I > 2M which is enough for 500 increments per day for 10 years. +const NUM_PAGES: usize = 20; +const MAX_SUPPORTED_RESIDENTIAL_KEYS: usize = 150; + +// List of tags. They should all be unique. And there should be less than NUM_TAGS. +const TAG_CREDENTIAL: usize = 0; +const GLOBAL_SIGNATURE_COUNTER: usize = 1; +const MASTER_KEYS: usize = 2; +const PIN_HASH: usize = 3; +const PIN_RETRIES: usize = 4; +const NUM_TAGS: usize = 5; + +const MAX_PIN_RETRIES: u8 = 6; + +#[derive(PartialEq, Eq, PartialOrd, Ord)] +enum Key { + // TODO(cretin): Test whether this doesn't consume too much memory. Otherwise, we can use less + // keys. Either only a simple enum value for all credentials, or group by rp_id. + Credential { + rp_id: Option, + credential_id: Option>, + user_handle: Option>, + }, + GlobalSignatureCounter, + MasterKeys, + PinHash, + PinRetries, +} + +pub struct MasterKeys<'a> { + pub encryption: &'a [u8; 32], + pub hmac: &'a [u8; 32], +} + +struct Config; + +impl StoreConfig for Config { + type Key = Key; + + fn num_tags(&self) -> usize { + NUM_TAGS + } + + fn keys(&self, entry: StoreEntry, mut add: impl FnMut(Key)) { + match entry.tag { + TAG_CREDENTIAL => { + let credential = match deserialize_credential(entry.data) { + None => { + debug_assert!(false); + return; + } + Some(credential) => credential, + }; + add(Key::Credential { + rp_id: Some(credential.rp_id.clone()), + credential_id: Some(credential.credential_id), + user_handle: None, + }); + add(Key::Credential { + rp_id: Some(credential.rp_id.clone()), + credential_id: None, + user_handle: None, + }); + add(Key::Credential { + rp_id: Some(credential.rp_id), + credential_id: None, + user_handle: Some(credential.user_handle), + }); + add(Key::Credential { + rp_id: None, + credential_id: None, + user_handle: None, + }); + } + GLOBAL_SIGNATURE_COUNTER => add(Key::GlobalSignatureCounter), + MASTER_KEYS => add(Key::MasterKeys), + PIN_HASH => add(Key::PinHash), + PIN_RETRIES => add(Key::PinRetries), + _ => debug_assert!(false), + } + } +} + +pub struct PersistentStore { + store: embedded_flash::Store, +} + +const PAGE_SIZE: usize = 0x1000; +const STORE_SIZE: usize = NUM_PAGES * PAGE_SIZE; + +#[cfg(not(test))] +#[link_section = ".app_state"] +static STORE: [u8; STORE_SIZE] = [0xff; STORE_SIZE]; + +impl PersistentStore { + /// Gives access to the persistent store. + /// + /// # Safety + /// + /// This should be at most one instance of persistent store per program lifetime. + pub fn new(rng: &mut impl Rng256) -> PersistentStore { + #[cfg(not(test))] + let storage = PersistentStore::new_prod_storage(); + #[cfg(test)] + let storage = PersistentStore::new_test_storage(); + let mut store = PersistentStore { + store: embedded_flash::Store::new(storage, Config).unwrap(), + }; + store.init(rng); + store + } + + #[cfg(not(test))] + fn new_prod_storage() -> Storage { + let store = unsafe { + // Safety: The store cannot alias because this function is called only once. + core::slice::from_raw_parts_mut(STORE.as_ptr() as *mut u8, STORE_SIZE) + }; + unsafe { + // Safety: The store is in a writeable flash region. + Storage::new(store).unwrap() + } + } + + #[cfg(test)] + fn new_test_storage() -> Storage { + let store = vec![0xff; STORE_SIZE].into_boxed_slice(); + let options = embedded_flash::BufferOptions { + word_size: 4, + page_size: PAGE_SIZE, + max_word_writes: 2, + max_page_erases: 10000, + strict_write: true, + }; + Storage::new(store, options) + } + + fn init(&mut self, rng: &mut impl Rng256) { + if self.store.find_one(&Key::MasterKeys).is_none() { + let master_encryption_key = rng.gen_uniform_u8x32(); + let master_hmac_key = rng.gen_uniform_u8x32(); + let mut master_keys = Vec::with_capacity(64); + master_keys.extend_from_slice(&master_encryption_key); + master_keys.extend_from_slice(&master_hmac_key); + self.store + .insert(StoreEntry { + tag: MASTER_KEYS, + data: &master_keys, + }) + .unwrap(); + } + if self.store.find_one(&Key::PinRetries).is_none() { + self.store + .insert(StoreEntry { + tag: PIN_RETRIES, + data: &[MAX_PIN_RETRIES], + }) + .unwrap(); + } + } + + pub fn find_credential( + &self, + rp_id: &str, + credential_id: &[u8], + ) -> Option { + let key = Key::Credential { + rp_id: Some(rp_id.into()), + credential_id: Some(credential_id.into()), + user_handle: None, + }; + let (_, entry) = self.store.find_one(&key)?; + debug_assert_eq!(entry.tag, TAG_CREDENTIAL); + let result = deserialize_credential(entry.data); + debug_assert!(result.is_some()); + result + } + + pub fn store_credential( + &mut self, + credential: PublicKeyCredentialSource, + ) -> Result<(), Ctap2StatusCode> { + let key = Key::Credential { + rp_id: Some(credential.rp_id.clone()), + credential_id: None, + user_handle: Some(credential.user_handle.clone()), + }; + let old_entry = self.store.find_one(&key); + if old_entry.is_none() && self.count_credentials() >= MAX_SUPPORTED_RESIDENTIAL_KEYS { + return Err(Ctap2StatusCode::CTAP2_ERR_KEY_STORE_FULL); + } + let credential = serialize_credential(credential)?; + let new_entry = StoreEntry { + tag: TAG_CREDENTIAL, + data: &credential, + }; + match old_entry { + None => self.store.insert(new_entry)?, + Some((index, old_entry)) => { + debug_assert_eq!(old_entry.tag, TAG_CREDENTIAL); + self.store.replace(index, new_entry)? + } + }; + Ok(()) + } + + pub fn filter_credential(&self, rp_id: &str) -> Vec { + self.store + .find_all(&Key::Credential { + rp_id: Some(rp_id.into()), + credential_id: None, + user_handle: None, + }) + .filter_map(|(_, entry)| { + debug_assert_eq!(entry.tag, TAG_CREDENTIAL); + let credential = deserialize_credential(entry.data); + debug_assert!(credential.is_some()); + credential + }) + .collect() + } + + pub fn count_credentials(&self) -> usize { + self.store + .find_all(&Key::Credential { + rp_id: None, + credential_id: None, + user_handle: None, + }) + .count() + } + + pub fn global_signature_counter(&self) -> u32 { + self.store + .find_one(&Key::GlobalSignatureCounter) + .map_or(0, |(_, entry)| { + u32::from_ne_bytes(*array_ref!(entry.data, 0, 4)) + }) + } + + pub fn incr_global_signature_counter(&mut self) { + let mut buffer = [0; core::mem::size_of::()]; + match self.store.find_one(&Key::GlobalSignatureCounter) { + None => { + buffer.copy_from_slice(&1u32.to_ne_bytes()); + self.store + .insert(StoreEntry { + tag: GLOBAL_SIGNATURE_COUNTER, + data: &buffer, + }) + .unwrap(); + } + Some((index, entry)) => { + let value = u32::from_ne_bytes(*array_ref!(entry.data, 0, 4)); + // In hopes that servers handle the wrapping gracefully. + buffer.copy_from_slice(&value.wrapping_add(1).to_ne_bytes()); + self.store + .replace( + index, + StoreEntry { + tag: GLOBAL_SIGNATURE_COUNTER, + data: &buffer, + }, + ) + .unwrap(); + } + } + } + + pub fn master_keys(&self) -> MasterKeys { + // We have as invariant that there is always exactly one MasterKeys entry in the store. + let (_, entry) = self.store.find_one(&Key::MasterKeys).unwrap(); + let data = entry.data; + // And this entry is well formed: the encryption key followed by the hmac key. + let encryption = array_ref!(data, 0, 32); + let hmac = array_ref!(data, 32, 32); + MasterKeys { encryption, hmac } + } + + pub fn pin_hash(&self) -> Option<&[u8; PIN_AUTH_LENGTH]> { + self.store + .find_one(&Key::PinHash) + .map(|(_, entry)| array_ref!(entry.data, 0, PIN_AUTH_LENGTH)) + } + + pub fn set_pin_hash(&mut self, pin_hash: &[u8; PIN_AUTH_LENGTH]) { + let entry = StoreEntry { + tag: PIN_HASH, + data: pin_hash, + }; + match self.store.find_one(&Key::PinHash) { + None => self.store.insert(entry).unwrap(), + Some((index, _)) => { + self.store.replace(index, entry).unwrap(); + } + } + } + + fn pin_retries_entry(&self) -> (StoreIndex, u8) { + let (index, entry) = self.store.find_one(&Key::PinRetries).unwrap(); + let data = entry.data; + debug_assert_eq!(data.len(), 1); + (index, data[0]) + } + + pub fn pin_retries(&self) -> u8 { + self.pin_retries_entry().1 + } + + pub fn decr_pin_retries(&mut self) { + let (index, old_value) = self.pin_retries_entry(); + let new_value = old_value.saturating_sub(1); + self.store + .replace( + index, + StoreEntry { + tag: PIN_RETRIES, + data: &[new_value], + }, + ) + .unwrap(); + } + + pub fn reset_pin_retries(&mut self) { + let (index, _) = self.pin_retries_entry(); + self.store + .replace( + index, + StoreEntry { + tag: PIN_RETRIES, + data: &[MAX_PIN_RETRIES], + }, + ) + .unwrap(); + } + + pub fn reset(&mut self, rng: &mut impl Rng256) { + loop { + let index = { + let mut iter = self.store.iter(); + match iter.next() { + None => break, + Some((index, _)) => index, + } + }; + self.store.delete(index).unwrap(); + } + self.init(rng); + } +} + +impl From for Ctap2StatusCode { + fn from(error: StoreError) -> Ctap2StatusCode { + match error { + StoreError::StoreFull => Ctap2StatusCode::CTAP2_ERR_KEY_STORE_FULL, + StoreError::InvalidTag => unreachable!(), + StoreError::InvalidPrecondition => unreachable!(), + } + } +} + +fn deserialize_credential(data: &[u8]) -> Option { + let cbor = cbor::read(data).ok()?; + cbor.try_into().ok() +} + +fn serialize_credential(credential: PublicKeyCredentialSource) -> Result, Ctap2StatusCode> { + let mut data = Vec::new(); + if cbor::write(credential.into(), &mut data) { + Ok(data) + } else { + Err(Ctap2StatusCode::CTAP2_ERR_INVALID_CREDENTIAL) + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::crypto; + use crate::crypto::rng256::{Rng256, ThreadRng256}; + use crate::ctap::data_formats::{PublicKeyCredentialSource, PublicKeyCredentialType}; + + fn create_credential_source( + rng: &mut ThreadRng256, + rp_id: &str, + user_handle: Vec, + ) -> PublicKeyCredentialSource { + let private_key = crypto::ecdsa::SecKey::gensk(rng); + PublicKeyCredentialSource { + key_type: PublicKeyCredentialType::PublicKey, + credential_id: rng.gen_uniform_u8x32().to_vec(), + private_key, + rp_id: String::from(rp_id), + user_handle, + other_ui: None, + } + } + + #[test] + fn format_overhead() { + // nRF52840 NVMC + const WORD_SIZE: usize = 4; + const PAGE_SIZE: usize = 0x1000; + const NUM_PAGES: usize = 100; + let store = vec![0xff; NUM_PAGES * PAGE_SIZE].into_boxed_slice(); + let options = embedded_flash::BufferOptions { + word_size: WORD_SIZE, + page_size: PAGE_SIZE, + max_word_writes: 2, + max_page_erases: 10000, + strict_write: true, + }; + let storage = Storage::new(store, options); + let store = embedded_flash::Store::new(storage, Config).unwrap(); + // We can replace 3 bytes with minimal overhead. + assert_eq!(store.replace_len(0), 2 * WORD_SIZE); + assert_eq!(store.replace_len(3), 2 * WORD_SIZE); + assert_eq!(store.replace_len(4), 3 * WORD_SIZE); + } + + #[test] + fn test_store() { + let mut rng = ThreadRng256 {}; + let mut persistent_store = PersistentStore::new(&mut rng); + assert_eq!(persistent_store.count_credentials(), 0); + let credential_source = create_credential_source(&mut rng, "example.com", vec![]); + assert!(persistent_store.store_credential(credential_source).is_ok()); + assert!(persistent_store.count_credentials() > 0); + } + + #[test] + #[allow(clippy::assertions_on_constants)] + fn test_fill_store() { + let mut rng = ThreadRng256 {}; + let mut persistent_store = PersistentStore::new(&mut rng); + assert_eq!(persistent_store.count_credentials(), 0); + + // To make this test work for bigger storages, implement better int -> Vec conversion. + assert!(MAX_SUPPORTED_RESIDENTIAL_KEYS < 256); + for i in 0..MAX_SUPPORTED_RESIDENTIAL_KEYS { + let credential_source = + create_credential_source(&mut rng, "example.com", vec![i as u8]); + assert!(persistent_store.store_credential(credential_source).is_ok()); + assert_eq!(persistent_store.count_credentials(), i + 1); + } + let credential_source = create_credential_source( + &mut rng, + "example.com", + vec![MAX_SUPPORTED_RESIDENTIAL_KEYS as u8], + ); + assert_eq!( + persistent_store.store_credential(credential_source), + Err(Ctap2StatusCode::CTAP2_ERR_KEY_STORE_FULL) + ); + assert_eq!( + persistent_store.count_credentials(), + MAX_SUPPORTED_RESIDENTIAL_KEYS + ); + } + + #[test] + #[allow(clippy::assertions_on_constants)] + fn test_overwrite() { + let mut rng = ThreadRng256 {}; + let mut persistent_store = PersistentStore::new(&mut rng); + assert_eq!(persistent_store.count_credentials(), 0); + // These should have different IDs. + let credential_source0 = create_credential_source(&mut rng, "example.com", vec![0x00]); + let credential_source1 = create_credential_source(&mut rng, "example.com", vec![0x00]); + let expected_credential = credential_source1.clone(); + + assert!(persistent_store + .store_credential(credential_source0) + .is_ok()); + assert!(persistent_store + .store_credential(credential_source1) + .is_ok()); + assert_eq!(persistent_store.count_credentials(), 1); + assert_eq!( + &persistent_store.filter_credential("example.com"), + &[expected_credential] + ); + + // To make this test work for bigger storages, implement better int -> Vec conversion. + assert!(MAX_SUPPORTED_RESIDENTIAL_KEYS < 256); + for i in 0..MAX_SUPPORTED_RESIDENTIAL_KEYS { + let credential_source = + create_credential_source(&mut rng, "example.com", vec![i as u8]); + assert!(persistent_store.store_credential(credential_source).is_ok()); + assert_eq!(persistent_store.count_credentials(), i + 1); + } + let credential_source = create_credential_source( + &mut rng, + "example.com", + vec![MAX_SUPPORTED_RESIDENTIAL_KEYS as u8], + ); + assert_eq!( + persistent_store.store_credential(credential_source), + Err(Ctap2StatusCode::CTAP2_ERR_KEY_STORE_FULL) + ); + assert_eq!( + persistent_store.count_credentials(), + MAX_SUPPORTED_RESIDENTIAL_KEYS + ); + } + + #[test] + fn test_filter() { + let mut rng = ThreadRng256 {}; + let mut persistent_store = PersistentStore::new(&mut rng); + assert_eq!(persistent_store.count_credentials(), 0); + let credential_source0 = create_credential_source(&mut rng, "example.com", vec![0x00]); + let credential_source1 = create_credential_source(&mut rng, "example.com", vec![0x01]); + let credential_source2 = + create_credential_source(&mut rng, "another.example.com", vec![0x02]); + let id0 = credential_source0.credential_id.clone(); + let id1 = credential_source1.credential_id.clone(); + assert!(persistent_store + .store_credential(credential_source0) + .is_ok()); + assert!(persistent_store + .store_credential(credential_source1) + .is_ok()); + assert!(persistent_store + .store_credential(credential_source2) + .is_ok()); + + let filtered_credentials = persistent_store.filter_credential("example.com"); + assert_eq!(filtered_credentials.len(), 2); + assert!( + (filtered_credentials[0].credential_id == id0 + && filtered_credentials[1].credential_id == id1) + || (filtered_credentials[1].credential_id == id0 + && filtered_credentials[0].credential_id == id1) + ); + } + + #[test] + fn test_find() { + let mut rng = ThreadRng256 {}; + let mut persistent_store = PersistentStore::new(&mut rng); + assert_eq!(persistent_store.count_credentials(), 0); + let credential_source0 = create_credential_source(&mut rng, "example.com", vec![0x00]); + let credential_source1 = create_credential_source(&mut rng, "example.com", vec![0x01]); + let id0 = credential_source0.credential_id.clone(); + let key0 = credential_source0.private_key.clone(); + assert!(persistent_store + .store_credential(credential_source0) + .is_ok()); + assert!(persistent_store + .store_credential(credential_source1) + .is_ok()); + + let no_credential = persistent_store.find_credential("another.example.com", &id0); + assert_eq!(no_credential, None); + let found_credential = persistent_store.find_credential("example.com", &id0); + let expected_credential = PublicKeyCredentialSource { + key_type: PublicKeyCredentialType::PublicKey, + credential_id: id0, + private_key: key0, + rp_id: String::from("example.com"), + user_handle: vec![0x00], + other_ui: None, + }; + assert_eq!(found_credential, Some(expected_credential)); + } + + #[test] + fn test_master_keys() { + let mut rng = ThreadRng256 {}; + let mut persistent_store = PersistentStore::new(&mut rng); + + // Master keys stay the same between resets. + let master_keys_1 = persistent_store.master_keys(); + let master_keys_2 = persistent_store.master_keys(); + assert_eq!(master_keys_2.encryption, master_keys_1.encryption); + assert_eq!(master_keys_2.hmac, master_keys_1.hmac); + + // Master keys change after reset. This test may fail if the random generator produces the + // same keys. + let master_encryption_key = master_keys_1.encryption.to_vec(); + let master_hmac_key = master_keys_1.hmac.to_vec(); + persistent_store.reset(&mut rng); + let master_keys_3 = persistent_store.master_keys(); + assert!(master_keys_3.encryption as &[u8] != &master_encryption_key[..]); + assert!(master_keys_3.hmac as &[u8] != &master_hmac_key[..]); + } + + #[test] + fn test_pin_hash() { + use crate::ctap::PIN_AUTH_LENGTH; + let mut rng = ThreadRng256 {}; + let mut persistent_store = PersistentStore::new(&mut rng); + + // Pin hash is initially not set. + assert!(persistent_store.pin_hash().is_none()); + + // Setting the pin hash sets the pin hash. + let random_data = rng.gen_uniform_u8x32(); + assert_eq!(random_data.len(), 2 * PIN_AUTH_LENGTH); + let pin_hash_1 = array_ref!(random_data, 0, PIN_AUTH_LENGTH); + let pin_hash_2 = array_ref!(random_data, PIN_AUTH_LENGTH, PIN_AUTH_LENGTH); + persistent_store.set_pin_hash(&pin_hash_1); + assert_eq!(persistent_store.pin_hash(), Some(pin_hash_1)); + assert_eq!(persistent_store.pin_hash(), Some(pin_hash_1)); + persistent_store.set_pin_hash(&pin_hash_2); + assert_eq!(persistent_store.pin_hash(), Some(pin_hash_2)); + assert_eq!(persistent_store.pin_hash(), Some(pin_hash_2)); + + // Resetting the storage resets the pin hash. + persistent_store.reset(&mut rng); + assert!(persistent_store.pin_hash().is_none()); + } + + #[test] + fn test_pin_retries() { + let mut rng = ThreadRng256 {}; + let mut persistent_store = PersistentStore::new(&mut rng); + + // The pin retries is initially at the maximum. + assert_eq!(persistent_store.pin_retries(), MAX_PIN_RETRIES); + + // Decrementing the pin retries decrements the pin retries. + for pin_retries in (0..MAX_PIN_RETRIES).rev() { + persistent_store.decr_pin_retries(); + assert_eq!(persistent_store.pin_retries(), pin_retries); + } + + // Decrementing the pin retries after zero does not modify the pin retries. + persistent_store.decr_pin_retries(); + assert_eq!(persistent_store.pin_retries(), 0); + + // Resetting the pin retries resets the pin retries. + persistent_store.reset_pin_retries(); + assert_eq!(persistent_store.pin_retries(), MAX_PIN_RETRIES); + } +} diff --git a/src/ctap/timed_permission.rs b/src/ctap/timed_permission.rs new file mode 100644 index 0000000..d56ba09 --- /dev/null +++ b/src/ctap/timed_permission.rs @@ -0,0 +1,188 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::timer::{ClockValue, Duration}; + +#[derive(Clone, Copy, Debug)] +pub enum TimedPermission { + Waiting, + Granted(ClockValue), +} + +impl TimedPermission { + pub fn waiting() -> TimedPermission { + TimedPermission::Waiting + } + + pub fn granted(now: ClockValue, grant_duration: Duration) -> TimedPermission { + TimedPermission::Granted(now.wrapping_add(grant_duration)) + } + + // Checks if the timeout is not reached, false for differing ClockValue frequencies. + pub fn is_granted(&self, now: ClockValue) -> bool { + if let TimedPermission::Granted(timeout) = self { + if let Some(remaining_duration) = timeout.wrapping_sub(now) { + return remaining_duration > Duration::from_ms(0); + } + } + false + } + + // Consumes the state and returns the current new permission state at time "now". + // Returns a new state for differing ClockValue frequencies. + pub fn check_expiration(self, now: ClockValue) -> TimedPermission { + if let TimedPermission::Granted(timeout) = self { + if let Some(remaining_duration) = timeout.wrapping_sub(now) { + if remaining_duration > Duration::from_ms(0) { + return TimedPermission::Granted(timeout); + } + } + } + TimedPermission::Waiting + } +} + +#[cfg(feature = "with_ctap1")] +#[derive(Debug)] +pub struct U2fUserPresenceState { + // If user presence was recently requested, its timeout is saved here. + needs_up: TimedPermission, + // Button touch timeouts, while user presence is requested, are saved here. + has_up: TimedPermission, + // This is the timeout duration of user presence requests. + request_duration: Duration, + // This is the timeout duration of button touches. + presence_duration: Duration, +} + +#[cfg(feature = "with_ctap1")] +impl U2fUserPresenceState { + pub fn new( + request_duration: Duration, + presence_duration: Duration, + ) -> U2fUserPresenceState { + U2fUserPresenceState { + needs_up: TimedPermission::Waiting, + has_up: TimedPermission::Waiting, + request_duration, + presence_duration, + } + } + + // Granting user presence is ignored if it needs activation, but waits. Also cleans up. + pub fn grant_up(&mut self, now: ClockValue) { + self.check_expiration(now); + if self.needs_up.is_granted(now) { + self.needs_up = TimedPermission::Waiting; + self.has_up = TimedPermission::granted(now, self.presence_duration); + } + } + + // This marks user presence as needed or uses it up if already granted. Also cleans up. + pub fn consume_up(&mut self, now: ClockValue) -> bool { + self.check_expiration(now); + if self.has_up.is_granted(now) { + self.has_up = TimedPermission::Waiting; + true + } else { + self.needs_up = TimedPermission::granted(now, self.request_duration); + false + } + } + + // Returns if user presence was requested. Also cleans up. + pub fn is_up_needed(&mut self, now: ClockValue) -> bool { + self.check_expiration(now); + self.needs_up.is_granted(now) + } + + // If you don't regularly call any other function, not cleaning up leads to overflow problems. + pub fn check_expiration(&mut self, now: ClockValue) { + self.needs_up = self.needs_up.check_expiration(now); + self.has_up = self.has_up.check_expiration(now); + } +} + +#[cfg(feature = "with_ctap1")] +#[cfg(test)] +mod test { + use super::*; + use core::isize; + + const CLOCK_FREQUENCY_HZ: usize = 32768; + const ZERO: ClockValue = ClockValue::new(0, CLOCK_FREQUENCY_HZ); + const BIG_POSITIVE: ClockValue = ClockValue::new(isize::MAX / 1000 - 1, CLOCK_FREQUENCY_HZ); + const NEGATIVE: ClockValue = ClockValue::new(-1, CLOCK_FREQUENCY_HZ); + const SMALL_NEGATIVE: ClockValue = ClockValue::new(isize::MIN / 1000 + 1, CLOCK_FREQUENCY_HZ); + const REQUEST_DURATION: Duration = Duration::from_ms(1000); + const PRESENCE_DURATION: Duration = Duration::from_ms(1000); + + fn grant_up_when_needed(start_time: ClockValue) { + let mut u2f_state = U2fUserPresenceState::new(REQUEST_DURATION, PRESENCE_DURATION); + assert!(!u2f_state.consume_up(start_time)); + assert!(u2f_state.is_up_needed(start_time)); + u2f_state.grant_up(start_time); + assert!(u2f_state.consume_up(start_time)); + assert!(!u2f_state.consume_up(start_time)); + } + + fn need_up_timeout(start_time: ClockValue) { + let mut u2f_state = U2fUserPresenceState::new(REQUEST_DURATION, PRESENCE_DURATION); + assert!(!u2f_state.consume_up(start_time)); + assert!(u2f_state.is_up_needed(start_time)); + // The timeout excludes equality, so it should be over at this instant. + assert!(!u2f_state.is_up_needed(start_time.wrapping_add(REQUEST_DURATION))); + } + + fn grant_up_timeout(start_time: ClockValue) { + let mut u2f_state = U2fUserPresenceState::new(REQUEST_DURATION, PRESENCE_DURATION); + assert!(!u2f_state.consume_up(start_time)); + assert!(u2f_state.is_up_needed(start_time)); + u2f_state.grant_up(start_time); + // The timeout excludes equality, so it should be over at this instant. + assert!(!u2f_state.consume_up(start_time.wrapping_add(PRESENCE_DURATION))); + } + + #[test] + fn test_grant_up_timeout() { + grant_up_timeout(ZERO); + grant_up_timeout(BIG_POSITIVE); + grant_up_timeout(NEGATIVE); + grant_up_timeout(SMALL_NEGATIVE); + } + + #[test] + fn test_need_up_timeout() { + need_up_timeout(ZERO); + need_up_timeout(BIG_POSITIVE); + need_up_timeout(NEGATIVE); + need_up_timeout(SMALL_NEGATIVE); + } + + #[test] + fn test_grant_up_when_needed() { + grant_up_when_needed(ZERO); + grant_up_when_needed(BIG_POSITIVE); + grant_up_when_needed(NEGATIVE); + grant_up_when_needed(SMALL_NEGATIVE); + } + + #[test] + fn test_grant_up_without_need() { + let mut u2f_state = U2fUserPresenceState::new(REQUEST_DURATION, PRESENCE_DURATION); + u2f_state.grant_up(ZERO); + assert!(!u2f_state.is_up_needed(ZERO)); + assert!(!u2f_state.consume_up(ZERO)); + } +} diff --git a/src/embedded_flash/buffer.rs b/src/embedded_flash/buffer.rs new file mode 100644 index 0000000..b7cf3f1 --- /dev/null +++ b/src/embedded_flash/buffer.rs @@ -0,0 +1,455 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::{Index, Storage, StorageError, StorageResult}; + +pub struct BufferStorage { + storage: Box<[u8]>, + options: BufferOptions, + word_writes: Box<[usize]>, + page_erases: Box<[usize]>, + snapshot: Snapshot, +} + +#[derive(Copy, Clone, Debug)] +pub struct BufferOptions { + /// Size of a word in bytes. + pub word_size: usize, + + /// Size of a page in bytes. + pub page_size: usize, + + /// How many times a word can be written between page erasures + pub max_word_writes: usize, + + /// How many times a page can be erased. + pub max_page_erases: usize, + + /// Bits cannot be written from 0 to 1. + pub strict_write: bool, +} + +impl BufferStorage { + /// Creates a fake embedded flash using a buffer. + /// + /// This implementation checks that no words are written more than `max_word_writes` between + /// page erasures and than no pages are erased more than `max_page_erases`. If `strict_write` is + /// true, it also checks that no bits are written from 0 to 1. It also permits to take snapshots + /// of the storage during write and erase operations (although words would still be written or + /// erased completely). + /// + /// # Panics + /// + /// The following preconditions must hold: + /// - `options.word_size` must be a power of two. + /// - `options.page_size` must be a power of two. + /// - `options.page_size` must be word-aligned. + /// - `storage.len()` must be page-aligned. + pub fn new(storage: Box<[u8]>, options: BufferOptions) -> BufferStorage { + assert!(options.word_size.is_power_of_two()); + assert!(options.page_size.is_power_of_two()); + let num_words = storage.len() / options.word_size; + let num_pages = storage.len() / options.page_size; + let buffer = BufferStorage { + storage, + options, + word_writes: vec![0; num_words].into_boxed_slice(), + page_erases: vec![0; num_pages].into_boxed_slice(), + snapshot: Snapshot::Ready, + }; + assert!(buffer.is_word_aligned(buffer.options.page_size)); + assert!(buffer.is_page_aligned(buffer.storage.len())); + buffer + } + + /// Takes a snapshot of the storage after a given amount of word operations. + /// + /// Each time a word is written or erased, the delay is decremented if positive. Otherwise, a + /// snapshot is taken before the operation is executed. + /// + /// # Panics + /// + /// Panics if a snapshot has been armed and not examined. + pub fn arm_snapshot(&mut self, delay: usize) { + self.snapshot.arm(delay); + } + + /// Unarms and returns the snapshot or the delay remaining. + /// + /// # Panics + /// + /// Panics if a snapshot was not armed. + pub fn get_snapshot(&mut self) -> Result, usize> { + self.snapshot.get() + } + + /// Takes a snapshot of the storage. + pub fn take_snapshot(&self) -> Box<[u8]> { + self.storage.clone() + } + + /// Returns the storage. + pub fn get_storage(self) -> Box<[u8]> { + self.storage + } + + fn is_word_aligned(&self, x: usize) -> bool { + x & (self.options.word_size - 1) == 0 + } + + fn is_page_aligned(&self, x: usize) -> bool { + x & (self.options.page_size - 1) == 0 + } + + /// Writes a slice to the storage. + /// + /// The slice `value` is written to `index`. The `erase` boolean specifies whether this is an + /// erase operation or a write operation which matters for the checks and updating the shadow + /// storage. This also takes a snapshot of the storage if a snapshot was armed and the delay has + /// elapsed. + /// + /// The following preconditions should hold: + /// - `index` is word-aligned. + /// - `value.len()` is word-aligned. + /// + /// The following checks are performed: + /// - The region of length `value.len()` starting at `index` fits in a storage page. + /// - A word is not written more than `max_word_writes`. + /// - A page is not erased more than `max_page_erases`. + /// - The new word only switches 1s to 0s (only if `strict_write` is set). + fn update_storage(&mut self, index: Index, value: &[u8], erase: bool) -> StorageResult<()> { + debug_assert!(self.is_word_aligned(index.byte) && self.is_word_aligned(value.len())); + let dst = index.range(value.len(), self)?.step_by(self.word_size()); + let src = value.chunks(self.word_size()); + // Check and update page shadow. + if erase { + let page = index.page; + assert!(self.page_erases[page] < self.max_page_erases()); + self.page_erases[page] += 1; + } + for (byte, val) in dst.zip(src) { + let range = byte..byte + self.word_size(); + // The driver doesn't write identical words. + if &self.storage[range.clone()] == val { + continue; + } + // Check and update word shadow. + let word = byte / self.word_size(); + if erase { + self.word_writes[word] = 0; + } else { + assert!(self.word_writes[word] < self.max_word_writes()); + self.word_writes[word] += 1; + } + // Check strict write. + if !erase && self.options.strict_write { + for (byte, &val) in range.clone().zip(val) { + assert_eq!(self.storage[byte] & val, val); + } + } + // Take snapshot if armed and delay expired. + self.snapshot.take(&self.storage); + // Write storage + self.storage[range].copy_from_slice(val); + } + Ok(()) + } +} + +impl Storage for BufferStorage { + fn word_size(&self) -> usize { + self.options.word_size + } + + fn page_size(&self) -> usize { + self.options.page_size + } + + fn num_pages(&self) -> usize { + self.storage.len() / self.options.page_size + } + + fn max_word_writes(&self) -> usize { + self.options.max_word_writes + } + + fn max_page_erases(&self) -> usize { + self.options.max_page_erases + } + + fn read_slice(&self, index: Index, length: usize) -> StorageResult<&[u8]> { + Ok(&self.storage[index.range(length, self)?]) + } + + fn write_slice(&mut self, index: Index, value: &[u8]) -> StorageResult<()> { + if !self.is_word_aligned(index.byte) || !self.is_word_aligned(value.len()) { + return Err(StorageError::NotAligned); + } + self.update_storage(index, value, false) + } + + fn erase_page(&mut self, page: usize) -> StorageResult<()> { + let index = Index { page, byte: 0 }; + let value = vec![0xff; self.page_size()]; + self.update_storage(index, &value, true) + } +} + +// Controls when a snapshot of the storage is taken. +// +// This can be used to simulate power-offs while the device is writing to the storage or erasing a +// page in the storage. +enum Snapshot { + // Mutable word operations have normal behavior. + Ready, + // If the delay is positive, mutable word operations decrement it. If the count is zero, mutable + // word operations take a snapshot of the storage. + Armed { delay: usize }, + // Mutable word operations have normal behavior. + Taken { storage: Box<[u8]> }, +} + +impl Snapshot { + fn arm(&mut self, delay: usize) { + match self { + Snapshot::Ready => *self = Snapshot::Armed { delay }, + _ => panic!(), + } + } + + fn get(&mut self) -> Result, usize> { + let mut snapshot = Snapshot::Ready; + std::mem::swap(self, &mut snapshot); + match snapshot { + Snapshot::Armed { delay } => Err(delay), + Snapshot::Taken { storage } => Ok(storage), + _ => panic!(), + } + } + + fn take(&mut self, storage: &[u8]) { + if let Snapshot::Armed { delay } = self { + if *delay == 0 { + let storage = storage.to_vec().into_boxed_slice(); + *self = Snapshot::Taken { storage }; + } else { + *delay -= 1; + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const NUM_PAGES: usize = 2; + const OPTIONS: BufferOptions = BufferOptions { + word_size: 4, + page_size: 16, + max_word_writes: 2, + max_page_erases: 3, + strict_write: true, + }; + // Those words are decreasing bit patterns. Bits are only changed from 1 to 0 and at last one + // bit is changed. + const BLANK_WORD: &[u8] = &[0xff, 0xff, 0xff, 0xff]; + const FIRST_WORD: &[u8] = &[0xee, 0xdd, 0xbb, 0x77]; + const SECOND_WORD: &[u8] = &[0xca, 0xc9, 0xa9, 0x65]; + const THIRD_WORD: &[u8] = &[0x88, 0x88, 0x88, 0x44]; + + fn new_storage() -> Box<[u8]> { + vec![0xff; NUM_PAGES * OPTIONS.page_size].into_boxed_slice() + } + + #[test] + fn words_are_decreasing() { + fn assert_is_decreasing(prev: &[u8], next: &[u8]) { + for (&prev, &next) in prev.iter().zip(next.iter()) { + assert_eq!(prev & next, next); + assert!(prev != next); + } + } + assert_is_decreasing(BLANK_WORD, FIRST_WORD); + assert_is_decreasing(FIRST_WORD, SECOND_WORD); + assert_is_decreasing(SECOND_WORD, THIRD_WORD); + } + + #[test] + fn options_ok() { + let buffer = BufferStorage::new(new_storage(), OPTIONS); + assert_eq!(buffer.word_size(), OPTIONS.word_size); + assert_eq!(buffer.page_size(), OPTIONS.page_size); + assert_eq!(buffer.num_pages(), NUM_PAGES); + assert_eq!(buffer.max_word_writes(), OPTIONS.max_word_writes); + assert_eq!(buffer.max_page_erases(), OPTIONS.max_page_erases); + } + + #[test] + fn read_write_ok() { + let mut buffer = BufferStorage::new(new_storage(), OPTIONS); + let index = Index { page: 0, byte: 0 }; + let next_index = Index { page: 0, byte: 4 }; + assert_eq!(buffer.read_slice(index, 4).unwrap(), BLANK_WORD); + buffer.write_slice(index, FIRST_WORD).unwrap(); + assert_eq!(buffer.read_slice(index, 4).unwrap(), FIRST_WORD); + assert_eq!(buffer.read_slice(next_index, 4).unwrap(), BLANK_WORD); + } + + #[test] + fn erase_ok() { + let mut buffer = BufferStorage::new(new_storage(), OPTIONS); + let index = Index { page: 0, byte: 0 }; + let other_index = Index { page: 1, byte: 0 }; + buffer.write_slice(index, FIRST_WORD).unwrap(); + buffer.write_slice(other_index, FIRST_WORD).unwrap(); + assert_eq!(buffer.read_slice(index, 4).unwrap(), FIRST_WORD); + assert_eq!(buffer.read_slice(other_index, 4).unwrap(), FIRST_WORD); + buffer.erase_page(0).unwrap(); + assert_eq!(buffer.read_slice(index, 4).unwrap(), BLANK_WORD); + assert_eq!(buffer.read_slice(other_index, 4).unwrap(), FIRST_WORD); + } + + #[test] + fn invalid_range() { + let mut buffer = BufferStorage::new(new_storage(), OPTIONS); + let index = Index { page: 0, byte: 12 }; + let half_index = Index { page: 0, byte: 14 }; + let over_index = Index { page: 0, byte: 16 }; + let bad_page = Index { page: 2, byte: 0 }; + + // Reading a word in the storage is ok. + assert!(buffer.read_slice(index, 4).is_ok()); + // Reading a half-word in the storage is ok. + assert!(buffer.read_slice(half_index, 2).is_ok()); + // Reading even a single byte outside a page is not ok. + assert!(buffer.read_slice(over_index, 1).is_err()); + // But reading an empty slice just after a page is ok. + assert!(buffer.read_slice(over_index, 0).is_ok()); + // Reading even an empty slice outside the storage is not ok. + assert!(buffer.read_slice(bad_page, 0).is_err()); + + // Writing a word in the storage is ok. + assert!(buffer.write_slice(index, FIRST_WORD).is_ok()); + // Writing an unaligned word is not ok. + assert!(buffer.write_slice(half_index, FIRST_WORD).is_err()); + // Writing a word outside a page is not ok. + assert!(buffer.write_slice(over_index, FIRST_WORD).is_err()); + // But writing an empty slice just after a page is ok. + assert!(buffer.write_slice(over_index, &[]).is_ok()); + // Writing even an empty slice outside the storage is not ok. + assert!(buffer.write_slice(bad_page, &[]).is_err()); + + // Only pages in the storage can be erased. + assert!(buffer.erase_page(0).is_ok()); + assert!(buffer.erase_page(2).is_err()); + } + + #[test] + fn write_twice_ok() { + let mut buffer = BufferStorage::new(new_storage(), OPTIONS); + let index = Index { page: 0, byte: 4 }; + assert!(buffer.write_slice(index, FIRST_WORD).is_ok()); + assert!(buffer.write_slice(index, SECOND_WORD).is_ok()); + } + + #[test] + fn write_twice_and_once_ok() { + let mut buffer = BufferStorage::new(new_storage(), OPTIONS); + let index = Index { page: 0, byte: 0 }; + let next_index = Index { page: 0, byte: 4 }; + assert!(buffer.write_slice(index, FIRST_WORD).is_ok()); + assert!(buffer.write_slice(index, SECOND_WORD).is_ok()); + assert!(buffer.write_slice(next_index, THIRD_WORD).is_ok()); + } + + #[test] + #[should_panic] + fn write_three_times_panics() { + let mut buffer = BufferStorage::new(new_storage(), OPTIONS); + let index = Index { page: 0, byte: 4 }; + assert!(buffer.write_slice(index, FIRST_WORD).is_ok()); + assert!(buffer.write_slice(index, SECOND_WORD).is_ok()); + let _ = buffer.write_slice(index, THIRD_WORD); + } + + #[test] + fn write_twice_then_once_ok() { + let mut buffer = BufferStorage::new(new_storage(), OPTIONS); + let index = Index { page: 0, byte: 0 }; + assert!(buffer.write_slice(index, FIRST_WORD).is_ok()); + assert!(buffer.write_slice(index, SECOND_WORD).is_ok()); + assert!(buffer.erase_page(0).is_ok()); + assert!(buffer.write_slice(index, FIRST_WORD).is_ok()); + } + + #[test] + fn erase_three_times_ok() { + let mut buffer = BufferStorage::new(new_storage(), OPTIONS); + assert!(buffer.erase_page(0).is_ok()); + assert!(buffer.erase_page(0).is_ok()); + assert!(buffer.erase_page(0).is_ok()); + } + + #[test] + fn erase_three_times_and_once_ok() { + let mut buffer = BufferStorage::new(new_storage(), OPTIONS); + assert!(buffer.erase_page(0).is_ok()); + assert!(buffer.erase_page(0).is_ok()); + assert!(buffer.erase_page(0).is_ok()); + assert!(buffer.erase_page(1).is_ok()); + } + + #[test] + #[should_panic] + fn erase_four_times_panics() { + let mut buffer = BufferStorage::new(new_storage(), OPTIONS); + assert!(buffer.erase_page(0).is_ok()); + assert!(buffer.erase_page(0).is_ok()); + assert!(buffer.erase_page(0).is_ok()); + let _ = buffer.erase_page(0).is_ok(); + } + + #[test] + #[should_panic] + fn switch_zero_to_one_panics() { + let mut buffer = BufferStorage::new(new_storage(), OPTIONS); + let index = Index { page: 0, byte: 0 }; + assert!(buffer.write_slice(index, SECOND_WORD).is_ok()); + let _ = buffer.write_slice(index, FIRST_WORD); + } + + #[test] + fn get_storage_ok() { + let mut buffer = BufferStorage::new(new_storage(), OPTIONS); + let index = Index { page: 0, byte: 4 }; + buffer.write_slice(index, FIRST_WORD).unwrap(); + let storage = buffer.get_storage(); + assert_eq!(&storage[..4], BLANK_WORD); + assert_eq!(&storage[4..8], FIRST_WORD); + } + + #[test] + fn snapshot_ok() { + let mut buffer = BufferStorage::new(new_storage(), OPTIONS); + let index = Index { page: 0, byte: 0 }; + let value = [FIRST_WORD, SECOND_WORD].concat(); + buffer.arm_snapshot(1); + buffer.write_slice(index, &value).unwrap(); + let storage = buffer.get_snapshot().unwrap(); + assert_eq!(&storage[..8], &[FIRST_WORD, BLANK_WORD].concat()[..]); + let storage = buffer.take_snapshot(); + assert_eq!(&storage[..8], &value[..]); + } +} diff --git a/src/embedded_flash/mod.rs b/src/embedded_flash/mod.rs new file mode 100644 index 0000000..5e54059 --- /dev/null +++ b/src/embedded_flash/mod.rs @@ -0,0 +1,25 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#[cfg(feature = "std")] +mod buffer; +mod storage; +mod store; +mod syscall; + +#[cfg(feature = "std")] +pub use self::buffer::{BufferOptions, BufferStorage}; +pub use self::storage::{Index, Storage, StorageError, StorageResult}; +pub use self::store::{Store, StoreConfig, StoreEntry, StoreError, StoreIndex}; +pub use self::syscall::SyscallStorage; diff --git a/src/embedded_flash/storage.rs b/src/embedded_flash/storage.rs new file mode 100644 index 0000000..fe87ac4 --- /dev/null +++ b/src/embedded_flash/storage.rs @@ -0,0 +1,107 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#[derive(Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct Index { + pub page: usize, + pub byte: usize, +} + +#[derive(Debug)] +pub enum StorageError { + BadFlash, + NotAligned, + OutOfBounds, + KernelError { code: isize }, +} + +pub type StorageResult = Result; + +/// Abstraction for embedded flash storage. +pub trait Storage { + /// Returns the size of a word in bytes. + fn word_size(&self) -> usize; + + /// Returns the size of a page in bytes. + fn page_size(&self) -> usize; + + /// Returns the number of pages in the storage. + fn num_pages(&self) -> usize; + + /// Returns how many times a word can be written between page erasures. + fn max_word_writes(&self) -> usize; + + /// Returns how many times a page can be erased in the lifetime of the flash. + fn max_page_erases(&self) -> usize; + + /// Reads a slice from the storage. + /// + /// The slice does not need to be word-aligned. + /// + /// # Errors + /// + /// The `index` must designate `length` bytes in the storage. + fn read_slice(&self, index: Index, length: usize) -> StorageResult<&[u8]>; + + /// Writes a word-aligned slice to the storage. + /// + /// The written words should not have been written too many times since last page erasure. + /// + /// # Errors + /// + /// The following preconditions must hold: + /// - `index` must be word-aligned. + /// - `value.len()` must be a multiple of the word size. + /// - `index` must designate `value.len()` bytes in the storage. + /// - `value` must be in memory until [read-only allow][tock_1274] is resolved. + /// + /// [tock_1274]: https://github.com/tock/tock/issues/1274. + fn write_slice(&mut self, index: Index, value: &[u8]) -> StorageResult<()>; + + /// Erases a page of the storage. + /// + /// # Errors + /// + /// The `page` must be in the storage. + fn erase_page(&mut self, page: usize) -> StorageResult<()>; +} + +impl Index { + /// Returns whether a slice fits in a storage page. + fn is_valid(self, length: usize, storage: &impl Storage) -> bool { + self.page < storage.num_pages() + && storage + .page_size() + .checked_sub(length) + .map(|limit| self.byte <= limit) + .unwrap_or(false) + } + + /// Returns the range of a valid slice. + /// + /// The range starts at `self` with `length` bytes. + pub fn range( + self, + length: usize, + storage: &impl Storage, + ) -> StorageResult> { + if self.is_valid(length, storage) { + let start = self.page * storage.page_size() + self.byte; + Ok(start..start + length) + } else { + Err(StorageError::OutOfBounds) + } + } +} diff --git a/src/embedded_flash/store/bitfield.rs b/src/embedded_flash/store/bitfield.rs new file mode 100644 index 0000000..60c6f86 --- /dev/null +++ b/src/embedded_flash/store/bitfield.rs @@ -0,0 +1,172 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/// Defines a consecutive sequence of bits. +#[derive(Copy, Clone)] +pub struct BitRange { + /// The first bit of the sequence. + pub start: usize, + + /// The length in bits of the sequence. + pub length: usize, +} + +impl BitRange { + /// Returns the first bit following a bit range. + pub fn end(self) -> usize { + self.start + self.length + } +} + +/// Defines a consecutive sequence of bytes. +/// +/// The bits in those bytes are ignored which essentially creates a gap in a sequence of bits. The +/// gap is necessarily at byte boundaries. This is used to ignore the user data in an entry +/// essentially providing a view of the entry information (header and footer). +#[derive(Copy, Clone)] +pub struct ByteGap { + pub start: usize, + pub length: usize, +} + +/// Empty gap. All bits count. +pub const NO_GAP: ByteGap = ByteGap { + start: 0, + length: 0, +}; + +impl ByteGap { + /// Translates a bit to skip the gap. + fn shift(self, bit: usize) -> usize { + if bit < 8 * self.start { + bit + } else { + bit + 8 * self.length + } + } +} + +/// Returns whether a bit is set in a sequence of bits. +/// +/// The sequence of bits is little-endian (both for bytes and bits) and defined by the bits that +/// are in `data` but not in `gap`. +pub fn is_zero(bit: usize, data: &[u8], gap: ByteGap) -> bool { + let bit = gap.shift(bit); + debug_assert!(bit < 8 * data.len()); + data[bit / 8] & (1 << (bit % 8)) == 0 +} + +/// Sets a bit to zero in a sequence of bits. +/// +/// The sequence of bits is little-endian (both for bytes and bits) and defined by the bits that +/// are in `data` but not in `gap`. +pub fn set_zero(bit: usize, data: &mut [u8], gap: ByteGap) { + let bit = gap.shift(bit); + debug_assert!(bit < 8 * data.len()); + data[bit / 8] &= !(1 << (bit % 8)); +} + +/// Returns a little-endian value in a sequence of bits. +/// +/// The sequence of bits is little-endian (both for bytes and bits) and defined by the bits that +/// are in `data` but not in `gap`. The range of bits where the value is stored in defined by +/// `range`. The value must fit in a `usize`. +pub fn get_range(range: BitRange, data: &[u8], gap: ByteGap) -> usize { + debug_assert!(range.length <= 8 * core::mem::size_of::()); + let mut result = 0; + for i in 0..range.length { + if !is_zero(range.start + i, data, gap) { + result |= 1 << i; + } + } + result +} + +/// Sets a little-endian value in a sequence of bits. +/// +/// The sequence of bits is little-endian (both for bytes and bits) and defined by the bits that +/// are in `data` but not in `gap`. The range of bits where the value is stored in defined by +/// `range`. The bits set to 1 in `value` must also be set to `1` in the sequence of bits. +pub fn set_range(range: BitRange, data: &mut [u8], gap: ByteGap, value: usize) { + debug_assert!(range.length == 8 * core::mem::size_of::() || value < 1 << range.length); + for i in 0..range.length { + if value & 1 << i == 0 { + set_zero(range.start + i, data, gap); + } + } +} + +/// Tests the `is_zero` and `set_zero` pair of functions. +#[test] +fn zero_ok() { + const GAP: ByteGap = ByteGap { + start: 2, + length: 1, + }; + for i in 0..24 { + assert!(!is_zero(i, &[0xffu8, 0xff, 0x00, 0xff] as &[u8], GAP)); + } + // Tests reading and setting a bit. The result should have all bits set to 1 except for the bit + // to test and the gap. + fn test(bit: usize, result: &[u8]) { + assert!(is_zero(bit, result, GAP)); + let mut data = vec![0xff; result.len()]; + // Set the gap bits to 0. + for i in 0..GAP.length { + data[GAP.start + i] = 0x00; + } + set_zero(bit, &mut data, GAP); + assert_eq!(data, result); + } + test(0, &[0xfe, 0xff, 0x00, 0xff]); + test(1, &[0xfd, 0xff, 0x00, 0xff]); + test(2, &[0xfb, 0xff, 0x00, 0xff]); + test(7, &[0x7f, 0xff, 0x00, 0xff]); + test(8, &[0xff, 0xfe, 0x00, 0xff]); + test(15, &[0xff, 0x7f, 0x00, 0xff]); + test(16, &[0xff, 0xff, 0x00, 0xfe]); + test(17, &[0xff, 0xff, 0x00, 0xfd]); + test(23, &[0xff, 0xff, 0x00, 0x7f]); +} + +/// Tests the `get_range` and `set_range` pair of functions. +#[test] +fn range_ok() { + // Tests reading and setting a range. The result should have all bits set to 1 except for the + // range to test and the gap. + fn test(start: usize, length: usize, value: usize, result: &[u8], gap: ByteGap) { + let range = BitRange { start, length }; + assert_eq!(get_range(range, result, gap), value); + let mut data = vec![0xff; result.len()]; + for i in 0..gap.length { + data[gap.start + i] = 0x00; + } + set_range(range, &mut data, gap, value); + assert_eq!(data, result); + } + test(0, 8, 42, &[42], NO_GAP); + test(3, 12, 0b11_0101, &[0b1010_1111, 0b1000_0001], NO_GAP); + test(0, 16, 0x1234, &[0x34, 0x12], NO_GAP); + test(4, 16, 0x1234, &[0x4f, 0x23, 0xf1], NO_GAP); + let mut gap = ByteGap { + start: 1, + length: 1, + }; + test(3, 12, 0b11_0101, &[0b1010_1111, 0x00, 0b1000_0001], gap); + gap.length = 2; + test(0, 16, 0x1234, &[0x34, 0x00, 0x00, 0x12], gap); + gap.start = 2; + gap.length = 1; + test(4, 16, 0x1234, &[0x4f, 0x23, 0x00, 0xf1], gap); +} diff --git a/src/embedded_flash/store/format.rs b/src/embedded_flash/store/format.rs new file mode 100644 index 0000000..cbef61f --- /dev/null +++ b/src/embedded_flash/store/format.rs @@ -0,0 +1,514 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::super::{Index, Storage}; +use super::{bitfield, StoreConfig, StoreEntry, StoreError}; +use alloc::vec::Vec; + +/// Whether a user entry is a replace entry. +pub enum IsReplace { + /// This is a replace entry. + Replace, + + /// This is an insert entry. + Insert, +} + +/// Helpers to parse the store format. +/// +/// See the store module-level documentation for information about the format. +pub struct Format { + pub word_size: usize, + pub page_size: usize, + pub num_pages: usize, + pub max_page_erases: usize, + pub num_tags: usize, + + /// Whether an entry is present. + /// + /// - 0 for entries (user entries or internal entries). + /// - 1 for free space until the end of the page. + present_bit: usize, + + /// Whether an entry is deleted. + /// + /// - 0 for deleted entries. + /// - 1 for alive entries. + deleted_bit: usize, + + /// Whether an entry is internal. + /// + /// - 0 for internal entries. + /// - 1 for user entries. + internal_bit: usize, + + /// Whether a user entry is a replace entry. + /// + /// - 0 for replace entries. + /// - 1 for insert entries. + replace_bit: usize, + + /// The data length of a user entry. + length_range: bitfield::BitRange, + + /// The tag of a user entry. + tag_range: bitfield::BitRange, + + /// The page index of a replace entry. + replace_page_range: bitfield::BitRange, + + /// The byte index of a replace entry. + replace_byte_range: bitfield::BitRange, + + /// The index of the page to erase. + /// + /// This is only present for internal entries. + old_page_range: bitfield::BitRange, + + /// The current erase count of the page to erase. + /// + /// This is only present for internal entries. + saved_erase_count_range: bitfield::BitRange, + + /// Whether a page is initialized. + /// + /// - 0 for initialized pages. + /// - 1 for uninitialized pages. + initialized_bit: usize, + + /// The erase count of a page. + erase_count_range: bitfield::BitRange, + + /// Whether a page is being compacted. + /// + /// - 0 for pages being compacted. + /// - 1 otherwise. + compacting_bit: usize, + + /// The page index to which a page is being compacted. + new_page_range: bitfield::BitRange, +} + +impl Format { + /// Returns a helper to parse the store format for a given storage and config. + /// + /// # Errors + /// + /// Returns `None` if any of the following conditions does not hold: + /// - The word size must be a power of two. + /// - The page size must be a power of two. + /// - There should be at least 2 pages in the storage. + /// - It should be possible to write a word at least twice. + /// - It should be possible to erase a page at least once. + /// - There should be at least 1 tag. + pub fn new(storage: &S, config: &C) -> Option { + let word_size = storage.word_size(); + let page_size = storage.page_size(); + let num_pages = storage.num_pages(); + let max_word_writes = storage.max_word_writes(); + let max_page_erases = storage.max_page_erases(); + let num_tags = config.num_tags(); + if !(word_size.is_power_of_two() + && page_size.is_power_of_two() + && num_pages > 1 + && max_word_writes >= 2 + && max_page_erases > 0 + && num_tags > 0) + { + return None; + } + // Compute how many bits we need to store the fields. + let page_bits = num_bits(num_pages); + let byte_bits = num_bits(page_size); + let tag_bits = num_bits(num_tags); + let erase_bits = num_bits(max_page_erases + 1); + // Compute the bit position of the fields. + let present_bit = 0; + let deleted_bit = present_bit + 1; + let internal_bit = deleted_bit + 1; + let replace_bit = internal_bit + 1; + let length_range = bitfield::BitRange { + start: replace_bit + 1, + length: byte_bits, + }; + let tag_range = bitfield::BitRange { + start: length_range.end(), + length: tag_bits, + }; + let replace_page_range = bitfield::BitRange { + start: tag_range.end(), + length: page_bits, + }; + let replace_byte_range = bitfield::BitRange { + start: replace_page_range.end(), + length: byte_bits, + }; + let old_page_range = bitfield::BitRange { + start: internal_bit + 1, + length: page_bits, + }; + let saved_erase_count_range = bitfield::BitRange { + start: old_page_range.end(), + length: erase_bits, + }; + let initialized_bit = 0; + let erase_count_range = bitfield::BitRange { + start: initialized_bit + 1, + length: erase_bits, + }; + let compacting_bit = erase_count_range.end(); + let new_page_range = bitfield::BitRange { + start: compacting_bit + 1, + length: page_bits, + }; + let format = Format { + word_size, + page_size, + num_pages, + max_page_erases, + num_tags, + present_bit, + deleted_bit, + internal_bit, + replace_bit, + length_range, + tag_range, + replace_page_range, + replace_byte_range, + old_page_range, + saved_erase_count_range, + initialized_bit, + erase_count_range, + compacting_bit, + new_page_range, + }; + // Make sure all the following conditions hold: + // - The page header is one word. + // - The internal entry is one word. + // - The entry header fits in one word. + if format.page_header_size() != word_size + || format.internal_entry_size() != word_size + || format.header_size() > word_size + { + return None; + } + Some(format) + } + + /// Ensures a user entry is valid. + pub fn validate_entry(&self, entry: StoreEntry) -> Result<(), StoreError> { + if entry.tag >= self.num_tags { + return Err(StoreError::InvalidTag); + } + if entry.data.len() >= self.page_size { + return Err(StoreError::StoreFull); + } + Ok(()) + } + + /// Returns the entry header length in bytes. + /// + /// This is the smallest number of bytes necessary to store all fields of the entry info up to + /// and including `length`. + pub fn header_size(&self) -> usize { + self.bits_to_bytes(self.length_range.end()) + } + + /// Returns the entry info length in bytes. + /// + /// This is the number of bytes necessary to store all fields of the entry info. This also + /// includes the internal padding to protect the `committed` bit from the `deleted` bit. + fn info_size(&self, is_replace: IsReplace) -> usize { + let suffix_bits = 2; // committed + complete + let info_bits = match is_replace { + IsReplace::Replace => self.replace_byte_range.end() + suffix_bits, + IsReplace::Insert => self.tag_range.end() + suffix_bits, + }; + let info_size = self.bits_to_bytes(info_bits); + // If the suffix bits would end up in the header, we need to add one byte for them. + if info_size == self.header_size() { + info_size + 1 + } else { + info_size + } + } + + /// Returns the length in bytes of an entry. + /// + /// This depends on the length of the user data and whether the entry replaces an old entry or + /// is an insertion. This also includes the internal padding to protect the `committed` bit from + /// the `deleted` bit. + pub fn entry_size(&self, is_replace: IsReplace, length: usize) -> usize { + let mut entry_size = length + self.info_size(is_replace); + let word_size = self.word_size; + entry_size = self.align_word(entry_size); + // The entry must be at least 2 words such that the `committed` and `deleted` bits are on + // different words. + if entry_size == word_size { + entry_size += word_size; + } + entry_size + } + + /// Returns the length in bytes of an internal entry. + pub fn internal_entry_size(&self) -> usize { + let length = self.bits_to_bytes(self.saved_erase_count_range.end()); + self.align_word(length) + } + + pub fn is_present(&self, header: &[u8]) -> bool { + bitfield::is_zero(self.present_bit, header, bitfield::NO_GAP) + } + + pub fn set_present(&self, header: &mut [u8]) { + bitfield::set_zero(self.present_bit, header, bitfield::NO_GAP) + } + + pub fn is_deleted(&self, header: &[u8]) -> bool { + bitfield::is_zero(self.deleted_bit, header, bitfield::NO_GAP) + } + + /// Returns whether an entry is present and not deleted. + pub fn is_alive(&self, header: &[u8]) -> bool { + self.is_present(header) && !self.is_deleted(header) + } + + pub fn set_deleted(&self, header: &mut [u8]) { + bitfield::set_zero(self.deleted_bit, header, bitfield::NO_GAP) + } + + pub fn is_internal(&self, header: &[u8]) -> bool { + bitfield::is_zero(self.internal_bit, header, bitfield::NO_GAP) + } + + pub fn set_internal(&self, header: &mut [u8]) { + bitfield::set_zero(self.internal_bit, header, bitfield::NO_GAP) + } + + pub fn is_replace(&self, header: &[u8]) -> IsReplace { + if bitfield::is_zero(self.replace_bit, header, bitfield::NO_GAP) { + IsReplace::Replace + } else { + IsReplace::Insert + } + } + + fn set_replace(&self, header: &mut [u8]) { + bitfield::set_zero(self.replace_bit, header, bitfield::NO_GAP) + } + + pub fn get_length(&self, header: &[u8]) -> usize { + bitfield::get_range(self.length_range, header, bitfield::NO_GAP) + } + + fn set_length(&self, header: &mut [u8], length: usize) { + bitfield::set_range(self.length_range, header, bitfield::NO_GAP, length) + } + + pub fn get_data<'a>(&self, entry: &'a [u8]) -> &'a [u8] { + &entry[self.header_size()..][..self.get_length(entry)] + } + + /// Returns the span of user data in an entry. + /// + /// The complement of this gap in the entry is exactly the entry info. The header is before the + /// gap and the footer is after the gap. + fn entry_gap(&self, entry: &[u8]) -> bitfield::ByteGap { + let start = self.header_size(); + let length = self.get_length(entry); + bitfield::ByteGap { start, length } + } + + pub fn get_tag(&self, entry: &[u8]) -> usize { + bitfield::get_range(self.tag_range, entry, self.entry_gap(entry)) + } + + fn set_tag(&self, entry: &mut [u8], tag: usize) { + bitfield::set_range(self.tag_range, entry, self.entry_gap(entry), tag) + } + + pub fn get_replace_index(&self, entry: &[u8]) -> Index { + let gap = self.entry_gap(entry); + let page = bitfield::get_range(self.replace_page_range, entry, gap); + let byte = bitfield::get_range(self.replace_byte_range, entry, gap); + Index { page, byte } + } + + fn set_replace_page(&self, entry: &mut [u8], page: usize) { + bitfield::set_range(self.replace_page_range, entry, self.entry_gap(entry), page) + } + + fn set_replace_byte(&self, entry: &mut [u8], byte: usize) { + bitfield::set_range(self.replace_byte_range, entry, self.entry_gap(entry), byte) + } + + /// Returns the bit position of the `committed` bit. + /// + /// This cannot be precomputed like other fields since it depends on the length of the entry. + fn committed_bit(&self, entry: &[u8]) -> usize { + 8 * entry.len() - 2 + } + + /// Returns the bit position of the `complete` bit. + /// + /// This cannot be precomputed like other fields since it depends on the length of the entry. + fn complete_bit(&self, entry: &[u8]) -> usize { + 8 * entry.len() - 1 + } + + pub fn is_committed(&self, entry: &[u8]) -> bool { + bitfield::is_zero(self.committed_bit(entry), entry, bitfield::NO_GAP) + } + + pub fn set_committed(&self, entry: &mut [u8]) { + bitfield::set_zero(self.committed_bit(entry), entry, bitfield::NO_GAP) + } + + pub fn is_complete(&self, entry: &[u8]) -> bool { + bitfield::is_zero(self.complete_bit(entry), entry, bitfield::NO_GAP) + } + + fn set_complete(&self, entry: &mut [u8]) { + bitfield::set_zero(self.complete_bit(entry), entry, bitfield::NO_GAP) + } + + pub fn get_old_page(&self, header: &[u8]) -> usize { + bitfield::get_range(self.old_page_range, header, bitfield::NO_GAP) + } + + pub fn set_old_page(&self, header: &mut [u8], old_page: usize) { + bitfield::set_range(self.old_page_range, header, bitfield::NO_GAP, old_page) + } + + pub fn get_saved_erase_count(&self, header: &[u8]) -> usize { + bitfield::get_range(self.saved_erase_count_range, header, bitfield::NO_GAP) + } + + pub fn set_saved_erase_count(&self, header: &mut [u8], erase_count: usize) { + bitfield::set_range( + self.saved_erase_count_range, + header, + bitfield::NO_GAP, + erase_count, + ) + } + + /// Builds an entry for replace or insert operations. + pub fn build_entry(&self, replace: Option, user_entry: StoreEntry) -> Vec { + let StoreEntry { tag, data } = user_entry; + let is_replace = match replace { + None => IsReplace::Insert, + Some(_) => IsReplace::Replace, + }; + let entry_len = self.entry_size(is_replace, data.len()); + let mut entry = Vec::with_capacity(entry_len); + // Build the header. + entry.resize(self.header_size(), 0xff); + self.set_present(&mut entry[..]); + self.set_length(&mut entry[..], data.len()); + // Add the data. + entry.extend_from_slice(data); + // Build the footer. + entry.resize(entry_len, 0xff); + self.set_tag(&mut entry[..], tag); + self.set_complete(&mut entry[..]); + match replace { + None => self.set_committed(&mut entry[..]), + Some(Index { page, byte }) => { + self.set_replace(&mut entry[..]); + self.set_replace_page(&mut entry[..], page); + self.set_replace_byte(&mut entry[..], byte); + } + } + entry + } + + /// Builds an entry for replace or insert operations. + pub fn build_erase_entry(&self, old_page: usize, saved_erase_count: usize) -> Vec { + let mut entry = vec![0xff; self.internal_entry_size()]; + self.set_present(&mut entry[..]); + self.set_internal(&mut entry[..]); + self.set_old_page(&mut entry[..], old_page); + self.set_saved_erase_count(&mut entry[..], saved_erase_count); + entry + } + + /// Returns the length in bytes of a page header entry. + /// + /// This includes the word padding. + pub fn page_header_size(&self) -> usize { + self.align_word(self.bits_to_bytes(self.erase_count_range.end())) + } + + pub fn is_initialized(&self, header: &[u8]) -> bool { + bitfield::is_zero(self.initialized_bit, header, bitfield::NO_GAP) + } + + pub fn set_initialized(&self, header: &mut [u8]) { + bitfield::set_zero(self.initialized_bit, header, bitfield::NO_GAP) + } + + pub fn get_erase_count(&self, header: &[u8]) -> usize { + bitfield::get_range(self.erase_count_range, header, bitfield::NO_GAP) + } + + pub fn set_erase_count(&self, header: &mut [u8], count: usize) { + bitfield::set_range(self.erase_count_range, header, bitfield::NO_GAP, count) + } + + pub fn is_compacting(&self, header: &[u8]) -> bool { + bitfield::is_zero(self.compacting_bit, header, bitfield::NO_GAP) + } + + pub fn set_compacting(&self, header: &mut [u8]) { + bitfield::set_zero(self.compacting_bit, header, bitfield::NO_GAP) + } + + pub fn get_new_page(&self, header: &[u8]) -> usize { + bitfield::get_range(self.new_page_range, header, bitfield::NO_GAP) + } + + pub fn set_new_page(&self, header: &mut [u8], new_page: usize) { + bitfield::set_range(self.new_page_range, header, bitfield::NO_GAP, new_page) + } + + /// Returns the smallest word boundary greater or equal to a value. + fn align_word(&self, value: usize) -> usize { + let word_size = self.word_size; + (value + word_size - 1) / word_size * word_size + } + + /// Returns the minimum number of bytes to represent a given number of bits. + fn bits_to_bytes(&self, bits: usize) -> usize { + (bits + 7) / 8 + } +} + +/// Returns the number of bits necessary to write numbers smaller than `x`. +fn num_bits(x: usize) -> usize { + x.next_power_of_two().trailing_zeros() as usize +} + +#[test] +fn num_bits_ok() { + assert_eq!(num_bits(0), 0); + assert_eq!(num_bits(1), 0); + assert_eq!(num_bits(2), 1); + assert_eq!(num_bits(3), 2); + assert_eq!(num_bits(4), 2); + assert_eq!(num_bits(5), 3); + assert_eq!(num_bits(8), 3); + assert_eq!(num_bits(9), 4); + assert_eq!(num_bits(16), 4); +} diff --git a/src/embedded_flash/store/mod.rs b/src/embedded_flash/store/mod.rs new file mode 100644 index 0000000..0431073 --- /dev/null +++ b/src/embedded_flash/store/mod.rs @@ -0,0 +1,1028 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Provides a multi-purpose data-structure. +//! +//! # Description +//! +//! The `Store` data-structure permits to iterate, find, insert, delete, and replace entries in a +//! multi-set. The mutable operations (insert, delete, and replace) are atomic, in the sense that if +//! power is lost during the operation, then the operation might either succeed or fail but the +//! store remains in a coherent state. The data-structure is flash-efficient, in the sense that it +//! tries to minimize the number of times a page is erased. +//! +//! An _entry_ is made of a _tag_, which is a number, and a _data_, which is a slice of bytes. The +//! tag is stored efficiently by using unassigned bits of the entry header and footer. For example, +//! it can be used to decide how to deserialize the data. It is not necessary to use tags since a +//! prefix of the data could be used to decide how to deserialize the rest. +//! +//! Entries can also be associated to a set of _keys_. The find operation permits to retrieve all +//! entries associated to a given key. The same key can be associated to multiple entries and the +//! same entry can be associated to multiple keys. +//! +//! # Storage +//! +//! The data-structure is parametric over its storage which must implement the `Storage` trait. +//! There are currently 2 implementations of this trait: +//! - `SyscallStorage` using the `embedded_flash` syscall API for production builds. +//! - `BufferStorage` using a heap-allocated buffer for testing. +//! +//! # Configuration +//! +//! The data-structure can be configured with the `StoreConfig` trait. By implementing this trait, +//! the number of possible tags and the association between keys and entries are defined. +//! +//! # Implementation +//! +//! The store is a page-aligned sequence of bits. It matches the following grammar: +//! +//! ```text +//! Store := Page* +//! Page := PageHeader (Entry | InternalEntry)* Padding(page) +//! PageHeader := // must fit in one word +//! initialized:1 +//! erase_count:erase_bits +//! compacting:1 +//! new_page:page_bits +//! Padding(word) +//! Entry := Header Data Footer +//! // Let X be the byte following `length` in `Info`. +//! Header := Info[..X] // must fit in one word +//! Footer := Info[X..] // must fit in one word +//! Info := +//! present=0 +//! deleted:1 +//! internal=1 +//! replace:1 +//! length:byte_bits +//! tag:tag_bits +//! [ // present if `replace` is 0 +//! replace_page:page_bits +//! replace_byte:byte_bits +//! ] +//! [Padding(bit)] // until `complete` is the last bit of a different word than `present` +//! committed:1 +//! complete=0 +//! InternalEntry := +//! present=0 +//! deleted:1 +//! internal=0 +//! old_page:page_bits +//! saved_erase_count:erase_bits +//! Padding(word) +//! Padding(X) := 1* until X-aligned +//! ``` +//! +//! For bit flags, a value of 0 means true and a value of 1 means false. So when erased, bits are +//! false. They can be set to true by writing 0. +//! +//! The `Entry` rule is for user entries and the `InternalEntry` rule is for internal entries of the +//! store. Currently, there is only one kind of internal entry: an entry to erase the page being +//! compacted. +//! +//! The `Header` and `Footer` rules are computed from the `Info` rule. An entry could simply be the +//! concatenation of internal metadata and the user data. However, to optimize the size in flash, we +//! splice the user data in the middle of the metadata. The reason is that we can only write twice +//! the same word and for replace entries we need to write the deleted bit and the committed bit +//! independently. Also, this is important for the complete bit to be the last written bit (since +//! slices are written to flash from low to high addresses). Here is the representation of a +//! specific replace entry for a specific configuration: +//! +//! ```text +//! page_bits=6 +//! byte_bits=9 +//! tag_bits=5 +//! +//! byte.bit name +//! 0.0 present +//! 0.1 deleted +//! 0.2 internal +//! 0.3 replace +//! 0.4 length (9 bits) +//! 1.5 tag (least significant 3 bits out of 5) +//! (the header ends at the first byte boundary after `length`) +//! 2.0 (2 bytes in this example) +//! (the footer starts immediately after the user data) +//! 4.0 tag (most significant 2 bits out of 5) +//! 4.2 replace_page (6 bits) +//! 5.0 replace_byte (9 bits) +//! 6.1 padding (make sure the 2 properties below hold) +//! 7.6 committed +//! 7.7 complete (on a different word than `present`) +//! 8.0 (word-aligned) +//! ``` +//! +//! The store should always contain at least one blank page, so that it is always possible to +//! compact. + +// TODO(cretin): We don't need inner padding for insert entries. The store format can be: +// InsertEntry | ReplaceEntry | InternalEntry (maybe rename to EraseEntry) +// InsertEntry padding is until `complete` is the last bit of a word. +// ReplaceEntry padding is until `complete` is the last bit of a different word than `present`. +// TODO(cretin): Add checksum (may play the same role as the completed bit) and recovery strategy? +// TODO(cretin): Add corruption (deterministic but undetermined reads) to fuzzing. +// TODO(cretin): Add more complex transactions? (this does not seem necessary yet) +// TODO(cretin): Add possibility to shred an entry (force compact page after delete)? + +mod bitfield; +mod format; + +use self::format::{Format, IsReplace}; +#[cfg(feature = "std")] +use super::BufferStorage; +use super::{Index, Storage}; +use alloc::collections::BTreeMap; +use alloc::vec::Vec; + +/// Configures a store. +pub trait StoreConfig { + /// How entries are keyed. + /// + /// To disable keys, this may be defined to `()` or even better a custom empty enum. + type Key: Ord; + + /// Number of entry tags. + /// + /// All tags must be smaller than this value. + /// + /// To disable tags, this function should return `1`. The only valid tag would then be `0`. + fn num_tags(&self) -> usize; + + /// Specifies the set of keys of an entry. + /// + /// If keys are not used, this function can immediately return. Otherwise, it should call + /// `associate_key` for each key that should be associated to `entry`. + fn keys(&self, entry: StoreEntry, associate_key: impl FnMut(Self::Key)); +} + +/// Errors returned by store operations. +#[derive(Debug, PartialEq, Eq)] +pub enum StoreError { + /// The operation could not proceed because the store is full. + StoreFull, + + /// The operation could not proceed because the provided tag is invalid. + InvalidTag, + + /// The operation could not proceed because the preconditions do not hold. + InvalidPrecondition, +} + +/// The position of an entry in the store. +#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Copy, Clone)] +pub struct StoreIndex { + /// The index of this entry in the storage. + index: Index, + + /// The generation at which this index is valid. + /// + /// See the documentation of the field with the same name in the `Store` struct. + generation: usize, +} + +/// A user entry. +#[cfg_attr(feature = "std", derive(Debug, PartialEq, Eq))] +#[derive(Copy, Clone)] +pub struct StoreEntry<'a> { + /// The tag of the entry. + /// + /// Must be smaller than the configured number of tags. + pub tag: usize, + + /// The data of the entry. + pub data: &'a [u8], +} + +/// Implements a configurable multi-set on top of any storage. +pub struct Store { + storage: S, + config: C, + format: Format, + + /// The index of the blank page reserved for compaction. + blank_page: usize, + + /// Counts the number of compactions since the store creation. + /// + /// A `StoreIndex` is valid only if they originate from the same generation. This is checked by + /// operations that take a `StoreIndex` as argument. + generation: usize, +} + +impl Store { + /// Creates a new store. + /// + /// Initializes the storage if it is fresh (filled with `0xff`). Rolls-back or completes an + /// operation if the store was powered off in the middle of that operation. In other words, + /// operations are atomic. + /// + /// # Errors + /// + /// Returns `None` if `storage` and/or `config` are not supported. + pub fn new(storage: S, config: C) -> Option> { + let format = Format::new(&storage, &config)?; + let blank_page = format.num_pages; + let mut store = Store { + storage, + config, + format, + blank_page, + generation: 0, + }; + // Finish any ongoing page compaction. + store.recover_compact_page(); + // Finish or roll-back any other entry-level operations. + store.recover_entry_operations(); + // Initialize uninitialized pages. + store.initialize_storage(); + Some(store) + } + + /// Iterates over all entries in the store. + pub fn iter(&self) -> impl Iterator { + Iter::new(self).filter_map(move |(index, entry)| { + if self.format.is_alive(entry) { + Some(( + StoreIndex { + index, + generation: self.generation, + }, + StoreEntry { + tag: self.format.get_tag(entry), + data: self.format.get_data(entry), + }, + )) + } else { + None + } + }) + } + + /// Iterates over all entries matching a key in the store. + pub fn find_all<'a>( + &'a self, + key: &'a C::Key, + ) -> impl Iterator + 'a { + self.iter().filter(move |&(_, entry)| { + let mut has_match = false; + self.config.keys(entry, |k| has_match |= key == &k); + has_match + }) + } + + /// Returns the first entry matching a key in the store. + /// + /// This is a convenience function for when at most one entry should match the key. + /// + /// # Panics + /// + /// In debug mode, panics if more than one entry matches the key. + pub fn find_one<'a>(&'a self, key: &'a C::Key) -> Option<(StoreIndex, StoreEntry<'a>)> { + let mut iter = self.find_all(key); + let first = iter.next()?; + let has_only_one_element = iter.next().is_none(); + debug_assert!(has_only_one_element); + Some(first) + } + + /// Deletes an entry from the store. + pub fn delete(&mut self, index: StoreIndex) -> Result<(), StoreError> { + if self.generation != index.generation { + return Err(StoreError::InvalidPrecondition); + } + self.delete_index(index.index); + Ok(()) + } + + /// Replaces an entry with another with the same tag in the store. + /// + /// This operation (like others) is atomic. If it returns successfully, then the old entry is + /// deleted and the new is inserted. If it fails, the old entry is not deleted and the new entry + /// is not inserted. If power is lost during the operation, during next startup, the operation + /// is either rolled-back (like in case of failure) or completed (like in case of success). + /// + /// # Errors + /// + /// Returns: + /// - `StoreFull` if the new entry does not fit in the store. + /// - `InvalidTag` if the tag of the new entry is not smaller than the configured number of + /// tags. + pub fn replace(&mut self, old: StoreIndex, new: StoreEntry) -> Result<(), StoreError> { + if self.generation != old.generation { + return Err(StoreError::InvalidPrecondition); + } + self.format.validate_entry(new)?; + let mut old_index = old.index; + // Find a slot. + let entry_len = self.replace_len(new.data.len()); + let index = self.find_slot_for_write(entry_len, Some(&mut old_index))?; + // Build a new entry replacing the old one. + let entry = self.format.build_entry(Some(old_index), new); + debug_assert_eq!(entry.len(), entry_len); + // Write the new entry. + self.write_entry(index, &entry); + // Commit the new entry, which both deletes the old entry and commits the new one. + self.commit_index(index); + Ok(()) + } + + /// Inserts an entry in the store. + /// + /// # Errors + /// + /// Returns: + /// - `StoreFull` if the new entry does not fit in the store. + /// - `InvalidTag` if the tag of the new entry is not smaller than the configured number of + /// tags. + pub fn insert(&mut self, entry: StoreEntry) -> Result<(), StoreError> { + self.format.validate_entry(entry)?; + // Build entry. + let entry = self.format.build_entry(None, entry); + // Find a slot. + let index = self.find_slot_for_write(entry.len(), None)?; + // Write entry. + self.write_entry(index, &entry); + Ok(()) + } + + /// Returns the byte cost of a replace operation. + /// + /// Computes the length in bytes that would be used in the storage if a replace operation is + /// executed provided the data of the new entry has `length` bytes. + pub fn replace_len(&self, length: usize) -> usize { + self.format.entry_size(IsReplace::Replace, length) + } + + /// Returns the byte cost of an insert operation. + /// + /// Computes the length in bytes that would be used in the storage if an insert operation is + /// executed provided the data of the inserted entry has `length` bytes. + pub fn insert_len(&self, length: usize) -> usize { + self.format.entry_size(IsReplace::Insert, length) + } + + /// Returns the erase count of all pages. + /// + /// The value at index `page` of the result is the number of times page `page` was erased. This + /// number is an underestimate in case power was lost when this page was erased. + pub fn compaction_info(&self) -> Vec { + let mut info = Vec::with_capacity(self.format.num_pages); + for page in 0..self.format.num_pages { + let (page_header, _) = self.read_page_header(page); + let erase_count = self.format.get_erase_count(page_header); + info.push(erase_count); + } + info + } + + /// Completes any ongoing page compaction. + fn recover_compact_page(&mut self) { + for page in 0..self.format.num_pages { + let (page_header, _) = self.read_page_header(page); + if self.format.is_compacting(page_header) { + let new_page = self.format.get_new_page(page_header); + self.compact_page(page, new_page); + } + } + } + + /// Rolls-back or completes any ongoing operation. + fn recover_entry_operations(&mut self) { + for page in 0..self.format.num_pages { + let (page_header, mut index) = self.read_page_header(page); + if !self.format.is_initialized(page_header) { + // Skip uninitialized pages. + continue; + } + while index.byte < self.format.page_size { + let entry_index = index; + let entry = self.read_entry(index); + index.byte += entry.len(); + if !self.format.is_alive(entry) { + // Skip deleted entries (or the page padding). + } else if self.format.is_internal(entry) { + // Finish page compaction. + self.erase_page(entry_index); + } else if !self.format.is_complete(entry) { + // Roll-back incomplete operations. + self.delete_index(entry_index); + } else if !self.format.is_committed(entry) { + // Finish complete but uncommitted operations. + self.commit_index(entry_index) + } + } + } + } + + /// Initializes uninitialized pages. + fn initialize_storage(&mut self) { + for page in 0..self.format.num_pages { + let (header, index) = self.read_page_header(page); + if self.format.is_initialized(header) { + // Update blank page. + let first_entry = self.read_entry(index); + if !self.format.is_present(first_entry) { + self.blank_page = page; + } + } else { + // We set the erase count to zero the very first time we initialize a page. + self.initialize_page(page, 0); + } + } + debug_assert!(self.blank_page != self.format.num_pages); + } + + /// Marks an entry as deleted. + /// + /// The provided index must point to the beginning of an entry. + fn delete_index(&mut self, index: Index) { + self.update_word(index, |format, word| format.set_deleted(word)); + } + + /// Finds a page with enough free space. + /// + /// Returns an index to the free space of a page which can hold an entry of `length` bytes. If + /// necessary, pages may be compacted to free space. In that case, if provided, the `old_index` + /// is updated according to compaction. + fn find_slot_for_write( + &mut self, + length: usize, + mut old_index: Option<&mut Index>, + ) -> Result { + loop { + if let Some(index) = self.choose_slot_for_write(length) { + return Ok(index); + } + match self.choose_page_for_compact() { + None => return Err(StoreError::StoreFull), + Some(page) => { + let blank_page = self.blank_page; + // Compact the chosen page and update the old index to point to the entry in the + // new page if it happened to be in the old page. This is essentially a way to + // avoid index invalidation due to compaction. + let map = self.compact_page(page, blank_page); + if let Some(old_index) = &mut old_index { + map_index(page, blank_page, &map, old_index); + } + } + } + } + } + + /// Returns whether a page has enough free space. + /// + /// Returns an index to the free space of a page with smallest free space that may hold `length` + /// bytes. + fn choose_slot_for_write(&self, length: usize) -> Option { + Iter::new(self) + .filter(|(index, entry)| { + index.page != self.blank_page + && !self.format.is_present(entry) + && length <= entry.len() + }) + .min_by_key(|(_, entry)| entry.len()) + .map(|(index, _)| index) + } + + /// Returns the page that should be compacted. + fn choose_page_for_compact(&self) -> Option { + // TODO(cretin): This could be optimized by using some cost function depending on: + // - the erase count + // - the length of the free space + // - the length of the alive entries + // We want to minimize this cost. We could also take into account the length of the entry we + // want to write to bound the number of compaction before failing with StoreFull. + // + // We should also make sure that all pages (including if they have no deleted entries and no + // free space) are eventually compacted (ideally to a heavily used page) to benefit from the + // low erase count of those pages. + (0..self.format.num_pages) + .map(|page| (page, self.page_info(page))) + .filter(|&(page, ref info)| { + page != self.blank_page + && info.erase_count < self.format.max_page_erases + && info.deleted_length > self.format.internal_entry_size() + }) + .min_by(|(_, lhs_info), (_, rhs_info)| lhs_info.compare_for_compaction(rhs_info)) + .map(|(page, _)| page) + } + + fn page_info(&self, page: usize) -> PageInfo { + let (page_header, mut index) = self.read_page_header(page); + let mut info = PageInfo { + erase_count: self.format.get_erase_count(page_header), + deleted_length: 0, + free_length: 0, + }; + while index.byte < self.format.page_size { + let entry = self.read_entry(index); + index.byte += entry.len(); + if !self.format.is_present(entry) { + debug_assert_eq!(info.free_length, 0); + info.free_length = entry.len(); + } else if self.format.is_deleted(entry) { + info.deleted_length += entry.len(); + } + } + debug_assert_eq!(index.page, page); + info + } + + fn read_slice(&self, index: Index, length: usize) -> &[u8] { + self.storage.read_slice(index, length).unwrap() + } + + /// Reads an entry (with header and footer) at a given index. + /// + /// If no entry is present, returns the free space up to the end of the page. + fn read_entry(&self, index: Index) -> &[u8] { + let first_byte = self.read_slice(index, 1); + let max_length = self.format.page_size - index.byte; + let mut length = if !self.format.is_present(first_byte) { + max_length + } else if self.format.is_internal(first_byte) { + self.format.internal_entry_size() + } else { + let header = self.read_slice(index, self.format.header_size()); + let replace = self.format.is_replace(header); + let length = self.format.get_length(header); + self.format.entry_size(replace, length) + }; + // Truncate the length to fit the page. This can only happen in case of corruption or + // partial writes. + length = core::cmp::min(length, max_length); + self.read_slice(index, length) + } + + /// Reads a page header. + /// + /// Also returns the index after the page header. + fn read_page_header(&self, page: usize) -> (&[u8], Index) { + let mut index = Index { page, byte: 0 }; + let page_header = self.read_slice(index, self.format.page_header_size()); + index.byte += page_header.len(); + (page_header, index) + } + + /// Updates a word at a given index. + /// + /// The `update` function is called with the word at `index`. The input value is the current + /// value of the word. The output value is the value that will be written. It should only change + /// bits from 1 to 0. + fn update_word(&mut self, index: Index, update: impl FnOnce(&Format, &mut [u8])) { + let word_size = self.format.word_size; + let mut word = self.read_slice(index, word_size).to_vec(); + update(&self.format, &mut word); + self.storage.write_slice(index, &word).unwrap(); + } + + fn write_entry(&mut self, index: Index, entry: &[u8]) { + self.storage.write_slice(index, entry).unwrap(); + } + + /// Initializes a page by writing the page header. + /// + /// If the page is not erased, it is first erased. + fn initialize_page(&mut self, page: usize, erase_count: usize) { + let index = Index { page, byte: 0 }; + let page = self.read_slice(index, self.format.page_size); + if !page.iter().all(|&byte| byte == 0xff) { + self.storage.erase_page(index.page).unwrap(); + } + self.update_word(index, |format, header| { + format.set_initialized(header); + format.set_erase_count(header, erase_count); + }); + self.blank_page = index.page; + } + + /// Commits a replace entry. + /// + /// Deletes the old entry and commits the new entry. + fn commit_index(&mut self, mut index: Index) { + let entry = self.read_entry(index); + index.byte += entry.len(); + let word_size = self.format.word_size; + debug_assert!(entry.len() >= 2 * word_size); + match self.format.is_replace(entry) { + IsReplace::Replace => { + let delete_index = self.format.get_replace_index(entry); + self.delete_index(delete_index); + } + IsReplace::Insert => debug_assert!(false), + }; + index.byte -= word_size; + self.update_word(index, |format, word| format.set_committed(word)); + } + + /// Compacts a page to an other. + /// + /// Returns the mapping from the alive entries in the old page to their index in the new page. + fn compact_page(&mut self, old_page: usize, new_page: usize) -> BTreeMap { + // Write the old page as being compacted to the new page. + let mut erase_count = 0; + self.update_word( + Index { + page: old_page, + byte: 0, + }, + |format, header| { + erase_count = format.get_erase_count(header); + format.set_compacting(header); + format.set_new_page(header, new_page); + }, + ); + // Copy alive entries from the old page to the new page. + let page_header_size = self.format.page_header_size(); + let mut old_index = Index { + page: old_page, + byte: page_header_size, + }; + let mut new_index = Index { + page: new_page, + byte: page_header_size, + }; + let mut map = BTreeMap::new(); + while old_index.byte < self.format.page_size { + let old_entry = self.read_entry(old_index); + let old_entry_index = old_index.byte; + old_index.byte += old_entry.len(); + if !self.format.is_alive(old_entry) { + continue; + } + let previous_mapping = map.insert(old_entry_index, new_index.byte); + debug_assert!(previous_mapping.is_none()); + // We need to copy the old entry because it is in the storage and we are going to write + // to the storage. Rust cannot tell that both entries don't overlap. + let old_entry = old_entry.to_vec(); + self.write_entry(new_index, &old_entry); + new_index.byte += old_entry.len(); + } + // Save the old page index and erase count to the new page. + let erase_index = new_index; + let erase_entry = self.format.build_erase_entry(old_page, erase_count); + self.storage.write_slice(new_index, &erase_entry).unwrap(); + // Erase the page. + self.erase_page(erase_index); + // Increase generation. + self.generation += 1; + map + } + + /// Commits an internal entry. + /// + /// The only kind of internal entry is to erase a page, which first erases the page, then + /// initializes it with the saved erase count, and finally deletes the internal entry. + fn erase_page(&mut self, erase_index: Index) { + let erase_entry = self.read_entry(erase_index); + debug_assert!(self.format.is_present(erase_entry)); + debug_assert!(!self.format.is_deleted(erase_entry)); + debug_assert!(self.format.is_internal(erase_entry)); + let old_page = self.format.get_old_page(erase_entry); + let erase_count = self.format.get_saved_erase_count(erase_entry) + 1; + // Erase the page. + self.storage.erase_page(old_page).unwrap(); + // Initialize the page. + self.initialize_page(old_page, erase_count); + // Delete the internal entry. + self.delete_index(erase_index); + } +} + +// Those functions are not meant for production. +#[cfg(feature = "std")] +impl Store { + /// Takes a snapshot of the storage after a given amount of word operations. + pub fn arm_snapshot(&mut self, delay: usize) { + self.storage.arm_snapshot(delay); + } + + /// Unarms and returns the snapshot or the delay remaining. + pub fn get_snapshot(&mut self) -> Result, usize> { + self.storage.get_snapshot() + } + + /// Takes a snapshot of the storage. + pub fn take_snapshot(&self) -> Box<[u8]> { + self.storage.take_snapshot() + } + + /// Returns the storage. + pub fn get_storage(self) -> Box<[u8]> { + self.storage.get_storage() + } + + /// Erases and initializes a page with a given erase count. + pub fn set_erase_count(&mut self, page: usize, erase_count: usize) { + self.initialize_page(page, erase_count); + } +} + +/// Maps an index from an old page to a new page if needed. +fn map_index(old_page: usize, new_page: usize, map: &BTreeMap, index: &mut Index) { + if index.page == old_page { + index.page = new_page; + index.byte = *map.get(&index.byte).unwrap(); + } +} + +/// Page information for compaction. +struct PageInfo { + /// How many times the page was erased. + erase_count: usize, + + /// Cumulative length of deleted entries (including header and footer). + deleted_length: usize, + + /// Length of the free space. + free_length: usize, +} + +impl PageInfo { + /// Returns whether a page should be compacted before another. + fn compare_for_compaction(&self, rhs: &PageInfo) -> core::cmp::Ordering { + self.erase_count + .cmp(&rhs.erase_count) + .then(rhs.deleted_length.cmp(&self.deleted_length)) + .then(self.free_length.cmp(&rhs.free_length)) + } +} + +/// Iterates over all entries (including free space) of a store. +struct Iter<'a, S: Storage, C: StoreConfig> { + store: &'a Store, + index: Index, +} + +impl<'a, S: Storage, C: StoreConfig> Iter<'a, S, C> { + fn new(store: &'a Store) -> Iter<'a, S, C> { + let index = Index { + page: 0, + byte: store.format.page_header_size(), + }; + Iter { store, index } + } +} + +impl<'a, S: Storage, C: StoreConfig> Iterator for Iter<'a, S, C> { + type Item = (Index, &'a [u8]); + + fn next(&mut self) -> Option<(Index, &'a [u8])> { + if self.index.byte == self.store.format.page_size { + self.index.page += 1; + self.index.byte = self.store.format.page_header_size(); + } + if self.index.page == self.store.format.num_pages { + return None; + } + let index = self.index; + let entry = self.store.read_entry(self.index); + self.index.byte += entry.len(); + Some((index, entry)) + } +} + +#[cfg(test)] +mod tests { + use super::super::{BufferOptions, BufferStorage}; + use super::*; + + struct Config; + + const WORD_SIZE: usize = 4; + const PAGE_SIZE: usize = 8 * WORD_SIZE; + const NUM_PAGES: usize = 3; + + impl StoreConfig for Config { + type Key = u8; + + fn num_tags(&self) -> usize { + 1 + } + + fn keys(&self, entry: StoreEntry, mut add: impl FnMut(u8)) { + assert_eq!(entry.tag, 0); + if !entry.data.is_empty() { + add(entry.data[0]); + } + } + } + + fn new_buffer(storage: Box<[u8]>) -> BufferStorage { + let options = BufferOptions { + word_size: WORD_SIZE, + page_size: PAGE_SIZE, + max_word_writes: 2, + max_page_erases: 2, + strict_write: true, + }; + BufferStorage::new(storage, options) + } + + fn new_store() -> Store { + let storage = vec![0xff; NUM_PAGES * PAGE_SIZE].into_boxed_slice(); + Store::new(new_buffer(storage), Config).unwrap() + } + + #[test] + fn insert_ok() { + let mut store = new_store(); + assert_eq!(store.iter().count(), 0); + let tag = 0; + let key = 1; + let data = &[key, 2]; + let entry = StoreEntry { tag, data }; + store.insert(entry).unwrap(); + assert_eq!(store.iter().count(), 1); + assert_eq!(store.find_one(&key).unwrap().1, entry); + } + + #[test] + fn delete_ok() { + let mut store = new_store(); + let tag = 0; + let key = 1; + let entry = StoreEntry { + tag, + data: &[key, 2], + }; + store.insert(entry).unwrap(); + assert_eq!(store.find_all(&key).count(), 1); + let (index, _) = store.find_one(&key).unwrap(); + store.delete(index).unwrap(); + assert_eq!(store.find_all(&key).count(), 0); + assert_eq!(store.iter().count(), 0); + } + + #[test] + fn insert_until_full() { + let mut store = new_store(); + let tag = 0; + let mut key = 0; + while store + .insert(StoreEntry { + tag, + data: &[key, 0], + }) + .is_ok() + { + key += 1; + } + assert!(key > 0); + } + + #[test] + fn compact_ok() { + let mut store = new_store(); + let tag = 0; + let mut key = 0; + while store + .insert(StoreEntry { + tag, + data: &[key, 0], + }) + .is_ok() + { + key += 1; + } + let (index, _) = store.find_one(&0).unwrap(); + store.delete(index).unwrap(); + store + .insert(StoreEntry { + tag: 0, + data: &[key, 0], + }) + .unwrap(); + for k in 1..=key { + assert_eq!(store.find_all(&k).count(), 1); + } + } + + #[test] + fn reboot_ok() { + let mut store = new_store(); + let tag = 0; + let key = 1; + let data = &[key, 2]; + let entry = StoreEntry { tag, data }; + store.insert(entry).unwrap(); + + // Reboot the store. + let store = store.get_storage(); + let store = Store::new(new_buffer(store), Config).unwrap(); + + assert_eq!(store.iter().count(), 1); + assert_eq!(store.find_one(&key).unwrap().1, entry); + } + + #[test] + fn replace_atomic() { + let tag = 0; + let key = 1; + let old_entry = StoreEntry { + tag, + data: &[key, 2, 3, 4, 5, 6], + }; + let new_entry = StoreEntry { + tag, + data: &[key, 7, 8, 9], + }; + let mut delay = 0; + loop { + let mut store = new_store(); + store.insert(old_entry).unwrap(); + store.arm_snapshot(delay); + let (index, _) = store.find_one(&key).unwrap(); + store.replace(index, new_entry).unwrap(); + let (complete, store) = match store.get_snapshot() { + Err(_) => (true, store.get_storage()), + Ok(store) => (false, store), + }; + let store = Store::new(new_buffer(store), Config).unwrap(); + assert_eq!(store.iter().count(), 1); + assert_eq!(store.find_all(&key).count(), 1); + let (_, cur_entry) = store.find_one(&key).unwrap(); + assert!((cur_entry == old_entry && !complete) || cur_entry == new_entry); + if complete { + break; + } + delay += 1; + } + } + + #[test] + fn compact_atomic() { + let tag = 0; + let mut delay = 0; + loop { + let mut store = new_store(); + let mut key = 0; + while store + .insert(StoreEntry { + tag, + data: &[key, 0], + }) + .is_ok() + { + key += 1; + } + let (index, _) = store.find_one(&0).unwrap(); + store.delete(index).unwrap(); + let (index, _) = store.find_one(&1).unwrap(); + store.arm_snapshot(delay); + store + .replace(index, StoreEntry { tag, data: &[1, 1] }) + .unwrap(); + let (complete, store) = match store.get_snapshot() { + Err(_) => (true, store.get_storage()), + Ok(store) => (false, store), + }; + let store = Store::new(new_buffer(store), Config).unwrap(); + assert_eq!(store.iter().count(), key as usize - 1); + for k in 2..key { + assert_eq!(store.find_all(&k).count(), 1); + assert_eq!( + store.find_one(&k).unwrap().1, + StoreEntry { tag, data: &[k, 0] } + ); + } + assert_eq!(store.find_all(&1).count(), 1); + let (_, entry) = store.find_one(&1).unwrap(); + assert_eq!(entry.tag, tag); + assert!((entry.data == [1, 0] && !complete) || entry.data == [1, 1]); + if complete { + break; + } + delay += 1; + } + } + + #[test] + fn invalid_tag() { + let mut store = new_store(); + let entry = StoreEntry { tag: 1, data: &[] }; + assert_eq!(store.insert(entry), Err(StoreError::InvalidTag)); + } + + #[test] + fn invalid_length() { + let mut store = new_store(); + let entry = StoreEntry { + tag: 0, + data: &[0; PAGE_SIZE], + }; + assert_eq!(store.insert(entry), Err(StoreError::StoreFull)); + } +} diff --git a/src/embedded_flash/syscall.rs b/src/embedded_flash/syscall.rs new file mode 100644 index 0000000..7fca17a --- /dev/null +++ b/src/embedded_flash/syscall.rs @@ -0,0 +1,195 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use super::{Index, Storage, StorageError, StorageResult}; +use libtock::syscalls; + +const DRIVER_NUMBER: usize = 0x50003; + +mod command_nr { + pub const GET_INFO: usize = 1; + pub mod get_info_nr { + pub const WORD_SIZE: usize = 0; + pub const PAGE_SIZE: usize = 1; + pub const MAX_WORD_WRITES: usize = 2; + pub const MAX_PAGE_ERASES: usize = 3; + } + pub const WRITE_SLICE: usize = 2; + pub const ERASE_PAGE: usize = 3; +} + +mod allow_nr { + pub const WRITE_SLICE: usize = 0; +} + +fn get_info(nr: usize) -> StorageResult { + let code = unsafe { syscalls::command(DRIVER_NUMBER, command_nr::GET_INFO, nr, 0) }; + if code < 0 { + Err(StorageError::KernelError { code }) + } else { + Ok(code as usize) + } +} + +pub struct SyscallStorage { + word_size: usize, + page_size: usize, + max_word_writes: usize, + max_page_erases: usize, + storage: &'static mut [u8], +} + +impl SyscallStorage { + /// Provides access to the embedded flash if available. + /// + /// # Safety + /// + /// The `storage` must be in a writeable flash region. + /// + /// # Errors + /// + /// Returns `BadFlash` if any of the following conditions do not hold: + /// - The word size is not a power of two. + /// - The page size is not a power of two. + /// - The page size is not a multiple of the word size. + /// + /// Returns `NotAligned` if any of the following conditions do not hold: + /// - `storage` is page-aligned. + /// - `storage.len()` is a multiple of the page size. + /// + /// # Examples + /// + /// ```rust + /// # extern crate ctap2; + /// # use ctap2::embedded_flash::SyscallStorage; + /// # use ctap2::embedded_flash::StorageResult; + /// # const NUM_PAGES: usize = 1; + /// # const PAGE_SIZE: usize = 1; + /// #[link_section = ".app_state"] + /// static mut STORAGE: [u8; NUM_PAGES * PAGE_SIZE] = [0xff; NUM_PAGES * PAGE_SIZE]; + /// # fn foo() -> StorageResult { + /// // This is safe because this is the only use of `STORAGE` in the whole program and this is + /// // called only once. + /// unsafe { SyscallStorage::new(&mut STORAGE) } + /// # } + /// ``` + pub unsafe fn new(storage: &'static mut [u8]) -> StorageResult { + let word_size = get_info(command_nr::get_info_nr::WORD_SIZE)?; + let page_size = get_info(command_nr::get_info_nr::PAGE_SIZE)?; + let max_word_writes = get_info(command_nr::get_info_nr::MAX_WORD_WRITES)?; + let max_page_erases = get_info(command_nr::get_info_nr::MAX_PAGE_ERASES)?; + if !word_size.is_power_of_two() || !page_size.is_power_of_two() { + return Err(StorageError::BadFlash); + } + let syscall = SyscallStorage { + word_size, + page_size, + max_word_writes, + max_page_erases, + storage, + }; + if !syscall.is_word_aligned(page_size) { + return Err(StorageError::BadFlash); + } + if syscall.is_page_aligned(syscall.storage.as_ptr() as usize) + && syscall.is_page_aligned(syscall.storage.len()) + { + Ok(syscall) + } else { + Err(StorageError::NotAligned) + } + } + + fn is_word_aligned(&self, x: usize) -> bool { + x & (self.word_size - 1) == 0 + } + + fn is_page_aligned(&self, x: usize) -> bool { + x & (self.page_size - 1) == 0 + } +} + +impl Storage for SyscallStorage { + fn word_size(&self) -> usize { + self.word_size + } + + fn page_size(&self) -> usize { + self.page_size + } + + fn num_pages(&self) -> usize { + self.storage.len() / self.page_size + } + + fn max_word_writes(&self) -> usize { + self.max_word_writes + } + + fn max_page_erases(&self) -> usize { + self.max_page_erases + } + + fn read_slice(&self, index: Index, length: usize) -> StorageResult<&[u8]> { + Ok(&self.storage[index.range(length, self)?]) + } + + fn write_slice(&mut self, index: Index, value: &[u8]) -> StorageResult<()> { + if !self.is_word_aligned(index.byte) || !self.is_word_aligned(value.len()) { + return Err(StorageError::NotAligned); + } + let range = index.range(value.len(), self)?; + let code = unsafe { + syscalls::allow_ptr( + DRIVER_NUMBER, + allow_nr::WRITE_SLICE, + // We rely on the driver not writing to the slice. This should use read-only allow + // when available. See https://github.com/tock/tock/issues/1274. + value.as_ptr() as *mut u8, + value.len(), + ) + }; + if code < 0 { + return Err(StorageError::KernelError { code }); + } + let code = unsafe { + syscalls::command( + DRIVER_NUMBER, + command_nr::WRITE_SLICE, + self.storage[range].as_ptr() as usize, + 0, + ) + }; + if code < 0 { + return Err(StorageError::KernelError { code }); + } + Ok(()) + } + + fn erase_page(&mut self, page: usize) -> StorageResult<()> { + let range = Index { page, byte: 0 }.range(self.page_size(), self)?; + let code = unsafe { + syscalls::command( + DRIVER_NUMBER, + command_nr::ERASE_PAGE, + self.storage[range].as_ptr() as usize, + 0, + ) + }; + if code < 0 { + return Err(StorageError::KernelError { code }); + } + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..b12f77b --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,21 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[macro_use] +extern crate alloc; +extern crate libtock; + +pub mod embedded_flash; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..753f165 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,388 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[macro_use] +extern crate alloc; +#[macro_use] +extern crate arrayref; +extern crate byteorder; +#[cfg(feature = "std")] +extern crate core; +extern crate ctap2; +extern crate libtock; +extern crate subtle; +#[macro_use] +extern crate cbor; +extern crate crypto; + +mod ctap; +mod usb_ctap_hid; + +use core::cell::Cell; +#[cfg(feature = "debug_ctap")] +use core::fmt::Write; +use crypto::rng256::TockRng256; +use ctap::hid::{ChannelID, CtapHid, KeepaliveStatus, ProcessedPacket}; +use ctap::status_code::Ctap2StatusCode; +use ctap::CtapState; +use libtock::buttons; +use libtock::buttons::ButtonState; +#[cfg(feature = "debug_ctap")] +use libtock::console::Console; +use libtock::led; +use libtock::result::TockValue; +use libtock::syscalls; +use libtock::timer; +#[cfg(feature = "debug_ctap")] +use libtock::timer::Timer; +use libtock::timer::{Duration, StopAlarmError, Timestamp}; + +const KEEPALIVE_DELAY_MS: isize = 100; +const KEEPALIVE_DELAY: Duration = Duration::from_ms(KEEPALIVE_DELAY_MS); +const SEND_TIMEOUT: Duration = Duration::from_ms(1000); + +fn main() { + // Setup the timer with a dummy callback (we only care about reading the current time, but the + // API forces us to set an alarm callback too). + let mut with_callback = timer::with_callback(|_, _| {}); + let timer = with_callback.init().unwrap(); + + // Setup USB driver. + if !usb_ctap_hid::setup() { + panic!("Cannot setup USB driver"); + } + + let mut rng = TockRng256 {}; + let mut ctap_state = CtapState::new(&mut rng, check_user_presence); + let mut ctap_hid = CtapHid::new(); + + let mut led_counter = 0; + let mut last_led_increment = timer.get_current_clock(); + + // Main loop. If CTAP1 is used, we register button presses for U2F while receiving and waiting. + // The way TockOS and apps currently interact, callbacks need a yield syscall to execute, + // making consistent blinking patterns and sending keepalives harder. + loop { + // Create the button callback, used for CTAP1. + #[cfg(feature = "with_ctap1")] + let button_touched = Cell::new(false); + #[cfg(feature = "with_ctap1")] + let mut buttons_callback = buttons::with_callback(|_button_num, state| { + match state { + ButtonState::Pressed => button_touched.set(true), + ButtonState::Released => (), + }; + }); + #[cfg(feature = "with_ctap1")] + let mut buttons = buttons_callback.init().unwrap(); + #[cfg(feature = "with_ctap1")] + // At the moment, all buttons are accepted. You can customize your setup here. + for mut button in &mut buttons { + button.enable().unwrap(); + } + + let mut pkt_request = [0; 64]; + let has_packet = match usb_ctap_hid::recv_with_timeout(&mut pkt_request, KEEPALIVE_DELAY) { + Some(usb_ctap_hid::SendOrRecvStatus::Received) => { + #[cfg(feature = "debug_ctap")] + print_packet_notice("Received packet", &timer); + true + } + Some(_) => panic!("Error receiving packet"), + None => false, + }; + + let now = timer.get_current_clock(); + #[cfg(feature = "with_ctap1")] + { + if button_touched.get() { + ctap_state.u2f_up_state.grant_up(now); + } + // Cleanup button callbacks. We miss button presses while processing though. + // Heavy computation mostly follows a registered touch luckily. Unregistering + // callbacks is important to not clash with those from check_user_presence. + for mut button in &mut buttons { + button.disable().unwrap(); + } + drop(buttons); + drop(buttons_callback); + } + + // These calls are making sure that even for long inactivity, wrapping clock values + // never randomly wink or grant user presence for U2F. + ctap_state.check_disable_reset(Timestamp::::from_clock_value(now)); + ctap_hid.wink_permission = ctap_hid.wink_permission.check_expiration(now); + + if has_packet { + let reply = ctap_hid.process_hid_packet(&pkt_request, now, &mut ctap_state); + // This block handles sending packets. + for mut pkt_reply in reply { + let status = usb_ctap_hid::send_or_recv_with_timeout(&mut pkt_reply, SEND_TIMEOUT); + match status { + None => { + #[cfg(feature = "debug_ctap")] + print_packet_notice("Sending packet timed out", &timer); + // TODO: reset the ctap_hid state. + // Since sending the packet timed out, we cancel this reply. + break; + } + Some(usb_ctap_hid::SendOrRecvStatus::Error) => panic!("Error sending packet"), + Some(usb_ctap_hid::SendOrRecvStatus::Sent) => { + #[cfg(feature = "debug_ctap")] + print_packet_notice("Sent packet", &timer); + } + Some(usb_ctap_hid::SendOrRecvStatus::Received) => { + #[cfg(feature = "debug_ctap")] + print_packet_notice("Received an UNEXPECTED packet", &timer); + // TODO: handle this unexpected packet. + } + } + } + } + + let now = timer.get_current_clock(); + if let Some(wait_duration) = now.wrapping_sub(last_led_increment) { + if wait_duration > KEEPALIVE_DELAY { + // Loops quickly when waiting for U2F user presence, so the next LED blink + // state is only set if enough time has elapsed. + led_counter += 1; + last_led_increment = now; + } + } else { + // This branch means the clock frequency changed. This should never happen. + led_counter += 1; + last_led_increment = now; + } + + if ctap_hid.wink_permission.is_granted(now) { + wink_leds(led_counter); + } else { + #[cfg(not(feature = "with_ctap1"))] + switch_off_leds(); + #[cfg(feature = "with_ctap1")] + { + if ctap_state.u2f_up_state.is_up_needed(now) { + // Flash the LEDs with an almost regular pattern. The inaccuracy comes from + // delay caused by processing and sending of packets. + blink_leds(led_counter); + } else { + switch_off_leds(); + } + } + } + } +} + +#[cfg(feature = "debug_ctap")] +fn print_packet_notice(notice_text: &str, timer: &Timer) { + let now_us = + (Timestamp::::from_clock_value(timer.get_current_clock()).ms() * 1000.0) as u64; + writeln!( + Console::new(), + "{} at {}.{:06} s", + notice_text, + now_us / 1_000_000, + now_us % 1_000_000 + ) + .unwrap(); +} + +// Returns whether the keepalive was sent, or false if cancelled. +fn send_keepalive_up_needed( + cid: ChannelID, + timeout: Duration, +) -> Result<(), Ctap2StatusCode> { + let keepalive_msg = CtapHid::keepalive(cid, KeepaliveStatus::UpNeeded); + for mut pkt in keepalive_msg { + let status = usb_ctap_hid::send_or_recv_with_timeout(&mut pkt, timeout); + match status { + None => { + #[cfg(feature = "debug_ctap")] + writeln!(Console::new(), "Sending a KEEPALIVE packet timed out").unwrap(); + // TODO: abort user presence test? + } + Some(usb_ctap_hid::SendOrRecvStatus::Error) => panic!("Error sending KEEPALIVE packet"), + Some(usb_ctap_hid::SendOrRecvStatus::Sent) => { + #[cfg(feature = "debug_ctap")] + writeln!(Console::new(), "Sent KEEPALIVE packet").unwrap(); + } + Some(usb_ctap_hid::SendOrRecvStatus::Received) => { + // We only parse one packet, because we only care about CANCEL. + let (received_cid, processed_packet) = CtapHid::process_single_packet(&pkt); + if received_cid != &cid { + #[cfg(feature = "debug_ctap")] + writeln!( + Console::new(), + "Received a packet on channel ID {:?} while sending a KEEPALIVE packet", + received_cid, + ) + .unwrap(); + return Ok(()); + } + match processed_packet { + ProcessedPacket::InitPacket { cmd, .. } => { + if cmd == CtapHid::COMMAND_CANCEL { + // We ignore the payload, we can't answer with an error code anyway. + #[cfg(feature = "debug_ctap")] + writeln!(Console::new(), "User presence check cancelled").unwrap(); + return Err(Ctap2StatusCode::CTAP2_ERR_KEEPALIVE_CANCEL); + } else { + #[cfg(feature = "debug_ctap")] + writeln!( + Console::new(), + "Discarded packet with command {} received while sending a KEEPALIVE packet", + cmd, + ) + .unwrap(); + } + } + ProcessedPacket::ContinuationPacket { .. } => { + #[cfg(feature = "debug_ctap")] + writeln!( + Console::new(), + "Discarded continuation packet received while sending a KEEPALIVE packet", + ) + .unwrap(); + } + } + } + } + } + Ok(()) +} + +fn blink_leds(pattern_seed: isize) { + for l in 0..led::count() { + if (pattern_seed ^ l).count_ones() & 1 != 0 { + led::get(l).unwrap().on(); + } else { + led::get(l).unwrap().off(); + } + } +} + +fn wink_leds(pattern_seed: isize) { + // This generates a "snake" pattern circling through the LEDs. + // Fox example with 4 LEDs the sequence of lit LEDs will be the following. + // 0 1 2 3 + // * * + // * * * + // * * + // * * * + // * * + // * * * + // * * + // * * * + // * * + let count = led::count(); + let a = (pattern_seed / 2) % count; + let b = ((pattern_seed + 1) / 2) % count; + let c = ((pattern_seed + 3) / 2) % count; + + for l in 0..count { + // On nRF52840-DK, logically swap LEDs 3 and 4 so that the order of LEDs form a circle. + let k = match l { + 2 => 3, + 3 => 2, + _ => l, + }; + if k == a || k == b || k == c { + led::get(l).unwrap().on(); + } else { + led::get(l).unwrap().off(); + } + } +} + +fn switch_off_leds() { + for l in 0..led::count() { + led::get(l).unwrap().off(); + } +} + +fn check_user_presence(cid: ChannelID) -> Result<(), Ctap2StatusCode> { + // The timeout is N times the keepalive delay. + const TIMEOUT_ITERATIONS: isize = ctap::TOUCH_TIMEOUT_MS / KEEPALIVE_DELAY_MS; + + // First, send a keep-alive packet to notify that the keep-alive status has changed. + send_keepalive_up_needed(cid, KEEPALIVE_DELAY)?; + + // Listen to the button presses. + let button_touched = Cell::new(false); + let mut buttons_callback = buttons::with_callback(|_button_num, state| { + match state { + ButtonState::Pressed => button_touched.set(true), + ButtonState::Released => (), + }; + }); + let mut buttons = buttons_callback.init().unwrap(); + // At the moment, all buttons are accepted. You can customize your setup here. + for mut button in &mut buttons { + button.enable().unwrap(); + } + + let mut keepalive_response = Ok(()); + for i in 0..TIMEOUT_ITERATIONS { + blink_leds(i); + + // Setup a keep-alive callback. + let keepalive_expired = Cell::new(false); + let mut keepalive_callback = timer::with_callback(|_, _| { + keepalive_expired.set(true); + }); + let mut keepalive = keepalive_callback.init().unwrap(); + let keepalive_alarm = keepalive.set_alarm(KEEPALIVE_DELAY).unwrap(); + + // Wait for a button touch or an alarm. + syscalls::yieldk_for(|| button_touched.get() || keepalive_expired.get()); + + // Cleanup alarm callback. + match keepalive.stop_alarm(keepalive_alarm) { + Ok(()) => (), + Err(TockValue::Expected(StopAlarmError::AlreadyDisabled)) => { + assert!(keepalive_expired.get()) + } + Err(e) => panic!("Unexpected error when stopping alarm: {:?}", e), + } + + // TODO: this may take arbitrary time. The keepalive_delay should be adjusted accordingly, + // so that LEDs blink with a consistent pattern. + if keepalive_expired.get() { + // Do not return immediately, because we must clean up still. + keepalive_response = send_keepalive_up_needed(cid, KEEPALIVE_DELAY); + } + + if button_touched.get() || keepalive_response.is_err() { + break; + } + } + + switch_off_leds(); + + // Cleanup button callbacks. + for mut button in &mut buttons { + button.disable().unwrap(); + } + + // Returns whether the user was present. + if keepalive_response.is_err() { + keepalive_response + } else if button_touched.get() { + Ok(()) + } else { + Err(Ctap2StatusCode::CTAP2_ERR_USER_ACTION_TIMEOUT) + } +} diff --git a/src/usb_ctap_hid.rs b/src/usb_ctap_hid.rs new file mode 100644 index 0000000..421e70b --- /dev/null +++ b/src/usb_ctap_hid.rs @@ -0,0 +1,344 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use core::cell::Cell; +#[cfg(feature = "debug_ctap")] +use core::fmt::Write; +#[cfg(feature = "debug_ctap")] +use libtock::console::Console; +use libtock::result::TockValue; +use libtock::result::{EALREADY, EBUSY, SUCCESS}; +use libtock::syscalls; +use libtock::timer; +use libtock::timer::{Duration, StopAlarmError}; + +const DRIVER_NUMBER: usize = 0x20009; + +mod command_nr { + pub const CHECK: usize = 0; + pub const CONNECT: usize = 1; + pub const TRANSMIT: usize = 2; + pub const RECEIVE: usize = 3; + pub const TRANSMIT_OR_RECEIVE: usize = 4; + pub const CANCEL: usize = 5; +} + +mod subscribe_nr { + pub const TRANSMIT: usize = 1; + pub const RECEIVE: usize = 2; + pub const TRANSMIT_OR_RECEIVE: usize = 3; + pub mod callback_status { + pub const TRANSMITTED: usize = 1; + pub const RECEIVED: usize = 2; + } +} + +mod allow_nr { + pub const TRANSMIT: usize = 1; + pub const RECEIVE: usize = 2; + pub const TRANSMIT_OR_RECEIVE: usize = 3; +} + +pub fn setup() -> bool { + let result = unsafe { syscalls::command(DRIVER_NUMBER, command_nr::CHECK, 0, 0) }; + if result != 0 { + return false; + } + + let result = unsafe { syscalls::command(DRIVER_NUMBER, command_nr::CONNECT, 0, 0) }; + if result != 0 { + return false; + } + + true +} + +#[allow(dead_code)] +pub fn recv(buf: &mut [u8; 64]) -> bool { + let result = syscalls::allow(DRIVER_NUMBER, allow_nr::RECEIVE, buf); + if result.is_err() { + return false; + } + + let done = Cell::new(false); + let mut alarm = |_, _, _| done.set(true); + let subscription = syscalls::subscribe(DRIVER_NUMBER, subscribe_nr::RECEIVE, &mut alarm); + if subscription.is_err() { + return false; + } + + let result_code = unsafe { syscalls::command(DRIVER_NUMBER, command_nr::RECEIVE, 0, 0) }; + if result_code != 0 { + return false; + } + + syscalls::yieldk_for(|| done.get()); + true +} + +#[allow(dead_code)] +pub fn send(buf: &mut [u8; 64]) -> bool { + let result = syscalls::allow(DRIVER_NUMBER, allow_nr::TRANSMIT, buf); + if result.is_err() { + return false; + } + + let done = Cell::new(false); + let mut alarm = |_, _, _| done.set(true); + let subscription = syscalls::subscribe(DRIVER_NUMBER, subscribe_nr::TRANSMIT, &mut alarm); + if subscription.is_err() { + return false; + } + + let result_code = unsafe { syscalls::command(DRIVER_NUMBER, command_nr::TRANSMIT, 0, 0) }; + if result_code != 0 { + return false; + } + + syscalls::yieldk_for(|| done.get()); + true +} + +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum SendOrRecvStatus { + Error, + Sent, + Received, +} + +// Either sends or receive a packet. +// Because USB transactions are initiated by the host, we don't decide whether an IN transaction +// (send for us), an OUT transaction (receive for us), or no transaction at all will happen next. +// +// - If an IN transaction happens first, the initial content of buf is sent to the host and the +// Sent status is returned. +// - If an OUT transaction happens first, the content of buf is replaced by the packet received +// from the host and Received status is returned. In that case, the original content of buf is not +// sent to the host, and it's up to the caller to retry sending or to handle the packet received +// from the host. +#[allow(dead_code)] +pub fn send_or_recv(buf: &mut [u8; 64]) -> SendOrRecvStatus { + let result = syscalls::allow(DRIVER_NUMBER, allow_nr::TRANSMIT_OR_RECEIVE, buf); + if result.is_err() { + return SendOrRecvStatus::Error; + } + + let status = Cell::new(None); + let mut alarm = |direction, _, _| { + status.set(Some(match direction { + subscribe_nr::callback_status::TRANSMITTED => SendOrRecvStatus::Sent, + subscribe_nr::callback_status::RECEIVED => SendOrRecvStatus::Received, + // Unknown direction sent by the kernel. + _ => SendOrRecvStatus::Error, + })); + }; + + let subscription = + syscalls::subscribe(DRIVER_NUMBER, subscribe_nr::TRANSMIT_OR_RECEIVE, &mut alarm); + if subscription.is_err() { + return SendOrRecvStatus::Error; + } + + let result_code = + unsafe { syscalls::command(DRIVER_NUMBER, command_nr::TRANSMIT_OR_RECEIVE, 0, 0) }; + if result_code != 0 { + return SendOrRecvStatus::Error; + } + + syscalls::yieldk_for(|| status.get().is_some()); + status.get().unwrap() +} + +// Same as recv, but with a timeout. +// If the timeout elapses, return None. +pub fn recv_with_timeout( + buf: &mut [u8; 64], + timeout_delay: Duration, +) -> Option { + let result = syscalls::allow(DRIVER_NUMBER, allow_nr::RECEIVE, buf); + if result.is_err() { + return Some(SendOrRecvStatus::Error); + } + + let status = Cell::new(None); + let mut alarm = |direction, _, _| { + status.set(Some(match direction { + subscribe_nr::callback_status::RECEIVED => SendOrRecvStatus::Received, + // Unknown direction or "transmitted" sent by the kernel. + _ => SendOrRecvStatus::Error, + })); + }; + + let subscription = syscalls::subscribe(DRIVER_NUMBER, subscribe_nr::RECEIVE, &mut alarm); + if subscription.is_err() { + return Some(SendOrRecvStatus::Error); + } + + // Setup a time-out callback. + let timeout_expired = Cell::new(false); + let mut timeout_callback = timer::with_callback(|_, _| { + timeout_expired.set(true); + }); + let mut timeout = match timeout_callback.init() { + Ok(x) => x, + Err(_) => return Some(SendOrRecvStatus::Error), + }; + let timeout_alarm = match timeout.set_alarm(timeout_delay) { + Ok(x) => x, + Err(_) => return Some(SendOrRecvStatus::Error), + }; + + // Trigger USB reception. + let result_code = unsafe { syscalls::command(DRIVER_NUMBER, command_nr::RECEIVE, 0, 0) }; + if result_code != 0 { + return Some(SendOrRecvStatus::Error); + } + + syscalls::yieldk_for(|| status.get().is_some() || timeout_expired.get()); + + // Cleanup alarm callback. + match timeout.stop_alarm(timeout_alarm) { + Ok(()) => (), + Err(TockValue::Expected(StopAlarmError::AlreadyDisabled)) => { + if !timeout_expired.get() { + #[cfg(feature = "debug_ctap")] + writeln!( + Console::new(), + "The receive timeout already expired, but the callback wasn't executed." + ) + .unwrap(); + } + } + Err(e) => panic!("Unexpected error when stopping alarm: {:?}", e), + } + + // Cancel USB transaction if necessary. + if status.get().is_none() { + #[cfg(feature = "debug_ctap")] + writeln!(Console::new(), "Cancelling USB receive due to timeout").unwrap(); + let result_code = unsafe { syscalls::command(DRIVER_NUMBER, command_nr::CANCEL, 0, 0) }; + match result_code { + // - SUCCESS means that we successfully cancelled the transaction. + // - EALREADY means that the transaction was already completed. + SUCCESS | EALREADY => (), + // - EBUSY means that the transaction is in progress. + EBUSY => { + // The app should wait for it, but it may never happen if the remote app crashes. + // We just return to avoid a deadlock. + #[cfg(feature = "debug_ctap")] + writeln!(Console::new(), "Couldn't cancel the USB receive").unwrap(); + } + _ => panic!( + "Unexpected error when cancelling USB receive: {:?}", + result_code + ), + } + } + + status.get() +} + +// Same as send_or_recv, but with a timeout. +// If the timeout elapses, return None. +pub fn send_or_recv_with_timeout( + buf: &mut [u8; 64], + timeout_delay: Duration, +) -> Option { + let result = syscalls::allow(DRIVER_NUMBER, allow_nr::TRANSMIT_OR_RECEIVE, buf); + if result.is_err() { + return Some(SendOrRecvStatus::Error); + } + + let status = Cell::new(None); + let mut alarm = |direction, _, _| { + status.set(Some(match direction { + subscribe_nr::callback_status::TRANSMITTED => SendOrRecvStatus::Sent, + subscribe_nr::callback_status::RECEIVED => SendOrRecvStatus::Received, + // Unknown direction sent by the kernel. + _ => SendOrRecvStatus::Error, + })); + }; + + let subscription = + syscalls::subscribe(DRIVER_NUMBER, subscribe_nr::TRANSMIT_OR_RECEIVE, &mut alarm); + if subscription.is_err() { + return Some(SendOrRecvStatus::Error); + } + + // Setup a time-out callback. + let timeout_expired = Cell::new(false); + let mut timeout_callback = timer::with_callback(|_, _| { + timeout_expired.set(true); + }); + let mut timeout = match timeout_callback.init() { + Ok(x) => x, + Err(_) => return Some(SendOrRecvStatus::Error), + }; + let timeout_alarm = match timeout.set_alarm(timeout_delay) { + Ok(x) => x, + Err(_) => return Some(SendOrRecvStatus::Error), + }; + + // Trigger USB transmission. + let result_code = + unsafe { syscalls::command(DRIVER_NUMBER, command_nr::TRANSMIT_OR_RECEIVE, 0, 0) }; + if result_code != 0 { + return Some(SendOrRecvStatus::Error); + } + + syscalls::yieldk_for(|| status.get().is_some() || timeout_expired.get()); + + // Cleanup alarm callback. + match timeout.stop_alarm(timeout_alarm) { + Ok(()) => (), + Err(TockValue::Expected(StopAlarmError::AlreadyDisabled)) => { + if !timeout_expired.get() { + #[cfg(feature = "debug_ctap")] + writeln!( + Console::new(), + "The send/receive timeout already expired, but the callback wasn't executed." + ) + .unwrap(); + } + } + Err(e) => panic!("Unexpected error when stopping alarm: {:?}", e), + } + + // Cancel USB transaction if necessary. + if status.get().is_none() { + #[cfg(feature = "debug_ctap")] + writeln!(Console::new(), "Cancelling USB transaction due to timeout").unwrap(); + let result_code = unsafe { syscalls::command(DRIVER_NUMBER, command_nr::CANCEL, 0, 0) }; + match result_code { + // - SUCCESS means that we successfully cancelled the transaction. + // - EALREADY means that the transaction was already completed. + SUCCESS | EALREADY => (), + // - EBUSY means that the transaction is in progress. + EBUSY => { + // The app should wait for it, but it may never happen if the remote app crashes. + // We just return to avoid a deadlock. + #[cfg(feature = "debug_ctap")] + writeln!(Console::new(), "Couldn't cancel the transaction").unwrap(); + } + _ => panic!( + "Unexpected error when cancelling USB transaction: {:?}", + result_code + ), + } + #[cfg(feature = "debug_ctap")] + writeln!(Console::new(), "Cancelled USB transaction!").unwrap(); + } + + status.get() +} diff --git a/third_party/libtock-rs b/third_party/libtock-rs new file mode 160000 index 0000000..ab2c945 --- /dev/null +++ b/third_party/libtock-rs @@ -0,0 +1 @@ +Subproject commit ab2c945184b98ecae3e70ac678e9f5231deef73b diff --git a/third_party/tock b/third_party/tock new file mode 160000 index 0000000..862452b --- /dev/null +++ b/third_party/tock @@ -0,0 +1 @@ +Subproject commit 862452b77ae0fc160231a2250de385dc7c358ef7 diff --git a/tools/gen_key_materials.sh b/tools/gen_key_materials.sh new file mode 100644 index 0000000..260d8eb --- /dev/null +++ b/tools/gen_key_materials.sh @@ -0,0 +1,169 @@ +#!/bin/bash +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +generate_crypto_materials () { + # Root CA key pair and certificate + local ca_priv_key=crypto_data/opensk_ca.key + local ca_cert_name=crypto_data/opensk_ca + + # Attestation key pair and certificate that will be embedded into the + # firmware. The certificate will be signed by the Root CA. + local opensk_key=crypto_data/opensk.key + local opensk_cert_name=crypto_data/opensk_cert + + # Rust file that we will generate will all cryptographic data. + local rust_file=src/ctap/key_material.rs + + # Allow invoker to override the command with a full path. + local openssl=${OPENSSL:-$(which openssl)} + + # We need openssl command to continue + if [ ! -x "${openssl}" ] + then + echo "Missing openssl command. Try to specify its full path using OPENSSL environment variable." + exit 1 + fi + + mkdir -p crypto_data + if [ ! -f "${ca_priv_key}" ] + then + "${openssl}" ecparam -genkey -name prime256v1 -out "${ca_priv_key}" + fi + + if [ ! -f "${ca_cert_name}.pem" ] + then + "${openssl}" req \ + -new \ + -key "${ca_priv_key}" \ + -out "${ca_cert_name}.csr" \ + -subj "/CN=Google OpenSK CA" + "${openssl}" x509 \ + -trustout \ + -req \ + -days 7305 \ + -in "${ca_cert_name}.csr" \ + -signkey "${ca_priv_key}" \ + -outform pem \ + -out "${ca_cert_name}.pem" \ + -sha256 + fi + + if [ ! -f "${opensk_key}" ] + then + "${openssl}" ecparam -genkey -name prime256v1 -out "${opensk_key}" + fi + + if [ ! -f "${opensk_cert_name}.pem" ] + then + "${openssl}" req \ + -new \ + -key "${opensk_key}" \ + -out "${opensk_cert_name}.csr" \ + -subj "/CN=Google OpenSK Hacker Edition" + "${openssl}" x509 \ + -req \ + -days 3652 \ + -in "${opensk_cert_name}.csr" \ + -CA "${ca_cert_name}.pem" \ + -CAkey "${ca_priv_key}" \ + -CAcreateserial \ + -outform pem \ + -out "${opensk_cert_name}.pem" \ + -sha256 + fi + + local cert_mtime=$(stat --printf="%Y" "${opensk_cert_name}.pem") + local rust_file_mtime=0 + # Only take into consideration the mtime of the file if it exists and if we're not forcing + # the rust file to be re-generated. + if [ -f "${rust_file}" -a "x$1" != "xY" ] + then + rust_file_mtime=$(stat --printf="%Y" "${rust_file}") + fi + if [ $cert_mtime -gt $rust_file_mtime ] + then + local cert_size=$("${openssl}" x509 \ + -in "${opensk_cert_name}.pem" \ + -outform der 2>/dev/null \ + | wc -c) + local cert_serial_hex=$("${openssl}" x509 \ + -in "${opensk_cert_name}.pem" \ + -noout \ + -serial \ + | cut -d'=' -f2) + # Pad with zeroes in case the serial is too short. We don't care if the + # serial is longer than 32 characters as we will only process the first 32 + # characters in the loop later. + cert_serial_hex="${cert_serial_hex}00000000000000000000000000000000" + + # Create header + echo "// This file had been generated by OpenSK deploy.sh script" > "${rust_file}" + echo "" >> "${rust_file}" + + echo "pub const AAGUID: [u8; 16] = [" >> "${rust_file}" + for i in `seq 0 2 30` + do + echo -n "0x${cert_serial_hex:$i:2}, " >> "${rust_file}" + done + echo "" >> "${rust_file}" + echo "];" >> "${rust_file}" + echo "" >> "${rust_file}" + + echo "pub const ATTESTATION_CERTIFICATE: [u8; ${cert_size}] = [" >> "${rust_file}" + "${openssl}" x509 \ + -in "${opensk_cert_name}.pem" \ + -outform der 2>/dev/null \ + | xxd -i >> "${rust_file}" + echo "];" >> "${rust_file}" + echo "" >> "${rust_file}" + + # Private key is tricky to extract as we want the raw value and not the DER encoding + # Example output of openssl ec -in file.key -noout -text: + # read EC key + # Private-Key: (256 bit) + # priv: + # 47:b3:58:b8:f0:09:1d:72:b1:03:34:62:9a:c7:b2: + # b2:e1:06:28:15:69:d4:82:b5:4e:21:6d:98:bf:65: + # 98:34 + # pub: + # 04:32:84:a1:3c:90:db:3f:db:d7:fb:ff:e9:00:c8: + # 8a:a1:79:2e:95:2e:7c:86:ec:19:03:97:6e:7c:d6: + # 67:eb:28:56:f1:d8:dd:cb:ae:ce:b9:cb:e4:6d:9d: + # 1d:76:96:fc:48:9b:2d:d5:80:86:04:3d:f9:fe:6c: + # f3:9a:45:bc:b1 + # ASN1 OID: prime256v1 + # NIST CURVE: P-256 + # + # The awk script starts printing lines after seeing a line starting with + # "priv:" and stops printing as soon as it reaches a line that doesn't start + # with a space. + # The sed script then converts the output into a proper hex-encode byte + # array by replacing the initial spaces on each line with "0x", replacing + # the semicolons at the end of each line by commas and replacing all + # remainging semicolons by ". 0x". + echo "pub const ATTESTATION_PRIVATE_KEY: [u8; 32] = [" >> "${rust_file}" + "${openssl}" ec \ + -in "${opensk_key}" \ + -noout \ + -text 2>/dev/null \ + | awk '/^priv:/{p=1;next}/^[^ ]/{p=0}p' \ + | sed -e 's/^ */0x/;s/:$/,/;s/:/, 0x/g' >> "${rust_file}" + echo "];" >> "${rust_file}" + echo "" >> "${rust_file}" + + # If the tool is installed, prettify the file. It will catch syntax errors earlier. + which rustfmt > /dev/null 2>&1 && rustfmt "${rust_file}" + fi +}