Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ab1b568fb | ||
|
|
c85a01579f | ||
|
|
bc0b30bc9e | ||
|
|
5b67f3f9a8 | ||
|
|
244a199316 | ||
|
|
1b70583243 | ||
|
|
3b9274e93e | ||
|
|
a969faaaa0 | ||
|
|
a79abc209a | ||
|
|
b396fc0f36 | ||
|
|
f2496a8e6d | ||
|
|
e4d82087a8 | ||
|
|
c847e7060a | ||
|
|
52343ed86f | ||
|
|
57ffafaa24 | ||
|
|
420f062a21 | ||
|
|
e02eaa2cac | ||
|
|
5c7df89198 | ||
|
|
42050f96af | ||
|
|
40d6040d41 | ||
|
|
eb65c4f07f | ||
|
|
2de660ae4d | ||
|
|
7e5e2a665f | ||
|
|
5e682d9e17 | ||
|
|
748b7e7fb8 | ||
|
|
b0c1b73897 |
7
.github/PULL_REQUEST_TEMPLATE.md
vendored
7
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -2,10 +2,5 @@ Fixes #<issue_number_goes_here>
|
|||||||
|
|
||||||
> It's a good idea to open an issue first for discussion.
|
> It's a good idea to open an issue first for discussion.
|
||||||
|
|
||||||
- [ ] Local tests pass (running `run_desktop_tests.sh`)
|
- [ ] Tests pass
|
||||||
- [ ] Tested against boards
|
|
||||||
- [ ] Nordic nRF52840 DK
|
|
||||||
- [ ] Nordic nRF52840 Dongle (JTAG programmed)
|
|
||||||
- [ ] Nordic nRF52840 Dongle (DFU programmed)
|
|
||||||
- [ ] Makerdiary nRF52840 MDK USB Dongle
|
|
||||||
- [ ] Appropriate changes to README are included in PR
|
- [ ] Appropriate changes to README are included in PR
|
||||||
9
.github/actions-rs/grcov.yml
vendored
Normal file
9
.github/actions-rs/grcov.yml
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
branch: true
|
||||||
|
ignore-not-existing: true
|
||||||
|
llvm: true
|
||||||
|
filter: covered
|
||||||
|
output-type: lcov
|
||||||
|
output-path: ./lcov.info
|
||||||
|
ignore:
|
||||||
|
- "third_party/*"
|
||||||
|
- "/*"
|
||||||
46
.github/workflows/bloat_formatter.sh
vendored
46
.github/workflows/bloat_formatter.sh
vendored
@@ -1,46 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Copyright 2022 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.
|
|
||||||
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
|
|
||||||
# New output file is $1
|
|
||||||
# Old output file is $2
|
|
||||||
TMP=comment.md
|
|
||||||
WARNING="Note: numbers above are a result of guesswork. They are not 100% correct and never will be."
|
|
||||||
NEW_SIZE=$(cat "$1" | sed -nr 's/.*100.0% (.*)KiB .text.*/\1/p')
|
|
||||||
OLD_SIZE=$(cat "$2" | sed -nr 's/.*100.0% (.*)KiB .text.*/\1/p')
|
|
||||||
|
|
||||||
echo "
|
|
||||||
OLD $OLD_SIZE kiB
|
|
||||||
NEW $NEW_SIZE kiB" > "$TMP"
|
|
||||||
|
|
||||||
echo "
|
|
||||||
Output of cargo bloat
|
|
||||||
======================
|
|
||||||
" >> "$TMP"
|
|
||||||
|
|
||||||
echo "Including PR" >> "$TMP"
|
|
||||||
cat "$1" >> "$TMP"
|
|
||||||
echo "Base branch" >> "$TMP"
|
|
||||||
cat "$2" >> "$TMP"
|
|
||||||
|
|
||||||
COMMENT="$(cat $TMP | sed "s/$WARNING//g" | sed 's/%/%25/g' | sed -z 's/\n/%0A/g')"
|
|
||||||
# No output for equality is intentional.
|
|
||||||
if (( $(echo "$NEW_SIZE > $OLD_SIZE" | bc -l) )); then
|
|
||||||
echo "::warning file=.github/workflows/cargo_bloat.yml,title=Binary size::$COMMENT"
|
|
||||||
fi
|
|
||||||
if (( $(echo "$NEW_SIZE < $OLD_SIZE" | bc -l) )); then
|
|
||||||
echo "::notice file=.github/workflows/cargo_bloat.yml,title=Binary size::$COMMENT"
|
|
||||||
fi
|
|
||||||
38
.github/workflows/boards_build.yml
vendored
38
.github/workflows/boards_build.yml
vendored
@@ -1,38 +0,0 @@
|
|||||||
---
|
|
||||||
name: Build supported boards
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'patches/tock/*'
|
|
||||||
- 'third_party/tock/**'
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build_boards:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, macos-10.15]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: "true"
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install Python dependencies
|
|
||||||
run: python -m pip install --upgrade pip setuptools wheel
|
|
||||||
- name: Set up OpenSK
|
|
||||||
run: ./setup.sh
|
|
||||||
|
|
||||||
- name: Building board nrf52840dk_opensk
|
|
||||||
run: ./deploy.py --board=nrf52840dk_opensk --no-app --programmer=none
|
|
||||||
- name: Building board nrf52840_dongle_opensk
|
|
||||||
run: ./deploy.py --board=nrf52840_dongle_opensk --no-app --programmer=none
|
|
||||||
- name: Building board nrf52840_dongle_dfu
|
|
||||||
run: ./deploy.py --board=nrf52840_dongle_dfu --no-app --programmer=none
|
|
||||||
- name: Building board nrf52840_mdk_dfu
|
|
||||||
run: ./deploy.py --board=nrf52840_mdk_dfu --no-app --programmer=none
|
|
||||||
25
.github/workflows/cargo_audit.yml
vendored
25
.github/workflows/cargo_audit.yml
vendored
@@ -1,25 +0,0 @@
|
|||||||
name: Security audit
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 0 * * *'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
audit:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.repository == 'google/OpenSK'
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: "true"
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install Python dependencies
|
|
||||||
run: python -m pip install --upgrade pip setuptools wheel
|
|
||||||
- name: Set up OpenSK
|
|
||||||
run: ./setup.sh
|
|
||||||
- uses: actions-rs/audit-check@v1
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
47
.github/workflows/cargo_bloat.yml
vendored
47
.github/workflows/cargo_bloat.yml
vendored
@@ -1,47 +0,0 @@
|
|||||||
name: Binary size report
|
|
||||||
on: pull_request
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
cargo_bloat:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
# Setup
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install Python dependencies
|
|
||||||
run: python -m pip install --upgrade pip setuptools wheel
|
|
||||||
- uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: install
|
|
||||||
args: cargo-bloat
|
|
||||||
|
|
||||||
# First run: PR
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
- name: Set up OpenSK
|
|
||||||
run: ./setup.sh
|
|
||||||
- name: Run bloat on the PR
|
|
||||||
run: RUSTFLAGS="-C link-arg=-icf=all -C force-frame-pointers=no" cargo bloat --release --target=thumbv7em-none-eabi --features=with_ctap1,vendor_hid --crates >> .github/workflows/bloat_output_new.txt
|
|
||||||
|
|
||||||
# Second run: PR
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
ref: ${{ github.base_ref }}
|
|
||||||
path: OpenSK_base
|
|
||||||
- name: Install old Rust toolchain
|
|
||||||
working-directory: ./OpenSK_base
|
|
||||||
run: rustup show
|
|
||||||
- name: Set up OpenSK
|
|
||||||
working-directory: ./OpenSK_base
|
|
||||||
run: ./setup.sh
|
|
||||||
- name: Run bloat on base
|
|
||||||
working-directory: ./OpenSK_base
|
|
||||||
run: RUSTFLAGS="-C link-arg=-icf=all -C force-frame-pointers=no" cargo bloat --release --target=thumbv7em-none-eabi --features=with_ctap1,vendor_hid --crates >> "$GITHUB_WORKSPACE/.github/workflows/bloat_output_old.txt"
|
|
||||||
|
|
||||||
- name: Run output formatter to echo workflow command
|
|
||||||
run: ./.github/workflows/bloat_formatter.sh bloat_output_new.txt bloat_output_old.txt bloat_comment.md
|
|
||||||
102
.github/workflows/cargo_check.yml
vendored
102
.github/workflows/cargo_check.yml
vendored
@@ -1,102 +0,0 @@
|
|||||||
name: Cargo check
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'examples/*.rs'
|
|
||||||
- 'libraries/**/*.rs'
|
|
||||||
- 'src/**/*.rs'
|
|
||||||
- 'patches/**'
|
|
||||||
- '**/Cargo.toml'
|
|
||||||
- '.cargo/config'
|
|
||||||
- '!third_party/**'
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
cargo_check:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: "true"
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install Python dependencies
|
|
||||||
run: python -m pip install --upgrade pip setuptools wheel
|
|
||||||
- name: Set up OpenSK
|
|
||||||
run: ./setup.sh
|
|
||||||
|
|
||||||
- name: Check OpenSK w/o features
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: check
|
|
||||||
args: --target thumbv7em-none-eabi --release
|
|
||||||
|
|
||||||
- name: Check OpenSK with_ctap1
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: check
|
|
||||||
args: --target thumbv7em-none-eabi --release --features with_ctap1
|
|
||||||
|
|
||||||
- name: Check OpenSK vendor_hid
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: check
|
|
||||||
args: --target thumbv7em-none-eabi --release --features vendor_hid
|
|
||||||
|
|
||||||
- name: Check OpenSK ed25519
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: check
|
|
||||||
args: --target thumbv7em-none-eabi --release --features ed25519
|
|
||||||
|
|
||||||
- name: Check OpenSK debug_ctap
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: check
|
|
||||||
args: --target thumbv7em-none-eabi --release --features debug_ctap
|
|
||||||
|
|
||||||
- name: Check OpenSK panic_console
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: check
|
|
||||||
args: --target thumbv7em-none-eabi --release --features panic_console
|
|
||||||
|
|
||||||
- name: Check OpenSK debug_allocations
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: check
|
|
||||||
args: --target thumbv7em-none-eabi --release --features debug_allocations
|
|
||||||
|
|
||||||
- name: Check OpenSK verbose
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: check
|
|
||||||
args: --target thumbv7em-none-eabi --release --features verbose
|
|
||||||
|
|
||||||
- name: Check OpenSK debug_ctap,with_ctap1
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: check
|
|
||||||
args: --target thumbv7em-none-eabi --release --features debug_ctap,with_ctap1
|
|
||||||
|
|
||||||
- name: Check OpenSK debug_ctap,with_ctap1,vendor_hid,ed25519,panic_console,debug_allocations,verbose
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: check
|
|
||||||
args: --target thumbv7em-none-eabi --release --features debug_ctap,with_ctap1,vendor_hid,ed25519,panic_console,debug_allocations,verbose
|
|
||||||
|
|
||||||
- name: Check examples
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: check
|
|
||||||
args: --target thumbv7em-none-eabi --release --examples
|
|
||||||
|
|
||||||
- name: Check bootloader
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: check
|
|
||||||
args: --manifest-path bootloader/Cargo.toml --target thumbv7em-none-eabi --release
|
|
||||||
34
.github/workflows/cargo_clippy.yml
vendored
34
.github/workflows/cargo_clippy.yml
vendored
@@ -1,34 +0,0 @@
|
|||||||
---
|
|
||||||
name: Cargo Clippy
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
cargo_clippy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: "true"
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install Python dependencies
|
|
||||||
run: python -m pip install --upgrade pip setuptools wheel
|
|
||||||
- name: Set up OpenSK
|
|
||||||
run: ./setup.sh
|
|
||||||
|
|
||||||
- uses: actions-rs/clippy-check@v1
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
args: --all-targets --features std
|
|
||||||
- name: Deny Clippy warnings (std)
|
|
||||||
run: cargo clippy --all-targets --features std -- -A clippy::new_without_default -D warnings
|
|
||||||
- name: Deny Clippy warnings (all)
|
|
||||||
run: cargo clippy --all-targets --features std,with_ctap1,ed25519,vendor_hid -- -A clippy::new_without_default -D warnings
|
|
||||||
- name: Deny Clippy warnings (all, nfc)
|
|
||||||
run: cargo clippy --all-targets --features std,with_ctap1,with_nfc,ed25519,vendor_hid -- -A clippy::new_without_default -D warnings
|
|
||||||
79
.github/workflows/cargo_fmt.yml
vendored
79
.github/workflows/cargo_fmt.yml
vendored
@@ -1,79 +0,0 @@
|
|||||||
name: Cargo format
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'examples/*.rs'
|
|
||||||
- 'libraries/**/*.rs'
|
|
||||||
- 'src/**/*.rs'
|
|
||||||
- 'tools/**/*.rs'
|
|
||||||
- 'patches/**'
|
|
||||||
- '**/Cargo.toml'
|
|
||||||
- '.cargo/config'
|
|
||||||
- '!third_party/**'
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
cargo_format:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: "true"
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install Python dependencies
|
|
||||||
run: python -m pip install --upgrade pip setuptools wheel
|
|
||||||
- name: Set up OpenSK
|
|
||||||
run: ./setup.sh
|
|
||||||
|
|
||||||
- name: Cargo format src/
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: fmt
|
|
||||||
args: --all -- --check
|
|
||||||
|
|
||||||
- name: Cargo format fuzz/
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: fmt
|
|
||||||
args: --manifest-path fuzz/Cargo.toml --all -- --check
|
|
||||||
|
|
||||||
- name: Cargo format libraries/cbor
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: fmt
|
|
||||||
args: --manifest-path libraries/cbor/Cargo.toml --all -- --check
|
|
||||||
|
|
||||||
- name: Cargo format libraries/cbor/fuzz
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: fmt
|
|
||||||
args: --manifest-path libraries/cbor/fuzz/Cargo.toml --all -- --check
|
|
||||||
|
|
||||||
- name: Cargo format libraries/crypto
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: fmt
|
|
||||||
args: --manifest-path libraries/crypto/Cargo.toml --all -- --check
|
|
||||||
|
|
||||||
- name: Cargo format libraries/persistent_store
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: fmt
|
|
||||||
args: --manifest-path libraries/persistent_store/Cargo.toml --all -- --check
|
|
||||||
|
|
||||||
- name: Cargo format tools/heapviz
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: fmt
|
|
||||||
args: --manifest-path tools/heapviz/Cargo.toml --all -- --check
|
|
||||||
|
|
||||||
- name: Cargo format bootloader
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: fmt
|
|
||||||
args: --manifest-path bootloader/Cargo.toml --all -- --check
|
|
||||||
32
.github/workflows/cargo_fuzz.yml
vendored
32
.github/workflows/cargo_fuzz.yml
vendored
@@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
name: Cargo fuzz build
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build_fuzzing:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: "true"
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install Python dependencies
|
|
||||||
run: python -m pip install --upgrade pip setuptools wheel
|
|
||||||
- name: Set up OpenSK
|
|
||||||
run: ./setup.sh
|
|
||||||
- name: Set up fuzzing
|
|
||||||
run: ./fuzzing_setup.sh
|
|
||||||
|
|
||||||
- name: Cargo fuzz build
|
|
||||||
run: cargo fuzz build
|
|
||||||
- name: Cargo fuzz build (libraries/cbor)
|
|
||||||
run: cd libraries/cbor && cargo fuzz build && cd ../..
|
|
||||||
- name: Cargo fuzz build (libraries/persistent_store)
|
|
||||||
run: cd libraries/persistent_store && cargo fuzz build && cd ../..
|
|
||||||
37
.github/workflows/cbor_test.yml
vendored
37
.github/workflows/cbor_test.yml
vendored
@@ -1,37 +0,0 @@
|
|||||||
---
|
|
||||||
name: CBOR tests
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'libraries/cbor/**'
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
cbor_test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: "true"
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install Python dependencies
|
|
||||||
run: python -m pip install --upgrade pip setuptools wheel
|
|
||||||
- name: Set up OpenSK
|
|
||||||
run: ./setup.sh
|
|
||||||
|
|
||||||
- name: Unit testing of CBOR library (release mode)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --manifest-path libraries/cbor/Cargo.toml --release
|
|
||||||
|
|
||||||
- name: Unit testing of CBOR library (debug mode)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --manifest-path libraries/cbor/Cargo.toml
|
|
||||||
28
.github/workflows/cifuzz.yml
vendored
28
.github/workflows/cifuzz.yml
vendored
@@ -1,28 +0,0 @@
|
|||||||
name: CIFuzz
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- develop
|
|
||||||
jobs:
|
|
||||||
Fuzzing:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Build Fuzzers
|
|
||||||
id: build
|
|
||||||
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
|
||||||
with:
|
|
||||||
oss-fuzz-project-name: 'opensk'
|
|
||||||
dry-run: false
|
|
||||||
language: rust
|
|
||||||
- name: Run Fuzzers
|
|
||||||
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
|
|
||||||
with:
|
|
||||||
oss-fuzz-project-name: 'opensk'
|
|
||||||
fuzz-seconds: 600
|
|
||||||
dry-run: false
|
|
||||||
- name: Upload Crash
|
|
||||||
uses: actions/upload-artifact@v1
|
|
||||||
if: failure() && steps.build.outcome == 'success'
|
|
||||||
with:
|
|
||||||
name: artifacts
|
|
||||||
path: ./out/artifacts
|
|
||||||
48
.github/workflows/coveralls.yml
vendored
48
.github/workflows/coveralls.yml
vendored
@@ -1,48 +0,0 @@
|
|||||||
---
|
|
||||||
name: OpenSK code coverage report
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'src/**/*.rs'
|
|
||||||
- 'libraries/**/*.rs'
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
coveralls:
|
|
||||||
name: OpenSK code coverage
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: "true"
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install Python dependencies
|
|
||||||
run: python -m pip install --upgrade pip setuptools wheel
|
|
||||||
- name: Set up OpenSK
|
|
||||||
run: ./setup.sh
|
|
||||||
- name: Install llvm tools
|
|
||||||
run: rustup component add llvm-tools-preview
|
|
||||||
|
|
||||||
- name: Install grcov
|
|
||||||
run: if [[ ! -e ~/.cargo/bin/grcov ]]; then cargo +stable install grcov; fi
|
|
||||||
- uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --features "with_ctap1,vendor_hid,ed25519,with_nfc,std" --no-fail-fast
|
|
||||||
env:
|
|
||||||
RUSTFLAGS: "-Zinstrument-coverage"
|
|
||||||
LLVM_PROFILE_FILE: "opensk-%p-%m.profraw"
|
|
||||||
- name: Run grcov
|
|
||||||
run: grcov . --binary-path ./target/debug/ --source-dir . --output-type lcov --ignore-not-existing ---output-path ./lcov.info --ignore "/*" --ignore "examples/*" --ignore "third_party/*"
|
|
||||||
- uses: coverallsapp/github-action@1.1.3
|
|
||||||
name: upload report to coveralls
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
path-to-lcov: "./lcov.info"
|
|
||||||
|
|
||||||
41
.github/workflows/crypto_test.yml
vendored
41
.github/workflows/crypto_test.yml
vendored
@@ -1,41 +0,0 @@
|
|||||||
---
|
|
||||||
name: Crypto library tests
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'libraries/crypto/**'
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
paths:
|
|
||||||
- 'libraries/crypto/**'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
crypto_test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: "true"
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install Python dependencies
|
|
||||||
run: python -m pip install --upgrade pip setuptools wheel
|
|
||||||
- name: Set up OpenSK
|
|
||||||
run: ./setup.sh
|
|
||||||
|
|
||||||
- run: echo "RUSTFLAGS=-C target-feature=+aes" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Unit testing of crypto library (release mode)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --manifest-path libraries/crypto/Cargo.toml --release --features std
|
|
||||||
|
|
||||||
- name: Unit testing of crypto library (debug mode)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --manifest-path libraries/crypto/Cargo.toml --features std
|
|
||||||
34
.github/workflows/heapviz_test.yml
vendored
34
.github/workflows/heapviz_test.yml
vendored
@@ -1,34 +0,0 @@
|
|||||||
---
|
|
||||||
name: Heapviz tool tests
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'tools/heapviz/**'
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
heapviz_test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Install ncurses
|
|
||||||
run: sudo apt-get install libncurses-dev
|
|
||||||
|
|
||||||
- name: Check heapviz tool
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: check
|
|
||||||
args: --manifest-path tools/heapviz/Cargo.toml
|
|
||||||
|
|
||||||
- name: Unit testing of heapviz tool (debug mode)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --manifest-path tools/heapviz/Cargo.toml
|
|
||||||
|
|
||||||
- name: Unit testing of heapviz tool (release mode)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --manifest-path tools/heapviz/Cargo.toml --release
|
|
||||||
40
.github/workflows/opensk_build.yml
vendored
40
.github/workflows/opensk_build.yml
vendored
@@ -1,40 +0,0 @@
|
|||||||
---
|
|
||||||
name: OpenSK build
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build_ctap2:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, macos-10.15]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: "true"
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install Python dependencies
|
|
||||||
run: python -m pip install --upgrade pip setuptools wheel
|
|
||||||
- name: Set up OpenSK
|
|
||||||
run: ./setup.sh
|
|
||||||
|
|
||||||
- name: Building sha256sum tool
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: build
|
|
||||||
args: --manifest-path third_party/tock/tools/sha256sum/Cargo.toml
|
|
||||||
|
|
||||||
- name: Building OpenSK
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: build
|
|
||||||
args: --release --target=thumbv7em-none-eabi --features with_ctap1,vendor_hid
|
|
||||||
- name: Compute SHA-256 sum
|
|
||||||
run: ./third_party/tock/tools/sha256sum/target/debug/sha256sum target/thumbv7em-none-eabi/release/ctap2
|
|
||||||
52
.github/workflows/opensk_test.yml
vendored
52
.github/workflows/opensk_test.yml
vendored
@@ -1,52 +0,0 @@
|
|||||||
---
|
|
||||||
name: OpenSK tests
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'src/**/*.rs'
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
ctap2_test:
|
|
||||||
name: CTAP2 unit tests
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: "true"
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install Python dependencies
|
|
||||||
run: python -m pip install --upgrade pip setuptools wheel
|
|
||||||
- name: Set up OpenSK
|
|
||||||
run: ./setup.sh
|
|
||||||
|
|
||||||
- name: Unit testing of CTAP2 (release mode)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --release --features std
|
|
||||||
|
|
||||||
- name: Unit testing of CTAP2 (debug mode)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --features std
|
|
||||||
|
|
||||||
- name: Unit testing of CTAP2 (release mode + CTAP1)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --release --features std,with_ctap1
|
|
||||||
|
|
||||||
- name: Unit testing of CTAP2 (debug mode + CTAP1)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --features std,with_ctap1
|
|
||||||
|
|
||||||
29
.github/workflows/persistent_store_test.yml
vendored
29
.github/workflows/persistent_store_test.yml
vendored
@@ -1,29 +0,0 @@
|
|||||||
---
|
|
||||||
name: Persistent store tests
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'libraries/peristent_store/**'
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
persistent_store_test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
|
|
||||||
- name: Unit testing of Persistent store library (release mode)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --manifest-path libraries/persistent_store/Cargo.toml --release --features=std
|
|
||||||
|
|
||||||
- name: Unit testing of Persistent store library (debug mode)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --manifest-path libraries/persistent_store/Cargo.toml --features=std
|
|
||||||
46
.github/workflows/python.yml
vendored
46
.github/workflows/python.yml
vendored
@@ -1,46 +0,0 @@
|
|||||||
name: pylint
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- '**/*.py'
|
|
||||||
- '.pylintrc'
|
|
||||||
- '!third_party/**'
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
jobs:
|
|
||||||
pylint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
|
||||||
uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: ${{ matrix.python-version }}
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
python -m pip install --upgrade pip setuptools wheel
|
|
||||||
pip install 'tockloader==1.5' pylint
|
|
||||||
- name: Register matcher
|
|
||||||
run: echo ::add-matcher::./.github/python_matcher.json
|
|
||||||
- name: Test code with pylint
|
|
||||||
run: ./tools/run_pylint.sh
|
|
||||||
|
|
||||||
yapf:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Set up Python 3.7
|
|
||||||
uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
python -m pip install --upgrade pip setuptools wheel
|
|
||||||
pip install 'yapf>=0.30.0' tockloader
|
|
||||||
- name: Test code formatting with yapf
|
|
||||||
run: |
|
|
||||||
echo ::add-matcher::./.github/python_matcher.json
|
|
||||||
yapf --style=yapf --recursive --exclude third_party --diff .
|
|
||||||
45
.github/workflows/reproducible.yml
vendored
45
.github/workflows/reproducible.yml
vendored
@@ -1,45 +0,0 @@
|
|||||||
---
|
|
||||||
name: Check that binaries are reproducible
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check_hashes:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, macos-10.15]
|
|
||||||
fail-fast: false
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: "true"
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install Python dependencies
|
|
||||||
run: python -m pip install --upgrade pip setuptools wheel
|
|
||||||
- name: Set up OpenSK
|
|
||||||
run: ./setup.sh
|
|
||||||
|
|
||||||
- name: Use sample cryptographic material
|
|
||||||
run: rm -R crypto_data/ && cp -r reproducible/sample_crypto_data crypto_data
|
|
||||||
- name: Computing cryptographic hashes
|
|
||||||
run: ./maintainers/reproduce_hashes.sh
|
|
||||||
|
|
||||||
- name: Upload reproduced binaries
|
|
||||||
uses: actions/upload-artifact@v1
|
|
||||||
with:
|
|
||||||
name: reproduced-${{ matrix.os }}
|
|
||||||
path: reproducible/reproduced.tar
|
|
||||||
|
|
||||||
- name: Comparing binary sizes
|
|
||||||
if: always()
|
|
||||||
run: git diff --no-index reproducible/reference_elf2tab_${{ matrix.os }}.txt reproducible/elf2tab.txt || true
|
|
||||||
- name: Comparing cryptographic hashes
|
|
||||||
if: always()
|
|
||||||
run: git diff --no-index reproducible/reference_binaries_${{ matrix.os }}.sha256sum reproducible/binaries.sha256sum || true
|
|
||||||
39
.github/workflows/rng256_test.yml
vendored
39
.github/workflows/rng256_test.yml
vendored
@@ -1,39 +0,0 @@
|
|||||||
---
|
|
||||||
name: RNG library tests
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'libraries/rng256/**'
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
paths:
|
|
||||||
- 'libraries/rng256/**'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
rng256_test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: "true"
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
run: rustup show
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.7
|
|
||||||
- name: Install Python dependencies
|
|
||||||
run: python -m pip install --upgrade pip setuptools wheel
|
|
||||||
- name: Set up OpenSK
|
|
||||||
run: ./setup.sh
|
|
||||||
|
|
||||||
- name: Unit testing of rng256library (release mode)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --manifest-path libraries/rng256/Cargo.toml --release --features std
|
|
||||||
|
|
||||||
- name: Unit testing of rng256 library (debug mode)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --manifest-path libraries/rng256/Cargo.toml --features std
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,6 +1,3 @@
|
|||||||
fuzz/artifacts
|
|
||||||
fuzz/corpus
|
|
||||||
fuzz/coverage
|
|
||||||
target/
|
target/
|
||||||
|
|
||||||
# Local installation of elf2tab.
|
# Local installation of elf2tab.
|
||||||
|
|||||||
543
.pylintrc
543
.pylintrc
@@ -1,318 +1,135 @@
|
|||||||
# This Pylint rcfile contains a best-effort configuration to uphold the
|
# File taken from Tensor2Tensor project
|
||||||
# best-practices and style described in the Google Python style guide:
|
# https://github.com/tensorflow/tensor2tensor/blob/master/pylintrc
|
||||||
# https://google.github.io/styleguide/pyguide.html
|
|
||||||
#
|
|
||||||
# Its canonical open-source location is:
|
|
||||||
# https://google.github.io/styleguide/pylintrc
|
|
||||||
|
|
||||||
[MAIN]
|
[MASTER]
|
||||||
|
|
||||||
# Files or directories to be skipped. They should be base names, not paths.
|
|
||||||
ignore=third_party
|
|
||||||
|
|
||||||
# Files or directories matching the regex patterns are skipped. The regex
|
|
||||||
# matches against base names, not paths.
|
|
||||||
ignore-patterns=
|
|
||||||
|
|
||||||
# Pickle collected data for later comparisons.
|
# Pickle collected data for later comparisons.
|
||||||
persistent=no
|
persistent=no
|
||||||
|
|
||||||
# List of plugins (as comma separated values of python modules names) to load,
|
# Set the cache size for astng objects.
|
||||||
# usually to register additional checkers.
|
cache-size=500
|
||||||
|
|
||||||
|
# Ignore Py3 files
|
||||||
|
ignore=get_references_web.py,get_references_web_single_group.py
|
||||||
|
|
||||||
load-plugins=
|
load-plugins=
|
||||||
|
pylint.extensions.bad_builtin,
|
||||||
# Use multiple processes to speed up Pylint.
|
pylint.extensions.docparams,
|
||||||
jobs=4
|
pylint.extensions.docstyle,
|
||||||
|
pylint.extensions.redefined_variable_type,
|
||||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
pylint.extensions.overlapping_exceptions,
|
||||||
# active Python interpreter and may run arbitrary code.
|
|
||||||
unsafe-load-any-extension=no
|
|
||||||
|
|
||||||
|
|
||||||
[MESSAGES CONTROL]
|
|
||||||
|
|
||||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
|
||||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
|
|
||||||
confidence=
|
|
||||||
|
|
||||||
# Enable the message, report, category or checker with the given id(s). You can
|
|
||||||
# either give multiple identifier separated by comma (,) or put this option
|
|
||||||
# multiple time (only on the command line, not in the configuration file where
|
|
||||||
# it should appear only once). See also the "--disable" option for examples.
|
|
||||||
#enable=
|
|
||||||
|
|
||||||
# Disable the message, report, category or checker with the given id(s). You
|
|
||||||
# can either give multiple identifiers separated by comma (,) or put this
|
|
||||||
# option multiple times (only on the command line, not in the configuration
|
|
||||||
# file where it should appear only once).You can also use "--disable=all" to
|
|
||||||
# disable everything first and then reenable specific checks. For example, if
|
|
||||||
# you want to run only the similarities checker, you can use "--disable=all
|
|
||||||
# --enable=similarities". If you want to run only the classes checker, but have
|
|
||||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
|
||||||
# --disable=W"
|
|
||||||
disable=abstract-method,
|
|
||||||
apply-builtin,
|
|
||||||
arguments-differ,
|
|
||||||
attribute-defined-outside-init,
|
|
||||||
backtick,
|
|
||||||
bad-option-value,
|
|
||||||
basestring-builtin,
|
|
||||||
buffer-builtin,
|
|
||||||
c-extension-no-member,
|
|
||||||
consider-using-enumerate,
|
|
||||||
cmp-builtin,
|
|
||||||
cmp-method,
|
|
||||||
coerce-builtin,
|
|
||||||
coerce-method,
|
|
||||||
delslice-method,
|
|
||||||
div-method,
|
|
||||||
duplicate-code,
|
|
||||||
eq-without-hash,
|
|
||||||
execfile-builtin,
|
|
||||||
file-builtin,
|
|
||||||
filter-builtin-not-iterating,
|
|
||||||
fixme,
|
|
||||||
getslice-method,
|
|
||||||
global-statement,
|
|
||||||
hex-method,
|
|
||||||
idiv-method,
|
|
||||||
implicit-str-concat-in-sequence,
|
|
||||||
import-error,
|
|
||||||
import-self,
|
|
||||||
import-star-module-level,
|
|
||||||
inconsistent-return-statements,
|
|
||||||
input-builtin,
|
|
||||||
intern-builtin,
|
|
||||||
invalid-str-codec,
|
|
||||||
locally-disabled,
|
|
||||||
long-builtin,
|
|
||||||
long-suffix,
|
|
||||||
map-builtin-not-iterating,
|
|
||||||
misplaced-comparison-constant,
|
|
||||||
missing-function-docstring,
|
|
||||||
metaclass-assignment,
|
|
||||||
next-method-called,
|
|
||||||
next-method-defined,
|
|
||||||
no-absolute-import,
|
|
||||||
no-else-break,
|
|
||||||
no-else-continue,
|
|
||||||
no-else-raise,
|
|
||||||
no-else-return,
|
|
||||||
no-init, # added
|
|
||||||
no-member,
|
|
||||||
no-name-in-module,
|
|
||||||
no-self-use,
|
|
||||||
nonzero-method,
|
|
||||||
oct-method,
|
|
||||||
old-division,
|
|
||||||
old-ne-operator,
|
|
||||||
old-octal-literal,
|
|
||||||
old-raise-syntax,
|
|
||||||
parameter-unpacking,
|
|
||||||
print-statement,
|
|
||||||
raising-string,
|
|
||||||
range-builtin-not-iterating,
|
|
||||||
raw_input-builtin,
|
|
||||||
rdiv-method,
|
|
||||||
reduce-builtin,
|
|
||||||
relative-import,
|
|
||||||
reload-builtin,
|
|
||||||
round-builtin,
|
|
||||||
setslice-method,
|
|
||||||
signature-differs,
|
|
||||||
standarderror-builtin,
|
|
||||||
suppressed-message,
|
|
||||||
sys-max-int,
|
|
||||||
too-few-public-methods,
|
|
||||||
too-many-ancestors,
|
|
||||||
too-many-arguments,
|
|
||||||
too-many-boolean-expressions,
|
|
||||||
too-many-branches,
|
|
||||||
too-many-instance-attributes,
|
|
||||||
too-many-locals,
|
|
||||||
too-many-nested-blocks,
|
|
||||||
too-many-public-methods,
|
|
||||||
too-many-return-statements,
|
|
||||||
too-many-statements,
|
|
||||||
trailing-newlines,
|
|
||||||
unichr-builtin,
|
|
||||||
unicode-builtin,
|
|
||||||
unnecessary-pass,
|
|
||||||
unpacking-in-except,
|
|
||||||
unrecognized-option,
|
|
||||||
useless-else-on-loop,
|
|
||||||
useless-object-inheritance,
|
|
||||||
useless-suppression,
|
|
||||||
using-cmp-argument,
|
|
||||||
wrong-import-order,
|
|
||||||
xrange-builtin,
|
|
||||||
zip-builtin-not-iterating,
|
|
||||||
|
|
||||||
|
|
||||||
[REPORTS]
|
[REPORTS]
|
||||||
|
|
||||||
# Set the output format. Available formats are text, parseable, colorized, msvs
|
# Set the output format.
|
||||||
# (visual studio) and html. You can also give a reporter class, eg
|
# output-format=sorted-text
|
||||||
# mypackage.mymodule.MyReporterClass.
|
|
||||||
output-format=text
|
|
||||||
|
|
||||||
# Put messages in a separate file for each module / package specified on the
|
# Put messages in a separate file for each module / package specified on the
|
||||||
# command line instead of printing them on stdout. Reports (if any) will be
|
# command line instead of printing them on stdout. Reports (if any) will be
|
||||||
# written in a file name "pylint_global.[txt|html]". This option is deprecated
|
# written in a file name "pylint_global.[txt|html]".
|
||||||
# and it will be removed in Pylint 2.0.
|
|
||||||
files-output=no
|
files-output=no
|
||||||
|
|
||||||
# Tells whether to display a full report or only the messages
|
# Tells whether to display a full report or only the messages.
|
||||||
reports=no
|
reports=no
|
||||||
|
|
||||||
# Python expression which should return a note less than 10 (10 is the highest
|
# Disable the report(s) with the given id(s).
|
||||||
# note). You have access to the variables errors warning, statement which
|
disable-report=R0001,R0002,R0003,R0004,R0101,R0102,R0201,R0202,R0220,R0401,R0402,R0701,R0801,R0901,R0902,R0903,R0904,R0911,R0912,R0913,R0914,R0915,R0921,R0922,R0923
|
||||||
# respectively contain the number of errors / warnings messages and the total
|
|
||||||
# number of statements analyzed. This is used by the global evaluation report
|
|
||||||
# (RP0004).
|
|
||||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
|
||||||
|
|
||||||
# Template used to display messages. This is a python new-style format string
|
# Error message template (continued on second line)
|
||||||
# used to format the message information. See doc for all details
|
msg-template={msg_id}:{line:3} {obj}: {msg} [{symbol}]
|
||||||
#msg-template=
|
|
||||||
|
|
||||||
|
# We don't need evaluation score
|
||||||
|
score=no
|
||||||
|
|
||||||
|
[MESSAGES CONTROL]
|
||||||
|
# List of checkers and warnings to enable.
|
||||||
|
enable=indexing-exception,old-raise-syntax
|
||||||
|
|
||||||
|
# List of checkers and warnings to disable.
|
||||||
|
disable=design,similarities,no-self-use,attribute-defined-outside-init,locally-disabled,star-args,pointless-except,bad-option-value,global-statement,fixme,suppressed-message,useless-suppression,locally-enabled,file-ignored,multiple-imports,c-extension-no-member,trailing-newlines,unsubscriptable-object,misplaced-comparison-constant,no-member,abstract-method,no-else-return,missing-docstring,wrong-import-order,protected-access,inconsistent-return-statements,invalid-unary-operand-type,import-error,no-name-in-module,arguments-differ,not-context-manager,unused-argument
|
||||||
|
|
||||||
[BASIC]
|
[BASIC]
|
||||||
|
|
||||||
|
# Required attributes for module, separated by a comma
|
||||||
|
required-attributes=
|
||||||
|
|
||||||
|
# Regular expression which should only match the name
|
||||||
|
# of functions or classes which do not require a docstring.
|
||||||
|
no-docstring-rgx=(__.*__|main)
|
||||||
|
|
||||||
|
# Min length in lines of a function that requires a docstring.
|
||||||
|
docstring-min-length=10
|
||||||
|
|
||||||
|
# Regular expression which should only match correct module names. The
|
||||||
|
# leading underscore is sanctioned for private modules by Google's style
|
||||||
|
# guide.
|
||||||
|
#
|
||||||
|
# There are exceptions to the basic rule (_?[a-z][a-z0-9_]*) to cover
|
||||||
|
# requirements of Python's module system.
|
||||||
|
module-rgx=^(_?[a-z][a-z0-9_]*)|__init__$
|
||||||
|
|
||||||
|
# Regular expression which should only match correct module level names
|
||||||
|
const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
|
||||||
|
|
||||||
|
# Regular expression which should only match correct class attribute
|
||||||
|
class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
|
||||||
|
|
||||||
|
# Regular expression which should only match correct class names
|
||||||
|
class-rgx=^_?[A-Z][a-zA-Z0-9]*$
|
||||||
|
|
||||||
|
# Regular expression which should only match correct function names.
|
||||||
|
# 'camel_case' and 'snake_case' group names are used for consistency of naming
|
||||||
|
# styles across functions and methods.
|
||||||
|
function-rgx=^(?:(?P<exempt>setUp|tearDown|setUpModule|tearDownModule)|(?P<camel_case>_?[A-Z][a-zA-Z0-9]*)|(?P<snake_case>_?[a-z][a-z0-9_]*))$
|
||||||
|
|
||||||
|
|
||||||
|
# Regular expression which should only match correct method names.
|
||||||
|
# 'camel_case' and 'snake_case' group names are used for consistency of naming
|
||||||
|
# styles across functions and methods. 'exempt' indicates a name which is
|
||||||
|
# consistent with all naming styles.
|
||||||
|
method-rgx=(?x)
|
||||||
|
^(?:(?P<exempt>_[a-z0-9_]+__|runTest|setUp|tearDown|setUpTestCase
|
||||||
|
|tearDownTestCase|setupSelf|tearDownClass|setUpClass
|
||||||
|
|(test|assert)_*[A-Z0-9][a-zA-Z0-9_]*|next)
|
||||||
|
|(?P<camel_case>_{0,2}[A-Z][a-zA-Z0-9_]*)
|
||||||
|
|(?P<snake_case>_{0,2}[a-z][a-z0-9_]*))$
|
||||||
|
|
||||||
|
|
||||||
|
# Regular expression which should only match correct instance attribute names
|
||||||
|
attr-rgx=^_{0,2}[a-z][a-z0-9_]*$
|
||||||
|
|
||||||
|
# Regular expression which should only match correct argument names
|
||||||
|
argument-rgx=^[a-z][a-z0-9_]*$
|
||||||
|
|
||||||
|
# Regular expression which should only match correct variable names
|
||||||
|
variable-rgx=^[a-z][a-z0-9_]*$
|
||||||
|
|
||||||
|
# Regular expression which should only match correct list comprehension /
|
||||||
|
# generator expression variable names
|
||||||
|
inlinevar-rgx=^[a-z][a-z0-9_]*$
|
||||||
|
|
||||||
# Good variable names which should always be accepted, separated by a comma
|
# Good variable names which should always be accepted, separated by a comma
|
||||||
good-names=main,_
|
good-names=main,_
|
||||||
|
|
||||||
# Bad variable names which should always be refused, separated by a comma
|
# Bad variable names which should always be refused, separated by a comma
|
||||||
bad-names=
|
bad-names=
|
||||||
|
|
||||||
# Colon-delimited sets of names that determine each other's naming style when
|
# List of builtins function names that should not be used, separated by a comma
|
||||||
# the name regexes allow several styles.
|
bad-functions=input,apply,reduce
|
||||||
name-group=
|
|
||||||
|
|
||||||
# Include a hint for the correct naming format with invalid-name
|
# List of decorators that define properties, such as abc.abstractproperty.
|
||||||
include-naming-hint=no
|
property-classes=abc.abstractproperty
|
||||||
|
|
||||||
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
|
||||||
# to this list to register other decorators that produce valid properties.
|
|
||||||
property-classes=abc.abstractproperty,cached_property.cached_property,cached_property.threaded_cached_property,cached_property.cached_property_with_ttl,cached_property.threaded_cached_property_with_ttl
|
|
||||||
|
|
||||||
# Regular expression matching correct function names
|
|
||||||
function-rgx=^(?:(?P<exempt>setUp|tearDown|setUpModule|tearDownModule)|(?P<camel_case>_?[A-Z][a-zA-Z0-9]*)|(?P<snake_case>_?[a-z][a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Regular expression matching correct variable names
|
|
||||||
variable-rgx=^[a-z][a-z0-9_]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct constant names
|
|
||||||
const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
|
|
||||||
|
|
||||||
# Regular expression matching correct attribute names
|
|
||||||
attr-rgx=^_{0,2}[a-z][a-z0-9_]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct argument names
|
|
||||||
argument-rgx=^[a-z][a-z0-9_]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct class attribute names
|
|
||||||
class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
|
|
||||||
|
|
||||||
# Regular expression matching correct inline iteration names
|
|
||||||
inlinevar-rgx=^[a-z][a-z0-9_]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct class names
|
|
||||||
class-rgx=^_?[A-Z][a-zA-Z0-9]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct module names
|
|
||||||
module-rgx=^(_?[a-z][a-z0-9_]*|__init__)$
|
|
||||||
|
|
||||||
# Regular expression matching correct method names
|
|
||||||
method-rgx=(?x)^(?:(?P<exempt>_[a-z0-9_]+__|runTest|setUp|tearDown|setUpTestCase|tearDownTestCase|setupSelf|tearDownClass|setUpClass|(test|assert)_*[A-Z0-9][a-zA-Z0-9_]*|next)|(?P<camel_case>_{0,2}[A-Z][a-zA-Z0-9_]*)|(?P<snake_case>_{0,2}[a-z][a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Regular expression which should only match function or class names that do
|
|
||||||
# not require a docstring.
|
|
||||||
no-docstring-rgx=(__.*__|main|test.*|.*test|.*Test)$
|
|
||||||
|
|
||||||
# Minimum line length for functions/classes that require docstrings, shorter
|
|
||||||
# ones are exempt.
|
|
||||||
docstring-min-length=10
|
|
||||||
|
|
||||||
|
|
||||||
[TYPECHECK]
|
[TYPECHECK]
|
||||||
|
|
||||||
# List of decorators that produce context managers, such as
|
|
||||||
# contextlib.contextmanager. Add to this list to register other decorators that
|
|
||||||
# produce valid context managers.
|
|
||||||
contextmanager-decorators=contextlib.contextmanager,contextlib2.contextmanager
|
|
||||||
|
|
||||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
# Tells whether missing members accessed in mixin class should be ignored. A
|
||||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
||||||
ignore-mixin-members=yes
|
ignore-mixin-members=yes
|
||||||
|
|
||||||
# List of module names for which member attributes should not be checked
|
# List of decorators that create context managers from functions, such as
|
||||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
# contextlib.contextmanager.
|
||||||
# and thus existing member attributes cannot be deduced by static analysis. It
|
contextmanager-decorators=contextlib.contextmanager,contextlib2.contextmanager
|
||||||
# supports qualified module names, as well as Unix pattern matching.
|
|
||||||
ignored-modules=
|
|
||||||
|
|
||||||
# List of class names for which member attributes should not be checked (useful
|
|
||||||
# for classes with dynamically set attributes). This supports the use of
|
|
||||||
# qualified names.
|
|
||||||
ignored-classes=optparse.Values,thread._local,_thread._local
|
|
||||||
|
|
||||||
# List of members which are set dynamically and missed by pylint inference
|
|
||||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
|
||||||
# expressions are accepted.
|
|
||||||
generated-members=
|
|
||||||
|
|
||||||
|
|
||||||
[FORMAT]
|
|
||||||
|
|
||||||
# Maximum number of characters on a single line.
|
|
||||||
max-line-length=80
|
|
||||||
|
|
||||||
# TODO(https://github.com/PyCQA/pylint/issues/3352): Direct pylint to exempt
|
|
||||||
# lines made too long by directives to pytype.
|
|
||||||
|
|
||||||
# Regexp for a line that is allowed to be longer than the limit.
|
|
||||||
ignore-long-lines=(?x)(
|
|
||||||
^\s*(\#\ )?<?https?://\S+>?$|
|
|
||||||
^\s*(from\s+\S+\s+)?import\s+.+$)
|
|
||||||
|
|
||||||
# Allow the body of an if to be on the same line as the test if there is no
|
|
||||||
# else.
|
|
||||||
single-line-if-stmt=yes
|
|
||||||
|
|
||||||
# List of optional constructs for which whitespace checking is disabled. `dict-
|
|
||||||
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
|
|
||||||
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
|
|
||||||
# `empty-line` allows space-only lines.
|
|
||||||
no-space-check=
|
|
||||||
|
|
||||||
# Maximum number of lines in a module
|
|
||||||
max-module-lines=99999
|
|
||||||
|
|
||||||
# String used as indentation unit. The internal Google style guide mandates 2
|
|
||||||
# spaces. Google's externaly-published style guide says 4, consistent with
|
|
||||||
# PEP 8. Here, we use 2 spaces, for conformity with many open-sourced Google
|
|
||||||
# projects (like TensorFlow).
|
|
||||||
indent-string=' '
|
|
||||||
|
|
||||||
# Number of spaces of indent required inside a hanging or continued line.
|
|
||||||
indent-after-paren=4
|
|
||||||
|
|
||||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
|
||||||
expected-line-ending-format=
|
|
||||||
|
|
||||||
|
|
||||||
[MISCELLANEOUS]
|
|
||||||
|
|
||||||
# List of note tags to take in consideration, separated by a comma.
|
|
||||||
notes=TODO
|
|
||||||
|
|
||||||
|
|
||||||
[STRING]
|
|
||||||
|
|
||||||
# This flag controls whether inconsistent-quotes generates a warning when the
|
|
||||||
# character used as a quote delimiter is used inconsistently within a module.
|
|
||||||
check-quote-consistency=yes
|
|
||||||
|
|
||||||
|
|
||||||
[VARIABLES]
|
[VARIABLES]
|
||||||
@@ -320,123 +137,99 @@ check-quote-consistency=yes
|
|||||||
# Tells whether we should check for unused import in __init__ files.
|
# Tells whether we should check for unused import in __init__ files.
|
||||||
init-import=no
|
init-import=no
|
||||||
|
|
||||||
# A regular expression matching the name of dummy variables (i.e. expectedly
|
# A regular expression matching names used for dummy variables (i.e. not used).
|
||||||
# not used).
|
|
||||||
dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_)
|
dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_)
|
||||||
|
|
||||||
# List of additional names supposed to be defined in builtins. Remember that
|
# List of additional names supposed to be defined in builtins. Remember that
|
||||||
# you should avoid to define new builtins when possible.
|
# you should avoid to define new builtins when possible.
|
||||||
additional-builtins=
|
additional-builtins=
|
||||||
|
|
||||||
# List of strings which can identify a callback function by name. A callback
|
|
||||||
# name must start or end with one of those strings.
|
|
||||||
callbacks=cb_,_cb
|
|
||||||
|
|
||||||
# List of qualified module names which can have objects that can redefine
|
[CLASSES]
|
||||||
# builtins.
|
|
||||||
redefining-builtins-modules=six,six.moves,past.builtins,future.builtins,functools
|
# List of method names used to declare (i.e. assign) instance attributes.
|
||||||
|
defining-attr-methods=__init__,__new__,setUp
|
||||||
|
|
||||||
|
# "class_" is also a valid for the first argument to a class method.
|
||||||
|
valid-classmethod-first-arg=cls,class_
|
||||||
|
|
||||||
|
|
||||||
[LOGGING]
|
[EXCEPTIONS]
|
||||||
|
|
||||||
# Logging modules to check that the string format arguments are in logging
|
overgeneral-exceptions=StandardError,Exception,BaseException
|
||||||
# function parameter format
|
|
||||||
logging-modules=logging,absl.logging,tensorflow.io.logging
|
|
||||||
|
|
||||||
|
|
||||||
[SIMILARITIES]
|
|
||||||
|
|
||||||
# Minimum lines number of a similarity.
|
|
||||||
min-similarity-lines=4
|
|
||||||
|
|
||||||
# Ignore comments when computing similarities.
|
|
||||||
ignore-comments=yes
|
|
||||||
|
|
||||||
# Ignore docstrings when computing similarities.
|
|
||||||
ignore-docstrings=yes
|
|
||||||
|
|
||||||
# Ignore imports when computing similarities.
|
|
||||||
ignore-imports=no
|
|
||||||
|
|
||||||
|
|
||||||
[SPELLING]
|
|
||||||
|
|
||||||
# Spelling dictionary name. Available dictionaries: none. To make it working
|
|
||||||
# install python-enchant package.
|
|
||||||
spelling-dict=
|
|
||||||
|
|
||||||
# List of comma separated words that should not be checked.
|
|
||||||
spelling-ignore-words=
|
|
||||||
|
|
||||||
# A path to a file that contains private dictionary; one word per line.
|
|
||||||
spelling-private-dict-file=
|
|
||||||
|
|
||||||
# Tells whether to store unknown words to indicated private dictionary in
|
|
||||||
# --spelling-private-dict-file option instead of raising a message.
|
|
||||||
spelling-store-unknown-words=no
|
|
||||||
|
|
||||||
|
|
||||||
[IMPORTS]
|
[IMPORTS]
|
||||||
|
|
||||||
# Deprecated modules which should not be used, separated by a comma
|
# Deprecated modules which should not be used, separated by a comma
|
||||||
deprecated-modules=regsub,
|
deprecated-modules=regsub,TERMIOS,Bastion,rexec,sets
|
||||||
TERMIOS,
|
|
||||||
Bastion,
|
|
||||||
rexec,
|
|
||||||
sets
|
|
||||||
|
|
||||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
|
||||||
# given file (report RP0402 must not be disabled)
|
|
||||||
import-graph=
|
|
||||||
|
|
||||||
# Create a graph of external dependencies in the given file (report RP0402 must
|
|
||||||
# not be disabled)
|
|
||||||
ext-import-graph=
|
|
||||||
|
|
||||||
# Create a graph of internal dependencies in the given file (report RP0402 must
|
|
||||||
# not be disabled)
|
|
||||||
int-import-graph=
|
|
||||||
|
|
||||||
# Force import order to recognize a module as part of the standard
|
|
||||||
# compatibility libraries.
|
|
||||||
known-standard-library=
|
|
||||||
|
|
||||||
# Force import order to recognize a module as part of a third party library.
|
|
||||||
known-third-party=enchant, absl
|
|
||||||
|
|
||||||
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
|
||||||
# 3 compatible code, which means that the block might have code that exists
|
|
||||||
# only in one or another interpreter, leading to false positives when analysed.
|
|
||||||
analyse-fallback-blocks=no
|
|
||||||
|
|
||||||
|
|
||||||
[CLASSES]
|
[FORMAT]
|
||||||
|
|
||||||
# List of method names used to declare (i.e. assign) instance attributes.
|
# Maximum number of characters on a single line.
|
||||||
defining-attr-methods=__init__,
|
max-line-length=80
|
||||||
__new__,
|
|
||||||
setUp
|
|
||||||
|
|
||||||
# List of member names, which should be excluded from the protected access
|
# Regexp for a line that is allowed to be longer than the limit.
|
||||||
# warning.
|
# This "ignore" regex is today composed of several independent parts:
|
||||||
exclude-protected=_asdict,
|
# (1) Long import lines
|
||||||
_fields,
|
# (2) URLs in comments or pydocs. Detecting URLs by regex is a hard problem and
|
||||||
_replace,
|
# no amount of tweaking will make a perfect regex AFAICT. This one is a good
|
||||||
_source,
|
# compromise.
|
||||||
_make
|
# (3) Constant string literals at the start of files don't need to be broken
|
||||||
|
# across lines. Allowing long paths and urls to be on a single
|
||||||
|
# line. Also requires that the string not be a triplequoted string.
|
||||||
|
ignore-long-lines=(?x)
|
||||||
|
(^\s*(import|from)\s
|
||||||
|
|^\s*(\#\ )?<?(https?|ftp):\/\/[^\s\/$.?#].[^\s]*>?$
|
||||||
|
|^[a-zA-Z_][a-zA-Z0-9_]*\s*=\s*("[^"]\S+"|'[^']\S+')
|
||||||
|
)
|
||||||
|
|
||||||
# List of valid names for the first argument in a class method.
|
# Maximum number of lines in a module
|
||||||
valid-classmethod-first-arg=cls,
|
max-module-lines=99999
|
||||||
class_
|
|
||||||
|
|
||||||
# List of valid names for the first argument in a metaclass class method.
|
# String used as indentation unit. We differ from PEP8's normal 4 spaces.
|
||||||
valid-metaclass-classmethod-first-arg=mcs
|
indent-string=' '
|
||||||
|
|
||||||
|
# Do not warn about multiple statements on a single line for constructs like
|
||||||
|
# if test: stmt
|
||||||
|
single-line-if-stmt=y
|
||||||
|
|
||||||
|
# Make sure : in dicts and trailing commas are checked for whitespace.
|
||||||
|
no-space-check=
|
||||||
|
|
||||||
|
|
||||||
[EXCEPTIONS]
|
[LOGGING]
|
||||||
|
|
||||||
# Exceptions that will emit a warning when being caught. Defaults to
|
# Add logging modules.
|
||||||
# "Exception"
|
logging-modules=logging,absl.logging
|
||||||
overgeneral-exceptions=StandardError,
|
|
||||||
Exception,
|
|
||||||
BaseException
|
[MISCELLANEOUS]
|
||||||
|
|
||||||
|
# List of note tags to take in consideration, separated by a comma.
|
||||||
|
notes=
|
||||||
|
|
||||||
|
|
||||||
|
# Maximum line length for lambdas
|
||||||
|
short-func-length=1
|
||||||
|
|
||||||
|
# List of module members that should be marked as deprecated.
|
||||||
|
# All of the string functions are listed in 4.1.4 Deprecated string functions
|
||||||
|
# in the Python 2.4 docs.
|
||||||
|
deprecated-members=string.atof,string.atoi,string.atol,string.capitalize,string.expandtabs,string.find,string.rfind,string.index,string.rindex,string.count,string.lower,string.split,string.rsplit,string.splitfields,string.join,string.joinfields,string.lstrip,string.rstrip,string.strip,string.swapcase,string.translate,string.upper,string.ljust,string.rjust,string.center,string.zfill,string.replace,sys.exitfunc,sys.maxint
|
||||||
|
|
||||||
|
|
||||||
|
# List of exceptions that do not need to be mentioned in the Raises section of
|
||||||
|
# a docstring.
|
||||||
|
ignore-exceptions=AssertionError,NotImplementedError,StopIteration,TypeError
|
||||||
|
|
||||||
|
|
||||||
|
# Number of spaces of indent required when the last token on the preceding line
|
||||||
|
# is an open (, [, or {.
|
||||||
|
indent-after-paren=4
|
||||||
|
|
||||||
|
# Set the linting for string quotes
|
||||||
|
string-quote=double
|
||||||
|
triple-quote=double
|
||||||
|
docstring-quote=double
|
||||||
|
|||||||
253
Cargo.lock
generated
253
Cargo.lock
generated
@@ -1,7 +1,5 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.19"
|
version = "0.7.19"
|
||||||
@@ -11,15 +9,6 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arbitrary"
|
|
||||||
version = "0.4.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "db55d72333851e17d572bec876e390cd3b11eb1ef53ae821dd9f3b653d2b4569"
|
|
||||||
dependencies = [
|
|
||||||
"derive_arbitrary",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayref"
|
name = "arrayref"
|
||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
@@ -59,6 +48,10 @@ version = "1.4.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cbor"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.73"
|
version = "1.0.73"
|
||||||
@@ -86,10 +79,12 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayref",
|
"arrayref",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"cbor",
|
||||||
"hex",
|
"hex",
|
||||||
|
"libtock_drivers",
|
||||||
|
"rand",
|
||||||
"regex",
|
"regex",
|
||||||
"ring",
|
"ring",
|
||||||
"rng256",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"subtle",
|
"subtle",
|
||||||
@@ -100,51 +95,19 @@ dependencies = [
|
|||||||
name = "ctap2"
|
name = "ctap2"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arbitrary",
|
|
||||||
"arrayref",
|
"arrayref",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"cbor",
|
||||||
"crypto",
|
"crypto",
|
||||||
"ed25519-compact",
|
|
||||||
"embedded-time",
|
|
||||||
"enum-iterator",
|
"enum-iterator",
|
||||||
"lang_items",
|
"lang_items",
|
||||||
"libtock_core",
|
"libtock_core",
|
||||||
"libtock_drivers",
|
"libtock_drivers",
|
||||||
"openssl",
|
|
||||||
"persistent_store",
|
"persistent_store",
|
||||||
"rand 0.8.5",
|
|
||||||
"rng256",
|
|
||||||
"sk-cbor",
|
|
||||||
"subtle",
|
"subtle",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "derive_arbitrary"
|
|
||||||
version = "0.4.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b1a012b5e473dc912f0db0546a1c9c6a194ce8494feb66fa0237160926f9e0e6"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ed25519-compact"
|
|
||||||
version = "1.0.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bee9df587982575886a8682edcee11877894349a805f25629c27f63abe3e9ae8"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "embedded-time"
|
|
||||||
version = "0.12.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d7a4b4d10ac48d08bfe3db7688c402baadb244721f30a77ce360bd24c3dffe58"
|
|
||||||
dependencies = [
|
|
||||||
"num",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "enum-iterator"
|
name = "enum-iterator"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
@@ -165,21 +128,6 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "foreign-types"
|
|
||||||
version = "0.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
|
||||||
dependencies = [
|
|
||||||
"foreign-types-shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "foreign-types-shared"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fuchsia-cprng"
|
name = "fuchsia-cprng"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@@ -205,9 +153,9 @@ checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.8"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
@@ -229,9 +177,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.133"
|
version = "0.2.134"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966"
|
checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libtock_codegen"
|
name = "libtock_codegen"
|
||||||
@@ -277,130 +225,16 @@ version = "2.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f"
|
|
||||||
dependencies = [
|
|
||||||
"num-complex",
|
|
||||||
"num-integer",
|
|
||||||
"num-iter",
|
|
||||||
"num-rational",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-complex"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5"
|
|
||||||
dependencies = [
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-integer"
|
|
||||||
version = "0.1.45"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg 1.1.0",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-iter"
|
|
||||||
version = "0.1.43"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg 1.1.0",
|
|
||||||
"num-integer",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-rational"
|
|
||||||
version = "0.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg 1.1.0",
|
|
||||||
"num-integer",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-traits"
|
|
||||||
version = "0.2.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg 1.1.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.14.0"
|
version = "1.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
|
checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "openssl"
|
|
||||||
version = "0.10.41"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"cfg-if",
|
|
||||||
"foreign-types",
|
|
||||||
"libc",
|
|
||||||
"once_cell",
|
|
||||||
"openssl-macros",
|
|
||||||
"openssl-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "openssl-macros"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "openssl-sys"
|
|
||||||
version = "0.9.75"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg 1.1.0",
|
|
||||||
"cc",
|
|
||||||
"libc",
|
|
||||||
"pkg-config",
|
|
||||||
"vcpkg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "persistent_store"
|
name = "persistent_store"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pkg-config"
|
|
||||||
version = "0.3.25"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ppv-lite86"
|
|
||||||
version = "0.2.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.43"
|
version = "1.0.43"
|
||||||
@@ -427,7 +261,7 @@ checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg 0.1.8",
|
"autocfg 0.1.8",
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha 0.1.1",
|
"rand_chacha",
|
||||||
"rand_core 0.4.2",
|
"rand_core 0.4.2",
|
||||||
"rand_hc",
|
"rand_hc",
|
||||||
"rand_isaac",
|
"rand_isaac",
|
||||||
@@ -438,17 +272,6 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand"
|
|
||||||
version = "0.8.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"rand_chacha 0.3.1",
|
|
||||||
"rand_core 0.6.4",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_chacha"
|
name = "rand_chacha"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@@ -459,16 +282,6 @@ dependencies = [
|
|||||||
"rand_core 0.3.1",
|
"rand_core 0.3.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_chacha"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
|
||||||
dependencies = [
|
|
||||||
"ppv-lite86",
|
|
||||||
"rand_core 0.6.4",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_core"
|
name = "rand_core"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@@ -484,15 +297,6 @@ version = "0.4.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.6.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_hc"
|
name = "rand_hc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -596,15 +400,6 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rng256"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"arrayref",
|
|
||||||
"libtock_drivers",
|
|
||||||
"rand 0.6.5",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.11"
|
version = "1.0.11"
|
||||||
@@ -633,19 +428,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.69"
|
version = "1.0.86"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e466864e431129c7e0d3476b92f20458e5879919a0596c6472738d9fa2d342f8"
|
checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sk-cbor"
|
|
||||||
version = "0.1.2"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spin"
|
name = "spin"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
@@ -660,9 +451,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.100"
|
version = "1.0.101"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e"
|
checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -671,9 +462,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.4"
|
version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
@@ -690,12 +481,6 @@ dependencies = [
|
|||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vcpkg"
|
|
||||||
version = "0.2.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
|||||||
19
Cargo.toml
19
Cargo.toml
@@ -13,37 +13,28 @@ edition = "2018"
|
|||||||
libtock_core = { path = "third_party/libtock-rs/core" }
|
libtock_core = { path = "third_party/libtock-rs/core" }
|
||||||
libtock_drivers = { path = "third_party/libtock-drivers" }
|
libtock_drivers = { path = "third_party/libtock-drivers" }
|
||||||
lang_items = { path = "third_party/lang-items" }
|
lang_items = { path = "third_party/lang-items" }
|
||||||
sk-cbor = { path = "libraries/cbor" }
|
cbor = { path = "libraries/cbor" }
|
||||||
crypto = { path = "libraries/crypto" }
|
crypto = { path = "libraries/crypto" }
|
||||||
rng256 = { path = "libraries/rng256" }
|
|
||||||
persistent_store = { path = "libraries/persistent_store" }
|
persistent_store = { path = "libraries/persistent_store" }
|
||||||
byteorder = { version = "1", default-features = false }
|
byteorder = { version = "1", default-features = false }
|
||||||
arrayref = "0.3.6"
|
arrayref = "0.3.6"
|
||||||
subtle = { version = "2.2", default-features = false, features = ["nightly"] }
|
subtle = { version = "2.2", default-features = false, features = ["nightly"] }
|
||||||
embedded-time = "0.12.1"
|
|
||||||
arbitrary = { version = "0.4.7", features = ["derive"], optional = true }
|
|
||||||
rand = { version = "0.8.4", optional = true }
|
|
||||||
ed25519-compact = { version = "1", default-features = false, optional = true }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
debug_allocations = ["lang_items/debug_allocations"]
|
debug_allocations = ["lang_items/debug_allocations"]
|
||||||
debug_ctap = ["libtock_drivers/debug_ctap"]
|
debug_ctap = ["crypto/derive_debug", "libtock_drivers/debug_ctap"]
|
||||||
panic_console = ["lang_items/panic_console"]
|
panic_console = ["lang_items/panic_console"]
|
||||||
std = ["crypto/std", "lang_items/std", "persistent_store/std", "rng256/std", "rand"]
|
std = ["cbor/std", "crypto/std", "crypto/derive_debug", "lang_items/std", "persistent_store/std"]
|
||||||
verbose = ["debug_ctap", "libtock_drivers/verbose_usb"]
|
verbose = ["debug_ctap", "libtock_drivers/verbose_usb"]
|
||||||
with_ctap1 = ["crypto/with_ctap1"]
|
with_ctap1 = ["crypto/with_ctap1"]
|
||||||
|
with_ctap2_1 = []
|
||||||
with_nfc = ["libtock_drivers/with_nfc"]
|
with_nfc = ["libtock_drivers/with_nfc"]
|
||||||
vendor_hid = ["libtock_drivers/vendor_hid"]
|
|
||||||
fuzz = ["arbitrary", "std"]
|
|
||||||
ed25519 = ["ed25519-compact"]
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
enum-iterator = "0.6.0"
|
enum-iterator = "0.6.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
sk-cbor = { path = "libraries/cbor" }
|
|
||||||
uuid = { version = "0.8", features = ["v4"] }
|
uuid = { version = "0.8", features = ["v4"] }
|
||||||
openssl = "0.10.36"
|
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
@@ -52,5 +43,3 @@ lto = true # Link Time Optimization usually reduces size of binaries and static
|
|||||||
[profile.release]
|
[profile.release]
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
lto = true # Link Time Optimization usually reduces size of binaries and static libraries
|
lto = true # Link Time Optimization usually reduces size of binaries and static libraries
|
||||||
opt-level = "z"
|
|
||||||
codegen-units = 1
|
|
||||||
|
|||||||
27
README.md
27
README.md
@@ -1,10 +1,9 @@
|
|||||||
# <img alt="OpenSK logo" src="docs/img/OpenSK.svg" width="200px">
|
# <img alt="OpenSK logo" src="docs/img/OpenSK.svg" width="200px">
|
||||||
|
|
||||||

|
This branch is unmaintained. It implements the CTAP 2.0 version of OpenSK.
|
||||||

|
Please check out the default branch for maintained code.
|
||||||

|
If you are a developer, go to the
|
||||||

|
[develop branch](https://github.com/google/OpenSK/tree/develop).
|
||||||
[](https://coveralls.io/github/google/OpenSK?branch=develop)
|
|
||||||
|
|
||||||
## OpenSK
|
## OpenSK
|
||||||
|
|
||||||
@@ -18,26 +17,18 @@ enclosure!
|
|||||||
You can see OpenSK in action in this
|
You can see OpenSK in action in this
|
||||||
[video on YouTube](https://www.youtube.com/watch?v=klEozvpw0xg)!
|
[video on YouTube](https://www.youtube.com/watch?v=klEozvpw0xg)!
|
||||||
|
|
||||||
You are viewing the branch for developers. New features are developed here
|
|
||||||
before they are stabilized. If you instead want to use the FIDO certified
|
|
||||||
firmware, please go back to the
|
|
||||||
[stable branch](https://github.com/google/OpenSK).
|
|
||||||
|
|
||||||
### FIDO2
|
### FIDO2
|
||||||
|
|
||||||
The develop branch implements the
|
This branch implements the
|
||||||
[CTAP2.1 specification](https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html).
|
[CTAP2.0 specification](https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html)
|
||||||
This branch is not FIDO certified. The implementation is backwards compatible
|
and is FIDO certified. OpenSK supports U2F, and non-discoverable credentials
|
||||||
to CTAP2.0. Additionally, OpenSK supports U2F, and non-discoverable credentials
|
|
||||||
created with either protocol are compatible with the other.
|
created with either protocol are compatible with the other.
|
||||||
|
|
||||||
### :warning: Disclaimer
|
### :warning: Disclaimer
|
||||||
|
|
||||||
This project is **proof-of-concept and a research platform**. It is **NOT**
|
This project is **proof-of-concept and a research platform**. It is **NOT**
|
||||||
meant for a daily usage. It comes with a few limitations:
|
meant for a daily usage. The cryptography implementations are not resistent
|
||||||
|
against side-channel attacks.
|
||||||
* This branch is under development, and therefore less rigorously tested than the stable branch.
|
|
||||||
* The cryptography implementations are not resistent against side-channel attacks.
|
|
||||||
|
|
||||||
We're still in the process of integrating the
|
We're still in the process of integrating the
|
||||||
[ARM® CryptoCell-310](https://developer.arm.com/ip-products/security-ip/cryptocell-300-family)
|
[ARM® CryptoCell-310](https://developer.arm.com/ip-products/security-ip/cryptocell-300-family)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ build = "build.rs"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
path = "../nrf52840_dongle_opensk/src/main.rs"
|
path = "../nrf52840_dongle/src/main.rs"
|
||||||
name = "nrf52840_dongle_dfu"
|
name = "nrf52840_dongle_dfu"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@@ -16,6 +16,3 @@ capsules = { path = "../../../capsules" }
|
|||||||
kernel = { path = "../../../kernel" }
|
kernel = { path = "../../../kernel" }
|
||||||
nrf52840 = { path = "../../../chips/nrf52840" }
|
nrf52840 = { path = "../../../chips/nrf52840" }
|
||||||
nrf52_components = { path = "../nrf52_components" }
|
nrf52_components = { path = "../nrf52_components" }
|
||||||
|
|
||||||
[features]
|
|
||||||
vendor_hid = ["capsules/vendor_hid"]
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "nrf52840_dongle_opensk"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Tock Project Developers <tock-dev@googlegroups.com>"]
|
|
||||||
build = "build.rs"
|
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
components = { path = "../../components" }
|
|
||||||
cortexm4 = { path = "../../../arch/cortex-m4" }
|
|
||||||
capsules = { path = "../../../capsules" }
|
|
||||||
kernel = { path = "../../../kernel" }
|
|
||||||
nrf52840 = { path = "../../../chips/nrf52840" }
|
|
||||||
nrf52_components = { path = "../nrf52_components" }
|
|
||||||
|
|
||||||
[features]
|
|
||||||
vendor_hid = ["capsules/vendor_hid"]
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# Makefile for building the tock kernel for the nRF development kit
|
|
||||||
|
|
||||||
TARGET=thumbv7em-none-eabi
|
|
||||||
PLATFORM=nrf52840_dongle_opensk
|
|
||||||
|
|
||||||
include ../../Makefile.common
|
|
||||||
|
|
||||||
TOCKLOADER=tockloader
|
|
||||||
|
|
||||||
# Where in the nrf52 flash to load the kernel with `tockloader`
|
|
||||||
KERNEL_ADDRESS=0x00000
|
|
||||||
|
|
||||||
# Upload programs over uart with tockloader
|
|
||||||
ifdef PORT
|
|
||||||
TOCKLOADER_GENERAL_FLAGS += --port $(PORT)
|
|
||||||
endif
|
|
||||||
|
|
||||||
TOCKLOADER_JTAG_FLAGS = --jlink --board nrf52dk
|
|
||||||
|
|
||||||
# Upload the kernel over JTAG
|
|
||||||
.PHONY: flash
|
|
||||||
flash: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).bin
|
|
||||||
$(TOCKLOADER) $(TOCKLOADER_GENERAL_FLAGS) flash --address $(KERNEL_ADDRESS) $(TOCKLOADER_JTAG_FLAGS) $<
|
|
||||||
|
|
||||||
# Upload the kernel over serial/bootloader
|
|
||||||
.PHONY: program
|
|
||||||
program: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).hex
|
|
||||||
$(error Cannot program nRF52840-Dongle over USB. Use \`make flash\` and JTAG)
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
Platform-Specific Instructions: nRF52840-Dongle
|
|
||||||
===================================
|
|
||||||
|
|
||||||
This is an adapted nrf52840\_dongle made to work with OpenSK.
|
|
||||||
|
|
||||||
The [nRF52840 Dongle](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle)
|
|
||||||
is a platform based around the nRF52840, an SoC with an ARM Cortex-M4 and a BLE radio.
|
|
||||||
The kit is uses a USB key form factor and includes 1 button, 1 red LED and 1 RGB LED.
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
To program the nRF52840 Dongle with Tock, you will need a JLink JTAG device and the
|
|
||||||
appropriate cables. An example setup is:
|
|
||||||
|
|
||||||
- [JLink JTAG Device](https://www.digikey.com/product-detail/en/segger-microcontroller-systems/8.08.90-J-LINK-EDU/899-1008-ND/2263130)
|
|
||||||
- [ARM to TagConnect Adapter](https://www.digikey.com/product-detail/en/tag-connect-llc/TC2050-ARM2010/TC2050-ARM2010-ND/3528170)
|
|
||||||
- [10pin TagConnect Cable](https://www.digikey.com/product-detail/en/tag-connect-llc/TC2050-IDC-NL/TC2050-IDC-NL-ND/2605367)
|
|
||||||
|
|
||||||
Then, follow the [Tock Getting Started guide](../../../doc/Getting_Started.md)
|
|
||||||
|
|
||||||
JTAG is the preferred method to program. The development kit has the JTAG pins exposed either
|
|
||||||
through the half-moons pads or, below the PCB, on a Tag-Connect TC2050 connector footprint.
|
|
||||||
You need to [install JTAG software](../../../doc/Getting_Started.md#optional-requirements).
|
|
||||||
|
|
||||||
## Programming the kernel
|
|
||||||
Once you have all software installed, you should be able to simply run
|
|
||||||
make flash in this directory to install a fresh kernel.
|
|
||||||
|
|
||||||
## Programming user-level applications
|
|
||||||
You can program an application via JTAG using `tockloader`:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ cd libtock-c/examples/<app>
|
|
||||||
$ make
|
|
||||||
$ tockloader install --jlink --board nrf52dk
|
|
||||||
```
|
|
||||||
|
|
||||||
## Debugging
|
|
||||||
|
|
||||||
See the [nrf52dk README](../nrf52dk/README.md) for information about debugging
|
|
||||||
the nRF52840 Dongle.
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
fn main() {
|
|
||||||
println!("cargo:rerun-if-changed=layout.ld");
|
|
||||||
println!("cargo:rerun-if-changed=../../kernel_layout.ld");
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# J-LINK GDB SERVER initialization
|
|
||||||
#
|
|
||||||
# This connects to a GDB Server listening
|
|
||||||
# for commands on localhost at tcp port 2331
|
|
||||||
target remote localhost:2331
|
|
||||||
monitor speed 30
|
|
||||||
file ../../../../target/thumbv7em-none-eabi/release/nrf52840_dongle
|
|
||||||
monitor reset
|
|
||||||
#
|
|
||||||
# CPU core initialization (to be done by user)
|
|
||||||
#
|
|
||||||
# Set the processor mode
|
|
||||||
# monitor reg cpsr = 0xd3
|
|
||||||
# Set auto JTAG speed
|
|
||||||
monitor speed auto
|
|
||||||
# Setup GDB FOR FASTER DOWNLOADS
|
|
||||||
set remote memory-write-packet-size 1024
|
|
||||||
set remote memory-write-packet-size fixed
|
|
||||||
# tui enable
|
|
||||||
# layout split
|
|
||||||
# layout service_pending_interrupts
|
|
||||||
b reset_handler
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
JLinkGDBServer -device nRF52840_xxAA -speed 1200 -if swd -AutoConnect 1 -port 2331
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
INCLUDE ../nrf52840_chip_layout.ld
|
|
||||||
INCLUDE ../../kernel_layout.ld
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
use core::fmt::Write;
|
|
||||||
use core::panic::PanicInfo;
|
|
||||||
use cortexm4;
|
|
||||||
use kernel::debug;
|
|
||||||
use kernel::debug::IoWrite;
|
|
||||||
use kernel::hil::led;
|
|
||||||
use kernel::hil::uart::{self, Configure};
|
|
||||||
use nrf52840::gpio::Pin;
|
|
||||||
|
|
||||||
use crate::CHIP;
|
|
||||||
use crate::PROCESSES;
|
|
||||||
|
|
||||||
struct Writer {
|
|
||||||
initialized: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
static mut WRITER: Writer = Writer { initialized: false };
|
|
||||||
|
|
||||||
impl Write for Writer {
|
|
||||||
fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
|
|
||||||
self.write(s.as_bytes());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IoWrite for Writer {
|
|
||||||
fn write(&mut self, buf: &[u8]) {
|
|
||||||
// Here, we create a second instance of the Uarte struct.
|
|
||||||
// This is okay because we only call this during a panic, and
|
|
||||||
// we will never actually process the interrupts
|
|
||||||
let uart = nrf52840::uart::Uarte::new();
|
|
||||||
if !self.initialized {
|
|
||||||
self.initialized = true;
|
|
||||||
uart.configure(uart::Parameters {
|
|
||||||
baud_rate: 115200,
|
|
||||||
stop_bits: uart::StopBits::One,
|
|
||||||
parity: uart::Parity::None,
|
|
||||||
hw_flow_control: false,
|
|
||||||
width: uart::Width::Eight,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for &c in buf {
|
|
||||||
unsafe {
|
|
||||||
uart.send_byte(c);
|
|
||||||
}
|
|
||||||
while !uart.tx_ready() {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(test))]
|
|
||||||
#[no_mangle]
|
|
||||||
#[panic_handler]
|
|
||||||
/// Panic handler
|
|
||||||
pub unsafe extern "C" fn panic_fmt(pi: &PanicInfo) -> ! {
|
|
||||||
// The nRF52840 Dongle LEDs (see back of board)
|
|
||||||
let led_kernel_pin = &nrf52840::gpio::GPIOPin::new(Pin::P0_06);
|
|
||||||
let led = &mut led::LedLow::new(led_kernel_pin);
|
|
||||||
let writer = &mut WRITER;
|
|
||||||
debug::panic(
|
|
||||||
&mut [led],
|
|
||||||
writer,
|
|
||||||
pi,
|
|
||||||
&cortexm4::support::nop,
|
|
||||||
&PROCESSES,
|
|
||||||
&CHIP,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,420 +0,0 @@
|
|||||||
//! Tock kernel for the Nordic Semiconductor nRF52840 dongle.
|
|
||||||
//!
|
|
||||||
//! It is based on nRF52840 SoC (Cortex M4 core with a BLE transceiver) with
|
|
||||||
//! many exported I/O and peripherals.
|
|
||||||
|
|
||||||
#![no_std]
|
|
||||||
// Disable this attribute when documenting, as a workaround for
|
|
||||||
// https://github.com/rust-lang/rust/issues/62184.
|
|
||||||
#![cfg_attr(not(doc), no_main)]
|
|
||||||
#![feature(const_in_array_repeat_expressions)]
|
|
||||||
#![deny(missing_docs)]
|
|
||||||
|
|
||||||
use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState};
|
|
||||||
use kernel::component::Component;
|
|
||||||
use kernel::hil::led::LedLow;
|
|
||||||
use kernel::hil::time::Counter;
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use kernel::{capabilities, create_capability, debug, debug_gpio, debug_verbose, static_init};
|
|
||||||
use nrf52840::gpio::Pin;
|
|
||||||
use nrf52840::interrupt_service::Nrf52840DefaultPeripherals;
|
|
||||||
use nrf52_components::{self, UartChannel, UartPins};
|
|
||||||
|
|
||||||
// The nRF52840 Dongle LEDs
|
|
||||||
const LED1_PIN: Pin = Pin::P0_06;
|
|
||||||
const LED2_R_PIN: Pin = Pin::P0_08;
|
|
||||||
const LED2_G_PIN: Pin = Pin::P1_09;
|
|
||||||
const LED2_B_PIN: Pin = Pin::P0_12;
|
|
||||||
|
|
||||||
// The nRF52840 Dongle button
|
|
||||||
const BUTTON_PIN: Pin = Pin::P1_06;
|
|
||||||
const BUTTON_RST_PIN: Pin = Pin::P0_18;
|
|
||||||
|
|
||||||
const UART_RTS: Option<Pin> = Some(Pin::P0_13);
|
|
||||||
const UART_TXD: Pin = Pin::P0_15;
|
|
||||||
const UART_CTS: Option<Pin> = Some(Pin::P0_17);
|
|
||||||
const UART_RXD: Pin = Pin::P0_20;
|
|
||||||
|
|
||||||
// SPI pins not currently in use, but left here for convenience
|
|
||||||
const _SPI_MOSI: Pin = Pin::P1_01;
|
|
||||||
const _SPI_MISO: Pin = Pin::P1_02;
|
|
||||||
const _SPI_CLK: Pin = Pin::P1_04;
|
|
||||||
|
|
||||||
/// UART Writer
|
|
||||||
pub mod io;
|
|
||||||
|
|
||||||
const VENDOR_ID: u16 = 0x1915; // Nordic Semiconductor
|
|
||||||
const PRODUCT_ID: u16 = 0x521f; // nRF52840 Dongle (PCA10059)
|
|
||||||
static STRINGS: &'static [&'static str] = &[
|
|
||||||
// Manufacturer
|
|
||||||
"Nordic Semiconductor ASA",
|
|
||||||
// Product
|
|
||||||
"OpenSK",
|
|
||||||
// Serial number
|
|
||||||
"v1.0",
|
|
||||||
];
|
|
||||||
|
|
||||||
// State for loading and holding applications.
|
|
||||||
// How should the kernel respond when a process faults.
|
|
||||||
const FAULT_RESPONSE: kernel::procs::FaultResponse = kernel::procs::FaultResponse::Panic;
|
|
||||||
|
|
||||||
// Number of concurrent processes this platform supports.
|
|
||||||
const NUM_PROCS: usize = 8;
|
|
||||||
|
|
||||||
static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; NUM_PROCS] =
|
|
||||||
[None; NUM_PROCS];
|
|
||||||
|
|
||||||
static mut STORAGE_LOCATIONS: [kernel::StorageLocation; 2] = [
|
|
||||||
// We implement NUM_PAGES = 20 as 16 + 4 to satisfy the MPU.
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0xC0000,
|
|
||||||
size: 0x10000, // 16 pages
|
|
||||||
storage_type: kernel::StorageType::STORE,
|
|
||||||
},
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0xD0000,
|
|
||||||
size: 0x4000, // 4 pages
|
|
||||||
storage_type: kernel::StorageType::STORE,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// Static reference to chip for panic dumps
|
|
||||||
static mut CHIP: Option<&'static nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>> = None;
|
|
||||||
|
|
||||||
/// Dummy buffer that causes the linker to reserve enough space for the stack.
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".stack_buffer"]
|
|
||||||
pub static mut STACK_MEMORY: [u8; 0x1000] = [0; 0x1000];
|
|
||||||
|
|
||||||
/// Supported drivers by the platform
|
|
||||||
pub struct Platform {
|
|
||||||
button: &'static capsules::button::Button<'static, nrf52840::gpio::GPIOPin<'static>>,
|
|
||||||
pconsole: &'static capsules::process_console::ProcessConsole<
|
|
||||||
'static,
|
|
||||||
components::process_console::Capability,
|
|
||||||
>,
|
|
||||||
console: &'static capsules::console::Console<'static>,
|
|
||||||
gpio: &'static capsules::gpio::GPIO<'static, nrf52840::gpio::GPIOPin<'static>>,
|
|
||||||
led: &'static capsules::led::LedDriver<
|
|
||||||
'static,
|
|
||||||
LedLow<'static, nrf52840::gpio::GPIOPin<'static>>,
|
|
||||||
>,
|
|
||||||
rng: &'static capsules::rng::RngDriver<'static>,
|
|
||||||
ipc: kernel::ipc::IPC<NUM_PROCS>,
|
|
||||||
analog_comparator: &'static capsules::analog_comparator::AnalogComparator<
|
|
||||||
'static,
|
|
||||||
nrf52840::acomp::Comparator<'static>,
|
|
||||||
>,
|
|
||||||
alarm: &'static capsules::alarm::AlarmDriver<
|
|
||||||
'static,
|
|
||||||
capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52840::rtc::Rtc<'static>>,
|
|
||||||
>,
|
|
||||||
nvmc: &'static nrf52840::nvmc::SyscallDriver,
|
|
||||||
usb: &'static capsules::usb::usb_ctap::CtapUsbSyscallDriver<
|
|
||||||
'static,
|
|
||||||
'static,
|
|
||||||
nrf52840::usbd::Usbd<'static>,
|
|
||||||
>,
|
|
||||||
crp: &'static capsules::firmware_protection::FirmwareProtection<nrf52840::uicr::Uicr>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl kernel::Platform for Platform {
|
|
||||||
fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
|
|
||||||
where
|
|
||||||
F: FnOnce(Option<&dyn kernel::Driver>) -> R,
|
|
||||||
{
|
|
||||||
match driver_num {
|
|
||||||
capsules::console::DRIVER_NUM => f(Some(self.console)),
|
|
||||||
capsules::gpio::DRIVER_NUM => f(Some(self.gpio)),
|
|
||||||
capsules::alarm::DRIVER_NUM => f(Some(self.alarm)),
|
|
||||||
capsules::led::DRIVER_NUM => f(Some(self.led)),
|
|
||||||
capsules::button::DRIVER_NUM => f(Some(self.button)),
|
|
||||||
capsules::rng::DRIVER_NUM => f(Some(self.rng)),
|
|
||||||
capsules::analog_comparator::DRIVER_NUM => f(Some(self.analog_comparator)),
|
|
||||||
nrf52840::nvmc::DRIVER_NUM => f(Some(self.nvmc)),
|
|
||||||
capsules::usb::usb_ctap::DRIVER_NUM => f(Some(self.usb)),
|
|
||||||
capsules::firmware_protection::DRIVER_NUM => f(Some(self.crp)),
|
|
||||||
kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
|
|
||||||
_ => f(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn filter_syscall(
|
|
||||||
&self,
|
|
||||||
process: &dyn kernel::procs::ProcessType,
|
|
||||||
syscall: &kernel::syscall::Syscall,
|
|
||||||
) -> Result<(), kernel::ReturnCode> {
|
|
||||||
use kernel::syscall::Syscall;
|
|
||||||
match *syscall {
|
|
||||||
Syscall::COMMAND {
|
|
||||||
driver_number: nrf52840::nvmc::DRIVER_NUM,
|
|
||||||
subdriver_number: cmd,
|
|
||||||
arg0: ptr,
|
|
||||||
arg1: len,
|
|
||||||
} if (cmd == 2 || cmd == 3) && !process.fits_in_storage_location(ptr, len) => {
|
|
||||||
Err(kernel::ReturnCode::EINVAL)
|
|
||||||
}
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Entry point in the vector table called on hard reset.
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe fn reset_handler() {
|
|
||||||
// Loads relocations and clears BSS
|
|
||||||
nrf52840::init();
|
|
||||||
|
|
||||||
let ppi = static_init!(nrf52840::ppi::Ppi, nrf52840::ppi::Ppi::new());
|
|
||||||
// Initialize chip peripheral drivers
|
|
||||||
let nrf52840_peripherals = static_init!(
|
|
||||||
Nrf52840DefaultPeripherals,
|
|
||||||
Nrf52840DefaultPeripherals::new(ppi)
|
|
||||||
);
|
|
||||||
|
|
||||||
// set up circular peripheral dependencies
|
|
||||||
nrf52840_peripherals.init();
|
|
||||||
let base_peripherals = &nrf52840_peripherals.nrf52;
|
|
||||||
|
|
||||||
let board_kernel = static_init!(
|
|
||||||
kernel::Kernel,
|
|
||||||
kernel::Kernel::new_with_storage(&PROCESSES, &STORAGE_LOCATIONS)
|
|
||||||
);
|
|
||||||
|
|
||||||
// GPIOs
|
|
||||||
let gpio = components::gpio::GpioComponent::new(
|
|
||||||
board_kernel,
|
|
||||||
components::gpio_component_helper!(
|
|
||||||
nrf52840::gpio::GPIOPin,
|
|
||||||
// left side of the USB plug
|
|
||||||
0 => &nrf52840_peripherals.gpio_port[Pin::P0_13],
|
|
||||||
1 => &nrf52840_peripherals.gpio_port[Pin::P0_15],
|
|
||||||
2 => &nrf52840_peripherals.gpio_port[Pin::P0_17],
|
|
||||||
3 => &nrf52840_peripherals.gpio_port[Pin::P0_20],
|
|
||||||
4 => &nrf52840_peripherals.gpio_port[Pin::P0_22],
|
|
||||||
5 => &nrf52840_peripherals.gpio_port[Pin::P0_24],
|
|
||||||
6 => &nrf52840_peripherals.gpio_port[Pin::P1_00],
|
|
||||||
7 => &nrf52840_peripherals.gpio_port[Pin::P0_09],
|
|
||||||
8 => &nrf52840_peripherals.gpio_port[Pin::P0_10],
|
|
||||||
// right side of the USB plug
|
|
||||||
9 => &nrf52840_peripherals.gpio_port[Pin::P0_31],
|
|
||||||
10 => &nrf52840_peripherals.gpio_port[Pin::P0_29],
|
|
||||||
11 => &nrf52840_peripherals.gpio_port[Pin::P0_02],
|
|
||||||
12 => &nrf52840_peripherals.gpio_port[Pin::P1_15],
|
|
||||||
13 => &nrf52840_peripherals.gpio_port[Pin::P1_13],
|
|
||||||
14 => &nrf52840_peripherals.gpio_port[Pin::P1_10],
|
|
||||||
// Below the PCB
|
|
||||||
15 => &nrf52840_peripherals.gpio_port[Pin::P0_26],
|
|
||||||
16 => &nrf52840_peripherals.gpio_port[Pin::P0_04],
|
|
||||||
17 => &nrf52840_peripherals.gpio_port[Pin::P0_11],
|
|
||||||
18 => &nrf52840_peripherals.gpio_port[Pin::P0_14],
|
|
||||||
19 => &nrf52840_peripherals.gpio_port[Pin::P1_11],
|
|
||||||
20 => &nrf52840_peripherals.gpio_port[Pin::P1_07],
|
|
||||||
21 => &nrf52840_peripherals.gpio_port[Pin::P1_01],
|
|
||||||
22 => &nrf52840_peripherals.gpio_port[Pin::P1_04],
|
|
||||||
23 => &nrf52840_peripherals.gpio_port[Pin::P1_02]
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.finalize(components::gpio_component_buf!(nrf52840::gpio::GPIOPin));
|
|
||||||
|
|
||||||
let button = components::button::ButtonComponent::new(
|
|
||||||
board_kernel,
|
|
||||||
components::button_component_helper!(
|
|
||||||
nrf52840::gpio::GPIOPin,
|
|
||||||
(
|
|
||||||
&nrf52840_peripherals.gpio_port[BUTTON_PIN],
|
|
||||||
kernel::hil::gpio::ActivationMode::ActiveLow,
|
|
||||||
kernel::hil::gpio::FloatingState::PullUp
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.finalize(components::button_component_buf!(nrf52840::gpio::GPIOPin));
|
|
||||||
|
|
||||||
let led = components::led::LedsComponent::new(components::led_component_helper!(
|
|
||||||
LedLow<'static, nrf52840::gpio::GPIOPin>,
|
|
||||||
LedLow::new(&nrf52840_peripherals.gpio_port[LED1_PIN]),
|
|
||||||
LedLow::new(&nrf52840_peripherals.gpio_port[LED2_R_PIN]),
|
|
||||||
LedLow::new(&nrf52840_peripherals.gpio_port[LED2_G_PIN]),
|
|
||||||
LedLow::new(&nrf52840_peripherals.gpio_port[LED2_B_PIN]),
|
|
||||||
))
|
|
||||||
.finalize(components::led_component_buf!(
|
|
||||||
LedLow<'static, nrf52840::gpio::GPIOPin>
|
|
||||||
));
|
|
||||||
|
|
||||||
let chip = static_init!(
|
|
||||||
nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
|
|
||||||
nrf52840::chip::NRF52::new(nrf52840_peripherals)
|
|
||||||
);
|
|
||||||
CHIP = Some(chip);
|
|
||||||
|
|
||||||
nrf52_components::startup::NrfStartupComponent::new(
|
|
||||||
false,
|
|
||||||
BUTTON_RST_PIN,
|
|
||||||
nrf52840::uicr::Regulator0Output::V3_0,
|
|
||||||
&base_peripherals.nvmc,
|
|
||||||
)
|
|
||||||
.finalize(());
|
|
||||||
|
|
||||||
// Create capabilities that the board needs to call certain protected kernel
|
|
||||||
// functions.
|
|
||||||
let process_management_capability =
|
|
||||||
create_capability!(capabilities::ProcessManagementCapability);
|
|
||||||
let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
|
|
||||||
let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
|
|
||||||
|
|
||||||
let gpio_port = &nrf52840_peripherals.gpio_port;
|
|
||||||
|
|
||||||
// Configure kernel debug gpios as early as possible
|
|
||||||
kernel::debug::assign_gpios(
|
|
||||||
Some(&gpio_port[LED2_R_PIN]),
|
|
||||||
Some(&gpio_port[LED2_G_PIN]),
|
|
||||||
Some(&gpio_port[LED2_B_PIN]),
|
|
||||||
);
|
|
||||||
|
|
||||||
let rtc = &base_peripherals.rtc;
|
|
||||||
rtc.start();
|
|
||||||
let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
|
|
||||||
.finalize(components::alarm_mux_component_helper!(nrf52840::rtc::Rtc));
|
|
||||||
let alarm = components::alarm::AlarmDriverComponent::new(board_kernel, mux_alarm)
|
|
||||||
.finalize(components::alarm_component_helper!(nrf52840::rtc::Rtc));
|
|
||||||
let uart_channel = UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD));
|
|
||||||
let channel = nrf52_components::UartChannelComponent::new(
|
|
||||||
uart_channel,
|
|
||||||
mux_alarm,
|
|
||||||
&base_peripherals.uarte0,
|
|
||||||
)
|
|
||||||
.finalize(());
|
|
||||||
|
|
||||||
let dynamic_deferred_call_clients =
|
|
||||||
static_init!([DynamicDeferredCallClientState; 3], Default::default());
|
|
||||||
let dynamic_deferred_caller = static_init!(
|
|
||||||
DynamicDeferredCall,
|
|
||||||
DynamicDeferredCall::new(dynamic_deferred_call_clients)
|
|
||||||
);
|
|
||||||
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(channel, 115200, dynamic_deferred_caller)
|
|
||||||
.finalize(());
|
|
||||||
|
|
||||||
let pconsole =
|
|
||||||
components::process_console::ProcessConsoleComponent::new(board_kernel, uart_mux)
|
|
||||||
.finalize(());
|
|
||||||
|
|
||||||
// Setup the console.
|
|
||||||
let console = components::console::ConsoleComponent::new(board_kernel, uart_mux).finalize(());
|
|
||||||
// Create the debugger object that handles calls to `debug!()`.
|
|
||||||
components::debug_writer::DebugWriterComponent::new(uart_mux).finalize(());
|
|
||||||
|
|
||||||
let rng = components::rng::RngComponent::new(board_kernel, &base_peripherals.trng).finalize(());
|
|
||||||
|
|
||||||
// Initialize AC using AIN5 (P0.29) as VIN+ and VIN- as AIN0 (P0.02)
|
|
||||||
// These are hardcoded pin assignments specified in the driver
|
|
||||||
let analog_comparator = components::analog_comparator::AcComponent::new(
|
|
||||||
&base_peripherals.acomp,
|
|
||||||
components::acomp_component_helper!(
|
|
||||||
nrf52840::acomp::Channel,
|
|
||||||
&nrf52840::acomp::CHANNEL_AC0
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.finalize(components::acomp_component_buf!(
|
|
||||||
nrf52840::acomp::Comparator
|
|
||||||
));
|
|
||||||
|
|
||||||
let nvmc = static_init!(
|
|
||||||
nrf52840::nvmc::SyscallDriver,
|
|
||||||
nrf52840::nvmc::SyscallDriver::new(
|
|
||||||
&base_peripherals.nvmc,
|
|
||||||
board_kernel.create_grant(&memory_allocation_capability),
|
|
||||||
dynamic_deferred_caller,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
nvmc.set_deferred_handle(
|
|
||||||
dynamic_deferred_caller
|
|
||||||
.register(nvmc)
|
|
||||||
.expect("no deferred call slot available for nvmc"),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Configure USB controller
|
|
||||||
let usb = components::usb_ctap::UsbCtapComponent::new(
|
|
||||||
board_kernel,
|
|
||||||
&nrf52840_peripherals.usbd,
|
|
||||||
capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840,
|
|
||||||
VENDOR_ID,
|
|
||||||
PRODUCT_ID,
|
|
||||||
STRINGS,
|
|
||||||
)
|
|
||||||
.finalize(components::usb_ctap_component_buf!(nrf52840::usbd::Usbd));
|
|
||||||
|
|
||||||
let crp = components::firmware_protection::FirmwareProtectionComponent::new(
|
|
||||||
board_kernel,
|
|
||||||
nrf52840::uicr::Uicr::new(),
|
|
||||||
)
|
|
||||||
.finalize(components::firmware_protection_component_helper!(
|
|
||||||
nrf52840::uicr::Uicr
|
|
||||||
));
|
|
||||||
|
|
||||||
nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(());
|
|
||||||
|
|
||||||
let platform = Platform {
|
|
||||||
button,
|
|
||||||
pconsole,
|
|
||||||
console,
|
|
||||||
led,
|
|
||||||
gpio,
|
|
||||||
rng,
|
|
||||||
alarm,
|
|
||||||
analog_comparator,
|
|
||||||
nvmc,
|
|
||||||
usb,
|
|
||||||
crp,
|
|
||||||
ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability),
|
|
||||||
};
|
|
||||||
|
|
||||||
platform.pconsole.start();
|
|
||||||
debug!("Initialization complete. Entering main loop\r");
|
|
||||||
debug!("{}", &nrf52840::ficr::FICR_INSTANCE);
|
|
||||||
|
|
||||||
/// These symbols are defined in the linker script.
|
|
||||||
extern "C" {
|
|
||||||
/// Beginning of the ROM region containing app images.
|
|
||||||
static _sapps: u8;
|
|
||||||
/// End of the ROM region containing app images.
|
|
||||||
static _eapps: u8;
|
|
||||||
/// Beginning of the RAM region for app memory.
|
|
||||||
static mut _sappmem: u8;
|
|
||||||
/// End of the RAM region for app memory.
|
|
||||||
static _eappmem: u8;
|
|
||||||
}
|
|
||||||
|
|
||||||
kernel::procs::load_processes(
|
|
||||||
board_kernel,
|
|
||||||
chip,
|
|
||||||
core::slice::from_raw_parts(
|
|
||||||
&_sapps as *const u8,
|
|
||||||
&_eapps as *const u8 as usize - &_sapps as *const u8 as usize,
|
|
||||||
),
|
|
||||||
core::slice::from_raw_parts_mut(
|
|
||||||
&mut _sappmem as *mut u8,
|
|
||||||
&_eappmem as *const u8 as usize - &_sappmem as *const u8 as usize,
|
|
||||||
),
|
|
||||||
&mut PROCESSES,
|
|
||||||
FAULT_RESPONSE,
|
|
||||||
&process_management_capability,
|
|
||||||
)
|
|
||||||
.unwrap_or_else(|err| {
|
|
||||||
debug!("Error loading processes!");
|
|
||||||
debug!("{:?}", err);
|
|
||||||
});
|
|
||||||
|
|
||||||
let scheduler = components::sched::round_robin::RoundRobinComponent::new(&PROCESSES)
|
|
||||||
.finalize(components::rr_component_helper!(NUM_PROCS));
|
|
||||||
board_kernel.kernel_loop(
|
|
||||||
&platform,
|
|
||||||
chip,
|
|
||||||
Some(&platform.ipc),
|
|
||||||
scheduler,
|
|
||||||
&main_loop_capability,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -12,6 +12,3 @@ capsules = { path = "../../../capsules" }
|
|||||||
kernel = { path = "../../../kernel" }
|
kernel = { path = "../../../kernel" }
|
||||||
nrf52840 = { path = "../../../chips/nrf52840" }
|
nrf52840 = { path = "../../../chips/nrf52840" }
|
||||||
nrf52_components = { path = "../nrf52_components" }
|
nrf52_components = { path = "../nrf52_components" }
|
||||||
|
|
||||||
[features]
|
|
||||||
vendor_hid = ["capsules/vendor_hid"]
|
|
||||||
|
|||||||
@@ -25,10 +25,7 @@ impl Write for Writer {
|
|||||||
|
|
||||||
impl IoWrite for Writer {
|
impl IoWrite for Writer {
|
||||||
fn write(&mut self, buf: &[u8]) {
|
fn write(&mut self, buf: &[u8]) {
|
||||||
// Here, we create a second instance of the Uarte struct.
|
let uart = unsafe { &mut nrf52840::uart::UARTE0 };
|
||||||
// This is okay because we only call this during a panic, and
|
|
||||||
// we will never actually process the interrupts
|
|
||||||
let uart = nrf52840::uart::Uarte::new();
|
|
||||||
if !self.initialized {
|
if !self.initialized {
|
||||||
self.initialized = true;
|
self.initialized = true;
|
||||||
uart.configure(uart::Parameters {
|
uart.configure(uart::Parameters {
|
||||||
@@ -54,8 +51,8 @@ impl IoWrite for Writer {
|
|||||||
/// Panic handler
|
/// Panic handler
|
||||||
pub unsafe extern "C" fn panic_fmt(pi: &PanicInfo) -> ! {
|
pub unsafe extern "C" fn panic_fmt(pi: &PanicInfo) -> ! {
|
||||||
// The nRF52840 Dongle LEDs (see back of board)
|
// The nRF52840 Dongle LEDs (see back of board)
|
||||||
let led_kernel_pin = &nrf52840::gpio::GPIOPin::new(Pin::P0_23);
|
const LED1_PIN: Pin = Pin::P0_23;
|
||||||
let led = &mut led::LedLow::new(led_kernel_pin);
|
let led = &mut led::LedLow::new(&mut nrf52840::gpio::PORT[LED1_PIN]);
|
||||||
let writer = &mut WRITER;
|
let writer = &mut WRITER;
|
||||||
debug::panic(
|
debug::panic(
|
||||||
&mut [led],
|
&mut [led],
|
||||||
|
|||||||
@@ -10,14 +10,13 @@
|
|||||||
#![feature(const_in_array_repeat_expressions)]
|
#![feature(const_in_array_repeat_expressions)]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
use capsules::virtual_alarm::VirtualMuxAlarm;
|
||||||
use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState};
|
use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState};
|
||||||
use kernel::component::Component;
|
use kernel::component::Component;
|
||||||
use kernel::hil::led::LedLow;
|
|
||||||
use kernel::hil::time::Counter;
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use kernel::{capabilities, create_capability, debug, debug_gpio, debug_verbose, static_init};
|
use kernel::{capabilities, create_capability, debug, debug_gpio, debug_verbose, static_init};
|
||||||
|
use kernel::hil::usb::UsbController;
|
||||||
use nrf52840::gpio::Pin;
|
use nrf52840::gpio::Pin;
|
||||||
use nrf52840::interrupt_service::Nrf52840DefaultPeripherals;
|
|
||||||
use nrf52_components::{self, UartChannel, UartPins};
|
use nrf52_components::{self, UartChannel, UartPins};
|
||||||
|
|
||||||
// The nRF52840 MDK USB Dongle LEDs
|
// The nRF52840 MDK USB Dongle LEDs
|
||||||
@@ -27,13 +26,17 @@ const LED1_B_PIN: Pin = Pin::P0_24;
|
|||||||
|
|
||||||
// The nRF52840 Dongle button
|
// The nRF52840 Dongle button
|
||||||
const BUTTON_PIN: Pin = Pin::P0_18;
|
const BUTTON_PIN: Pin = Pin::P0_18;
|
||||||
const _BUTTON_RST_PIN: Pin = Pin::P0_02;
|
const BUTTON_RST_PIN: Pin = Pin::P0_02;
|
||||||
|
|
||||||
const UART_RTS: Option<Pin> = Some(Pin::P0_21);
|
const UART_RTS: Option<Pin> = Some(Pin::P0_21);
|
||||||
const UART_TXD: Pin = Pin::P0_20;
|
const UART_TXD: Pin = Pin::P0_20;
|
||||||
const UART_CTS: Option<Pin> = Some(Pin::P0_03);
|
const UART_CTS: Option<Pin> = Some(Pin::P0_03);
|
||||||
const UART_RXD: Pin = Pin::P0_19;
|
const UART_RXD: Pin = Pin::P0_19;
|
||||||
|
|
||||||
|
// Constants related to the configuration of the 15.4 network stack
|
||||||
|
const SRC_MAC: u16 = 0xf00f;
|
||||||
|
const PAN_ID: u16 = 0xABCD;
|
||||||
|
|
||||||
/// UART Writer
|
/// UART Writer
|
||||||
pub mod io;
|
pub mod io;
|
||||||
|
|
||||||
@@ -58,22 +61,13 @@ const NUM_PROCS: usize = 8;
|
|||||||
static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; NUM_PROCS] =
|
static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; NUM_PROCS] =
|
||||||
[None; NUM_PROCS];
|
[None; NUM_PROCS];
|
||||||
|
|
||||||
static mut STORAGE_LOCATIONS: [kernel::StorageLocation; 2] = [
|
static mut STORAGE_LOCATIONS: [kernel::StorageLocation; 1] = [kernel::StorageLocation {
|
||||||
// We implement NUM_PAGES = 20 as 16 + 4 to satisfy the MPU.
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0xC0000,
|
address: 0xC0000,
|
||||||
size: 0x10000, // 16 pages
|
size: 0x40000,
|
||||||
storage_type: kernel::StorageType::STORE,
|
}];
|
||||||
},
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0xD0000,
|
|
||||||
size: 0x4000, // 4 pages
|
|
||||||
storage_type: kernel::StorageType::STORE,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// Static reference to chip for panic dumps
|
// Static reference to chip for panic dumps
|
||||||
static mut CHIP: Option<&'static nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>> = None;
|
static mut CHIP: Option<&'static nrf52840::chip::Chip> = None;
|
||||||
|
|
||||||
/// Dummy buffer that causes the linker to reserve enough space for the stack.
|
/// Dummy buffer that causes the linker to reserve enough space for the stack.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -82,6 +76,12 @@ pub static mut STACK_MEMORY: [u8; 0x1000] = [0; 0x1000];
|
|||||||
|
|
||||||
/// Supported drivers by the platform
|
/// Supported drivers by the platform
|
||||||
pub struct Platform {
|
pub struct Platform {
|
||||||
|
ble_radio: &'static capsules::ble_advertising_driver::BLE<
|
||||||
|
'static,
|
||||||
|
nrf52840::ble_radio::Radio<'static>,
|
||||||
|
VirtualMuxAlarm<'static, nrf52840::rtc::Rtc<'static>>,
|
||||||
|
>,
|
||||||
|
ieee802154_radio: &'static capsules::ieee802154::RadioDriver<'static>,
|
||||||
button: &'static capsules::button::Button<'static, nrf52840::gpio::GPIOPin<'static>>,
|
button: &'static capsules::button::Button<'static, nrf52840::gpio::GPIOPin<'static>>,
|
||||||
pconsole: &'static capsules::process_console::ProcessConsole<
|
pconsole: &'static capsules::process_console::ProcessConsole<
|
||||||
'static,
|
'static,
|
||||||
@@ -89,12 +89,10 @@ pub struct Platform {
|
|||||||
>,
|
>,
|
||||||
console: &'static capsules::console::Console<'static>,
|
console: &'static capsules::console::Console<'static>,
|
||||||
gpio: &'static capsules::gpio::GPIO<'static, nrf52840::gpio::GPIOPin<'static>>,
|
gpio: &'static capsules::gpio::GPIO<'static, nrf52840::gpio::GPIOPin<'static>>,
|
||||||
led: &'static capsules::led::LedDriver<
|
led: &'static capsules::led::LED<'static, nrf52840::gpio::GPIOPin<'static>>,
|
||||||
'static,
|
|
||||||
LedLow<'static, nrf52840::gpio::GPIOPin<'static>>,
|
|
||||||
>,
|
|
||||||
rng: &'static capsules::rng::RngDriver<'static>,
|
rng: &'static capsules::rng::RngDriver<'static>,
|
||||||
ipc: kernel::ipc::IPC<NUM_PROCS>,
|
temp: &'static capsules::temperature::TemperatureSensor<'static>,
|
||||||
|
ipc: kernel::ipc::IPC,
|
||||||
analog_comparator: &'static capsules::analog_comparator::AnalogComparator<
|
analog_comparator: &'static capsules::analog_comparator::AnalogComparator<
|
||||||
'static,
|
'static,
|
||||||
nrf52840::acomp::Comparator<'static>,
|
nrf52840::acomp::Comparator<'static>,
|
||||||
@@ -123,6 +121,9 @@ impl kernel::Platform for Platform {
|
|||||||
capsules::led::DRIVER_NUM => f(Some(self.led)),
|
capsules::led::DRIVER_NUM => f(Some(self.led)),
|
||||||
capsules::button::DRIVER_NUM => f(Some(self.button)),
|
capsules::button::DRIVER_NUM => f(Some(self.button)),
|
||||||
capsules::rng::DRIVER_NUM => f(Some(self.rng)),
|
capsules::rng::DRIVER_NUM => f(Some(self.rng)),
|
||||||
|
capsules::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)),
|
||||||
|
capsules::ieee802154::DRIVER_NUM => f(Some(self.ieee802154_radio)),
|
||||||
|
capsules::temperature::DRIVER_NUM => f(Some(self.temp)),
|
||||||
capsules::analog_comparator::DRIVER_NUM => f(Some(self.analog_comparator)),
|
capsules::analog_comparator::DRIVER_NUM => f(Some(self.analog_comparator)),
|
||||||
nrf52840::nvmc::DRIVER_NUM => f(Some(self.nvmc)),
|
nrf52840::nvmc::DRIVER_NUM => f(Some(self.nvmc)),
|
||||||
capsules::usb::usb_ctap::DRIVER_NUM => f(Some(self.usb)),
|
capsules::usb::usb_ctap::DRIVER_NUM => f(Some(self.usb)),
|
||||||
@@ -157,17 +158,6 @@ pub unsafe fn reset_handler() {
|
|||||||
// Loads relocations and clears BSS
|
// Loads relocations and clears BSS
|
||||||
nrf52840::init();
|
nrf52840::init();
|
||||||
|
|
||||||
let ppi = static_init!(nrf52840::ppi::Ppi, nrf52840::ppi::Ppi::new());
|
|
||||||
// Initialize chip peripheral drivers
|
|
||||||
let nrf52840_peripherals = static_init!(
|
|
||||||
Nrf52840DefaultPeripherals,
|
|
||||||
Nrf52840DefaultPeripherals::new(ppi)
|
|
||||||
);
|
|
||||||
|
|
||||||
// set up circular peripheral dependencies
|
|
||||||
nrf52840_peripherals.init();
|
|
||||||
let base_peripherals = &nrf52840_peripherals.nrf52;
|
|
||||||
|
|
||||||
let board_kernel = static_init!(
|
let board_kernel = static_init!(
|
||||||
kernel::Kernel,
|
kernel::Kernel,
|
||||||
kernel::Kernel::new_with_storage(&PROCESSES, &STORAGE_LOCATIONS)
|
kernel::Kernel::new_with_storage(&PROCESSES, &STORAGE_LOCATIONS)
|
||||||
@@ -178,21 +168,20 @@ pub unsafe fn reset_handler() {
|
|||||||
components::gpio_component_helper!(
|
components::gpio_component_helper!(
|
||||||
nrf52840::gpio::GPIOPin,
|
nrf52840::gpio::GPIOPin,
|
||||||
// left side of the USB plug. Right side is used for UART
|
// left side of the USB plug. Right side is used for UART
|
||||||
0 => &nrf52840_peripherals.gpio_port[Pin::P0_04],
|
0 => &nrf52840::gpio::PORT[Pin::P0_04],
|
||||||
1 => &nrf52840_peripherals.gpio_port[Pin::P0_05],
|
1 => &nrf52840::gpio::PORT[Pin::P0_05],
|
||||||
2 => &nrf52840_peripherals.gpio_port[Pin::P0_06],
|
2 => &nrf52840::gpio::PORT[Pin::P0_06],
|
||||||
3 => &nrf52840_peripherals.gpio_port[Pin::P0_07],
|
3 => &nrf52840::gpio::PORT[Pin::P0_07],
|
||||||
4 => &nrf52840_peripherals.gpio_port[Pin::P0_08]
|
4 => &nrf52840::gpio::PORT[Pin::P0_08]
|
||||||
),
|
),
|
||||||
)
|
).finalize(components::gpio_component_buf!(nrf52840::gpio::GPIOPin));
|
||||||
.finalize(components::gpio_component_buf!(nrf52840::gpio::GPIOPin));
|
|
||||||
|
|
||||||
let button = components::button::ButtonComponent::new(
|
let button = components::button::ButtonComponent::new(
|
||||||
board_kernel,
|
board_kernel,
|
||||||
components::button_component_helper!(
|
components::button_component_helper!(
|
||||||
nrf52840::gpio::GPIOPin,
|
nrf52840::gpio::GPIOPin,
|
||||||
(
|
(
|
||||||
&nrf52840_peripherals.gpio_port[BUTTON_PIN],
|
&nrf52840::gpio::PORT[BUTTON_PIN],
|
||||||
kernel::hil::gpio::ActivationMode::ActiveLow,
|
kernel::hil::gpio::ActivationMode::ActiveLow,
|
||||||
kernel::hil::gpio::FloatingState::PullUp
|
kernel::hil::gpio::FloatingState::PullUp
|
||||||
)
|
)
|
||||||
@@ -201,21 +190,32 @@ pub unsafe fn reset_handler() {
|
|||||||
.finalize(components::button_component_buf!(nrf52840::gpio::GPIOPin));
|
.finalize(components::button_component_buf!(nrf52840::gpio::GPIOPin));
|
||||||
|
|
||||||
let led = components::led::LedsComponent::new(components::led_component_helper!(
|
let led = components::led::LedsComponent::new(components::led_component_helper!(
|
||||||
LedLow<'static, nrf52840::gpio::GPIOPin>,
|
nrf52840::gpio::GPIOPin,
|
||||||
LedLow::new(&nrf52840_peripherals.gpio_port[LED1_R_PIN]),
|
(
|
||||||
LedLow::new(&nrf52840_peripherals.gpio_port[LED1_G_PIN]),
|
&nrf52840::gpio::PORT[LED1_R_PIN],
|
||||||
LedLow::new(&nrf52840_peripherals.gpio_port[LED1_B_PIN]),
|
kernel::hil::gpio::ActivationMode::ActiveLow
|
||||||
|
),
|
||||||
|
(
|
||||||
|
&nrf52840::gpio::PORT[LED1_G_PIN],
|
||||||
|
kernel::hil::gpio::ActivationMode::ActiveLow
|
||||||
|
),
|
||||||
|
(
|
||||||
|
&nrf52840::gpio::PORT[LED1_B_PIN],
|
||||||
|
kernel::hil::gpio::ActivationMode::ActiveLow
|
||||||
|
)
|
||||||
))
|
))
|
||||||
.finalize(components::led_component_buf!(
|
.finalize(components::led_component_buf!(nrf52840::gpio::GPIOPin));
|
||||||
LedLow<'static, nrf52840::gpio::GPIOPin>
|
|
||||||
));
|
|
||||||
|
|
||||||
let chip = static_init!(
|
let chip = static_init!(nrf52840::chip::Chip, nrf52840::chip::new());
|
||||||
nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
|
|
||||||
nrf52840::chip::NRF52::new(nrf52840_peripherals)
|
|
||||||
);
|
|
||||||
CHIP = Some(chip);
|
CHIP = Some(chip);
|
||||||
|
|
||||||
|
nrf52_components::startup::NrfStartupComponent::new(
|
||||||
|
false,
|
||||||
|
BUTTON_RST_PIN,
|
||||||
|
nrf52840::uicr::Regulator0Output::V3_0,
|
||||||
|
)
|
||||||
|
.finalize(());
|
||||||
|
|
||||||
// Create capabilities that the board needs to call certain protected kernel
|
// Create capabilities that the board needs to call certain protected kernel
|
||||||
// functions.
|
// functions.
|
||||||
let process_management_capability =
|
let process_management_capability =
|
||||||
@@ -223,7 +223,7 @@ pub unsafe fn reset_handler() {
|
|||||||
let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
|
let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
|
||||||
let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
|
let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
|
||||||
|
|
||||||
let gpio_port = &nrf52840_peripherals.gpio_port;
|
let gpio_port = &nrf52840::gpio::PORT;
|
||||||
|
|
||||||
// Configure kernel debug gpios as early as possible
|
// Configure kernel debug gpios as early as possible
|
||||||
kernel::debug::assign_gpios(
|
kernel::debug::assign_gpios(
|
||||||
@@ -232,19 +232,14 @@ pub unsafe fn reset_handler() {
|
|||||||
Some(&gpio_port[LED1_B_PIN]),
|
Some(&gpio_port[LED1_B_PIN]),
|
||||||
);
|
);
|
||||||
|
|
||||||
let rtc = &base_peripherals.rtc;
|
let rtc = &nrf52840::rtc::RTC;
|
||||||
rtc.start();
|
rtc.start();
|
||||||
let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
|
let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
|
||||||
.finalize(components::alarm_mux_component_helper!(nrf52840::rtc::Rtc));
|
.finalize(components::alarm_mux_component_helper!(nrf52840::rtc::Rtc));
|
||||||
let alarm = components::alarm::AlarmDriverComponent::new(board_kernel, mux_alarm)
|
let alarm = components::alarm::AlarmDriverComponent::new(board_kernel, mux_alarm)
|
||||||
.finalize(components::alarm_component_helper!(nrf52840::rtc::Rtc));
|
.finalize(components::alarm_component_helper!(nrf52840::rtc::Rtc));
|
||||||
let uart_channel = UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD));
|
let uart_channel = UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD));
|
||||||
let channel = nrf52_components::UartChannelComponent::new(
|
let channel = nrf52_components::UartChannelComponent::new(uart_channel, mux_alarm).finalize(());
|
||||||
uart_channel,
|
|
||||||
mux_alarm,
|
|
||||||
&base_peripherals.uarte0,
|
|
||||||
)
|
|
||||||
.finalize(());
|
|
||||||
|
|
||||||
let dynamic_deferred_call_clients =
|
let dynamic_deferred_call_clients =
|
||||||
static_init!([DynamicDeferredCallClientState; 2], Default::default());
|
static_init!([DynamicDeferredCallClientState; 2], Default::default());
|
||||||
@@ -268,12 +263,34 @@ pub unsafe fn reset_handler() {
|
|||||||
// Create the debugger object that handles calls to `debug!()`.
|
// Create the debugger object that handles calls to `debug!()`.
|
||||||
components::debug_writer::DebugWriterComponent::new(uart_mux).finalize(());
|
components::debug_writer::DebugWriterComponent::new(uart_mux).finalize(());
|
||||||
|
|
||||||
let rng = components::rng::RngComponent::new(board_kernel, &base_peripherals.trng).finalize(());
|
let ble_radio =
|
||||||
|
nrf52_components::BLEComponent::new(board_kernel, &nrf52840::ble_radio::RADIO, mux_alarm)
|
||||||
|
.finalize(());
|
||||||
|
|
||||||
|
let (ieee802154_radio, _mux_mac) = components::ieee802154::Ieee802154Component::new(
|
||||||
|
board_kernel,
|
||||||
|
&nrf52840::ieee802154_radio::RADIO,
|
||||||
|
&nrf52840::aes::AESECB,
|
||||||
|
PAN_ID,
|
||||||
|
SRC_MAC,
|
||||||
|
)
|
||||||
|
.finalize(components::ieee802154_component_helper!(
|
||||||
|
nrf52840::ieee802154_radio::Radio,
|
||||||
|
nrf52840::aes::AesECB<'static>
|
||||||
|
));
|
||||||
|
|
||||||
|
let temp = components::temperature::TemperatureComponent::new(
|
||||||
|
board_kernel,
|
||||||
|
&nrf52840::temperature::TEMP,
|
||||||
|
)
|
||||||
|
.finalize(());
|
||||||
|
|
||||||
|
let rng = components::rng::RngComponent::new(board_kernel, &nrf52840::trng::TRNG).finalize(());
|
||||||
|
|
||||||
// Initialize AC using AIN5 (P0.29) as VIN+ and VIN- as AIN0 (P0.02)
|
// Initialize AC using AIN5 (P0.29) as VIN+ and VIN- as AIN0 (P0.02)
|
||||||
// These are hardcoded pin assignments specified in the driver
|
// These are hardcoded pin assignments specified in the driver
|
||||||
let analog_comparator = components::analog_comparator::AcComponent::new(
|
let analog_comparator = components::analog_comparator::AcComponent::new(
|
||||||
&base_peripherals.acomp,
|
&nrf52840::acomp::ACOMP,
|
||||||
components::acomp_component_helper!(
|
components::acomp_component_helper!(
|
||||||
nrf52840::acomp::Channel,
|
nrf52840::acomp::Channel,
|
||||||
&nrf52840::acomp::CHANNEL_AC0
|
&nrf52840::acomp::CHANNEL_AC0
|
||||||
@@ -286,37 +303,66 @@ pub unsafe fn reset_handler() {
|
|||||||
let nvmc = static_init!(
|
let nvmc = static_init!(
|
||||||
nrf52840::nvmc::SyscallDriver,
|
nrf52840::nvmc::SyscallDriver,
|
||||||
nrf52840::nvmc::SyscallDriver::new(
|
nrf52840::nvmc::SyscallDriver::new(
|
||||||
&base_peripherals.nvmc,
|
&nrf52840::nvmc::NVMC,
|
||||||
board_kernel.create_grant(&memory_allocation_capability),
|
board_kernel.create_grant(&memory_allocation_capability),
|
||||||
dynamic_deferred_caller,
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
nvmc.set_deferred_handle(
|
|
||||||
dynamic_deferred_caller
|
|
||||||
.register(nvmc)
|
|
||||||
.expect("no deferred call slot available for nvmc"),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Configure USB controller
|
// Configure USB controller
|
||||||
let usb = components::usb_ctap::UsbCtapComponent::new(
|
let usb:
|
||||||
board_kernel,
|
&'static capsules::usb::usb_ctap::CtapUsbSyscallDriver<
|
||||||
&nrf52840_peripherals.usbd,
|
'static,
|
||||||
|
'static,
|
||||||
|
nrf52840::usbd::Usbd<'static>,
|
||||||
|
> = {
|
||||||
|
let usb_ctap = static_init!(
|
||||||
|
capsules::usb::usbc_ctap_hid::ClientCtapHID<
|
||||||
|
'static,
|
||||||
|
'static,
|
||||||
|
nrf52840::usbd::Usbd<'static>,
|
||||||
|
>,
|
||||||
|
capsules::usb::usbc_ctap_hid::ClientCtapHID::new(
|
||||||
|
&nrf52840::usbd::USBD,
|
||||||
capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840,
|
capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840,
|
||||||
VENDOR_ID,
|
VENDOR_ID,
|
||||||
PRODUCT_ID,
|
PRODUCT_ID,
|
||||||
STRINGS,
|
STRINGS,
|
||||||
)
|
)
|
||||||
.finalize(components::usb_ctap_component_buf!(nrf52840::usbd::Usbd));
|
);
|
||||||
|
nrf52840::usbd::USBD.set_client(usb_ctap);
|
||||||
|
|
||||||
nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(());
|
// Enable power events to be sent to USB controller
|
||||||
|
nrf52840::power::POWER.set_usb_client(&nrf52840::usbd::USBD);
|
||||||
|
nrf52840::power::POWER.enable_interrupts();
|
||||||
|
|
||||||
|
// Configure the USB userspace driver
|
||||||
|
let usb_driver = static_init!(
|
||||||
|
capsules::usb::usb_ctap::CtapUsbSyscallDriver<
|
||||||
|
'static,
|
||||||
|
'static,
|
||||||
|
nrf52840::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 _
|
||||||
|
};
|
||||||
|
|
||||||
|
nrf52_components::NrfClockComponent::new().finalize(());
|
||||||
|
|
||||||
let platform = Platform {
|
let platform = Platform {
|
||||||
button,
|
button,
|
||||||
|
ble_radio,
|
||||||
|
ieee802154_radio,
|
||||||
pconsole,
|
pconsole,
|
||||||
console,
|
console,
|
||||||
led,
|
led,
|
||||||
gpio,
|
gpio,
|
||||||
rng,
|
rng,
|
||||||
|
temp,
|
||||||
alarm,
|
alarm,
|
||||||
analog_comparator,
|
analog_comparator,
|
||||||
nvmc,
|
nvmc,
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "nrf52840dk_opensk"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Tock Project Developers <tock-dev@googlegroups.com>"]
|
|
||||||
build = "build.rs"
|
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
components = { path = "../../components" }
|
|
||||||
cortexm4 = { path = "../../../arch/cortex-m4" }
|
|
||||||
capsules = { path = "../../../capsules" }
|
|
||||||
kernel = { path = "../../../kernel" }
|
|
||||||
nrf52840 = { path = "../../../chips/nrf52840" }
|
|
||||||
nrf52_components = { path = "../nrf52_components" }
|
|
||||||
|
|
||||||
[features]
|
|
||||||
vendor_hid = ["capsules/vendor_hid"]
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
# Makefile for building the tock kernel for the nRF development kit
|
|
||||||
|
|
||||||
TARGET=thumbv7em-none-eabi
|
|
||||||
PLATFORM=nrf52840dk_opensk
|
|
||||||
|
|
||||||
include ../../Makefile.common
|
|
||||||
|
|
||||||
TOCKLOADER=tockloader
|
|
||||||
|
|
||||||
# Where in the SAM4L flash to load the kernel with `tockloader`
|
|
||||||
KERNEL_ADDRESS=0x00000
|
|
||||||
|
|
||||||
# Upload programs over uart with tockloader
|
|
||||||
ifdef PORT
|
|
||||||
TOCKLOADER_GENERAL_FLAGS += --port $(PORT)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Upload the kernel over JTAG
|
|
||||||
.PHONY: flash
|
|
||||||
flash: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).bin
|
|
||||||
$(TOCKLOADER) $(TOCKLOADER_GENERAL_FLAGS) flash --address $(KERNEL_ADDRESS) --board nrf52dk --jlink $<
|
|
||||||
|
|
||||||
# Upload the kernel over JTAG using OpenOCD
|
|
||||||
.PHONY: flash-openocd
|
|
||||||
flash-openocd: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).bin
|
|
||||||
$(TOCKLOADER) $(TOCKLOADER_GENERAL_FLAGS) flash --address $(KERNEL_ADDRESS) --board nrf52dk --openocd $<
|
|
||||||
|
|
||||||
# Upload the kernel over serial/bootloader
|
|
||||||
.PHONY: program
|
|
||||||
program: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).hex
|
|
||||||
$(error Cannot program nRF52840DK over USB. Use \`make flash\` and JTAG)
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
Platform-Specific Instructions: nRF52840-DK
|
|
||||||
===================================
|
|
||||||
|
|
||||||
This is an adapted nrf52840dk made to work with OpenSK.
|
|
||||||
|
|
||||||
The [nRF52840 Development
|
|
||||||
Kit](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) is a platform
|
|
||||||
based around the nRF52840, an SoC with an ARM Cortex-M4 and a BLE
|
|
||||||
radio. The kit is Arduino shield compatible and includes several
|
|
||||||
buttons.
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
First, follow the [Tock Getting Started guide](../../../doc/Getting_Started.md)
|
|
||||||
|
|
||||||
JTAG is the preferred method to program. The development kit has an
|
|
||||||
integrated JTAG debugger, you simply need to [install JTAG
|
|
||||||
software](../../../doc/Getting_Started.md#loading-the-kernel-onto-a-board).
|
|
||||||
|
|
||||||
## Programming the kernel
|
|
||||||
Once you have all software installed, you should be able to simply run
|
|
||||||
make flash in this directory to install a fresh kernel.
|
|
||||||
|
|
||||||
## Programming user-level applications
|
|
||||||
You can program an application over USB using the integrated JTAG and `tockloader`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ cd libtock-c/examples/<app>
|
|
||||||
$ make
|
|
||||||
$ tockloader install --jlink --board nrf52dk
|
|
||||||
```
|
|
||||||
|
|
||||||
The same options (`--jlink --board nrf52dk`) must be passed for other tockloader commands
|
|
||||||
such as `erase-apps` or `list`.
|
|
||||||
|
|
||||||
Viewing console output on the nrf52840dk is slightly different from other boards. You must use
|
|
||||||
```bash
|
|
||||||
$ tockloader listen
|
|
||||||
```
|
|
||||||
**followed by a press of the reset button** in order to view console output starting from the boot
|
|
||||||
sequence. Notably, you should not
|
|
||||||
pass the `--jlink` option to `tockloader listen`.
|
|
||||||
|
|
||||||
## Console output
|
|
||||||
|
|
||||||
This board supports two methods for writing messages to a console interface
|
|
||||||
(console driver for applications as well as debug statements in the kernel).
|
|
||||||
|
|
||||||
By default, messages are written to a UART interface over the GPIO pins `P0.05`
|
|
||||||
to `P0.08` (see the [main.rs](src/main.rs) file).
|
|
||||||
|
|
||||||
If you don't have any UART cables or want to use a different interface, there is
|
|
||||||
also a console over the Segger RTT protocol. This only requires a micro-USB
|
|
||||||
cable on the USB debugging port (the same used to flash Tock on the board), and
|
|
||||||
is enabled by setting the `USB_DEBUGGING` constant to `true` in the
|
|
||||||
[main.rs](src/main.rs) file.
|
|
||||||
This disables the UART interface.
|
|
||||||
|
|
||||||
For instructions about how to receive RTT messages on the host, see the
|
|
||||||
[corresponding capsule](../../../capsules/src/segger_rtt.rs).
|
|
||||||
|
|
||||||
## Debugging
|
|
||||||
|
|
||||||
See the [nrf52dk README](../nrf52dk/README.md) for information about debugging
|
|
||||||
the nRF52840dk.
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
use std::env;
|
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
println!("cargo:rerun-if-changed=layout.ld");
|
|
||||||
println!("cargo:rerun-if-changed=../../kernel_layout.ld");
|
|
||||||
|
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
|
||||||
let dest_path = Path::new(&out_dir).join("locations.rs");
|
|
||||||
fs::write(
|
|
||||||
&dest_path,
|
|
||||||
"
|
|
||||||
static mut STORAGE_LOCATIONS: [kernel::StorageLocation; 2] = [
|
|
||||||
// We implement NUM_PAGES = 20 as 16 + 4 to satisfy the MPU.
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0xC0000,
|
|
||||||
size: 0x10000, // 16 pages
|
|
||||||
storage_type: kernel::StorageType::STORE,
|
|
||||||
},
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0xD0000,
|
|
||||||
size: 0x4000, // 4 pages
|
|
||||||
storage_type: kernel::StorageType::STORE,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
"
|
|
||||||
).unwrap();
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# J-LINK GDB SERVER initialization
|
|
||||||
#
|
|
||||||
# This connects to a GDB Server listening
|
|
||||||
# for commands on localhost at tcp port 2331
|
|
||||||
target remote localhost:2331
|
|
||||||
monitor speed 30
|
|
||||||
file ../../../../target/thumbv7em-none-eabi/release/nrf52dk
|
|
||||||
monitor reset
|
|
||||||
#
|
|
||||||
# CPU core initialization (to be done by user)
|
|
||||||
#
|
|
||||||
# Set the processor mode
|
|
||||||
# monitor reg cpsr = 0xd3
|
|
||||||
# Set auto JTAG speed
|
|
||||||
monitor speed auto
|
|
||||||
# Setup GDB FOR FASTER DOWNLOADS
|
|
||||||
set remote memory-write-packet-size 1024
|
|
||||||
set remote memory-write-packet-size fixed
|
|
||||||
# tui enable
|
|
||||||
# layout split
|
|
||||||
# layout service_pending_interrupts
|
|
||||||
b reset_handler
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
JLinkGDBServer -device nrf52 -speed 1200 -if swd -AutoConnect 1 -port 2331
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
INCLUDE ../nrf52840_chip_layout.ld
|
|
||||||
INCLUDE ../../kernel_layout.ld
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
use core::fmt::Write;
|
|
||||||
use core::panic::PanicInfo;
|
|
||||||
use cortexm4;
|
|
||||||
use kernel::debug;
|
|
||||||
use kernel::debug::IoWrite;
|
|
||||||
use kernel::hil::led;
|
|
||||||
use kernel::hil::uart;
|
|
||||||
use kernel::hil::uart::Configure;
|
|
||||||
use nrf52840::gpio::Pin;
|
|
||||||
|
|
||||||
use crate::CHIP;
|
|
||||||
use crate::PROCESSES;
|
|
||||||
|
|
||||||
enum Writer {
|
|
||||||
WriterUart(/* initialized */ bool),
|
|
||||||
WriterRtt(&'static capsules::segger_rtt::SeggerRttMemory<'static>),
|
|
||||||
}
|
|
||||||
|
|
||||||
static mut WRITER: Writer = Writer::WriterUart(false);
|
|
||||||
|
|
||||||
fn wait() {
|
|
||||||
for _ in 0..100 {
|
|
||||||
cortexm4::support::nop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the RTT memory buffer used to output panic messages.
|
|
||||||
pub unsafe fn set_rtt_memory(
|
|
||||||
rtt_memory: &'static mut capsules::segger_rtt::SeggerRttMemory<'static>,
|
|
||||||
) {
|
|
||||||
WRITER = Writer::WriterRtt(rtt_memory);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Write for Writer {
|
|
||||||
fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
|
|
||||||
self.write(s.as_bytes());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IoWrite for Writer {
|
|
||||||
fn write(&mut self, buf: &[u8]) {
|
|
||||||
match self {
|
|
||||||
Writer::WriterUart(ref mut initialized) => {
|
|
||||||
// Here, we create a second instance of the Uarte struct.
|
|
||||||
// This is okay because we only call this during a panic, and
|
|
||||||
// we will never actually process the interrupts
|
|
||||||
let uart = nrf52840::uart::Uarte::new();
|
|
||||||
if !*initialized {
|
|
||||||
*initialized = true;
|
|
||||||
uart.configure(uart::Parameters {
|
|
||||||
baud_rate: 115200,
|
|
||||||
stop_bits: uart::StopBits::One,
|
|
||||||
parity: uart::Parity::None,
|
|
||||||
hw_flow_control: false,
|
|
||||||
width: uart::Width::Eight,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for &c in buf {
|
|
||||||
unsafe {
|
|
||||||
uart.send_byte(c);
|
|
||||||
}
|
|
||||||
while !uart.tx_ready() {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Writer::WriterRtt(rtt_memory) => {
|
|
||||||
let up_buffer = unsafe { &*rtt_memory.get_up_buffer_ptr() };
|
|
||||||
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))]
|
|
||||||
#[no_mangle]
|
|
||||||
#[panic_handler]
|
|
||||||
/// Panic handler
|
|
||||||
pub unsafe extern "C" fn panic_fmt(pi: &PanicInfo) -> ! {
|
|
||||||
// The nRF52840DK LEDs (see back of board)
|
|
||||||
let led_kernel_pin = &nrf52840::gpio::GPIOPin::new(Pin::P0_13);
|
|
||||||
let led = &mut led::LedLow::new(led_kernel_pin);
|
|
||||||
let writer = &mut WRITER;
|
|
||||||
debug::panic(
|
|
||||||
&mut [led],
|
|
||||||
writer,
|
|
||||||
pi,
|
|
||||||
&cortexm4::support::nop,
|
|
||||||
&PROCESSES,
|
|
||||||
&CHIP,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,493 +0,0 @@
|
|||||||
//! Tock kernel for the Nordic Semiconductor nRF52840 development kit (DK).
|
|
||||||
//!
|
|
||||||
//! It is based on nRF52840 SoC (Cortex M4 core with a BLE transceiver) with
|
|
||||||
//! many exported I/O and peripherals.
|
|
||||||
//!
|
|
||||||
//! Pin Configuration
|
|
||||||
//! -------------------
|
|
||||||
//!
|
|
||||||
//! ### `GPIO`
|
|
||||||
//!
|
|
||||||
//! | # | Pin | Ix | Header | Arduino |
|
|
||||||
//! |----|-------|----|--------|---------|
|
|
||||||
//! | 0 | P1.01 | 33 | P3 1 | D0 |
|
|
||||||
//! | 1 | P1.02 | 34 | P3 2 | D1 |
|
|
||||||
//! | 2 | P1.03 | 35 | P3 3 | D2 |
|
|
||||||
//! | 3 | P1.04 | 36 | P3 4 | D3 |
|
|
||||||
//! | 4 | P1.05 | 37 | P3 5 | D4 |
|
|
||||||
//! | 5 | P1.06 | 38 | P3 6 | D5 |
|
|
||||||
//! | 6 | P1.07 | 39 | P3 7 | D6 |
|
|
||||||
//! | 7 | P1.08 | 40 | P3 8 | D7 |
|
|
||||||
//! | 8 | P1.10 | 42 | P4 1 | D8 |
|
|
||||||
//! | 9 | P1.11 | 43 | P4 2 | D9 |
|
|
||||||
//! | 10 | P1.12 | 44 | P4 3 | D10 |
|
|
||||||
//! | 11 | P1.13 | 45 | P4 4 | D11 |
|
|
||||||
//! | 12 | P1.14 | 46 | P4 5 | D12 |
|
|
||||||
//! | 13 | P1.15 | 47 | P4 6 | D13 |
|
|
||||||
//! | 14 | P0.26 | 26 | P4 9 | D14 |
|
|
||||||
//! | 15 | P0.27 | 27 | P4 10 | D15 |
|
|
||||||
//!
|
|
||||||
//! ### `GPIO` / Analog Inputs
|
|
||||||
//!
|
|
||||||
//! | # | Pin | Header | Arduino |
|
|
||||||
//! |----|------------|--------|---------|
|
|
||||||
//! | 16 | P0.03 AIN1 | P2 1 | A0 |
|
|
||||||
//! | 17 | P0.04 AIN2 | P2 2 | A1 |
|
|
||||||
//! | 18 | P0.28 AIN4 | P2 3 | A2 |
|
|
||||||
//! | 19 | P0.29 AIN5 | P2 4 | A3 |
|
|
||||||
//! | 20 | P0.30 AIN6 | P2 5 | A4 |
|
|
||||||
//! | 21 | P0.31 AIN7 | P2 6 | A5 |
|
|
||||||
//! | 22 | P0.02 AIN0 | P4 8 | AVDD |
|
|
||||||
//!
|
|
||||||
//! ### Onboard Functions
|
|
||||||
//!
|
|
||||||
//! | Pin | Header | Function |
|
|
||||||
//! |-------|--------|----------|
|
|
||||||
//! | P0.05 | P6 3 | UART RTS |
|
|
||||||
//! | P0.06 | P6 4 | UART TXD |
|
|
||||||
//! | P0.07 | P6 5 | UART CTS |
|
|
||||||
//! | P0.08 | P6 6 | UART RXT |
|
|
||||||
//! | P0.11 | P24 1 | Button 1 |
|
|
||||||
//! | P0.12 | P24 2 | Button 2 |
|
|
||||||
//! | P0.13 | P24 3 | LED 1 |
|
|
||||||
//! | P0.14 | P24 4 | LED 2 |
|
|
||||||
//! | P0.15 | P24 5 | LED 3 |
|
|
||||||
//! | P0.16 | P24 6 | LED 4 |
|
|
||||||
//! | P0.18 | P24 8 | Reset |
|
|
||||||
//! | P0.19 | P24 9 | SPI CLK |
|
|
||||||
//! | P0.20 | P24 10 | SPI MOSI |
|
|
||||||
//! | P0.21 | P24 11 | SPI MISO |
|
|
||||||
//! | P0.24 | P24 14 | Button 3 |
|
|
||||||
//! | P0.25 | P24 15 | Button 4 |
|
|
||||||
|
|
||||||
#![no_std]
|
|
||||||
// Disable this attribute when documenting, as a workaround for
|
|
||||||
// https://github.com/rust-lang/rust/issues/62184.
|
|
||||||
#![cfg_attr(not(doc), no_main)]
|
|
||||||
#![feature(const_in_array_repeat_expressions)]
|
|
||||||
#![deny(missing_docs)]
|
|
||||||
|
|
||||||
use core::env;
|
|
||||||
use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState};
|
|
||||||
use kernel::component::Component;
|
|
||||||
use kernel::hil::led::LedLow;
|
|
||||||
use kernel::hil::time::Counter;
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use kernel::{capabilities, create_capability, debug, debug_gpio, debug_verbose, static_init};
|
|
||||||
use nrf52840::gpio::Pin;
|
|
||||||
use nrf52840::interrupt_service::Nrf52840DefaultPeripherals;
|
|
||||||
use nrf52_components::{self, UartChannel, UartPins};
|
|
||||||
|
|
||||||
// The nRF52840DK LEDs (see back of board)
|
|
||||||
const LED1_PIN: Pin = Pin::P0_13;
|
|
||||||
const LED2_PIN: Pin = Pin::P0_14;
|
|
||||||
const LED3_PIN: Pin = Pin::P0_15;
|
|
||||||
const LED4_PIN: Pin = Pin::P0_16;
|
|
||||||
|
|
||||||
// The nRF52840DK buttons (see back of board)
|
|
||||||
const BUTTON1_PIN: Pin = Pin::P0_11;
|
|
||||||
const BUTTON2_PIN: Pin = Pin::P0_12;
|
|
||||||
const BUTTON3_PIN: Pin = Pin::P0_24;
|
|
||||||
const BUTTON4_PIN: Pin = Pin::P0_25;
|
|
||||||
const BUTTON_RST_PIN: Pin = Pin::P0_18;
|
|
||||||
|
|
||||||
const UART_RTS: Option<Pin> = Some(Pin::P0_05);
|
|
||||||
const UART_TXD: Pin = Pin::P0_06;
|
|
||||||
const UART_CTS: Option<Pin> = Some(Pin::P0_07);
|
|
||||||
const UART_RXD: Pin = Pin::P0_08;
|
|
||||||
|
|
||||||
const SPI_MOSI: Pin = Pin::P0_20;
|
|
||||||
const SPI_MISO: Pin = Pin::P0_21;
|
|
||||||
const SPI_CLK: Pin = Pin::P0_19;
|
|
||||||
|
|
||||||
/// Debug Writer
|
|
||||||
pub mod io;
|
|
||||||
|
|
||||||
// Whether to use UART debugging or Segger RTT (USB) debugging.
|
|
||||||
// - Set to false to use UART.
|
|
||||||
// - Set to true to use Segger RTT over USB.
|
|
||||||
const USB_DEBUGGING: bool = true;
|
|
||||||
|
|
||||||
const VENDOR_ID: u16 = 0x1915; // Nordic Semiconductor
|
|
||||||
const PRODUCT_ID: u16 = 0x521f; // nRF52840 Dongle (PCA10059)
|
|
||||||
static STRINGS: &'static [&'static str] = &[
|
|
||||||
// Manufacturer
|
|
||||||
"Nordic Semiconductor ASA",
|
|
||||||
// Product
|
|
||||||
"OpenSK",
|
|
||||||
// Serial number
|
|
||||||
"v1.0",
|
|
||||||
];
|
|
||||||
|
|
||||||
// State for loading and holding applications.
|
|
||||||
// How should the kernel respond when a process faults.
|
|
||||||
const FAULT_RESPONSE: kernel::procs::FaultResponse = kernel::procs::FaultResponse::Panic;
|
|
||||||
|
|
||||||
// Number of concurrent processes this platform supports.
|
|
||||||
const NUM_PROCS: usize = 8;
|
|
||||||
|
|
||||||
static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; NUM_PROCS] =
|
|
||||||
[None; NUM_PROCS];
|
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/locations.rs"));
|
|
||||||
|
|
||||||
static mut CHIP: Option<&'static nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>> = None;
|
|
||||||
|
|
||||||
/// Dummy buffer that causes the linker to reserve enough space for the stack.
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".stack_buffer"]
|
|
||||||
pub static mut STACK_MEMORY: [u8; 0x1000] = [0; 0x1000];
|
|
||||||
|
|
||||||
/// Supported drivers by the platform
|
|
||||||
pub struct Platform {
|
|
||||||
button: &'static capsules::button::Button<'static, nrf52840::gpio::GPIOPin<'static>>,
|
|
||||||
pconsole: &'static capsules::process_console::ProcessConsole<
|
|
||||||
'static,
|
|
||||||
components::process_console::Capability,
|
|
||||||
>,
|
|
||||||
console: &'static capsules::console::Console<'static>,
|
|
||||||
gpio: &'static capsules::gpio::GPIO<'static, nrf52840::gpio::GPIOPin<'static>>,
|
|
||||||
led: &'static capsules::led::LedDriver<
|
|
||||||
'static,
|
|
||||||
kernel::hil::led::LedLow<'static, nrf52840::gpio::GPIOPin<'static>>,
|
|
||||||
>,
|
|
||||||
rng: &'static capsules::rng::RngDriver<'static>,
|
|
||||||
ipc: kernel::ipc::IPC<NUM_PROCS>,
|
|
||||||
analog_comparator: &'static capsules::analog_comparator::AnalogComparator<
|
|
||||||
'static,
|
|
||||||
nrf52840::acomp::Comparator<'static>,
|
|
||||||
>,
|
|
||||||
alarm: &'static capsules::alarm::AlarmDriver<
|
|
||||||
'static,
|
|
||||||
capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52840::rtc::Rtc<'static>>,
|
|
||||||
>,
|
|
||||||
nvmc: &'static nrf52840::nvmc::SyscallDriver,
|
|
||||||
usb: &'static capsules::usb::usb_ctap::CtapUsbSyscallDriver<
|
|
||||||
'static,
|
|
||||||
'static,
|
|
||||||
nrf52840::usbd::Usbd<'static>,
|
|
||||||
>,
|
|
||||||
crp: &'static capsules::firmware_protection::FirmwareProtection<nrf52840::uicr::Uicr>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl kernel::Platform for Platform {
|
|
||||||
fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
|
|
||||||
where
|
|
||||||
F: FnOnce(Option<&dyn kernel::Driver>) -> R,
|
|
||||||
{
|
|
||||||
match driver_num {
|
|
||||||
capsules::console::DRIVER_NUM => f(Some(self.console)),
|
|
||||||
capsules::gpio::DRIVER_NUM => f(Some(self.gpio)),
|
|
||||||
capsules::alarm::DRIVER_NUM => f(Some(self.alarm)),
|
|
||||||
capsules::led::DRIVER_NUM => f(Some(self.led)),
|
|
||||||
capsules::button::DRIVER_NUM => f(Some(self.button)),
|
|
||||||
capsules::rng::DRIVER_NUM => f(Some(self.rng)),
|
|
||||||
capsules::analog_comparator::DRIVER_NUM => f(Some(self.analog_comparator)),
|
|
||||||
nrf52840::nvmc::DRIVER_NUM => f(Some(self.nvmc)),
|
|
||||||
capsules::usb::usb_ctap::DRIVER_NUM => f(Some(self.usb)),
|
|
||||||
capsules::firmware_protection::DRIVER_NUM => f(Some(self.crp)),
|
|
||||||
kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
|
|
||||||
_ => f(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn filter_syscall(
|
|
||||||
&self,
|
|
||||||
process: &dyn kernel::procs::ProcessType,
|
|
||||||
syscall: &kernel::syscall::Syscall,
|
|
||||||
) -> Result<(), kernel::ReturnCode> {
|
|
||||||
use kernel::syscall::Syscall;
|
|
||||||
match *syscall {
|
|
||||||
Syscall::COMMAND {
|
|
||||||
driver_number: nrf52840::nvmc::DRIVER_NUM,
|
|
||||||
subdriver_number: cmd,
|
|
||||||
arg0: ptr,
|
|
||||||
arg1: len,
|
|
||||||
} if (cmd == 2 || cmd == 3) && !process.fits_in_storage_location(ptr, len) => {
|
|
||||||
Err(kernel::ReturnCode::EINVAL)
|
|
||||||
}
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Entry point in the vector table called on hard reset.
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe fn reset_handler() {
|
|
||||||
// Loads relocations and clears BSS
|
|
||||||
nrf52840::init();
|
|
||||||
let ppi = static_init!(nrf52840::ppi::Ppi, nrf52840::ppi::Ppi::new());
|
|
||||||
// Initialize chip peripheral drivers
|
|
||||||
let nrf52840_peripherals = static_init!(
|
|
||||||
Nrf52840DefaultPeripherals,
|
|
||||||
Nrf52840DefaultPeripherals::new(ppi)
|
|
||||||
);
|
|
||||||
|
|
||||||
// set up circular peripheral dependencies
|
|
||||||
nrf52840_peripherals.init();
|
|
||||||
let base_peripherals = &nrf52840_peripherals.nrf52;
|
|
||||||
|
|
||||||
let uart_channel = if USB_DEBUGGING {
|
|
||||||
// Initialize early so any panic beyond this point can use the RTT memory object.
|
|
||||||
let mut rtt_memory_refs =
|
|
||||||
components::segger_rtt::SeggerRttMemoryComponent::new().finalize(());
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
self::io::set_rtt_memory(&mut *rtt_memory_refs.get_rtt_memory_ptr());
|
|
||||||
|
|
||||||
UartChannel::Rtt(rtt_memory_refs)
|
|
||||||
} else {
|
|
||||||
UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD))
|
|
||||||
};
|
|
||||||
|
|
||||||
let board_kernel = static_init!(
|
|
||||||
kernel::Kernel,
|
|
||||||
kernel::Kernel::new_with_storage(&PROCESSES, &STORAGE_LOCATIONS)
|
|
||||||
);
|
|
||||||
|
|
||||||
let gpio = components::gpio::GpioComponent::new(
|
|
||||||
board_kernel,
|
|
||||||
components::gpio_component_helper!(
|
|
||||||
nrf52840::gpio::GPIOPin,
|
|
||||||
0 => &nrf52840_peripherals.gpio_port[Pin::P1_01],
|
|
||||||
1 => &nrf52840_peripherals.gpio_port[Pin::P1_02],
|
|
||||||
2 => &nrf52840_peripherals.gpio_port[Pin::P1_03],
|
|
||||||
3 => &nrf52840_peripherals.gpio_port[Pin::P1_04],
|
|
||||||
4 => &nrf52840_peripherals.gpio_port[Pin::P1_05],
|
|
||||||
5 => &nrf52840_peripherals.gpio_port[Pin::P1_06],
|
|
||||||
6 => &nrf52840_peripherals.gpio_port[Pin::P1_07],
|
|
||||||
7 => &nrf52840_peripherals.gpio_port[Pin::P1_08],
|
|
||||||
8 => &nrf52840_peripherals.gpio_port[Pin::P1_10],
|
|
||||||
9 => &nrf52840_peripherals.gpio_port[Pin::P1_11],
|
|
||||||
10 => &nrf52840_peripherals.gpio_port[Pin::P1_12],
|
|
||||||
11 => &nrf52840_peripherals.gpio_port[Pin::P1_13],
|
|
||||||
12 => &nrf52840_peripherals.gpio_port[Pin::P1_14],
|
|
||||||
13 => &nrf52840_peripherals.gpio_port[Pin::P1_15],
|
|
||||||
14 => &nrf52840_peripherals.gpio_port[Pin::P0_26],
|
|
||||||
15 => &nrf52840_peripherals.gpio_port[Pin::P0_27]
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.finalize(components::gpio_component_buf!(nrf52840::gpio::GPIOPin));
|
|
||||||
|
|
||||||
let button = components::button::ButtonComponent::new(
|
|
||||||
board_kernel,
|
|
||||||
components::button_component_helper!(
|
|
||||||
nrf52840::gpio::GPIOPin,
|
|
||||||
(
|
|
||||||
&nrf52840_peripherals.gpio_port[BUTTON1_PIN],
|
|
||||||
kernel::hil::gpio::ActivationMode::ActiveLow,
|
|
||||||
kernel::hil::gpio::FloatingState::PullUp
|
|
||||||
), //13
|
|
||||||
(
|
|
||||||
&nrf52840_peripherals.gpio_port[BUTTON2_PIN],
|
|
||||||
kernel::hil::gpio::ActivationMode::ActiveLow,
|
|
||||||
kernel::hil::gpio::FloatingState::PullUp
|
|
||||||
), //14
|
|
||||||
(
|
|
||||||
&nrf52840_peripherals.gpio_port[BUTTON3_PIN],
|
|
||||||
kernel::hil::gpio::ActivationMode::ActiveLow,
|
|
||||||
kernel::hil::gpio::FloatingState::PullUp
|
|
||||||
), //15
|
|
||||||
(
|
|
||||||
&nrf52840_peripherals.gpio_port[BUTTON4_PIN],
|
|
||||||
kernel::hil::gpio::ActivationMode::ActiveLow,
|
|
||||||
kernel::hil::gpio::FloatingState::PullUp
|
|
||||||
) //16
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.finalize(components::button_component_buf!(nrf52840::gpio::GPIOPin));
|
|
||||||
|
|
||||||
let led = components::led::LedsComponent::new(components::led_component_helper!(
|
|
||||||
LedLow<'static, nrf52840::gpio::GPIOPin>,
|
|
||||||
LedLow::new(&nrf52840_peripherals.gpio_port[LED1_PIN]),
|
|
||||||
LedLow::new(&nrf52840_peripherals.gpio_port[LED2_PIN]),
|
|
||||||
LedLow::new(&nrf52840_peripherals.gpio_port[LED3_PIN]),
|
|
||||||
LedLow::new(&nrf52840_peripherals.gpio_port[LED4_PIN]),
|
|
||||||
))
|
|
||||||
.finalize(components::led_component_buf!(
|
|
||||||
LedLow<'static, nrf52840::gpio::GPIOPin>
|
|
||||||
));
|
|
||||||
|
|
||||||
let chip = static_init!(
|
|
||||||
nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
|
|
||||||
nrf52840::chip::NRF52::new(nrf52840_peripherals)
|
|
||||||
);
|
|
||||||
CHIP = Some(chip);
|
|
||||||
|
|
||||||
nrf52_components::startup::NrfStartupComponent::new(
|
|
||||||
false,
|
|
||||||
BUTTON_RST_PIN,
|
|
||||||
nrf52840::uicr::Regulator0Output::DEFAULT,
|
|
||||||
&base_peripherals.nvmc,
|
|
||||||
)
|
|
||||||
.finalize(());
|
|
||||||
|
|
||||||
// Create capabilities that the board needs to call certain protected kernel
|
|
||||||
// functions.
|
|
||||||
let process_management_capability =
|
|
||||||
create_capability!(capabilities::ProcessManagementCapability);
|
|
||||||
let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
|
|
||||||
let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
|
|
||||||
let gpio_port = &nrf52840_peripherals.gpio_port;
|
|
||||||
// Configure kernel debug gpios as early as possible
|
|
||||||
kernel::debug::assign_gpios(
|
|
||||||
Some(&gpio_port[LED1_PIN]),
|
|
||||||
Some(&gpio_port[LED2_PIN]),
|
|
||||||
Some(&gpio_port[LED3_PIN]),
|
|
||||||
);
|
|
||||||
|
|
||||||
let rtc = &base_peripherals.rtc;
|
|
||||||
rtc.start();
|
|
||||||
let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
|
|
||||||
.finalize(components::alarm_mux_component_helper!(nrf52840::rtc::Rtc));
|
|
||||||
let alarm = components::alarm::AlarmDriverComponent::new(board_kernel, mux_alarm)
|
|
||||||
.finalize(components::alarm_component_helper!(nrf52840::rtc::Rtc));
|
|
||||||
|
|
||||||
let channel = nrf52_components::UartChannelComponent::new(
|
|
||||||
uart_channel,
|
|
||||||
mux_alarm,
|
|
||||||
&base_peripherals.uarte0,
|
|
||||||
)
|
|
||||||
.finalize(());
|
|
||||||
|
|
||||||
let dynamic_deferred_call_clients =
|
|
||||||
static_init!([DynamicDeferredCallClientState; 3], Default::default());
|
|
||||||
let dynamic_deferred_caller = static_init!(
|
|
||||||
DynamicDeferredCall,
|
|
||||||
DynamicDeferredCall::new(dynamic_deferred_call_clients)
|
|
||||||
);
|
|
||||||
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(channel, 115200, dynamic_deferred_caller)
|
|
||||||
.finalize(());
|
|
||||||
|
|
||||||
let pconsole =
|
|
||||||
components::process_console::ProcessConsoleComponent::new(board_kernel, uart_mux)
|
|
||||||
.finalize(());
|
|
||||||
|
|
||||||
// Setup the console.
|
|
||||||
let console = components::console::ConsoleComponent::new(board_kernel, uart_mux).finalize(());
|
|
||||||
// Create the debugger object that handles calls to `debug!()`.
|
|
||||||
components::debug_writer::DebugWriterComponent::new(uart_mux).finalize(());
|
|
||||||
|
|
||||||
let rng = components::rng::RngComponent::new(board_kernel, &base_peripherals.trng).finalize(());
|
|
||||||
|
|
||||||
base_peripherals.spim0.configure(
|
|
||||||
nrf52840::pinmux::Pinmux::new(SPI_MOSI as u32),
|
|
||||||
nrf52840::pinmux::Pinmux::new(SPI_MISO as u32),
|
|
||||||
nrf52840::pinmux::Pinmux::new(SPI_CLK as u32),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Initialize AC using AIN5 (P0.29) as VIN+ and VIN- as AIN0 (P0.02)
|
|
||||||
// These are hardcoded pin assignments specified in the driver
|
|
||||||
let analog_comparator = components::analog_comparator::AcComponent::new(
|
|
||||||
&base_peripherals.acomp,
|
|
||||||
components::acomp_component_helper!(
|
|
||||||
nrf52840::acomp::Channel,
|
|
||||||
&nrf52840::acomp::CHANNEL_AC0
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.finalize(components::acomp_component_buf!(
|
|
||||||
nrf52840::acomp::Comparator
|
|
||||||
));
|
|
||||||
|
|
||||||
let nvmc = static_init!(
|
|
||||||
nrf52840::nvmc::SyscallDriver,
|
|
||||||
nrf52840::nvmc::SyscallDriver::new(
|
|
||||||
&base_peripherals.nvmc,
|
|
||||||
board_kernel.create_grant(&memory_allocation_capability),
|
|
||||||
dynamic_deferred_caller,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
nvmc.set_deferred_handle(
|
|
||||||
dynamic_deferred_caller
|
|
||||||
.register(nvmc)
|
|
||||||
.expect("no deferred call slot available for nvmc"),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Configure USB controller
|
|
||||||
let usb = components::usb_ctap::UsbCtapComponent::new(
|
|
||||||
board_kernel,
|
|
||||||
&nrf52840_peripherals.usbd,
|
|
||||||
capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840,
|
|
||||||
VENDOR_ID,
|
|
||||||
PRODUCT_ID,
|
|
||||||
STRINGS,
|
|
||||||
)
|
|
||||||
.finalize(components::usb_ctap_component_buf!(nrf52840::usbd::Usbd));
|
|
||||||
|
|
||||||
let crp = components::firmware_protection::FirmwareProtectionComponent::new(
|
|
||||||
board_kernel,
|
|
||||||
nrf52840::uicr::Uicr::new(),
|
|
||||||
)
|
|
||||||
.finalize(components::firmware_protection_component_helper!(
|
|
||||||
nrf52840::uicr::Uicr
|
|
||||||
));
|
|
||||||
|
|
||||||
nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(());
|
|
||||||
|
|
||||||
let platform = Platform {
|
|
||||||
button,
|
|
||||||
pconsole,
|
|
||||||
console,
|
|
||||||
led,
|
|
||||||
gpio,
|
|
||||||
rng,
|
|
||||||
alarm,
|
|
||||||
analog_comparator,
|
|
||||||
nvmc,
|
|
||||||
usb,
|
|
||||||
crp,
|
|
||||||
ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability),
|
|
||||||
};
|
|
||||||
|
|
||||||
platform.pconsole.start();
|
|
||||||
debug!("Initialization complete. Entering main loop\r");
|
|
||||||
debug!("{}", &nrf52840::ficr::FICR_INSTANCE);
|
|
||||||
|
|
||||||
/// These symbols are defined in the linker script.
|
|
||||||
extern "C" {
|
|
||||||
/// Beginning of the ROM region containing app images.
|
|
||||||
static _sapps: u8;
|
|
||||||
/// End of the ROM region containing app images.
|
|
||||||
static _eapps: u8;
|
|
||||||
/// Beginning of the RAM region for app memory.
|
|
||||||
static mut _sappmem: u8;
|
|
||||||
/// End of the RAM region for app memory.
|
|
||||||
static _eappmem: u8;
|
|
||||||
}
|
|
||||||
|
|
||||||
kernel::procs::load_processes(
|
|
||||||
board_kernel,
|
|
||||||
chip,
|
|
||||||
core::slice::from_raw_parts(
|
|
||||||
&_sapps as *const u8,
|
|
||||||
&_eapps as *const u8 as usize - &_sapps as *const u8 as usize,
|
|
||||||
),
|
|
||||||
core::slice::from_raw_parts_mut(
|
|
||||||
&mut _sappmem as *mut u8,
|
|
||||||
&_eappmem as *const u8 as usize - &_sappmem as *const u8 as usize,
|
|
||||||
),
|
|
||||||
&mut PROCESSES,
|
|
||||||
FAULT_RESPONSE,
|
|
||||||
&process_management_capability,
|
|
||||||
)
|
|
||||||
.unwrap_or_else(|err| {
|
|
||||||
debug!("Error loading processes!");
|
|
||||||
debug!("{:?}", err);
|
|
||||||
});
|
|
||||||
|
|
||||||
let scheduler = components::sched::round_robin::RoundRobinComponent::new(&PROCESSES)
|
|
||||||
.finalize(components::rr_component_helper!(NUM_PROCS));
|
|
||||||
board_kernel.kernel_loop(
|
|
||||||
&platform,
|
|
||||||
chip,
|
|
||||||
Some(&platform.ipc),
|
|
||||||
scheduler,
|
|
||||||
&main_loop_capability,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "nrf52840dk_opensk_a"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Tock Project Developers <tock-dev@googlegroups.com>"]
|
|
||||||
build = "build.rs"
|
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
path = "../nrf52840dk_opensk/src/main.rs"
|
|
||||||
name = "nrf52840dk_opensk_a"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
components = { path = "../../components" }
|
|
||||||
cortexm4 = { path = "../../../arch/cortex-m4" }
|
|
||||||
capsules = { path = "../../../capsules" }
|
|
||||||
kernel = { path = "../../../kernel" }
|
|
||||||
nrf52840 = { path = "../../../chips/nrf52840" }
|
|
||||||
nrf52_components = { path = "../nrf52_components" }
|
|
||||||
|
|
||||||
[features]
|
|
||||||
vendor_hid = ["capsules/vendor_hid"]
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
# Makefile for building the tock kernel for the nRF development kit
|
|
||||||
|
|
||||||
TARGET=thumbv7em-none-eabi
|
|
||||||
PLATFORM=nrf52840dk_opensk_a
|
|
||||||
|
|
||||||
include ../../Makefile.common
|
|
||||||
|
|
||||||
TOCKLOADER=tockloader
|
|
||||||
|
|
||||||
# Where in the SAM4L flash to load the kernel with `tockloader`
|
|
||||||
KERNEL_ADDRESS=0x20000
|
|
||||||
|
|
||||||
# Upload programs over uart with tockloader
|
|
||||||
ifdef PORT
|
|
||||||
TOCKLOADER_GENERAL_FLAGS += --port $(PORT)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Upload the kernel over JTAG
|
|
||||||
.PHONY: flash
|
|
||||||
flash: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).bin
|
|
||||||
$(TOCKLOADER) $(TOCKLOADER_GENERAL_FLAGS) flash --address $(KERNEL_ADDRESS) --board nrf52dk --jlink $<
|
|
||||||
|
|
||||||
# Upload the kernel over JTAG using OpenOCD
|
|
||||||
.PHONY: flash-openocd
|
|
||||||
flash-openocd: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).bin
|
|
||||||
$(TOCKLOADER) $(TOCKLOADER_GENERAL_FLAGS) flash --address $(KERNEL_ADDRESS) --board nrf52dk --openocd $<
|
|
||||||
|
|
||||||
# Upload the kernel over serial/bootloader
|
|
||||||
.PHONY: program
|
|
||||||
program: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).hex
|
|
||||||
$(error Cannot program nRF52840DK over USB. Use \`make flash\` and JTAG)
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
Platform-Specific Instructions: nRF52840-DK, partition A
|
|
||||||
===================================
|
|
||||||
|
|
||||||
This is an upgrade partition for the adapted nrf52840dk in `../nrf52840dk_opensk`.
|
|
||||||
|
|
||||||
Compared to our regular board definition for the nrf52840dk, changes are:
|
|
||||||
- a `layout.ld` with 128 kB for kernel and app
|
|
||||||
- the matching kernel address in the `Makefile`
|
|
||||||
- different `StorageLocation`s in `build.rs`
|
|
||||||
|
|
||||||
For everything else, please check the README in `../nrf52840dk_opensk`.
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
use std::env;
|
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
println!("cargo:rerun-if-changed=layout.ld");
|
|
||||||
println!("cargo:rerun-if-changed=../../kernel_layout.ld");
|
|
||||||
|
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
|
||||||
let dest_path = Path::new(&out_dir).join("locations.rs");
|
|
||||||
fs::write(
|
|
||||||
&dest_path,
|
|
||||||
"
|
|
||||||
static mut STORAGE_LOCATIONS: [kernel::StorageLocation; 5] = [
|
|
||||||
// We implement NUM_PAGES = 20 as 16 + 4 to satisfy the MPU.
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0xC0000,
|
|
||||||
size: 0x10000, // 16 pages
|
|
||||||
storage_type: kernel::StorageType::STORE,
|
|
||||||
},
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0xD0000,
|
|
||||||
size: 0x4000, // 4 pages
|
|
||||||
storage_type: kernel::StorageType::STORE,
|
|
||||||
},
|
|
||||||
// Partitions can also be split to maximize MPU happiness.
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0x60000,
|
|
||||||
size: 0x20000,
|
|
||||||
storage_type: kernel::StorageType::PARTITION,
|
|
||||||
},
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0x80000,
|
|
||||||
size: 0x20000,
|
|
||||||
storage_type: kernel::StorageType::PARTITION,
|
|
||||||
},
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0x5000,
|
|
||||||
size: 0x1000,
|
|
||||||
storage_type: kernel::StorageType::METADATA,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
"
|
|
||||||
).unwrap();
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/* Memory Space Definitions, 1M flash, 256K ram */
|
|
||||||
MEMORY
|
|
||||||
{
|
|
||||||
rom (rx) : ORIGIN = 0x00020000, LENGTH = 128K
|
|
||||||
prog (rx) : ORIGIN = 0x00040000, LENGTH = 128K
|
|
||||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 256K
|
|
||||||
}
|
|
||||||
|
|
||||||
MPU_MIN_ALIGN = 8K;
|
|
||||||
PAGE_SIZE = 4K;
|
|
||||||
|
|
||||||
INCLUDE ../../kernel_layout.ld
|
|
||||||
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "nrf52840dk_opensk_b"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Tock Project Developers <tock-dev@googlegroups.com>"]
|
|
||||||
build = "build.rs"
|
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
path = "../nrf52840dk_opensk/src/main.rs"
|
|
||||||
name = "nrf52840dk_opensk_b"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
components = { path = "../../components" }
|
|
||||||
cortexm4 = { path = "../../../arch/cortex-m4" }
|
|
||||||
capsules = { path = "../../../capsules" }
|
|
||||||
kernel = { path = "../../../kernel" }
|
|
||||||
nrf52840 = { path = "../../../chips/nrf52840" }
|
|
||||||
nrf52_components = { path = "../nrf52_components" }
|
|
||||||
|
|
||||||
[features]
|
|
||||||
vendor_hid = ["capsules/vendor_hid"]
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
# Makefile for building the tock kernel for the nRF development kit
|
|
||||||
|
|
||||||
TARGET=thumbv7em-none-eabi
|
|
||||||
PLATFORM=nrf52840dk_opensk_b
|
|
||||||
|
|
||||||
include ../../Makefile.common
|
|
||||||
|
|
||||||
TOCKLOADER=tockloader
|
|
||||||
|
|
||||||
# Where in the SAM4L flash to load the kernel with `tockloader`
|
|
||||||
KERNEL_ADDRESS=0x60000
|
|
||||||
|
|
||||||
# Upload programs over uart with tockloader
|
|
||||||
ifdef PORT
|
|
||||||
TOCKLOADER_GENERAL_FLAGS += --port $(PORT)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Upload the kernel over JTAG
|
|
||||||
.PHONY: flash
|
|
||||||
flash: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).bin
|
|
||||||
$(TOCKLOADER) $(TOCKLOADER_GENERAL_FLAGS) flash --address $(KERNEL_ADDRESS) --board nrf52dk --jlink $<
|
|
||||||
|
|
||||||
# Upload the kernel over JTAG using OpenOCD
|
|
||||||
.PHONY: flash-openocd
|
|
||||||
flash-openocd: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).bin
|
|
||||||
$(TOCKLOADER) $(TOCKLOADER_GENERAL_FLAGS) flash --address $(KERNEL_ADDRESS) --board nrf52dk --openocd $<
|
|
||||||
|
|
||||||
# Upload the kernel over serial/bootloader
|
|
||||||
.PHONY: program
|
|
||||||
program: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).hex
|
|
||||||
$(error Cannot program nRF52840DK over USB. Use \`make flash\` and JTAG)
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
Platform-Specific Instructions: nRF52840-DK, partition B
|
|
||||||
===================================
|
|
||||||
|
|
||||||
This is an upgrade partition for the adapted nrf52840dk in `../nrf52840dk_opensk`.
|
|
||||||
|
|
||||||
Compared to our regular board definition for the nrf52840dk, changes are:
|
|
||||||
- a `layout.ld` with 128 kB for kernel and app
|
|
||||||
- the matching kernel address in the `Makefile`
|
|
||||||
- different `StorageLocation`s in `build.rs`
|
|
||||||
|
|
||||||
For everything else, please check the README in `../nrf52840dk_opensk`.
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
use std::env;
|
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
println!("cargo:rerun-if-changed=layout.ld");
|
|
||||||
println!("cargo:rerun-if-changed=../../kernel_layout.ld");
|
|
||||||
|
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
|
||||||
let dest_path = Path::new(&out_dir).join("locations.rs");
|
|
||||||
fs::write(
|
|
||||||
&dest_path,
|
|
||||||
"
|
|
||||||
static mut STORAGE_LOCATIONS: [kernel::StorageLocation; 5] = [
|
|
||||||
// We implement NUM_PAGES = 20 as 16 + 4 to satisfy the MPU.
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0xC0000,
|
|
||||||
size: 0x10000, // 16 pages
|
|
||||||
storage_type: kernel::StorageType::STORE,
|
|
||||||
},
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0xD0000,
|
|
||||||
size: 0x4000, // 4 pages
|
|
||||||
storage_type: kernel::StorageType::STORE,
|
|
||||||
},
|
|
||||||
// Partitions can also be split to maximize MPU happiness.
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0x20000,
|
|
||||||
size: 0x20000,
|
|
||||||
storage_type: kernel::StorageType::PARTITION,
|
|
||||||
},
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0x40000,
|
|
||||||
size: 0x20000,
|
|
||||||
storage_type: kernel::StorageType::PARTITION,
|
|
||||||
},
|
|
||||||
kernel::StorageLocation {
|
|
||||||
address: 0x4000,
|
|
||||||
size: 0x1000,
|
|
||||||
storage_type: kernel::StorageType::METADATA,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
"
|
|
||||||
).unwrap();
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/* Memory Space Definitions, 1M flash, 256K ram */
|
|
||||||
MEMORY
|
|
||||||
{
|
|
||||||
rom (rx) : ORIGIN = 0x00060000, LENGTH = 128K
|
|
||||||
prog (rx) : ORIGIN = 0x00080000, LENGTH = 128K
|
|
||||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 256K
|
|
||||||
}
|
|
||||||
|
|
||||||
MPU_MIN_ALIGN = 8K;
|
|
||||||
PAGE_SIZE = 4K;
|
|
||||||
|
|
||||||
INCLUDE ../../kernel_layout.ld
|
|
||||||
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
[target.thumbv7em-none-eabi]
|
|
||||||
linker = "arm-none-eabi-gcc"
|
|
||||||
282
bootloader/Cargo.lock
generated
282
bootloader/Cargo.lock
generated
@@ -1,282 +0,0 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "aligned"
|
|
||||||
version = "0.3.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3a785a543aea40f5e4e2e93bb2655d31bc21bb391fff65697150973e383f16bb"
|
|
||||||
dependencies = [
|
|
||||||
"as-slice",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "as-slice"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "45403b49e3954a4b8428a0ac21a4b7afadccf92bfd96273f1a58cd4812496ae0"
|
|
||||||
dependencies = [
|
|
||||||
"generic-array 0.12.4",
|
|
||||||
"generic-array 0.13.3",
|
|
||||||
"generic-array 0.14.6",
|
|
||||||
"stable_deref_trait",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bare-metal"
|
|
||||||
version = "0.2.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
|
|
||||||
dependencies = [
|
|
||||||
"rustc_version",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bitfield"
|
|
||||||
version = "0.13.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bootloader"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"byteorder",
|
|
||||||
"cortex-m 0.6.7",
|
|
||||||
"cortex-m-rt",
|
|
||||||
"cortex-m-rt-macros",
|
|
||||||
"panic-abort",
|
|
||||||
"rtt-target",
|
|
||||||
"tock-registers",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "byteorder"
|
|
||||||
version = "1.4.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cortex-m"
|
|
||||||
version = "0.6.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9075300b07c6a56263b9b582c214d0ff037b00d45ec9fde1cc711490c56f1bb9"
|
|
||||||
dependencies = [
|
|
||||||
"aligned",
|
|
||||||
"bare-metal",
|
|
||||||
"bitfield",
|
|
||||||
"cortex-m 0.7.6",
|
|
||||||
"volatile-register",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cortex-m"
|
|
||||||
version = "0.7.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "70858629a458fdfd39f9675c4dc309411f2a3f83bede76988d81bf1a0ecee9e0"
|
|
||||||
dependencies = [
|
|
||||||
"bare-metal",
|
|
||||||
"bitfield",
|
|
||||||
"embedded-hal",
|
|
||||||
"volatile-register",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cortex-m-rt"
|
|
||||||
version = "0.7.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3c433da385b720d5bb9f52362fa2782420798e68d40d67bfe4b0d992aba5dfe7"
|
|
||||||
dependencies = [
|
|
||||||
"cortex-m-rt-macros",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cortex-m-rt-macros"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "embedded-hal"
|
|
||||||
version = "0.2.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
|
|
||||||
dependencies = [
|
|
||||||
"nb 0.1.3",
|
|
||||||
"void",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "generic-array"
|
|
||||||
version = "0.12.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
|
|
||||||
dependencies = [
|
|
||||||
"typenum",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "generic-array"
|
|
||||||
version = "0.13.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309"
|
|
||||||
dependencies = [
|
|
||||||
"typenum",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "generic-array"
|
|
||||||
version = "0.14.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
|
|
||||||
dependencies = [
|
|
||||||
"typenum",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nb"
|
|
||||||
version = "0.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
|
|
||||||
dependencies = [
|
|
||||||
"nb 1.0.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nb"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "panic-abort"
|
|
||||||
version = "0.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4e20e6499bbbc412f280b04a42346b356c6fa0753d5fd22b7bd752ff34c778ee"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "1.0.43"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "1.0.21"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rtt-target"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "065d6058bb1204f51a562a67209e1817cf714759d5cf845aa45c75fa7b0b9d9b"
|
|
||||||
dependencies = [
|
|
||||||
"cortex-m 0.7.6",
|
|
||||||
"ufmt-write",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc_version"
|
|
||||||
version = "0.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
|
||||||
dependencies = [
|
|
||||||
"semver",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "semver"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
|
||||||
dependencies = [
|
|
||||||
"semver-parser",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "semver-parser"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "stable_deref_trait"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "1.0.100"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tock-registers"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f521a79accce68c417c9c77ce22108056b626126da1932f7e2e9b5bbffee0cea"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "typenum"
|
|
||||||
version = "1.15.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ufmt-write"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-ident"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vcell"
|
|
||||||
version = "0.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "version_check"
|
|
||||||
version = "0.9.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "void"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "volatile-register"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6"
|
|
||||||
dependencies = [
|
|
||||||
"vcell",
|
|
||||||
]
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "bootloader"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = [
|
|
||||||
"Fabian Kaczmarczyck <kaczmarczyck@google.com>",
|
|
||||||
]
|
|
||||||
build = "build.rs"
|
|
||||||
license = "Apache-2.0"
|
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
byteorder = { version = "1", default-features = false }
|
|
||||||
cortex-m = "^0.6.0"
|
|
||||||
cortex-m-rt = "*"
|
|
||||||
cortex-m-rt-macros = "*"
|
|
||||||
panic-abort = "0.3.2"
|
|
||||||
rtt-target = { version = "*", features = ["cortex-m"] }
|
|
||||||
tock-registers = { version = "0.6.0", features = ["no_std_unit_tests"] }
|
|
||||||
|
|
||||||
[profile.dev]
|
|
||||||
panic = "abort"
|
|
||||||
lto = true
|
|
||||||
opt-level = 3
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
panic = "abort"
|
|
||||||
lto = true
|
|
||||||
# Level "z" may decrease the binary size more of necessary.
|
|
||||||
opt-level = 3
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
# OpenSK Bootloader
|
|
||||||
|
|
||||||
This bootloader supports upgradability for OpenSK. Its functionality is to
|
|
||||||
|
|
||||||
- check images on A/B partitions,
|
|
||||||
- boot the most recent valid partition.
|
|
||||||
|
|
||||||
## How to use
|
|
||||||
|
|
||||||
The bootloader is built and deployed by OpenSK's `deploy.py`. If your board
|
|
||||||
defines a metadata address, it is detected as an upgradable board and this
|
|
||||||
bootloader is flashed to memory address 0.
|
|
||||||
|
|
||||||
## How to debug
|
|
||||||
|
|
||||||
The bootloader prints debug message over RTT when compiled in debug mode. Using
|
|
||||||
`nrfjprog` for flashing and inspecting memory is recommended for debugging.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
RUSTFLAGS="-C link-arg=-Wl,-Tlink.x -C link-arg=-nostartfiles" \
|
|
||||||
cargo build --target thumbv7em-none-eabi
|
|
||||||
llvm-objcopy -O ihex target/thumbv7em-none-eabi/debug/bootloader \
|
|
||||||
target/thumbv7em-none-eabi/debug/bootloader.hex
|
|
||||||
nrfjprog --program target/thumbv7em-none-eabi/debug/bootloader.hex \
|
|
||||||
--sectorerase -f nrf52 --reset
|
|
||||||
```
|
|
||||||
|
|
||||||
To read the debug messages, open two terminals for:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
JLinkRTTLogger -device NRF52840_XXAA -if swd -speed 1000 -RTTchannel 0
|
|
||||||
JLinkRTTClient
|
|
||||||
```
|
|
||||||
|
|
||||||
The first command also logs the output to a file. The second shows all output in
|
|
||||||
real time.
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
// Copyright 2021 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.
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
println!("cargo:rerun-if-changed=memory.x");
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/* Copyright 2021 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
MEMORY
|
|
||||||
{
|
|
||||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K
|
|
||||||
RAM (rwx) : ORIGIN = 0x20020000, LENGTH = 128K
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
[toolchain]
|
|
||||||
channel = "nightly-2021-03-25"
|
|
||||||
components = ["clippy", "rustfmt"]
|
|
||||||
targets = ["thumbv7em-none-eabi"]
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
// Copyright 2020-2022 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 tock_registers::register_bitfields;
|
|
||||||
|
|
||||||
register_bitfields! [u32,
|
|
||||||
// Generic or shared bitfields
|
|
||||||
pub Task [
|
|
||||||
ENABLE OFFSET(0) NUMBITS(1)
|
|
||||||
],
|
|
||||||
|
|
||||||
pub Byte [
|
|
||||||
VALUE OFFSET(0) NUMBITS(8)
|
|
||||||
],
|
|
||||||
|
|
||||||
pub Busy [
|
|
||||||
/// Asserted when AES_BUSY or DES_BUSY or HASH_BUSY are asserted or when the DIN FIFO is not empty
|
|
||||||
BUSY OFFSET(0) NUMBITS(1) [
|
|
||||||
Ready = 0,
|
|
||||||
Busy = 1
|
|
||||||
]
|
|
||||||
],
|
|
||||||
|
|
||||||
// CC_CTL register bitfields
|
|
||||||
pub CryptoMode [
|
|
||||||
/// Determines the active cryptographic engine
|
|
||||||
MODE OFFSET(0) NUMBITS(5) [
|
|
||||||
Bypass = 0,
|
|
||||||
Aes = 1,
|
|
||||||
AesToHash = 2,
|
|
||||||
AesAndHash = 3,
|
|
||||||
Des = 4,
|
|
||||||
DesToHash = 5,
|
|
||||||
DesAndHash = 6,
|
|
||||||
Hash = 7,
|
|
||||||
AesMacAndBypass = 9,
|
|
||||||
AesToHashAndDout = 10
|
|
||||||
]
|
|
||||||
],
|
|
||||||
|
|
||||||
// HOST_RGF register bitfields
|
|
||||||
pub Interrupts [
|
|
||||||
/// This interrupt is asserted when all data was delivered to DIN buffer from SRAM
|
|
||||||
SRAM_TO_DIN OFFSET(4) NUMBITS(1),
|
|
||||||
/// This interrupt is asserted when all data was delivered to SRAM buffer from DOUT
|
|
||||||
DOUT_TO_SRAM OFFSET(5) NUMBITS(1),
|
|
||||||
/// This interrupt is asserted when all data was delivered to DIN buffer from memory
|
|
||||||
MEM_TO_DIN OFFSET(6) NUMBITS(1),
|
|
||||||
/// This interrupt is asserted when all data was delivered to memory buffer from DOUT
|
|
||||||
DOUT_TO_MEM OFFSET(7) NUMBITS(1),
|
|
||||||
AXI_ERROR OFFSET(8) NUMBITS(1),
|
|
||||||
/// The PKA end of operation interrupt status
|
|
||||||
PKA_EXP OFFSET(9) NUMBITS(1),
|
|
||||||
/// The RNG interrupt status
|
|
||||||
RNG OFFSET(10) NUMBITS(1),
|
|
||||||
/// The GPR interrupt status
|
|
||||||
SYM_DMA_COMPLETED OFFSET(11) NUMBITS(1)
|
|
||||||
],
|
|
||||||
|
|
||||||
pub RgfEndianness [
|
|
||||||
/// DOUT write endianness
|
|
||||||
DOUT_WR_BG OFFSET(3) NUMBITS(1) [
|
|
||||||
LittleEndian = 0,
|
|
||||||
BigEndian = 1
|
|
||||||
],
|
|
||||||
/// DIN write endianness
|
|
||||||
DIN_RD_BG OFFSET(7) NUMBITS(1) [
|
|
||||||
LittleEndian = 0,
|
|
||||||
BigEndian = 1
|
|
||||||
],
|
|
||||||
/// DOUT write word endianness
|
|
||||||
DOUT_WR_WBG OFFSET(11) NUMBITS(1) [
|
|
||||||
LittleEndian = 0,
|
|
||||||
BigEndian = 1
|
|
||||||
],
|
|
||||||
/// DIN write word endianness
|
|
||||||
DIN_RD_WBG OFFSET(15) NUMBITS(1) [
|
|
||||||
LittleEndian = 0,
|
|
||||||
BigEndian = 1
|
|
||||||
]
|
|
||||||
],
|
|
||||||
|
|
||||||
// DIN and DOUT register bitfields
|
|
||||||
pub LliWord1 [
|
|
||||||
/// Total number of bytes to read using DMA in this entry
|
|
||||||
BYTES_NUM OFFSET(0) NUMBITS(30),
|
|
||||||
/// Indicates the first LLI entry
|
|
||||||
FIRST OFFSET(30) NUMBITS(1),
|
|
||||||
/// Indicates the last LLI entry
|
|
||||||
LAST OFFSET(31) NUMBITS(1)
|
|
||||||
],
|
|
||||||
|
|
||||||
pub HashControl [
|
|
||||||
// bit 2 is reserved but to simplify the logic we include it in the bitfield.
|
|
||||||
MODE OFFSET(0) NUMBITS(4) [
|
|
||||||
MD5 = 0,
|
|
||||||
SHA1 = 1,
|
|
||||||
SHA256 = 2,
|
|
||||||
SHA224 = 10
|
|
||||||
]
|
|
||||||
],
|
|
||||||
|
|
||||||
pub PaddingConfig [
|
|
||||||
/// Enable Padding generation. must be reset upon completion of padding.
|
|
||||||
DO_PAD OFFSET(2) NUMBITS(1)
|
|
||||||
]
|
|
||||||
];
|
|
||||||
@@ -1,283 +0,0 @@
|
|||||||
// Copyright 2019-2022 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.
|
|
||||||
|
|
||||||
//! CryptoCell 310
|
|
||||||
//!
|
|
||||||
//! Author
|
|
||||||
//! -------------------
|
|
||||||
//!
|
|
||||||
//! * Author: Jean-Michel Picod <jmichel@google.com>
|
|
||||||
//! * Date: October 1 2019
|
|
||||||
|
|
||||||
use super::bitfields;
|
|
||||||
use super::registers::{CryptoCellRegisters, NordicCC310Registers};
|
|
||||||
use super::static_ref::StaticRef;
|
|
||||||
use core::cell::Cell;
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
use rtt_target::rprintln;
|
|
||||||
|
|
||||||
const SHA256_INIT_VALUE: [u32; 8] = [
|
|
||||||
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19,
|
|
||||||
];
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
enum DigestAlgorithm {
|
|
||||||
Sha256 = 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
enum OperationMode {
|
|
||||||
Idle,
|
|
||||||
Hash,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CryptoCell310 {
|
|
||||||
registers: StaticRef<CryptoCellRegisters>,
|
|
||||||
power: StaticRef<NordicCC310Registers>,
|
|
||||||
current_op: Cell<OperationMode>,
|
|
||||||
|
|
||||||
hash_ctx: Cell<[u32; 8]>,
|
|
||||||
hash_total_size: Cell<u64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
const CC310_BASE: StaticRef<CryptoCellRegisters> =
|
|
||||||
unsafe { StaticRef::new(0x5002B000 as *const CryptoCellRegisters) };
|
|
||||||
const CC310_POWER: StaticRef<NordicCC310Registers> =
|
|
||||||
unsafe { StaticRef::new(0x5002A500 as *const NordicCC310Registers) };
|
|
||||||
|
|
||||||
// Identification "signature" for CryptoCell. According to the documentation, the value
|
|
||||||
// held by this register is a fixed value, used by Host driver to verify CryptoCell presence
|
|
||||||
// at this address.
|
|
||||||
// This value was read from a CryptoCell-310 on a nRF52840-dongle kit.
|
|
||||||
const CC310_SIGNATURE: u32 = 0x20E00000;
|
|
||||||
|
|
||||||
impl CryptoCell310 {
|
|
||||||
/// Creates a new instance of cryptocell state.
|
|
||||||
pub const fn new() -> Self {
|
|
||||||
CryptoCell310 {
|
|
||||||
registers: CC310_BASE,
|
|
||||||
power: CC310_POWER,
|
|
||||||
current_op: Cell::new(OperationMode::Idle),
|
|
||||||
|
|
||||||
hash_ctx: Cell::new(SHA256_INIT_VALUE),
|
|
||||||
hash_total_size: Cell::new(0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enable(&self) {
|
|
||||||
self.power.enable.write(bitfields::Task::ENABLE::SET);
|
|
||||||
for _i in 1..10 {
|
|
||||||
let read_signature = self.registers.host_rgf.signature.get();
|
|
||||||
if read_signature != CC310_SIGNATURE {
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
rprintln!(
|
|
||||||
"[loop {}] Invalid CC310 signature. Expected {}, got {}\n",
|
|
||||||
_i,
|
|
||||||
CC310_SIGNATURE,
|
|
||||||
read_signature
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if self.registers.host_rgf.signature.get() != CC310_SIGNATURE {
|
|
||||||
panic!("Failed to initialize CC310");
|
|
||||||
}
|
|
||||||
// Make sure everything is set to little endian
|
|
||||||
self.registers.host_rgf.endian.write(
|
|
||||||
bitfields::RgfEndianness::DOUT_WR_BG::LittleEndian
|
|
||||||
+ bitfields::RgfEndianness::DIN_RD_BG::LittleEndian
|
|
||||||
+ bitfields::RgfEndianness::DOUT_WR_WBG::LittleEndian
|
|
||||||
+ bitfields::RgfEndianness::DIN_RD_WBG::LittleEndian,
|
|
||||||
);
|
|
||||||
// Always start the clock for DMA engine. It's too hard to keep
|
|
||||||
// track of which submodule needs DMA otherwise.
|
|
||||||
self.registers
|
|
||||||
.misc
|
|
||||||
.dma_clk_enable
|
|
||||||
.write(bitfields::Task::ENABLE::SET);
|
|
||||||
self.registers.host_rgf.interrupt_mask.write(
|
|
||||||
bitfields::Interrupts::SRAM_TO_DIN::CLEAR
|
|
||||||
+ bitfields::Interrupts::DOUT_TO_SRAM::CLEAR
|
|
||||||
+ bitfields::Interrupts::MEM_TO_DIN::CLEAR
|
|
||||||
+ bitfields::Interrupts::DOUT_TO_MEM::CLEAR
|
|
||||||
+ bitfields::Interrupts::AXI_ERROR::SET
|
|
||||||
+ bitfields::Interrupts::PKA_EXP::SET
|
|
||||||
+ bitfields::Interrupts::RNG::SET
|
|
||||||
+ bitfields::Interrupts::SYM_DMA_COMPLETED::CLEAR,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn disable(&self) {
|
|
||||||
self.registers.host_rgf.interrupt_mask.set(0);
|
|
||||||
self.power.enable.write(bitfields::Task::ENABLE::CLEAR);
|
|
||||||
self.registers
|
|
||||||
.misc
|
|
||||||
.dma_clk_enable
|
|
||||||
.write(bitfields::Task::ENABLE::CLEAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear_data(&self) {
|
|
||||||
let mut ctx = self.hash_ctx.get();
|
|
||||||
ctx.iter_mut().for_each(|b| *b = 0);
|
|
||||||
self.hash_ctx.set(ctx);
|
|
||||||
self.hash_total_size.set(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds data to the current hash computation.
|
|
||||||
///
|
|
||||||
/// You have to know in advance if is this is going to be the last block, and indicate that
|
|
||||||
/// correctly. Sizes of chunks before the last need to be multiples of 64.
|
|
||||||
pub fn update(&self, data: &[u8], is_last_block: bool) {
|
|
||||||
// Start CryptoCell
|
|
||||||
self.enable();
|
|
||||||
|
|
||||||
while self.registers.ctrl.hash_busy.is_set(bitfields::Busy::BUSY) {}
|
|
||||||
while self
|
|
||||||
.registers
|
|
||||||
.ctrl
|
|
||||||
.crypto_busy
|
|
||||||
.is_set(bitfields::Busy::BUSY)
|
|
||||||
{}
|
|
||||||
while self
|
|
||||||
.registers
|
|
||||||
.din
|
|
||||||
.mem_dma_busy
|
|
||||||
.is_set(bitfields::Busy::BUSY)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// Start HASH module and configure it
|
|
||||||
self.current_op.set(OperationMode::Hash);
|
|
||||||
self.registers
|
|
||||||
.misc
|
|
||||||
.hash_clk_enable
|
|
||||||
.write(bitfields::Task::ENABLE::SET);
|
|
||||||
self.registers
|
|
||||||
.ctrl
|
|
||||||
.crypto_ctl
|
|
||||||
.write(bitfields::CryptoMode::MODE::Hash);
|
|
||||||
self.registers
|
|
||||||
.hash
|
|
||||||
.padding
|
|
||||||
.write(bitfields::Task::ENABLE::SET);
|
|
||||||
let size = self.hash_total_size.get();
|
|
||||||
self.registers.hash.hash_len_lsb.set(size as u32);
|
|
||||||
self.registers
|
|
||||||
.hash
|
|
||||||
.hash_len_msb
|
|
||||||
.set(size.wrapping_shr(32) as u32);
|
|
||||||
self.registers
|
|
||||||
.hash
|
|
||||||
.control
|
|
||||||
.set(DigestAlgorithm::Sha256 as u32);
|
|
||||||
|
|
||||||
// Digest must be set backwards because writing to HASH[0]
|
|
||||||
// starts computation
|
|
||||||
let mut digest = self.hash_ctx.get();
|
|
||||||
for i in (0..digest.len()).rev() {
|
|
||||||
self.registers.hash.hash[i].set(digest[i]);
|
|
||||||
}
|
|
||||||
while self.registers.ctrl.hash_busy.is_set(bitfields::Busy::BUSY) {}
|
|
||||||
|
|
||||||
// Process data
|
|
||||||
if !data.is_empty() {
|
|
||||||
if is_last_block {
|
|
||||||
self.registers
|
|
||||||
.hash
|
|
||||||
.auto_hw_padding
|
|
||||||
.write(bitfields::Task::ENABLE::SET);
|
|
||||||
}
|
|
||||||
self.registers.din.src_lli_word0.set(data.as_ptr() as u32);
|
|
||||||
self.registers
|
|
||||||
.din
|
|
||||||
.src_lli_word1
|
|
||||||
.write(bitfields::LliWord1::BYTES_NUM.val(data.len() as u32));
|
|
||||||
while !self
|
|
||||||
.registers
|
|
||||||
.host_rgf
|
|
||||||
.interrupts
|
|
||||||
.is_set(bitfields::Interrupts::MEM_TO_DIN)
|
|
||||||
{}
|
|
||||||
self.registers
|
|
||||||
.host_rgf
|
|
||||||
.interrupt_clear
|
|
||||||
.write(bitfields::Interrupts::MEM_TO_DIN::SET);
|
|
||||||
} else {
|
|
||||||
// use DO_PAD to complete padding of previous operation
|
|
||||||
self.registers
|
|
||||||
.hash
|
|
||||||
.pad_config
|
|
||||||
.write(bitfields::PaddingConfig::DO_PAD::SET);
|
|
||||||
}
|
|
||||||
while self
|
|
||||||
.registers
|
|
||||||
.ctrl
|
|
||||||
.crypto_busy
|
|
||||||
.is_set(bitfields::Busy::BUSY)
|
|
||||||
{}
|
|
||||||
while self
|
|
||||||
.registers
|
|
||||||
.din
|
|
||||||
.mem_dma_busy
|
|
||||||
.is_set(bitfields::Busy::BUSY)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// Update context and total size
|
|
||||||
for i in (0..digest.len()).rev() {
|
|
||||||
digest[i] = self.registers.hash.hash[i].get();
|
|
||||||
}
|
|
||||||
self.hash_ctx.set(digest);
|
|
||||||
let new_size: u64 = ((self.registers.hash.hash_len_msb.get() as u64) << 32)
|
|
||||||
+ (self.registers.hash.hash_len_lsb.get() as u64);
|
|
||||||
self.hash_total_size.set(new_size);
|
|
||||||
|
|
||||||
// Disable HASH module
|
|
||||||
self.registers
|
|
||||||
.hash
|
|
||||||
.padding
|
|
||||||
.write(bitfields::Task::ENABLE::SET);
|
|
||||||
self.registers
|
|
||||||
.hash
|
|
||||||
.auto_hw_padding
|
|
||||||
.write(bitfields::Task::ENABLE::CLEAR);
|
|
||||||
self.registers
|
|
||||||
.hash
|
|
||||||
.pad_config
|
|
||||||
.write(bitfields::PaddingConfig::DO_PAD::CLEAR);
|
|
||||||
while self
|
|
||||||
.registers
|
|
||||||
.ctrl
|
|
||||||
.crypto_busy
|
|
||||||
.is_set(bitfields::Busy::BUSY)
|
|
||||||
{}
|
|
||||||
self.registers
|
|
||||||
.misc
|
|
||||||
.hash_clk_enable
|
|
||||||
.write(bitfields::Task::ENABLE::CLEAR);
|
|
||||||
|
|
||||||
self.disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clears the data for potential reuse, and returns the result.
|
|
||||||
pub fn finalize_and_clear(&self) -> [u8; 32] {
|
|
||||||
use byteorder::{BigEndian, ByteOrder};
|
|
||||||
let words = self.hash_ctx.get();
|
|
||||||
let mut bytes = [0u8; 32];
|
|
||||||
for (i, word) in words.iter().enumerate() {
|
|
||||||
BigEndian::write_u32(&mut bytes[4 * i..4 * i + 4], *word);
|
|
||||||
}
|
|
||||||
self.clear_data();
|
|
||||||
bytes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,176 +0,0 @@
|
|||||||
// Copyright 2021-2022 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_main]
|
|
||||||
#![no_std]
|
|
||||||
|
|
||||||
mod bitfields;
|
|
||||||
mod crypto_cell;
|
|
||||||
mod registers;
|
|
||||||
mod static_ref;
|
|
||||||
|
|
||||||
extern crate cortex_m;
|
|
||||||
extern crate cortex_m_rt as rt;
|
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
|
||||||
use core::convert::TryInto;
|
|
||||||
use core::ptr;
|
|
||||||
use cortex_m::asm;
|
|
||||||
use panic_abort as _;
|
|
||||||
use rt::entry;
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
use rtt_target::{rprintln, rtt_init_print};
|
|
||||||
|
|
||||||
/// Size of a flash page in bytes.
|
|
||||||
const PAGE_SIZE: usize = 0x1000;
|
|
||||||
|
|
||||||
/// A flash page.
|
|
||||||
type Page = [u8; PAGE_SIZE];
|
|
||||||
|
|
||||||
/// Reads a page of memory.
|
|
||||||
unsafe fn read_page(address: usize) -> Page {
|
|
||||||
debug_assert!(address % PAGE_SIZE == 0);
|
|
||||||
let address_pointer = address as *const Page;
|
|
||||||
ptr::read(address_pointer)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parsed metadata for a firmware partition.
|
|
||||||
struct Metadata {
|
|
||||||
checksum: [u8; 32],
|
|
||||||
timestamp: u32,
|
|
||||||
address: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Metadata {
|
|
||||||
pub const DATA_LEN: usize = 40;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads the metadata from a flash page.
|
|
||||||
impl From<Page> for Metadata {
|
|
||||||
fn from(page: Page) -> Self {
|
|
||||||
Metadata {
|
|
||||||
checksum: page[0..32].try_into().unwrap(),
|
|
||||||
timestamp: LittleEndian::read_u32(&page[32..36]),
|
|
||||||
address: LittleEndian::read_u32(&page[36..Metadata::DATA_LEN]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Location of a firmware partition's data.
|
|
||||||
struct BootPartition {
|
|
||||||
firmware_address: usize,
|
|
||||||
metadata_address: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BootPartition {
|
|
||||||
const FIRMWARE_LENGTH: usize = 0x00040000;
|
|
||||||
|
|
||||||
/// Reads the metadata, returns the timestamp if all checks pass.
|
|
||||||
pub fn read_timestamp(&self) -> Result<u32, ()> {
|
|
||||||
let metadata_page = unsafe { read_page(self.metadata_address) };
|
|
||||||
let hash_value = self.compute_upgrade_hash(&metadata_page);
|
|
||||||
let metadata = Metadata::from(metadata_page);
|
|
||||||
if self.firmware_address != metadata.address as usize {
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
rprintln!(
|
|
||||||
"Firmware address mismatch: expected 0x{:08X}, metadata 0x{:08X}",
|
|
||||||
self.firmware_address,
|
|
||||||
metadata.address as usize
|
|
||||||
);
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
if hash_value != metadata.checksum {
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
rprintln!("Hash mismatch");
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
Ok(metadata.timestamp)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the SHA256 of metadata information and partition data.
|
|
||||||
///
|
|
||||||
/// Assumes that firmware address and length are divisible by the page size.
|
|
||||||
/// This is the hardware implementation on the cryptocell.
|
|
||||||
#[allow(clippy::assertions_on_constants)]
|
|
||||||
fn compute_upgrade_hash(&self, metadata_page: &[u8]) -> [u8; 32] {
|
|
||||||
debug_assert!(self.firmware_address % PAGE_SIZE == 0);
|
|
||||||
debug_assert!(BootPartition::FIRMWARE_LENGTH % PAGE_SIZE == 0);
|
|
||||||
let cc310 = crypto_cell::CryptoCell310::new();
|
|
||||||
for page_offset in (0..BootPartition::FIRMWARE_LENGTH).step_by(PAGE_SIZE) {
|
|
||||||
let page = unsafe { read_page(self.firmware_address + page_offset) };
|
|
||||||
cc310.update(&page, false);
|
|
||||||
}
|
|
||||||
cc310.update(&metadata_page[32..Metadata::DATA_LEN], true);
|
|
||||||
cc310.finalize_and_clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Jump to the firmware.
|
|
||||||
pub fn boot(&self) -> ! {
|
|
||||||
let address = self.firmware_address;
|
|
||||||
|
|
||||||
// Clear any pending Cryptocell interrupt in NVIC
|
|
||||||
let peripherals = cortex_m::Peripherals::take().unwrap();
|
|
||||||
unsafe {
|
|
||||||
// We could only clear cryptocell interrupts, but let's clean up before booting.
|
|
||||||
// Example code to clear more specifically:
|
|
||||||
// const CC310_IRQ: u16 = 42;
|
|
||||||
// peripherals.NVIC.icpr[usize::from(CC310_IRQ / 32)].write(1 << (CC310_IRQ % 32));
|
|
||||||
peripherals.NVIC.icer[0].write(0xffff_ffff);
|
|
||||||
peripherals.NVIC.icpr[0].write(0xffff_ffff);
|
|
||||||
peripherals.NVIC.icer[1].write(0xffff_ffff);
|
|
||||||
peripherals.NVIC.icpr[1].write(0xffff_ffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
rprintln!("Boot jump to {:08X}", address);
|
|
||||||
let address_pointer = address as *const u32;
|
|
||||||
// https://docs.rs/cortex-m/0.7.2/cortex_m/asm/fn.bootload.html
|
|
||||||
unsafe { asm::bootload(address_pointer) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[entry]
|
|
||||||
fn main() -> ! {
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
rtt_init_print!();
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
rprintln!("Starting bootloader");
|
|
||||||
let partition_a = BootPartition {
|
|
||||||
firmware_address: 0x20000,
|
|
||||||
metadata_address: 0x4000,
|
|
||||||
};
|
|
||||||
let partition_b = BootPartition {
|
|
||||||
firmware_address: 0x60000,
|
|
||||||
metadata_address: 0x5000,
|
|
||||||
};
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
rprintln!("Reading partition A");
|
|
||||||
let timestamp_a = partition_a.read_timestamp();
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
rprintln!("Reading partition B");
|
|
||||||
let timestamp_b = partition_b.read_timestamp();
|
|
||||||
|
|
||||||
match (timestamp_a, timestamp_b) {
|
|
||||||
(Ok(t1), Ok(t2)) => {
|
|
||||||
if t1 >= t2 {
|
|
||||||
partition_a.boot()
|
|
||||||
} else {
|
|
||||||
partition_b.boot()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(Ok(_), Err(_)) => partition_a.boot(),
|
|
||||||
(Err(_), Ok(_)) => partition_b.boot(),
|
|
||||||
(Err(_), Err(_)) => panic!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
// Copyright 2020-2022 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::bitfields::{
|
|
||||||
Busy, CryptoMode, HashControl, Interrupts, LliWord1, PaddingConfig, RgfEndianness, Task,
|
|
||||||
};
|
|
||||||
use tock_registers::register_structs;
|
|
||||||
use tock_registers::registers::{ReadOnly, ReadWrite, WriteOnly};
|
|
||||||
|
|
||||||
register_structs! {
|
|
||||||
pub CryptoCellControlRegisters {
|
|
||||||
/// Defines the cryptographic flow
|
|
||||||
(0x0000 => pub crypto_ctl: WriteOnly<u32, CryptoMode::Register>),
|
|
||||||
(0x0004 => _reserved0),
|
|
||||||
/// This register is set whent the cryptographic core is busy
|
|
||||||
(0x0010 => pub crypto_busy: ReadOnly<u32, Busy::Register>),
|
|
||||||
(0x0014 => _reserved1),
|
|
||||||
/// This register is set when the Hash engine is busy
|
|
||||||
(0x001C => pub hash_busy: ReadOnly<u32, Busy::Register>),
|
|
||||||
(0x0020 => @END),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register_structs! {
|
|
||||||
pub CryptoCellDinRegisters {
|
|
||||||
(0x0000 => _reserved0),
|
|
||||||
/// Indicates whether memoty (AXI) source DMA (DIN) is busy
|
|
||||||
(0x0020 => pub mem_dma_busy: ReadOnly<u32, Busy::Register>),
|
|
||||||
(0x0024 => _reserved1),
|
|
||||||
/// This register is used in direct LLI mode - holds the location of the data source
|
|
||||||
/// in the memory (AXI)
|
|
||||||
(0x0028 => pub src_lli_word0: WriteOnly<u32>),
|
|
||||||
/// This register is used in direct LLI mode - holds the number of bytes to be read
|
|
||||||
/// from the memory (AXI).
|
|
||||||
/// Writing to this register triggers the DMA.
|
|
||||||
(0x002C => pub src_lli_word1: WriteOnly<u32, LliWord1::Register>),
|
|
||||||
(0x0030 => @END),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register_structs! {
|
|
||||||
pub CryptoCellHashRegisters {
|
|
||||||
/// Write initial hash value or read final hash value
|
|
||||||
(0x0000 => pub hash: [ReadWrite<u32>; 9]),
|
|
||||||
(0x0024 => _reserved0),
|
|
||||||
/// HW padding automatically activated by engine.
|
|
||||||
/// For the special case of ZERO bytes data vector this register should not be used! instead use HASH_PAD_CFG
|
|
||||||
(0x0044 => pub auto_hw_padding: WriteOnly<u32, Task::Register>),
|
|
||||||
(0x0048 => _reserved1),
|
|
||||||
/// Selects which HASH mode to run
|
|
||||||
(0x0180 => pub control: ReadWrite<u32, HashControl::Register>),
|
|
||||||
/// This register enables the hash hw padding.
|
|
||||||
(0x0184 => pub padding: ReadWrite<u32, Task::Register>),
|
|
||||||
/// HASH_PAD_CFG Register.
|
|
||||||
(0x0188 => pub pad_config: ReadWrite<u32, PaddingConfig::Register>),
|
|
||||||
/// This register hold the length of current hash operation
|
|
||||||
(0x018C => pub hash_len_lsb: ReadWrite<u32>),
|
|
||||||
/// This register hold the length of current hash operation
|
|
||||||
(0x0190 => pub hash_len_msb: ReadWrite<u32>),
|
|
||||||
(0x0194 => @END),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register_structs! {
|
|
||||||
pub CryptoCellHostRgfRegisters {
|
|
||||||
/// The Interrupt Request register.
|
|
||||||
/// Each bit of this register holds the interrupt status of a single interrupt source.
|
|
||||||
(0x0000 => pub interrupts: ReadOnly<u32, Interrupts::Register>),
|
|
||||||
/// The Interrupt Mask register. Each bit of this register holds the mask of a single
|
|
||||||
/// interrupt source.
|
|
||||||
(0x0004 => pub interrupt_mask: ReadWrite<u32, Interrupts::Register>),
|
|
||||||
/// Interrupt Clear Register
|
|
||||||
(0x0008 => pub interrupt_clear: WriteOnly<u32, Interrupts::Register>),
|
|
||||||
/// This register defines the endianness of the Host-accessible registers.
|
|
||||||
(0x000C => pub endian: ReadWrite<u32, RgfEndianness::Register>),
|
|
||||||
(0x0010 => _reserved0),
|
|
||||||
/// This register holds the CryptoCell product signature.
|
|
||||||
(0x0024 => pub signature: ReadOnly<u32>),
|
|
||||||
(0x0028 => @END),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register_structs! {
|
|
||||||
pub CryptoCellMiscRegisters {
|
|
||||||
(0x0000 => _reserved0),
|
|
||||||
/// The HASH clock enable register
|
|
||||||
(0x0018 => pub hash_clk_enable: ReadWrite<u32, Task::Register>),
|
|
||||||
/// The PKA clock enable register
|
|
||||||
(0x001C => _reserved1),
|
|
||||||
/// The DMA clock enable register
|
|
||||||
(0x0020 => pub dma_clk_enable: ReadWrite<u32, Task::Register>),
|
|
||||||
/// the CryptoCell clocks' status register
|
|
||||||
(0x0024 => @END),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register_structs! {
|
|
||||||
pub NordicCC310Registers {
|
|
||||||
(0x0000 => pub enable: ReadWrite<u32, Task::Register>),
|
|
||||||
(0x0004 => @END),
|
|
||||||
},
|
|
||||||
|
|
||||||
pub CryptoCellRegisters {
|
|
||||||
(0x0000 => _reserved0),
|
|
||||||
/// HASH registers
|
|
||||||
/// - Base address: 0x0640
|
|
||||||
(0x0640 => pub hash: CryptoCellHashRegisters),
|
|
||||||
(0x07D4 => _reserved1),
|
|
||||||
/// Misc registers
|
|
||||||
/// - Base address: 0x0800
|
|
||||||
(0x0800 => pub misc: CryptoCellMiscRegisters),
|
|
||||||
(0x0824 => _reserved2),
|
|
||||||
/// CryptoCell control registers
|
|
||||||
/// - Base address: 0x0900
|
|
||||||
(0x0900 => pub ctrl: CryptoCellControlRegisters),
|
|
||||||
(0x0920 => _reserved3),
|
|
||||||
/// HOST_RGF registers
|
|
||||||
/// - Base address: 0x0A00
|
|
||||||
(0x0A00 => pub host_rgf: CryptoCellHostRgfRegisters),
|
|
||||||
(0x0A28 => _reserved4),
|
|
||||||
/// DIN registers
|
|
||||||
/// - Base address: 0x0C00
|
|
||||||
(0x0C00 => pub din: CryptoCellDinRegisters),
|
|
||||||
(0x0C30 => @END),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
//! Wrapper type for safe pointers to static memory.
|
|
||||||
//!
|
|
||||||
//! Imported from:
|
|
||||||
//! https://github.com/tock/tock/blob/master/kernel/src/utilities/static_ref.rs
|
|
||||||
|
|
||||||
use core::ops::Deref;
|
|
||||||
|
|
||||||
/// A pointer to statically allocated mutable data such as memory mapped I/O
|
|
||||||
/// registers.
|
|
||||||
///
|
|
||||||
/// This is a simple wrapper around a raw pointer that encapsulates an unsafe
|
|
||||||
/// dereference in a safe manner. It serve the role of creating a `&'static T`
|
|
||||||
/// given a raw address and acts similarly to `extern` definitions, except
|
|
||||||
/// `StaticRef` is subject to module and crate boundaries, while `extern`
|
|
||||||
/// definitions can be imported anywhere.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct StaticRef<T> {
|
|
||||||
ptr: *const T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> StaticRef<T> {
|
|
||||||
/// Create a new `StaticRef` from a raw pointer
|
|
||||||
///
|
|
||||||
/// ## Safety
|
|
||||||
///
|
|
||||||
/// Callers must pass in a reference to statically allocated memory which
|
|
||||||
/// does not overlap with other values.
|
|
||||||
pub const unsafe fn new(ptr: *const T) -> StaticRef<T> {
|
|
||||||
StaticRef { ptr }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Clone for StaticRef<T> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
StaticRef { ptr: self.ptr }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Copy for StaticRef<T> {}
|
|
||||||
|
|
||||||
impl<T> Deref for StaticRef<T> {
|
|
||||||
type Target = T;
|
|
||||||
fn deref(&self) -> &'static T {
|
|
||||||
unsafe { &*self.ptr }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
49
build.rs
49
build.rs
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2019-2021 Google LLC
|
// Copyright 2019 Google LLC
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
@@ -12,24 +12,15 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
extern crate alloc;
|
use std::env;
|
||||||
|
|
||||||
use openssl::{bn, ec, nid};
|
|
||||||
use sk_cbor::cbor_map;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Write};
|
use std::io::Read;
|
||||||
|
use std::io::Write;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::{env, fs};
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
const UPGRADE_FILE: &str = "crypto_data/opensk_upgrade_pub.pem";
|
|
||||||
println!("cargo:rerun-if-changed=crypto_data/aaguid.txt");
|
println!("cargo:rerun-if-changed=crypto_data/aaguid.txt");
|
||||||
println!("cargo:rerun-if-changed={}", UPGRADE_FILE);
|
|
||||||
println!("cargo:rerun-if-changed=layout.ld");
|
|
||||||
println!("cargo:rerun-if-changed=nrf52840_layout.ld");
|
|
||||||
println!("cargo:rerun-if-changed=nrf52840_layout_a.ld");
|
|
||||||
println!("cargo:rerun-if-changed=nrf52840_layout_b.ld");
|
|
||||||
|
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
let aaguid_bin_path = Path::new(&out_dir).join("opensk_aaguid.bin");
|
let aaguid_bin_path = Path::new(&out_dir).join("opensk_aaguid.bin");
|
||||||
@@ -41,36 +32,4 @@ fn main() {
|
|||||||
content.truncate(36);
|
content.truncate(36);
|
||||||
let aaguid = Uuid::parse_str(&content).unwrap();
|
let aaguid = Uuid::parse_str(&content).unwrap();
|
||||||
aaguid_bin_file.write_all(aaguid.as_bytes()).unwrap();
|
aaguid_bin_file.write_all(aaguid.as_bytes()).unwrap();
|
||||||
|
|
||||||
// COSE encoding the public key, then write it out.
|
|
||||||
let pem_bytes = fs::read(UPGRADE_FILE).unwrap();
|
|
||||||
let ec_key = ec::EcKey::public_key_from_pem(&pem_bytes).ok().unwrap();
|
|
||||||
let group = ec::EcGroup::from_curve_name(nid::Nid::X9_62_PRIME256V1).unwrap();
|
|
||||||
let conversion_form = ec::PointConversionForm::UNCOMPRESSED;
|
|
||||||
let mut ctx = bn::BigNumContext::new().unwrap();
|
|
||||||
let raw_bytes = ec_key
|
|
||||||
.public_key()
|
|
||||||
.to_bytes(&group, conversion_form, &mut ctx)
|
|
||||||
.unwrap();
|
|
||||||
const POINT_LEN: usize = 32;
|
|
||||||
assert_eq!(raw_bytes.len(), 1 + 2 * POINT_LEN);
|
|
||||||
assert_eq!(raw_bytes[0], 0x04);
|
|
||||||
let x_bytes = &raw_bytes[1..][..POINT_LEN];
|
|
||||||
let y_bytes = &raw_bytes[1 + POINT_LEN..][..POINT_LEN];
|
|
||||||
|
|
||||||
const EC2_KEY_TYPE: i64 = 2;
|
|
||||||
const P_256_CURVE: i64 = 1;
|
|
||||||
const ES256_ALGORITHM: i64 = -7;
|
|
||||||
let pub_key_cbor = sk_cbor::cbor_map! {
|
|
||||||
1 => EC2_KEY_TYPE,
|
|
||||||
3 => ES256_ALGORITHM,
|
|
||||||
-1 => P_256_CURVE,
|
|
||||||
-2 => x_bytes,
|
|
||||||
-3 => y_bytes,
|
|
||||||
};
|
|
||||||
let mut cbor_bytes = vec![];
|
|
||||||
sk_cbor::writer::write(pub_key_cbor, &mut cbor_bytes).unwrap();
|
|
||||||
let upgrade_pubkey_path = Path::new(&out_dir).join("opensk_upgrade_pubkey_cbor.bin");
|
|
||||||
let mut upgrade_pub_bin_file = File::create(&upgrade_pubkey_path).unwrap();
|
|
||||||
upgrade_pub_bin_file.write_all(&cbor_bytes).unwrap();
|
|
||||||
}
|
}
|
||||||
|
|||||||
514
deploy.py
514
deploy.py
@@ -26,8 +26,6 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import time
|
|
||||||
from typing import Dict, List, Tuple
|
|
||||||
|
|
||||||
import colorama
|
import colorama
|
||||||
from six.moves import input
|
from six.moves import input
|
||||||
@@ -37,9 +35,6 @@ from tockloader import tbfh
|
|||||||
from tockloader import tockloader as loader
|
from tockloader import tockloader as loader
|
||||||
from tockloader.exceptions import TockLoaderException
|
from tockloader.exceptions import TockLoaderException
|
||||||
|
|
||||||
import tools.configure
|
|
||||||
from tools.deploy_partition import create_metadata, pad_to
|
|
||||||
|
|
||||||
PROGRAMMERS = frozenset(("jlink", "openocd", "pyocd", "nordicdfu", "none"))
|
PROGRAMMERS = frozenset(("jlink", "openocd", "pyocd", "nordicdfu", "none"))
|
||||||
|
|
||||||
# This structure allows us to support out-of-tree boards as well as (in the
|
# This structure allows us to support out-of-tree boards as well as (in the
|
||||||
@@ -55,19 +50,12 @@ OpenSKBoard = collections.namedtuple(
|
|||||||
"page_size",
|
"page_size",
|
||||||
# Flash address at which the kernel will be written
|
# Flash address at which the kernel will be written
|
||||||
"kernel_address",
|
"kernel_address",
|
||||||
# Set to None if padding is not required for the board.
|
# Set to None is padding is not required for the board.
|
||||||
# This creates a fake Tock OS application that starts at the
|
# This creates a fake Tock OS application that starts at the
|
||||||
# address specified by this parameter (must match the `prog` value
|
# address specified by this parameter (must match the `prog` value
|
||||||
# specified on the board's `layout.ld` file) and will end at
|
# specified on the board's `layout.ld` file) and will end at
|
||||||
# `app_address`.
|
# `app_address`.
|
||||||
"padding_address",
|
"padding_address",
|
||||||
# If present, enforce that the firmware image equals this value,
|
|
||||||
# padding it with 0xFF bytes.
|
|
||||||
"firmware_size",
|
|
||||||
# Set to None if metadata is not required for the board.
|
|
||||||
# Writes the metadata that is checked by the custom bootloader for
|
|
||||||
# upgradable board.
|
|
||||||
"metadata_address",
|
|
||||||
# Linker script to produce a working app for this board
|
# Linker script to produce a working app for this board
|
||||||
"app_ldscript",
|
"app_ldscript",
|
||||||
# Flash address at which the app should be written
|
# Flash address at which the app should be written
|
||||||
@@ -95,18 +83,18 @@ OpenSKBoard = collections.namedtuple(
|
|||||||
"nordic_dfu",
|
"nordic_dfu",
|
||||||
])
|
])
|
||||||
|
|
||||||
nrf52840dk_opensk_board = OpenSKBoard(
|
SUPPORTED_BOARDS = {
|
||||||
path="third_party/tock/boards/nordic/nrf52840dk_opensk",
|
"nrf52840dk":
|
||||||
|
OpenSKBoard(
|
||||||
|
path="third_party/tock/boards/nordic/nrf52840dk",
|
||||||
arch="thumbv7em-none-eabi",
|
arch="thumbv7em-none-eabi",
|
||||||
page_size=4096,
|
page_size=4096,
|
||||||
kernel_address=0,
|
kernel_address=0,
|
||||||
padding_address=0x30000,
|
padding_address=0x30000,
|
||||||
firmware_size=None,
|
|
||||||
metadata_address=None,
|
|
||||||
app_ldscript="nrf52840_layout.ld",
|
app_ldscript="nrf52840_layout.ld",
|
||||||
app_address=0x40000,
|
app_address=0x40000,
|
||||||
storage_address=0xC0000,
|
storage_address=0xC0000,
|
||||||
storage_size=0x14000,
|
storage_size=0x40000,
|
||||||
pyocd_target="nrf52840",
|
pyocd_target="nrf52840",
|
||||||
openocd_board="nordic_nrf52840_dongle.cfg",
|
openocd_board="nordic_nrf52840_dongle.cfg",
|
||||||
openocd_options=[],
|
openocd_options=[],
|
||||||
@@ -114,55 +102,77 @@ nrf52840dk_opensk_board = OpenSKBoard(
|
|||||||
jlink_if="swd",
|
jlink_if="swd",
|
||||||
jlink_device="nrf52840_xxaa",
|
jlink_device="nrf52840_xxaa",
|
||||||
nordic_dfu=False,
|
nordic_dfu=False,
|
||||||
)
|
),
|
||||||
|
"nrf52840_dongle":
|
||||||
SUPPORTED_BOARDS = {
|
OpenSKBoard(
|
||||||
"nrf52840dk_opensk":
|
path="third_party/tock/boards/nordic/nrf52840_dongle",
|
||||||
nrf52840dk_opensk_board,
|
arch="thumbv7em-none-eabi",
|
||||||
"nrf52840dk_opensk_a":
|
page_size=4096,
|
||||||
nrf52840dk_opensk_board._replace(
|
kernel_address=0,
|
||||||
path=nrf52840dk_opensk_board.path + "_a",
|
padding_address=0x30000,
|
||||||
kernel_address=0x20000,
|
app_ldscript="nrf52840_layout.ld",
|
||||||
padding_address=None,
|
|
||||||
firmware_size=0x40000,
|
|
||||||
metadata_address=0x4000,
|
|
||||||
app_ldscript="nrf52840_layout_a.ld",
|
|
||||||
app_address=0x40000,
|
app_address=0x40000,
|
||||||
|
storage_address=0xC0000,
|
||||||
|
storage_size=0x40000,
|
||||||
|
pyocd_target="nrf52840",
|
||||||
|
openocd_board="nordic_nrf52840_dongle.cfg",
|
||||||
|
openocd_options=[],
|
||||||
|
openocd_commands={},
|
||||||
|
jlink_if="swd",
|
||||||
|
jlink_device="nrf52840_xxaa",
|
||||||
|
nordic_dfu=False,
|
||||||
),
|
),
|
||||||
"nrf52840dk_opensk_b":
|
|
||||||
nrf52840dk_opensk_board._replace(
|
|
||||||
path=nrf52840dk_opensk_board.path + "_b",
|
|
||||||
kernel_address=0x60000,
|
|
||||||
padding_address=None,
|
|
||||||
firmware_size=0x40000,
|
|
||||||
metadata_address=0x5000,
|
|
||||||
app_ldscript="nrf52840_layout_b.ld",
|
|
||||||
app_address=0x80000,
|
|
||||||
),
|
|
||||||
"nrf52840_dongle_opensk":
|
|
||||||
nrf52840dk_opensk_board._replace(
|
|
||||||
path="third_party/tock/boards/nordic/nrf52840_dongle_opensk",),
|
|
||||||
"nrf52840_dongle_dfu":
|
"nrf52840_dongle_dfu":
|
||||||
nrf52840dk_opensk_board._replace(
|
OpenSKBoard(
|
||||||
path="third_party/tock/boards/nordic/nrf52840_dongle_dfu",
|
path="third_party/tock/boards/nordic/nrf52840_dongle_dfu",
|
||||||
|
arch="thumbv7em-none-eabi",
|
||||||
|
page_size=4096,
|
||||||
kernel_address=0x1000,
|
kernel_address=0x1000,
|
||||||
|
padding_address=0x30000,
|
||||||
|
app_ldscript="nrf52840_layout.ld",
|
||||||
|
app_address=0x40000,
|
||||||
|
storage_address=0xC0000,
|
||||||
|
storage_size=0x40000,
|
||||||
|
pyocd_target="nrf52840",
|
||||||
|
openocd_board="nordic_nrf52840_dongle.cfg",
|
||||||
|
openocd_options=[],
|
||||||
|
openocd_commands={},
|
||||||
|
jlink_if="swd",
|
||||||
|
jlink_device="nrf52840_xxaa",
|
||||||
nordic_dfu=True,
|
nordic_dfu=True,
|
||||||
),
|
),
|
||||||
"nrf52840_mdk_dfu":
|
"nrf52840_mdk_dfu":
|
||||||
nrf52840dk_opensk_board._replace(
|
OpenSKBoard(
|
||||||
path="third_party/tock/boards/nordic/nrf52840_mdk_dfu",
|
path="third_party/tock/boards/nordic/nrf52840_mdk_dfu",
|
||||||
|
arch="thumbv7em-none-eabi",
|
||||||
|
page_size=4096,
|
||||||
kernel_address=0x1000,
|
kernel_address=0x1000,
|
||||||
|
padding_address=0x30000,
|
||||||
|
app_ldscript="nrf52840_layout.ld",
|
||||||
|
app_address=0x40000,
|
||||||
|
storage_address=0xC0000,
|
||||||
|
storage_size=0x40000,
|
||||||
|
pyocd_target="nrf52840",
|
||||||
|
openocd_board="nordic_nrf52840_dongle.cfg",
|
||||||
|
openocd_options=[],
|
||||||
|
openocd_commands={},
|
||||||
|
jlink_if="swd",
|
||||||
|
jlink_device="nrf52840_xxaa",
|
||||||
nordic_dfu=True,
|
nordic_dfu=True,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# The STACK_SIZE value below must match the one used in the linker script
|
||||||
|
# used by the board.
|
||||||
|
# e.g. for Nordic nRF52840 boards the file is `nrf52840_layout.ld`.
|
||||||
|
STACK_SIZE = 0x4000
|
||||||
|
|
||||||
# The following value must match the one used in the file
|
# The following value must match the one used in the file
|
||||||
# `src/entry_point.rs`
|
# `src/entry_point.rs`
|
||||||
APP_HEAP_SIZE = 90000
|
APP_HEAP_SIZE = 90000
|
||||||
|
|
||||||
|
|
||||||
def get_supported_boards() -> Tuple[str]:
|
def get_supported_boards():
|
||||||
"""Returns a tuple all valid supported boards."""
|
|
||||||
boards = []
|
boards = []
|
||||||
for name, props in SUPPORTED_BOARDS.items():
|
for name, props in SUPPORTED_BOARDS.items():
|
||||||
if all((os.path.exists(os.path.join(props.path, "Cargo.toml")),
|
if all((os.path.exists(os.path.join(props.path, "Cargo.toml")),
|
||||||
@@ -171,28 +181,28 @@ def get_supported_boards() -> Tuple[str]:
|
|||||||
return tuple(set(boards))
|
return tuple(set(boards))
|
||||||
|
|
||||||
|
|
||||||
def fatal(msg: str):
|
def fatal(msg):
|
||||||
print(f"{colorama.Fore.RED + colorama.Style.BRIGHT}fatal:"
|
print(f"{colorama.Fore.RED + colorama.Style.BRIGHT}fatal:"
|
||||||
f"{colorama.Style.RESET_ALL} {msg}")
|
f"{colorama.Style.RESET_ALL} {msg}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def error(msg: str):
|
def error(msg):
|
||||||
print(f"{colorama.Fore.RED}error:{colorama.Style.RESET_ALL} {msg}")
|
print(f"{colorama.Fore.RED}error:{colorama.Style.RESET_ALL} {msg}")
|
||||||
|
|
||||||
|
|
||||||
def info(msg: str):
|
def info(msg):
|
||||||
print(f"{colorama.Fore.GREEN + colorama.Style.BRIGHT}info:"
|
print(f"{colorama.Fore.GREEN + colorama.Style.BRIGHT}info:"
|
||||||
f"{colorama.Style.RESET_ALL} {msg}")
|
f"{colorama.Style.RESET_ALL} {msg}")
|
||||||
|
|
||||||
|
|
||||||
def assert_mandatory_binary(binary_name: str):
|
def assert_mandatory_binary(binary):
|
||||||
if not shutil.which(binary_name):
|
if not shutil.which(binary):
|
||||||
fatal((f"Couldn't find {binary_name} binary. Make sure it is installed and "
|
fatal((f"Couldn't find {binary} binary. Make sure it is installed and "
|
||||||
"that your PATH is set correctly."))
|
"that your PATH is set correctly."))
|
||||||
|
|
||||||
|
|
||||||
def assert_python_library(module: str):
|
def assert_python_library(module):
|
||||||
try:
|
try:
|
||||||
__import__(module)
|
__import__(module)
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
@@ -238,18 +248,6 @@ class RemoveConstAction(argparse.Action):
|
|||||||
|
|
||||||
|
|
||||||
class OpenSKInstaller:
|
class OpenSKInstaller:
|
||||||
"""Checks, builds and installs various parts of OpenSK.
|
|
||||||
|
|
||||||
This module can perform the following tasks:
|
|
||||||
- build and install Tock OS
|
|
||||||
- check, build and install the main ctap2 application
|
|
||||||
- build and install example applications
|
|
||||||
- write padding
|
|
||||||
- erase apps and persistent storage
|
|
||||||
- write metadata entries for upgradable boards
|
|
||||||
|
|
||||||
OpenSKInstaller(args).run()
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
self.args = args
|
self.args = args
|
||||||
@@ -257,7 +255,6 @@ class OpenSKInstaller:
|
|||||||
self.tab_folder = os.path.join("target", "tab")
|
self.tab_folder = os.path.join("target", "tab")
|
||||||
board = SUPPORTED_BOARDS[self.args.board]
|
board = SUPPORTED_BOARDS[self.args.board]
|
||||||
self.tockloader_default_args = argparse.Namespace(
|
self.tockloader_default_args = argparse.Namespace(
|
||||||
app_address=board.app_address,
|
|
||||||
arch=board.arch,
|
arch=board.arch,
|
||||||
board=self.args.board,
|
board=self.args.board,
|
||||||
bundle_apps=False,
|
bundle_apps=False,
|
||||||
@@ -270,7 +267,7 @@ class OpenSKInstaller:
|
|||||||
jlink_speed=1200,
|
jlink_speed=1200,
|
||||||
openocd=self.args.programmer == "openocd",
|
openocd=self.args.programmer == "openocd",
|
||||||
openocd_board=board.openocd_board,
|
openocd_board=board.openocd_board,
|
||||||
openocd_cmd=self.args.openocd_cmd,
|
openocd_cmd="openocd",
|
||||||
openocd_commands=copy.copy(board.openocd_commands),
|
openocd_commands=copy.copy(board.openocd_commands),
|
||||||
openocd_options=copy.copy(board.openocd_options),
|
openocd_options=copy.copy(board.openocd_options),
|
||||||
jtag=False,
|
jtag=False,
|
||||||
@@ -279,21 +276,7 @@ class OpenSKInstaller:
|
|||||||
port=None,
|
port=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
def checked_command(self,
|
def checked_command(self, cmd, env=None, cwd=None):
|
||||||
cmd: List[str],
|
|
||||||
env: Dict[str, str] = None,
|
|
||||||
cwd: str = None):
|
|
||||||
"""Executes the given command.
|
|
||||||
|
|
||||||
Outside of debug mode, the command's output is muted. Exits if the called
|
|
||||||
process returns an error.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
cmd: A list of strings. The first string is the command, the other list
|
|
||||||
elements are parameters to that command."
|
|
||||||
env: The dictionary of environment variables.
|
|
||||||
cwd: The directory to execute from.
|
|
||||||
"""
|
|
||||||
stdout = None if self.args.verbose_build else subprocess.DEVNULL
|
stdout = None if self.args.verbose_build else subprocess.DEVNULL
|
||||||
try:
|
try:
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
@@ -301,11 +284,7 @@ class OpenSKInstaller:
|
|||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
fatal(f"Failed to execute {cmd[0]}: {str(e)}")
|
fatal(f"Failed to execute {cmd[0]}: {str(e)}")
|
||||||
|
|
||||||
def checked_command_output(self,
|
def checked_command_output(self, cmd, env=None, cwd=None):
|
||||||
cmd: List[str],
|
|
||||||
env: Dict[str, str] = None,
|
|
||||||
cwd: str = None) -> str:
|
|
||||||
"""Executes cmd like checked_command, but returns the output."""
|
|
||||||
cmd_output = ""
|
cmd_output = ""
|
||||||
try:
|
try:
|
||||||
cmd_output = subprocess.run(
|
cmd_output = subprocess.run(
|
||||||
@@ -321,7 +300,6 @@ class OpenSKInstaller:
|
|||||||
return cmd_output.decode()
|
return cmd_output.decode()
|
||||||
|
|
||||||
def update_rustc_if_needed(self):
|
def update_rustc_if_needed(self):
|
||||||
"""Updates the Rust and installs the necessary target toolchain."""
|
|
||||||
target_toolchain_fullstring = "stable"
|
target_toolchain_fullstring = "stable"
|
||||||
with open("rust-toolchain", "r", encoding="utf-8") as f:
|
with open("rust-toolchain", "r", encoding="utf-8") as f:
|
||||||
content = f.readlines()
|
content = f.readlines()
|
||||||
@@ -361,7 +339,6 @@ class OpenSKInstaller:
|
|||||||
info("Rust toolchain up-to-date")
|
info("Rust toolchain up-to-date")
|
||||||
|
|
||||||
def build_tockos(self):
|
def build_tockos(self):
|
||||||
"""Buids Tock OS with the parameters specified in args."""
|
|
||||||
info(f"Building Tock OS for board {self.args.board}")
|
info(f"Building Tock OS for board {self.args.board}")
|
||||||
props = SUPPORTED_BOARDS[self.args.board]
|
props = SUPPORTED_BOARDS[self.args.board]
|
||||||
out_directory = os.path.join("third_party", "tock", "target", props.arch,
|
out_directory = os.path.join("third_party", "tock", "target", props.arch,
|
||||||
@@ -371,66 +348,17 @@ class OpenSKInstaller:
|
|||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
if self.args.verbose_build:
|
if self.args.verbose_build:
|
||||||
env["V"] = "1"
|
env["V"] = "1"
|
||||||
if "vendor_hid" in self.args.features:
|
|
||||||
env["CARGO_FLAGS"] = "--features=vendor_hid"
|
|
||||||
self.checked_command(["make"], cwd=props.path, env=env)
|
self.checked_command(["make"], cwd=props.path, env=env)
|
||||||
|
|
||||||
def build_example(self):
|
def build_example(self):
|
||||||
"""Builds an example with the name from args."""
|
|
||||||
info(f"Building example {self.args.application}")
|
info(f"Building example {self.args.application}")
|
||||||
self._build_app_or_example(is_example=True)
|
self._build_app_or_example(is_example=True)
|
||||||
|
|
||||||
def build_opensk(self):
|
def build_opensk(self):
|
||||||
"""Runs essential tests in OpenSK, then builds it if successful."""
|
|
||||||
info("Building OpenSK application")
|
info("Building OpenSK application")
|
||||||
self._check_invariants()
|
|
||||||
self._build_app_or_example(is_example=False)
|
self._build_app_or_example(is_example=False)
|
||||||
|
|
||||||
def build_bootloader(self):
|
def _build_app_or_example(self, is_example):
|
||||||
"""Builds the upgrade bootloader."""
|
|
||||||
props = SUPPORTED_BOARDS[self.args.board]
|
|
||||||
info("Building bootloader")
|
|
||||||
rust_flags = [
|
|
||||||
f"--remap-path-prefix={os.getcwd()}=",
|
|
||||||
"-C",
|
|
||||||
"link-arg=-Wl,-Tlink.x",
|
|
||||||
"-C",
|
|
||||||
"link-arg=-nostartfiles",
|
|
||||||
]
|
|
||||||
env = os.environ.copy()
|
|
||||||
env["RUSTFLAGS"] = " ".join(rust_flags)
|
|
||||||
cargo_command = ["cargo", "build", "--release", f"--target={props.arch}"]
|
|
||||||
self.checked_command(cargo_command, cwd="bootloader", env=env)
|
|
||||||
binary_path = os.path.join("target", props.arch, "release", "bootloader")
|
|
||||||
objcopy_command = [
|
|
||||||
"llvm-objcopy", "-O", "binary", binary_path, f"{binary_path}.bin"
|
|
||||||
]
|
|
||||||
self.checked_command(objcopy_command, cwd="bootloader")
|
|
||||||
|
|
||||||
def flash_bootloader(self):
|
|
||||||
"""Flashes the upgrade bootloader."""
|
|
||||||
props = SUPPORTED_BOARDS[self.args.board]
|
|
||||||
info("Flashing bootloader")
|
|
||||||
bin_file = os.path.join("bootloader", "target", props.arch, "release",
|
|
||||||
"bootloader.bin")
|
|
||||||
if not os.path.exists(bin_file):
|
|
||||||
fatal(f"File not found: {bin_file}")
|
|
||||||
with open(bin_file, "rb") as bootloader_bin:
|
|
||||||
bootloader = bootloader_bin.read()
|
|
||||||
self.write_binary(bootloader, 0)
|
|
||||||
|
|
||||||
def _build_app_or_example(self, is_example: bool):
|
|
||||||
"""Builds the application specified through args.
|
|
||||||
|
|
||||||
This function specifies the used compile time flags, specifying the linker
|
|
||||||
script and reducing the binary size. It compiles the application and calls
|
|
||||||
elf2tab to create a TAB file out of the produced binary.
|
|
||||||
|
|
||||||
The settings in self.args have to match is_example.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
is_example: Whether args.application is an example or the main ctap2 app.
|
|
||||||
"""
|
|
||||||
assert self.args.application
|
assert self.args.application
|
||||||
# Ideally we would build a TAB file for all boards at once but depending on
|
# Ideally we would build a TAB file for all boards at once but depending on
|
||||||
# the chip on the board, the link script could be totally different.
|
# the chip on the board, the link script could be totally different.
|
||||||
@@ -445,10 +373,6 @@ class OpenSKInstaller:
|
|||||||
"-D",
|
"-D",
|
||||||
"warnings",
|
"warnings",
|
||||||
f"--remap-path-prefix={os.getcwd()}=",
|
f"--remap-path-prefix={os.getcwd()}=",
|
||||||
"-C",
|
|
||||||
"link-arg=-icf=all",
|
|
||||||
"-C",
|
|
||||||
"force-frame-pointers=no",
|
|
||||||
]
|
]
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
env["RUSTFLAGS"] = " ".join(rust_flags)
|
env["RUSTFLAGS"] = " ".join(rust_flags)
|
||||||
@@ -470,18 +394,7 @@ class OpenSKInstaller:
|
|||||||
# Create a TAB file
|
# Create a TAB file
|
||||||
self.create_tab_file({props.arch: app_path})
|
self.create_tab_file({props.arch: app_path})
|
||||||
|
|
||||||
def _check_invariants(self):
|
def generate_crypto_materials(self, force_regenerate):
|
||||||
"""Runs selected unit tests to check preconditions in the code."""
|
|
||||||
print("Testing invariants in customization.rs...")
|
|
||||||
features = ["std"]
|
|
||||||
features.extend(self.args.features)
|
|
||||||
self.checked_command_output([
|
|
||||||
"cargo", "test", f"--features={','.join(features)}", "--lib",
|
|
||||||
"customization"
|
|
||||||
])
|
|
||||||
|
|
||||||
def generate_crypto_materials(self, force_regenerate: bool):
|
|
||||||
"""Calls a shell script that generates cryptographic material."""
|
|
||||||
has_error = subprocess.call([
|
has_error = subprocess.call([
|
||||||
os.path.join("tools", "gen_key_materials.sh"),
|
os.path.join("tools", "gen_key_materials.sh"),
|
||||||
"Y" if force_regenerate else "N",
|
"Y" if force_regenerate else "N",
|
||||||
@@ -490,18 +403,17 @@ class OpenSKInstaller:
|
|||||||
error(("Something went wrong while trying to generate ECC "
|
error(("Something went wrong while trying to generate ECC "
|
||||||
"key and/or certificate for OpenSK"))
|
"key and/or certificate for OpenSK"))
|
||||||
|
|
||||||
def create_tab_file(self, binary_names: Dict[str, str]):
|
def create_tab_file(self, binaries):
|
||||||
"""Checks and uses elf2tab to generated an TAB file out of the binaries."""
|
assert binaries
|
||||||
assert binary_names
|
|
||||||
assert self.args.application
|
assert self.args.application
|
||||||
info("Generating Tock TAB file for application/example "
|
info("Generating Tock TAB file for application/example "
|
||||||
f"{self.args.application}")
|
f"{self.args.application}")
|
||||||
elf2tab_ver = self.checked_command_output(
|
elf2tab_ver = self.checked_command_output(
|
||||||
["elf2tab/bin/elf2tab", "--version"]).split(
|
["elf2tab/bin/elf2tab", "--version"]).split(
|
||||||
"\n", maxsplit=1)[0]
|
"\n", maxsplit=1)[0]
|
||||||
if elf2tab_ver != "elf2tab 0.7.0":
|
if elf2tab_ver != "elf2tab 0.6.0":
|
||||||
error(("Detected unsupported elf2tab version {elf2tab_ver!a}. The "
|
error(("Detected unsupported elf2tab version {elf2tab_ver!a}. The "
|
||||||
"following commands may fail. Please use 0.7.0 instead."))
|
"following commands may fail. Please use 0.6.0 instead."))
|
||||||
os.makedirs(self.tab_folder, exist_ok=True)
|
os.makedirs(self.tab_folder, exist_ok=True)
|
||||||
tab_filename = os.path.join(self.tab_folder, f"{self.args.application}.tab")
|
tab_filename = os.path.join(self.tab_folder, f"{self.args.application}.tab")
|
||||||
elf2tab_args = [
|
elf2tab_args = [
|
||||||
@@ -510,23 +422,13 @@ class OpenSKInstaller:
|
|||||||
]
|
]
|
||||||
if self.args.verbose_build:
|
if self.args.verbose_build:
|
||||||
elf2tab_args.append("--verbose")
|
elf2tab_args.append("--verbose")
|
||||||
stack_sizes = set()
|
for arch, app_file in binaries.items():
|
||||||
for arch, app_file in binary_names.items():
|
|
||||||
dest_file = os.path.join(self.tab_folder, f"{arch}.elf")
|
dest_file = os.path.join(self.tab_folder, f"{arch}.elf")
|
||||||
shutil.copyfile(app_file, dest_file)
|
shutil.copyfile(app_file, dest_file)
|
||||||
elf2tab_args.append(dest_file)
|
elf2tab_args.append(dest_file)
|
||||||
# extract required stack size directly from binary
|
|
||||||
nm = self.checked_command_output(
|
|
||||||
["nm", "--print-size", "--radix=x", app_file])
|
|
||||||
for line in nm.splitlines():
|
|
||||||
if "STACK_MEMORY" in line:
|
|
||||||
required_stack_size = int(line.split(" ", maxsplit=2)[1], 16)
|
|
||||||
stack_sizes.add(required_stack_size)
|
|
||||||
if len(stack_sizes) != 1:
|
|
||||||
error("Detected different stack sizes across tab files.")
|
|
||||||
|
|
||||||
elf2tab_args.extend([
|
elf2tab_args.extend([
|
||||||
f"--stack={stack_sizes.pop()}", f"--app-heap={APP_HEAP_SIZE}",
|
f"--stack={STACK_SIZE}", f"--app-heap={APP_HEAP_SIZE}",
|
||||||
"--kernel-heap=1024", "--protected-region-size=64"
|
"--kernel-heap=1024", "--protected-region-size=64"
|
||||||
])
|
])
|
||||||
if self.args.elf2tab_output:
|
if self.args.elf2tab_output:
|
||||||
@@ -535,11 +437,12 @@ class OpenSKInstaller:
|
|||||||
else:
|
else:
|
||||||
self.checked_command(elf2tab_args)
|
self.checked_command(elf2tab_args)
|
||||||
|
|
||||||
def install_tab_file(self, tab_filename: str):
|
def install_tab_file(self, tab_filename):
|
||||||
"""Calls Tockloader to install a TAB file."""
|
|
||||||
assert self.args.application
|
assert self.args.application
|
||||||
info(f"Installing Tock application {self.args.application}")
|
info(f"Installing Tock application {self.args.application}")
|
||||||
|
board_props = SUPPORTED_BOARDS[self.args.board]
|
||||||
args = copy.copy(self.tockloader_default_args)
|
args = copy.copy(self.tockloader_default_args)
|
||||||
|
setattr(args, "app_address", board_props.app_address)
|
||||||
setattr(args, "erase", self.args.clear_apps)
|
setattr(args, "erase", self.args.clear_apps)
|
||||||
setattr(args, "make", False)
|
setattr(args, "make", False)
|
||||||
setattr(args, "no_replace", False)
|
setattr(args, "no_replace", False)
|
||||||
@@ -552,86 +455,46 @@ class OpenSKInstaller:
|
|||||||
fatal("Couldn't install Tock application "
|
fatal("Couldn't install Tock application "
|
||||||
f"{self.args.application}: {str(e)}")
|
f"{self.args.application}: {str(e)}")
|
||||||
|
|
||||||
def get_padding(self) -> bytes:
|
def get_padding(self):
|
||||||
"""Creates a padding application binary."""
|
|
||||||
padding = tbfh.TBFHeaderPadding(
|
padding = tbfh.TBFHeaderPadding(
|
||||||
SUPPORTED_BOARDS[self.args.board].app_address -
|
SUPPORTED_BOARDS[self.args.board].app_address -
|
||||||
SUPPORTED_BOARDS[self.args.board].padding_address)
|
SUPPORTED_BOARDS[self.args.board].padding_address)
|
||||||
return padding.get_binary()
|
return padding.get_binary()
|
||||||
|
|
||||||
def write_binary(self, binary: bytes, address: int):
|
def install_tock_os(self):
|
||||||
"""Writes a binary to the device's flash at the given address."""
|
|
||||||
tock = loader.TockLoader(self.tockloader_default_args)
|
|
||||||
tock.open()
|
|
||||||
try:
|
|
||||||
tock.flash_binary(binary, address)
|
|
||||||
except TockLoaderException as e:
|
|
||||||
fatal(f"Couldn't write binary: {str(e)}")
|
|
||||||
|
|
||||||
def read_kernel(self) -> bytes:
|
|
||||||
"""Reads the kernel file from disk and returns it as a byte array."""
|
|
||||||
board_props = SUPPORTED_BOARDS[self.args.board]
|
board_props = SUPPORTED_BOARDS[self.args.board]
|
||||||
kernel_file = os.path.join("third_party", "tock", "target",
|
kernel_file = os.path.join("third_party", "tock", "target",
|
||||||
board_props.arch, "release",
|
board_props.arch, "release",
|
||||||
f"{self.args.board}.bin")
|
f"{self.args.board}.bin")
|
||||||
if not os.path.exists(kernel_file):
|
info(f"Flashing file {kernel_file}.")
|
||||||
fatal(f"File not found: {kernel_file}")
|
with open(kernel_file, "rb") as f:
|
||||||
with open(kernel_file, "rb") as firmware:
|
kernel = f.read()
|
||||||
kernel = firmware.read()
|
args = copy.copy(self.tockloader_default_args)
|
||||||
|
setattr(args, "address", board_props.app_address)
|
||||||
# Pads the kernel to the expected length.
|
tock = loader.TockLoader(args)
|
||||||
if board_props.padding_address is None:
|
tock.open()
|
||||||
end_address = board_props.app_address
|
try:
|
||||||
else:
|
tock.flash_binary(kernel, board_props.kernel_address)
|
||||||
end_address = board_props.padding_address
|
except TockLoaderException as e:
|
||||||
kernel_size = end_address - board_props.kernel_address
|
fatal(f"Couldn't install Tock OS: {str(e)}")
|
||||||
return pad_to(kernel, kernel_size)
|
|
||||||
|
|
||||||
def install_tock_os(self):
|
|
||||||
"""Reads the kernel from disk and writes it to the device's flash."""
|
|
||||||
kernel = self.read_kernel()
|
|
||||||
board_props = SUPPORTED_BOARDS[self.args.board]
|
|
||||||
self.write_binary(kernel, board_props.kernel_address)
|
|
||||||
|
|
||||||
def install_padding(self):
|
def install_padding(self):
|
||||||
"""Generates a padding application and writes it to the address in args."""
|
padding = self.get_padding()
|
||||||
board_props = SUPPORTED_BOARDS[self.args.board]
|
board_props = SUPPORTED_BOARDS[self.args.board]
|
||||||
if board_props.padding_address is None:
|
|
||||||
return
|
|
||||||
info("Flashing padding application")
|
info("Flashing padding application")
|
||||||
self.write_binary(self.get_padding(), board_props.padding_address)
|
args = copy.copy(self.tockloader_default_args)
|
||||||
|
setattr(args, "address", board_props.padding_address)
|
||||||
def install_metadata(self):
|
tock = loader.TockLoader(args)
|
||||||
"""Generates and writes firmware metadata at the metadata address."""
|
tock.open()
|
||||||
board_props = SUPPORTED_BOARDS[self.args.board]
|
try:
|
||||||
if board_props.metadata_address is None:
|
tock.flash_binary(padding, args.address)
|
||||||
return
|
except TockLoaderException as e:
|
||||||
|
fatal(f"Couldn't install padding: {str(e)}")
|
||||||
kernel = self.read_kernel()
|
|
||||||
app_tab_path = "target/tab/ctap2.tab"
|
|
||||||
if not os.path.exists(app_tab_path):
|
|
||||||
fatal(f"File not found: {app_tab_path}")
|
|
||||||
app_tab = tab.TAB(app_tab_path)
|
|
||||||
arch = board_props.arch
|
|
||||||
if arch not in app_tab.get_supported_architectures():
|
|
||||||
fatal(f"Architecture not found: {arch}")
|
|
||||||
app = app_tab.extract_app(arch).get_binary(board_props.app_address)
|
|
||||||
|
|
||||||
kernel_size = board_props.app_address - board_props.kernel_address
|
|
||||||
app_size = board_props.firmware_size - kernel_size
|
|
||||||
# The kernel is already padded when read.
|
|
||||||
firmware_image = kernel + pad_to(app, app_size)
|
|
||||||
|
|
||||||
metadata = create_metadata(firmware_image, board_props.kernel_address)
|
|
||||||
if self.args.verbose_build:
|
|
||||||
info(f"Metadata bytes: {metadata}")
|
|
||||||
|
|
||||||
info("Flashing metadata application")
|
|
||||||
self.write_binary(metadata, board_props.metadata_address)
|
|
||||||
|
|
||||||
def clear_apps(self):
|
def clear_apps(self):
|
||||||
"""Uses Tockloader to erase all applications on the device."""
|
|
||||||
args = copy.copy(self.tockloader_default_args)
|
args = copy.copy(self.tockloader_default_args)
|
||||||
|
board_props = SUPPORTED_BOARDS[self.args.board]
|
||||||
|
setattr(args, "app_address", board_props.app_address)
|
||||||
# Ensure we don't force erase all apps but only the apps starting
|
# Ensure we don't force erase all apps but only the apps starting
|
||||||
# at `board.app_address`. This makes sure we don't erase the padding.
|
# at `board.app_address`. This makes sure we don't erase the padding.
|
||||||
setattr(args, "force", False)
|
setattr(args, "force", False)
|
||||||
@@ -645,7 +508,6 @@ class OpenSKInstaller:
|
|||||||
info(f"A non-critical error occurred while erasing apps: {str(e)}")
|
info(f"A non-critical error occurred while erasing apps: {str(e)}")
|
||||||
|
|
||||||
def clear_storage(self):
|
def clear_storage(self):
|
||||||
"""Overwrites the storage's flash with 0xFF bytes."""
|
|
||||||
if self.args.programmer == "none":
|
if self.args.programmer == "none":
|
||||||
return 0
|
return 0
|
||||||
info("Erasing the persistent storage")
|
info("Erasing the persistent storage")
|
||||||
@@ -653,7 +515,12 @@ class OpenSKInstaller:
|
|||||||
# Use tockloader if possible
|
# Use tockloader if possible
|
||||||
if self.args.programmer in ("jlink", "openocd"):
|
if self.args.programmer in ("jlink", "openocd"):
|
||||||
storage = bytes([0xFF] * board_props.storage_size)
|
storage = bytes([0xFF] * board_props.storage_size)
|
||||||
self.write_binary(storage, board_props.storage_address)
|
tock = loader.TockLoader(self.tockloader_default_args)
|
||||||
|
tock.open()
|
||||||
|
try:
|
||||||
|
tock.flash_binary(storage, board_props.storage_address)
|
||||||
|
except TockLoaderException as e:
|
||||||
|
fatal(f"Couldn't erase the persistent storage: {str(e)}")
|
||||||
return 0
|
return 0
|
||||||
if self.args.programmer == "pyocd":
|
if self.args.programmer == "pyocd":
|
||||||
self.checked_command([
|
self.checked_command([
|
||||||
@@ -664,11 +531,11 @@ class OpenSKInstaller:
|
|||||||
fatal(f"Programmer {self.args.programmer} is not supported.")
|
fatal(f"Programmer {self.args.programmer} is not supported.")
|
||||||
|
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
def verify_flashed_app(self, expected_app: str) -> bool:
|
def verify_flashed_app(self, expected_app):
|
||||||
"""Uses Tockloader to check if an app of the expected name was written."""
|
|
||||||
if self.args.programmer not in ("jlink", "openocd"):
|
if self.args.programmer not in ("jlink", "openocd"):
|
||||||
return False
|
return False
|
||||||
tock = loader.TockLoader(self.tockloader_default_args)
|
args = copy.copy(self.tockloader_default_args)
|
||||||
|
tock = loader.TockLoader(args)
|
||||||
tock.open()
|
tock.open()
|
||||||
app_found = False
|
app_found = False
|
||||||
with tock._start_communication_with_board():
|
with tock._start_communication_with_board():
|
||||||
@@ -676,8 +543,7 @@ class OpenSKInstaller:
|
|||||||
app_found = expected_app in apps
|
app_found = expected_app in apps
|
||||||
return app_found
|
return app_found
|
||||||
|
|
||||||
def create_hex_file(self, dest_file: str):
|
def create_hex_file(self, dest_file):
|
||||||
"""Creates an intelhex file from the kernel and app binaries on disk."""
|
|
||||||
# We produce an intelhex file with everything in it
|
# We produce an intelhex file with everything in it
|
||||||
# https://en.wikipedia.org/wiki/Intel_HEX
|
# https://en.wikipedia.org/wiki/Intel_HEX
|
||||||
# pylint: disable=g-import-not-at-top,import-outside-toplevel
|
# pylint: disable=g-import-not-at-top,import-outside-toplevel
|
||||||
@@ -687,8 +553,12 @@ class OpenSKInstaller:
|
|||||||
|
|
||||||
if self.args.tockos:
|
if self.args.tockos:
|
||||||
# Process kernel
|
# Process kernel
|
||||||
|
kernel_path = os.path.join("third_party", "tock", "target",
|
||||||
|
board_props.arch, "release",
|
||||||
|
f"{self.args.board}.bin")
|
||||||
|
with open(kernel_path, "rb") as kernel:
|
||||||
kern_hex = intelhex.IntelHex()
|
kern_hex = intelhex.IntelHex()
|
||||||
kern_hex.frombytes(self.read_kernel(), offset=board_props.kernel_address)
|
kern_hex.frombytes(kernel.read(), offset=board_props.kernel_address)
|
||||||
final_hex.merge(kern_hex, overlap="error")
|
final_hex.merge(kern_hex, overlap="error")
|
||||||
|
|
||||||
if self.args.application:
|
if self.args.application:
|
||||||
@@ -716,7 +586,6 @@ class OpenSKInstaller:
|
|||||||
final_hex.tofile(dest_file, format="hex")
|
final_hex.tofile(dest_file, format="hex")
|
||||||
|
|
||||||
def check_prerequisites(self):
|
def check_prerequisites(self):
|
||||||
"""Checks versions of the used tools, exits on version mismatch."""
|
|
||||||
if not tockloader.__version__.startswith("1.5."):
|
if not tockloader.__version__.startswith("1.5."):
|
||||||
fatal(("Your version of tockloader seems incompatible: found "
|
fatal(("Your version of tockloader seems incompatible: found "
|
||||||
f"{tockloader.__version__}, expected 1.5.x."))
|
f"{tockloader.__version__}, expected 1.5.x."))
|
||||||
@@ -747,41 +616,19 @@ class OpenSKInstaller:
|
|||||||
if self.args.programmer == "none":
|
if self.args.programmer == "none":
|
||||||
assert_python_library("intelhex")
|
assert_python_library("intelhex")
|
||||||
|
|
||||||
def configure_device(self):
|
def run(self):
|
||||||
"""Checks the device configuration, and sets it according to args."""
|
|
||||||
configure_response = tools.configure.main(
|
|
||||||
argparse.Namespace(
|
|
||||||
batch=False,
|
|
||||||
certificate=self.args.config_cert,
|
|
||||||
priv_key=self.args.config_pkey,
|
|
||||||
lock=self.args.lock_device,
|
|
||||||
use_vendor_hid="vendor_hid" in self.args.features,
|
|
||||||
))
|
|
||||||
if not configure_response:
|
|
||||||
return None
|
|
||||||
return configure_response[0]
|
|
||||||
|
|
||||||
def run(self) -> int:
|
|
||||||
"""Reads args to decide and run all required tasks."""
|
|
||||||
self.check_prerequisites()
|
self.check_prerequisites()
|
||||||
self.update_rustc_if_needed()
|
self.update_rustc_if_needed()
|
||||||
|
|
||||||
if not (self.args.tockos or self.args.application or
|
if not (self.args.tockos or self.args.application or
|
||||||
self.args.clear_storage or self.args.configure):
|
self.args.clear_storage):
|
||||||
info("Nothing to do.")
|
info("Nothing to do.")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if self.args.check_patches:
|
|
||||||
subprocess.run(["./maintainers/patches", "check"], check=False)
|
|
||||||
|
|
||||||
# Compile what needs to be compiled
|
# Compile what needs to be compiled
|
||||||
board_props = SUPPORTED_BOARDS[self.args.board]
|
|
||||||
if self.args.tockos:
|
if self.args.tockos:
|
||||||
self.build_tockos()
|
self.build_tockos()
|
||||||
|
|
||||||
if board_props.metadata_address is not None:
|
|
||||||
self.build_bootloader()
|
|
||||||
|
|
||||||
if self.args.application == "ctap2":
|
if self.args.application == "ctap2":
|
||||||
self.generate_crypto_materials(self.args.regenerate_keys)
|
self.generate_crypto_materials(self.args.regenerate_keys)
|
||||||
self.build_opensk()
|
self.build_opensk()
|
||||||
@@ -795,6 +642,7 @@ class OpenSKInstaller:
|
|||||||
self.clear_storage()
|
self.clear_storage()
|
||||||
|
|
||||||
# Flashing
|
# Flashing
|
||||||
|
board_props = SUPPORTED_BOARDS[self.args.board]
|
||||||
if self.args.programmer in ("jlink", "openocd"):
|
if self.args.programmer in ("jlink", "openocd"):
|
||||||
# We rely on Tockloader to do the job
|
# We rely on Tockloader to do the job
|
||||||
if self.args.clear_apps:
|
if self.args.clear_apps:
|
||||||
@@ -802,21 +650,21 @@ class OpenSKInstaller:
|
|||||||
if self.args.tockos:
|
if self.args.tockos:
|
||||||
# Install Tock OS
|
# Install Tock OS
|
||||||
self.install_tock_os()
|
self.install_tock_os()
|
||||||
if board_props.metadata_address is not None:
|
|
||||||
# Install the bootloader
|
|
||||||
self.flash_bootloader()
|
|
||||||
# Install padding and application if needed
|
# Install padding and application if needed
|
||||||
if self.args.application:
|
if self.args.application:
|
||||||
self.install_padding()
|
self.install_padding()
|
||||||
self.install_tab_file(f"target/tab/{self.args.application}.tab")
|
self.install_tab_file(f"target/tab/{self.args.application}.tab")
|
||||||
self.install_metadata()
|
if self.verify_flashed_app(self.args.application):
|
||||||
if not self.verify_flashed_app(self.args.application):
|
info("You're all set!")
|
||||||
error(("It seems that something went wrong. App/example not found "
|
return 0
|
||||||
"on your board. Ensure the connections between the programmer "
|
error(
|
||||||
"and the board are correct."))
|
("It seems that something went wrong. App/example not found "
|
||||||
|
"on your board. Ensure the connections between the programmer and "
|
||||||
|
"the board are correct."))
|
||||||
return 1
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
elif self.args.programmer in ("pyocd", "nordicdfu", "none"):
|
if self.args.programmer in ("pyocd", "nordicdfu", "none"):
|
||||||
dest_file = f"target/{self.args.board}_merged.hex"
|
dest_file = f"target/{self.args.board}_merged.hex"
|
||||||
os.makedirs("target", exist_ok=True)
|
os.makedirs("target", exist_ok=True)
|
||||||
self.create_hex_file(dest_file)
|
self.create_hex_file(dest_file)
|
||||||
@@ -853,7 +701,7 @@ class OpenSKInstaller:
|
|||||||
fatal("Multiple DFU devices are detected. Please only connect one.")
|
fatal("Multiple DFU devices are detected. Please only connect one.")
|
||||||
# Run the command without capturing stdout so that we show progress
|
# Run the command without capturing stdout so that we show progress
|
||||||
info("Flashing device using DFU...")
|
info("Flashing device using DFU...")
|
||||||
dfu_return_code = subprocess.run(
|
return subprocess.run(
|
||||||
[
|
[
|
||||||
"nrfutil", "dfu", "usb-serial", f"--package={dfu_pkg_file}",
|
"nrfutil", "dfu", "usb-serial", f"--package={dfu_pkg_file}",
|
||||||
f"--serial-number={serial_number[0]}"
|
f"--serial-number={serial_number[0]}"
|
||||||
@@ -861,57 +709,26 @@ class OpenSKInstaller:
|
|||||||
check=False,
|
check=False,
|
||||||
timeout=None,
|
timeout=None,
|
||||||
).returncode
|
).returncode
|
||||||
if dfu_return_code != 0:
|
|
||||||
return dfu_return_code
|
|
||||||
|
|
||||||
# Configure OpenSK through vendor specific command if needed
|
# Configure OpenSK through vendor specific command if needed
|
||||||
if self.args.programmer == "none":
|
|
||||||
if any([
|
if any([
|
||||||
self.args.lock_device,
|
self.args.lock_device,
|
||||||
self.args.config_cert,
|
self.args.config_cert,
|
||||||
self.args.config_pkey,
|
self.args.config_pkey,
|
||||||
]):
|
]):
|
||||||
fatal("Unexpected arguments to configure your device. Since you "
|
# pylint: disable=g-import-not-at-top,import-outside-toplevel
|
||||||
"selected the programmer \"none\", the device is not ready to be "
|
import tools.configure
|
||||||
"configured yet.")
|
tools.configure.main(
|
||||||
return 0
|
argparse.Namespace(
|
||||||
|
batch=False,
|
||||||
# Perform checks if OpenSK was flashed.
|
certificate=self.args.config_cert,
|
||||||
if self.args.application == "ctap2" or self.args.configure:
|
priv_key=self.args.config_pkey,
|
||||||
self.configure()
|
lock=self.args.lock_device,
|
||||||
return 0
|
))
|
||||||
|
|
||||||
def configure(self):
|
|
||||||
info("Configuring device.")
|
|
||||||
# Trying to check or configure the device. Booting might take some time.
|
|
||||||
for i in range(5):
|
|
||||||
# Increasing wait time, total of 10 seconds.
|
|
||||||
time.sleep(i)
|
|
||||||
devices = tools.configure.get_opensk_devices(False)
|
|
||||||
if devices:
|
|
||||||
break
|
|
||||||
|
|
||||||
if not devices:
|
|
||||||
fatal("No device to configure found.")
|
|
||||||
status = self.configure_device()
|
|
||||||
if not status:
|
|
||||||
fatal("Could not read device configuration.")
|
|
||||||
|
|
||||||
if status["cert"] and status["pkey"]:
|
|
||||||
info("You're all set!")
|
|
||||||
else:
|
|
||||||
info("Your device is not yet configured, and lacks some functionality. "
|
|
||||||
"If you run into issues, this command might help:\n\n"
|
|
||||||
"./tools/configure.py \\\n"
|
|
||||||
" --certificate=crypto_data/opensk_cert.pem \\\n"
|
|
||||||
" --private-key=crypto_data/opensk.key\n\n"
|
|
||||||
"Please read the Certificate considerations in docs/customization.md"
|
|
||||||
" to understand the privacy trade-off.")
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def main(args):
|
def main(args):
|
||||||
"""Verifies some args, then runs a new OpenSKInstaller."""
|
|
||||||
colorama.init()
|
colorama.init()
|
||||||
|
|
||||||
# Make sure the current working directory is the right one before running
|
# Make sure the current working directory is the right one before running
|
||||||
@@ -1004,14 +821,6 @@ if __name__ == "__main__":
|
|||||||
help=("Sets the method to be used to flash Tock OS or the application "
|
help=("Sets the method to be used to flash Tock OS or the application "
|
||||||
"on the target board."),
|
"on the target board."),
|
||||||
)
|
)
|
||||||
main_parser.add_argument(
|
|
||||||
"--openocd_cmd",
|
|
||||||
dest="openocd_cmd",
|
|
||||||
metavar="CMD",
|
|
||||||
default="openocd",
|
|
||||||
help=("Specifies a custom command to use when calling openocd. Can be "
|
|
||||||
"used to pass arguments i.e. 'openocd -s /tmp/openocd_scripts'."),
|
|
||||||
)
|
|
||||||
|
|
||||||
main_parser.add_argument(
|
main_parser.add_argument(
|
||||||
"--no-tockos",
|
"--no-tockos",
|
||||||
@@ -1071,6 +880,14 @@ if __name__ == "__main__":
|
|||||||
help=("Compiles the OpenSK application without backward compatible "
|
help=("Compiles the OpenSK application without backward compatible "
|
||||||
"support for U2F/CTAP1 protocol."),
|
"support for U2F/CTAP1 protocol."),
|
||||||
)
|
)
|
||||||
|
main_parser.add_argument(
|
||||||
|
"--ctap2.1",
|
||||||
|
action="append_const",
|
||||||
|
const="with_ctap2_1",
|
||||||
|
dest="features",
|
||||||
|
help=("Compiles the OpenSK application with backward compatible "
|
||||||
|
"support for CTAP2.1 protocol."),
|
||||||
|
)
|
||||||
main_parser.add_argument(
|
main_parser.add_argument(
|
||||||
"--nfc",
|
"--nfc",
|
||||||
action="append_const",
|
action="append_const",
|
||||||
@@ -1078,20 +895,6 @@ if __name__ == "__main__":
|
|||||||
dest="features",
|
dest="features",
|
||||||
help=("Compiles the OpenSK application with support for nfc."),
|
help=("Compiles the OpenSK application with support for nfc."),
|
||||||
)
|
)
|
||||||
main_parser.add_argument(
|
|
||||||
"--configure",
|
|
||||||
action="store_true",
|
|
||||||
default=True,
|
|
||||||
dest="configure",
|
|
||||||
help="Configure.",
|
|
||||||
)
|
|
||||||
main_parser.add_argument(
|
|
||||||
"--vendor-hid",
|
|
||||||
action="append_const",
|
|
||||||
const="vendor_hid",
|
|
||||||
dest="features",
|
|
||||||
help=("Compiles the OpenSK application to support two HID usage pages."),
|
|
||||||
)
|
|
||||||
main_parser.add_argument(
|
main_parser.add_argument(
|
||||||
"--regen-keys",
|
"--regen-keys",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
@@ -1112,25 +915,6 @@ if __name__ == "__main__":
|
|||||||
help=("When set, the output of elf2tab is appended to this file."),
|
help=("When set, the output of elf2tab is appended to this file."),
|
||||||
)
|
)
|
||||||
|
|
||||||
main_parser.add_argument(
|
|
||||||
"--ed25519",
|
|
||||||
action="append_const",
|
|
||||||
const="ed25519",
|
|
||||||
dest="features",
|
|
||||||
help=("Adds support for credentials that use EdDSA algorithm over "
|
|
||||||
"curve Ed25519. "
|
|
||||||
"Current implementation is not side-channel resilient due to use "
|
|
||||||
"of variable-time arithmetic for computations over secret key."),
|
|
||||||
)
|
|
||||||
|
|
||||||
main_parser.add_argument(
|
|
||||||
"--disable-check-patches",
|
|
||||||
action="store_false",
|
|
||||||
default=True,
|
|
||||||
dest="check_patches",
|
|
||||||
help=("Don't check that patches are in sync with their submodules."),
|
|
||||||
)
|
|
||||||
|
|
||||||
main_parser.set_defaults(features=["with_ctap1"])
|
main_parser.set_defaults(features=["with_ctap1"])
|
||||||
|
|
||||||
# Start parsing to know if we're going to list things or not.
|
# Start parsing to know if we're going to list things or not.
|
||||||
@@ -1164,7 +948,7 @@ if __name__ == "__main__":
|
|||||||
dest="application",
|
dest="application",
|
||||||
action="store_const",
|
action="store_const",
|
||||||
const="store_latency",
|
const="store_latency",
|
||||||
help=("Compiles and installs the store_latency example which prints "
|
help=("Compiles and installs the store_latency example which print "
|
||||||
"latency statistics of the persistent store library."))
|
"latency statistics of the persistent store library."))
|
||||||
apps_group.add_argument(
|
apps_group.add_argument(
|
||||||
"--erase_storage",
|
"--erase_storage",
|
||||||
|
|||||||
@@ -59,48 +59,14 @@ Follow these steps:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### JLink
|
1. Depending on the programmer you're using, you may have to adapt the next
|
||||||
|
command line. Run our script for compiling/flashing Tock OS on your device:
|
||||||
Run our script for compiling/flashing Tock OS on your device:
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ ./deploy.py --board=nrf52840_dongle --programmer=jlink
|
$ ./deploy.py --board=nrf52840_dongle --programmer=jlink
|
||||||
```
|
```
|
||||||
|
|
||||||
#### OpenOCD
|
1. Remove the programming cable and the USB-A extension cable.
|
||||||
|
|
||||||
1. Create your openocd config, named `nordic_nrf52840_dongle.cfg` in the
|
|
||||||
appropriate location:
|
|
||||||
```shell
|
|
||||||
mkdir -p ${HOME}/.openocd/board
|
|
||||||
touch ${HOME}/.openocd/board/nordic_nrf52840_dongle.cfg
|
|
||||||
```
|
|
||||||
|
|
||||||
Paste the following st-link example and edit the specific setup to your needs:
|
|
||||||
```
|
|
||||||
# Specific setup
|
|
||||||
source [find interface/stlink-dap.cfg]
|
|
||||||
transport select dapdirect_swd
|
|
||||||
|
|
||||||
# The rest should be kept the same
|
|
||||||
set CHIPNAME nrf52840
|
|
||||||
source [find target/nrf52.cfg]
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Test your config:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
openocd -f board/nordic_nrf52840_dongle.cfg
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Run the deploy script with the appropriate options, i.e.:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
./deploy.py --board=nrf52840_dongle --opensk --programmer=openocd
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Finally, remove the programming cable and the USB-A extension cable.
|
|
||||||
|
|
||||||
### Buttons and LEDs
|
### Buttons and LEDs
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ is the easiest and most convenient. You can flash OpenSK with these steps:
|
|||||||
1. Run our script for compiling/flashing Tock OS and OpenSK on your device:
|
1. Run our script for compiling/flashing Tock OS and OpenSK on your device:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
./deploy.py --board=nrf52840dk_opensk --opensk
|
./deploy.py --board=nrf52840dk --opensk
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Connect a micro USB cable to the device USB port.
|
1. Connect a micro USB cable to the device USB port.
|
||||||
@@ -48,33 +48,3 @@ There are 3 switches that need to be in the correct position:
|
|||||||
* Power (bottom left): On
|
* Power (bottom left): On
|
||||||
* nRF power source (center left): VDD
|
* nRF power source (center left): VDD
|
||||||
* SW6 (top right): DEFAULT
|
* SW6 (top right): DEFAULT
|
||||||
|
|
||||||
### Upgradability
|
|
||||||
|
|
||||||
There are variants of the board that introduce A/B partitions for upgrading the
|
|
||||||
firmware. You can bootstrap an upgradable board using one of the two commands:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
./deploy.py --board=nrf52840dk_opensk_a --opensk
|
|
||||||
./deploy.py --board=nrf52840dk_opensk_b --opensk
|
|
||||||
```
|
|
||||||
|
|
||||||
Afterwards, you can upgrade the other partition with
|
|
||||||
|
|
||||||
```shell
|
|
||||||
./tools/perform_upgrade.sh nrf52840dk_opensk_b
|
|
||||||
./tools/perform_upgrade.sh nrf52840dk_opensk_a
|
|
||||||
```
|
|
||||||
|
|
||||||
respectively. You can only upgrade the partition that is not currently running,
|
|
||||||
so always alternate your calls to `perform_upgrade.sh`. Otherwise, this script
|
|
||||||
works like `deploy.py`. You can call it even after you locked down your device,
|
|
||||||
to deploy changes to your development board.
|
|
||||||
|
|
||||||
If you deploy with `--vendor-hid`, also add this flag to `perform_upgrade.sh`,
|
|
||||||
for example:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
./deploy.py --board=nrf52840dk_opensk_a --opensk --vendor-hid
|
|
||||||
./tools/perform_upgrade.sh nrf52840dk_opensk_b --vendor-hid
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ File | Purpose
|
|||||||
`opensk_cert.csr` | Certificate sign request for the attestation certificate
|
`opensk_cert.csr` | Certificate sign request for the attestation certificate
|
||||||
`opensk_cert.pem` | PEM encoded certificate used for the authenticator
|
`opensk_cert.pem` | PEM encoded certificate used for the authenticator
|
||||||
`opensk.key` | ECC secp256r1 private key used for the autenticator
|
`opensk.key` | ECC secp256r1 private key used for the autenticator
|
||||||
`opensk_upgrade.key` | Private key for signing upgrades through CTAP
|
|
||||||
`opensk_upgrade_pub.pem` | Public key added to the firmware for verifying upgrades
|
|
||||||
|
|
||||||
If you want to use your own attestation certificate and private key,
|
If you want to use your own attestation certificate and private key,
|
||||||
replace the `opensk_cert.pem` and `opensk.key` files. The script at
|
replace the `opensk_cert.pem` and `opensk.key` files. The script at
|
||||||
@@ -51,45 +49,30 @@ If you build your own security key, depending on the hardware you use, there are
|
|||||||
a few things you can personalize:
|
a few things you can personalize:
|
||||||
|
|
||||||
1. If you have multiple buttons, choose the buttons responsible for user
|
1. If you have multiple buttons, choose the buttons responsible for user
|
||||||
presence in `src/main.rs`.
|
presence in `main.rs`.
|
||||||
1. If you have colored LEDs, like different blinking patterns and want to play
|
2. Decide whether you want to use batch attestation. There is a boolean flag in
|
||||||
around with the code in `src/main.rs` more, take a look at e.g. `wink_leds`.
|
`ctap/mod.rs`. It is mandatory for U2F, and you can create your own
|
||||||
1. You find more options and documentation in `src/ctap/customization.rs`,
|
self-signed certificate. The flag is used for FIDO2 and has some privacy
|
||||||
including:
|
implications. Please check
|
||||||
* The default level for the credProtect extension.
|
[WebAuthn](https://www.w3.org/TR/webauthn/#attestation) for more
|
||||||
* The default minimum PIN length, and what relying parties can set it.
|
information.
|
||||||
* Whether you want to enforce alwaysUv.
|
3. Decide whether you want to use signature counters. Currently, only global
|
||||||
* Settings for enterprise attestation.
|
signature counters are implemented, as they are the default option for U2F.
|
||||||
* The maximum PIN retries.
|
The flag in `ctap/mod.rs` only turns them off for FIDO2. The most privacy
|
||||||
* Whether you want to use batch attestation.
|
preserving solution is individual or no signature counters. Again, please
|
||||||
* Whether you want to use signature counters.
|
check [WebAuthn](https://www.w3.org/TR/webauthn/#signature-counter) for
|
||||||
* Various constants to adapt to different hardware.
|
documentation.
|
||||||
|
4. Depending on your available flash storage, choose an appropriate maximum
|
||||||
### Testing and Fuzzing
|
number of supported resident keys and number of pages in
|
||||||
|
`ctap/storage.rs`.
|
||||||
You might want to test your changes before deploying them. To run unit tests,
|
5. Change the default level for the credProtect extension in `ctap/mod.rs`.
|
||||||
make sure that at least the `std` feature is included, e.g.:
|
When changing the default, resident credentials become undiscoverable without
|
||||||
|
user verification. This helps privacy, but can make usage less comfortable
|
||||||
```shell
|
for credentials that need less protection.
|
||||||
cargo test --features=std,with_ctap1
|
6. Increase the default minimum length for PINs in `ctap/storage.rs`.
|
||||||
```
|
The current minimum is 4. Values from 4 to 63 are allowed. Requiring longer
|
||||||
|
PINs can help establish trust between users and relying parties. It makes
|
||||||
Alternatively, you can simply call our test script to also test all libraries,
|
user verification harder to break, but less convenient.
|
||||||
run clippy, check formatting and more:
|
NIST recommends at least 6-digit PINs in section 5.1.9.1 of their
|
||||||
|
[Digital Identity Guidelines](https://pages.nist.gov/800-63-3/sp800-63b.html).
|
||||||
```shell
|
You can add relying parties to the list of readers of the minimum PIN length.
|
||||||
./run_desktop_tests.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
OpenSK is fuzzed with the [OSS-Fuzz](https://github.com/google/oss-fuzz)
|
|
||||||
project. You can also run fuzzing locally. First install:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
cargo +stable install cargo-fuzz --version 0.10.2
|
|
||||||
```
|
|
||||||
|
|
||||||
Then choose a fuzz target from `fuzz/fuzz_targets/`, e.g.:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
cargo fuzz run fuzz_target_process_ctap1
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ driver, before faulting the app, you can use the `--panic-console` flag of the
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
# Example on Nordic nRF52840-DK board
|
# Example on Nordic nRF52840-DK board
|
||||||
./deploy.py --board=nrf52840dk_opensk --opensk --panic-console
|
./deploy.py --board=nrf52840dk --opensk --panic-console
|
||||||
```
|
```
|
||||||
|
|
||||||
### Memory allocations
|
### Memory allocations
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ following:
|
|||||||
* `nrfutil` (can be installed using `pip3 install nrfutil`) if you want to flash
|
* `nrfutil` (can be installed using `pip3 install nrfutil`) if you want to flash
|
||||||
a device with DFU
|
a device with DFU
|
||||||
* `uuid-runtime` if you are missing the `uuidgen` command.
|
* `uuid-runtime` if you are missing the `uuidgen` command.
|
||||||
* `llvm` if you want to use the upgradability feature.
|
|
||||||
|
|
||||||
The proprietary software to use the default programmer can be found on the
|
The proprietary software to use the default programmer can be found on the
|
||||||
[Segger website](https://www.segger.com/downloads/jlink). Please follow their
|
[Segger website](https://www.segger.com/downloads/jlink). Please follow their
|
||||||
@@ -39,48 +38,16 @@ haven't tested them on Windows and other platforms.
|
|||||||
|
|
||||||
### Compiling the firmware
|
### Compiling the firmware
|
||||||
|
|
||||||
If this is your first time installing OpenSK, please skip directly to
|
If you are switching branches or used an old version of OpenSK before, we have
|
||||||
[Initial setup](#Initial-setup). Else, see
|
tools to help you migrate to our develop branch. You find more information on
|
||||||
[Updating your setup](#Updating-your-setup) below.
|
how to update your setup or reset your storage in its
|
||||||
|
[install instructions](https://github.com/google/OpenSK/blob/develop/docs/install.md).
|
||||||
|
|
||||||
#### Updating your setup
|
To clone and setup the repository for the stable branch, run the following
|
||||||
|
|
||||||
Depending on the difference to your last state, you may need some of the
|
|
||||||
following steps:
|
|
||||||
|
|
||||||
* If you are not just testing minor changes, reset and redo the setup. This
|
|
||||||
will delete all uncommited changes.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
./reset.sh
|
|
||||||
./setup.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
* Flash your board according to the
|
|
||||||
[flashing instructions below](#Flashing-a-firmware]. If you come from an
|
|
||||||
OpenSK version before the 2.0 certified one, your credential storage is not
|
|
||||||
backwards compatible and you have to reset it. :warning: You will lose
|
|
||||||
logins to all websites that you registered with OpenSK. To erase your
|
|
||||||
persistent storage, run the deploy script twice: Once with the application
|
|
||||||
parameter `--erase_storage`, and once with `--opensk` as usual.
|
|
||||||
|
|
||||||
This reset also clears the certificate. For a privacy discussion, see the
|
|
||||||
[certificate section in Customization](customization.md#Certificate-considerations).
|
|
||||||
If you want to reinstall it, you also need to rerun:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
./tools/configure.py \
|
|
||||||
--certificate=crypto_data/opensk_cert.pem \
|
|
||||||
--private-key=crypto_data/opensk.key
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Initial setup
|
|
||||||
|
|
||||||
To clone and setup the repository for the develop branch, run the following
|
|
||||||
commands:
|
commands:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git clone -b develop https://github.com/google/OpenSK.git
|
git clone https://github.com/google/OpenSK.git
|
||||||
cd OpenSK
|
cd OpenSK
|
||||||
./setup.sh
|
./setup.sh
|
||||||
```
|
```
|
||||||
@@ -137,36 +104,14 @@ We recommend that you flash your development board with JTAG and dongles with
|
|||||||
DFU, as described in the [board documentation](#Flashing-a-firmware) linked
|
DFU, as described in the [board documentation](#Flashing-a-firmware) linked
|
||||||
above. However, we support other programmers:
|
above. However, we support other programmers:
|
||||||
|
|
||||||
* OpenOCD: `./deploy.py --board=nrf52840_dongle_opensk --opensk
|
* OpenOCD: `./deploy.py --board=nrf52840_dongle --opensk --programmer=openocd`
|
||||||
--programmer=openocd`
|
* pyOCD: `./deploy.py --board=nrf52840_dongle --opensk --programmer=pyocd`
|
||||||
* pyOCD: `./deploy.py --board=nrf52840_dongle_opensk --opensk
|
* Custom: `./deploy.py --board=nrf52840_dongle --opensk --programmer=none`.
|
||||||
--programmer=pyocd`
|
In this case, an IntelHex file will be created and how to program a board is
|
||||||
* Custom: `./deploy.py --board=nrf52840_dongle_opensk --opensk
|
left to the user.
|
||||||
--programmer=none`. In this case, an IntelHex file will be created and how
|
|
||||||
to program a board is left to the user.
|
|
||||||
|
|
||||||
If your board is already flashed with Tock OS, you may skip installing it:
|
If your board is already flashed with Tock OS, you may skip installing it:
|
||||||
`./deploy.py --board=nrf52840dk_opensk --opensk --no-tockos`
|
`./deploy.py --board=nrf52840dk --opensk --no-tockos`
|
||||||
|
|
||||||
For more options, we invite you to read the help of our `deploy.py` script by
|
For more options, we invite you to read the help of our `deploy.py` script by
|
||||||
running `./deploy.py --help`.
|
running `./deploy.py --help`.
|
||||||
|
|
||||||
### Upgradability
|
|
||||||
|
|
||||||
We experiment with a new CTAP command to allow upgrading your device without
|
|
||||||
access to its debugging port. For that purpose, the flash storage is split into
|
|
||||||
4 parts:
|
|
||||||
|
|
||||||
* the bootloader to decide with partition to boot
|
|
||||||
* firmware partition A
|
|
||||||
* firmware partition B
|
|
||||||
* the persistent storage for credentials
|
|
||||||
|
|
||||||
The storage is backward compatible to non-upgradable boards. Deploying an
|
|
||||||
upgradable board automatically installs the bootloader. Please keep in mind that
|
|
||||||
you have to safely store your private signing key for upgrades if you want to
|
|
||||||
use this feature. For more information on the cryptographic material, see
|
|
||||||
[Customization](customization.md).
|
|
||||||
|
|
||||||
So far, upgradability is only supported for the development board. See the
|
|
||||||
instructions on the [board specific page](boards/nrf52840dk.md).
|
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ extern crate lang_items;
|
|||||||
|
|
||||||
use libtock_drivers::console::{Console, BUFFER_SIZE};
|
use libtock_drivers::console::{Console, BUFFER_SIZE};
|
||||||
|
|
||||||
libtock_core::stack_size! {0x800}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Write messages of length up to the console driver's buffer size.
|
// Write messages of length up to the console driver's buffer size.
|
||||||
let mut buf = [0; BUFFER_SIZE];
|
let mut buf = [0; BUFFER_SIZE];
|
||||||
|
|||||||
@@ -20,14 +20,14 @@ extern crate lang_items;
|
|||||||
use alloc::format;
|
use alloc::format;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
use crypto::{aes256, cbc, ecdsa, sha256, Hash256};
|
use crypto::{
|
||||||
|
aes256, cbc, ecdsa, rng256, sha256, Decrypt16BytesBlock, Encrypt16BytesBlock, Hash256,
|
||||||
|
};
|
||||||
use libtock_drivers::console::Console;
|
use libtock_drivers::console::Console;
|
||||||
use libtock_drivers::result::FlexUnwrap;
|
use libtock_drivers::result::FlexUnwrap;
|
||||||
use libtock_drivers::timer;
|
use libtock_drivers::timer;
|
||||||
use libtock_drivers::timer::{Timer, Timestamp};
|
use libtock_drivers::timer::Timer;
|
||||||
use rng256::TockRng256;
|
use libtock_drivers::timer::Timestamp;
|
||||||
|
|
||||||
libtock_core::stack_size! {0x800}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut console = Console::new();
|
let mut console = Console::new();
|
||||||
@@ -36,7 +36,7 @@ fn main() {
|
|||||||
let mut with_callback = timer::with_callback(|_, _| {});
|
let mut with_callback = timer::with_callback(|_, _| {});
|
||||||
let timer = with_callback.init().flex_unwrap();
|
let timer = with_callback.init().flex_unwrap();
|
||||||
|
|
||||||
let mut rng = TockRng256 {};
|
let mut rng = rng256::TockRng256 {};
|
||||||
|
|
||||||
writeln!(console, "****************************************").unwrap();
|
writeln!(console, "****************************************").unwrap();
|
||||||
writeln!(
|
writeln!(
|
||||||
@@ -76,11 +76,11 @@ fn main() {
|
|||||||
// CBC
|
// CBC
|
||||||
let mut blocks = Vec::new();
|
let mut blocks = Vec::new();
|
||||||
for i in 0..8 {
|
for i in 0..8 {
|
||||||
blocks.resize(1 << (i + 4), 0);
|
blocks.resize(1 << i, [0; 16]);
|
||||||
bench(
|
bench(
|
||||||
&mut console,
|
&mut console,
|
||||||
&timer,
|
&timer,
|
||||||
&format!("cbc::cbc_encrypt({} bytes)", blocks.len()),
|
&format!("cbc::cbc_encrypt({} bytes)", blocks.len() * 16),
|
||||||
|| {
|
|| {
|
||||||
cbc::cbc_encrypt(&ek, [0; 16], &mut blocks);
|
cbc::cbc_encrypt(&ek, [0; 16], &mut blocks);
|
||||||
},
|
},
|
||||||
@@ -90,11 +90,11 @@ fn main() {
|
|||||||
|
|
||||||
let mut blocks = Vec::new();
|
let mut blocks = Vec::new();
|
||||||
for i in 0..8 {
|
for i in 0..8 {
|
||||||
blocks.resize(1 << (i + 4), 0);
|
blocks.resize(1 << i, [0; 16]);
|
||||||
bench(
|
bench(
|
||||||
&mut console,
|
&mut console,
|
||||||
&timer,
|
&timer,
|
||||||
&format!("cbc::cbc_decrypt({} bytes)", blocks.len()),
|
&format!("cbc::cbc_decrypt({} bytes)", blocks.len() * 16),
|
||||||
|| {
|
|| {
|
||||||
cbc::cbc_decrypt(&dk, [0; 16], &mut blocks);
|
cbc::cbc_decrypt(&dk, [0; 16], &mut blocks);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,14 +17,12 @@
|
|||||||
extern crate lang_items;
|
extern crate lang_items;
|
||||||
|
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
use ctap2::env::tock::take_storage;
|
use ctap2::embedded_flash::new_storage;
|
||||||
use libtock_drivers::console::Console;
|
use libtock_drivers::console::Console;
|
||||||
use libtock_drivers::led;
|
use libtock_drivers::led;
|
||||||
use libtock_drivers::result::FlexUnwrap;
|
use libtock_drivers::result::FlexUnwrap;
|
||||||
use persistent_store::{Storage, StorageIndex};
|
use persistent_store::{Storage, StorageIndex};
|
||||||
|
|
||||||
libtock_core::stack_size! {0x800}
|
|
||||||
|
|
||||||
fn is_page_erased(storage: &dyn Storage, page: usize) -> bool {
|
fn is_page_erased(storage: &dyn Storage, page: usize) -> bool {
|
||||||
let index = StorageIndex { page, byte: 0 };
|
let index = StorageIndex { page, byte: 0 };
|
||||||
let length = storage.page_size();
|
let length = storage.page_size();
|
||||||
@@ -37,10 +35,10 @@ fn is_page_erased(storage: &dyn Storage, page: usize) -> bool {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
led::get(1).flex_unwrap().on().flex_unwrap(); // red on dongle
|
led::get(1).flex_unwrap().on().flex_unwrap(); // red on dongle
|
||||||
let mut storage = take_storage().unwrap();
|
const NUM_PAGES: usize = 20; // should be at least ctap::storage::NUM_PAGES
|
||||||
let num_pages = storage.num_pages();
|
let mut storage = new_storage(NUM_PAGES);
|
||||||
writeln!(Console::new(), "Erase {} pages of storage:", num_pages).unwrap();
|
writeln!(Console::new(), "Erase {} pages of storage:", NUM_PAGES).unwrap();
|
||||||
for page in 0..num_pages {
|
for page in 0..NUM_PAGES {
|
||||||
write!(Console::new(), "- Page {} ", page).unwrap();
|
write!(Console::new(), "- Page {} ", page).unwrap();
|
||||||
if is_page_erased(&storage, page) {
|
if is_page_erased(&storage, page) {
|
||||||
writeln!(Console::new(), "skipped (was already erased).").unwrap();
|
writeln!(Console::new(), "skipped (was already erased).").unwrap();
|
||||||
|
|||||||
@@ -7,11 +7,10 @@ extern crate libtock_drivers;
|
|||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
use libtock_drivers::console::Console;
|
use libtock_drivers::console::Console;
|
||||||
|
|
||||||
libtock_core::stack_size! {0x4000}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "with_nfc"))]
|
#[cfg(not(feature = "with_nfc"))]
|
||||||
mod example {
|
mod example {
|
||||||
use super::{Console, Write};
|
use super::Console;
|
||||||
|
use super::Write;
|
||||||
|
|
||||||
pub fn nfc(console: &mut Console) {
|
pub fn nfc(console: &mut Console) {
|
||||||
writeln!(console, "NFC feature flag is missing!").unwrap();
|
writeln!(console, "NFC feature flag is missing!").unwrap();
|
||||||
@@ -20,15 +19,20 @@ mod example {
|
|||||||
|
|
||||||
#[cfg(feature = "with_nfc")]
|
#[cfg(feature = "with_nfc")]
|
||||||
mod example {
|
mod example {
|
||||||
use super::{Console, Write};
|
use super::Console;
|
||||||
|
use super::Write;
|
||||||
use libtock_core::result::CommandError;
|
use libtock_core::result::CommandError;
|
||||||
use libtock_drivers::nfc::{NfcTag, RecvOp};
|
use libtock_drivers::nfc::NfcTag;
|
||||||
use libtock_drivers::result::{FlexUnwrap, TockError};
|
use libtock_drivers::nfc::RecvOp;
|
||||||
|
use libtock_drivers::result::FlexUnwrap;
|
||||||
|
use libtock_drivers::result::TockError;
|
||||||
use libtock_drivers::timer;
|
use libtock_drivers::timer;
|
||||||
use libtock_drivers::timer::{Timer, Timestamp};
|
use libtock_drivers::timer::Timer;
|
||||||
|
use libtock_drivers::timer::Timestamp;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
#[allow(clippy::upper_case_acronyms)]
|
// The actual lint upper_case_acronyms is not supported in all toolchains.
|
||||||
|
#[allow(clippy::all)]
|
||||||
enum ReturnCode {
|
enum ReturnCode {
|
||||||
/// Operation completed successfully
|
/// Operation completed successfully
|
||||||
SUCCESS,
|
SUCCESS,
|
||||||
|
|||||||
@@ -17,8 +17,6 @@
|
|||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
extern crate lang_items;
|
extern crate lang_items;
|
||||||
|
|
||||||
libtock_core::stack_size! {0x800}
|
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
use libtock_drivers::console::Console;
|
use libtock_drivers::console::Console;
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
extern crate lang_items;
|
extern crate lang_items;
|
||||||
|
|
||||||
libtock_core::stack_size! {0x800}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
panic!("Bye world!")
|
panic!("Bye world!")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,17 +17,13 @@
|
|||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
extern crate lang_items;
|
extern crate lang_items;
|
||||||
|
|
||||||
use alloc::string::{String, ToString};
|
use alloc::vec;
|
||||||
use alloc::vec::Vec;
|
|
||||||
use alloc::{format, vec};
|
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
use ctap2::env::tock::{take_storage, TockStorage};
|
use ctap2::embedded_flash::{new_storage, Storage};
|
||||||
use libtock_drivers::console::Console;
|
use libtock_drivers::console::Console;
|
||||||
use libtock_drivers::timer::{self, Duration, Timer, Timestamp};
|
use libtock_drivers::timer::{self, Duration, Timer, Timestamp};
|
||||||
use persistent_store::Store;
|
use persistent_store::Store;
|
||||||
|
|
||||||
libtock_core::stack_size! {0x2000}
|
|
||||||
|
|
||||||
fn timestamp(timer: &Timer) -> Timestamp<f64> {
|
fn timestamp(timer: &Timer) -> Timestamp<f64> {
|
||||||
Timestamp::<f64>::from_clock_value(timer.get_current_clock().ok().unwrap())
|
Timestamp::<f64>::from_clock_value(timer.get_current_clock().ok().unwrap())
|
||||||
}
|
}
|
||||||
@@ -39,61 +35,28 @@ fn measure<T>(timer: &Timer, operation: impl FnOnce() -> T) -> (T, Duration<f64>
|
|||||||
(result, after - before)
|
(result, after - before)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn boot_store(mut storage: TockStorage, erase: bool) -> Store<TockStorage> {
|
// Only use one store at a time.
|
||||||
use persistent_store::Storage;
|
unsafe fn boot_store(num_pages: usize, erase: bool) -> Store<Storage> {
|
||||||
let num_pages = storage.num_pages();
|
let mut storage = new_storage(num_pages);
|
||||||
if erase {
|
if erase {
|
||||||
for page in 0..num_pages {
|
for page in 0..num_pages {
|
||||||
|
use persistent_store::Storage;
|
||||||
storage.erase_page(page).unwrap();
|
storage.erase_page(page).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Store::new(storage).ok().unwrap()
|
Store::new(storage).ok().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
fn compute_latency(timer: &Timer, num_pages: usize, key_increment: usize, word_length: usize) {
|
||||||
struct StorageConfig {
|
|
||||||
num_pages: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn storage_config(storage: &TockStorage) -> StorageConfig {
|
|
||||||
use persistent_store::Storage;
|
|
||||||
StorageConfig {
|
|
||||||
num_pages: storage.num_pages(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
struct Stat {
|
|
||||||
key_increment: usize,
|
|
||||||
entry_length: usize, // words
|
|
||||||
boot_ms: f64,
|
|
||||||
compaction_ms: f64,
|
|
||||||
insert_ms: f64,
|
|
||||||
remove_ms: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compute_latency(
|
|
||||||
storage: TockStorage,
|
|
||||||
timer: &Timer,
|
|
||||||
num_pages: usize,
|
|
||||||
key_increment: usize,
|
|
||||||
word_length: usize,
|
|
||||||
) -> (TockStorage, Stat) {
|
|
||||||
let mut stat = Stat {
|
|
||||||
key_increment,
|
|
||||||
entry_length: word_length,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut console = Console::new();
|
let mut console = Console::new();
|
||||||
writeln!(
|
writeln!(
|
||||||
console,
|
console,
|
||||||
"\nLatency for key_increment={} word_length={}.",
|
"\nLatency for num_pages={} key_increment={} word_length={}.",
|
||||||
key_increment, word_length
|
num_pages, key_increment, word_length
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut store = boot_store(storage, true);
|
let mut store = unsafe { boot_store(num_pages, true) };
|
||||||
let total_capacity = store.capacity().unwrap().total();
|
let total_capacity = store.capacity().unwrap().total();
|
||||||
assert_eq!(store.capacity().unwrap().used(), 0);
|
assert_eq!(store.capacity().unwrap().used(), 0);
|
||||||
assert_eq!(store.lifetime().unwrap().used(), 0);
|
assert_eq!(store.lifetime().unwrap().used(), 0);
|
||||||
@@ -109,33 +72,33 @@ fn compute_latency(
|
|||||||
let ((), time) = measure(timer, || {
|
let ((), time) = measure(timer, || {
|
||||||
for i in 0..count {
|
for i in 0..count {
|
||||||
let key = 1 + key_increment * i;
|
let key = 1 + key_increment * i;
|
||||||
store.insert(key, &vec![0; 4 * word_length]).unwrap();
|
// For some reason the kernel sometimes fails.
|
||||||
|
while store.insert(key, &vec![0; 4 * word_length]).is_err() {
|
||||||
|
// We never enter this loop in practice, but we still need it for the kernel.
|
||||||
|
writeln!(console, "Retry insert.").unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
writeln!(console, "Setup: {:.1}ms for {} entries.", time.ms(), count).unwrap();
|
writeln!(console, "Setup: {:.1}ms for {} entries.", time.ms(), count).unwrap();
|
||||||
|
|
||||||
// Measure latency of insert.
|
// Measure latency of insert.
|
||||||
let key = 1 + key_increment * count;
|
let key = 1 + key_increment * count;
|
||||||
let ((), time) = measure(timer, || {
|
let ((), time) = measure(&timer, || {
|
||||||
store.insert(key, &vec![0; 4 * word_length]).unwrap()
|
store.insert(key, &vec![0; 4 * word_length]).unwrap()
|
||||||
});
|
});
|
||||||
writeln!(console, "Insert: {:.1}ms.", time.ms()).unwrap();
|
writeln!(console, "Insert: {:.1}ms.", time.ms()).unwrap();
|
||||||
stat.insert_ms = time.ms();
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
store.lifetime().unwrap().used(),
|
store.lifetime().unwrap().used(),
|
||||||
num_pages + (1 + count) * (1 + word_length)
|
num_pages + (1 + count) * (1 + word_length)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Measure latency of boot.
|
// Measure latency of boot.
|
||||||
let storage = store.extract_storage();
|
let (mut store, time) = measure(&timer, || unsafe { boot_store(num_pages, false) });
|
||||||
let (mut store, time) = measure(timer, || boot_store(storage, false));
|
|
||||||
writeln!(console, "Boot: {:.1}ms.", time.ms()).unwrap();
|
writeln!(console, "Boot: {:.1}ms.", time.ms()).unwrap();
|
||||||
stat.boot_ms = time.ms();
|
|
||||||
|
|
||||||
// Measure latency of remove.
|
// Measure latency of remove.
|
||||||
let ((), time) = measure(timer, || store.remove(key).unwrap());
|
let ((), time) = measure(&timer, || store.remove(key).unwrap());
|
||||||
writeln!(console, "Remove: {:.1}ms.", time.ms()).unwrap();
|
writeln!(console, "Remove: {:.1}ms.", time.ms()).unwrap();
|
||||||
stat.remove_ms = time.ms();
|
|
||||||
|
|
||||||
// Measure latency of compaction.
|
// Measure latency of compaction.
|
||||||
let length = total_capacity + num_pages - store.lifetime().unwrap().used();
|
let length = total_capacity + num_pages - store.lifetime().unwrap().used();
|
||||||
@@ -148,81 +111,28 @@ fn compute_latency(
|
|||||||
assert_eq!(store.lifetime().unwrap().used(), num_pages + total_capacity);
|
assert_eq!(store.lifetime().unwrap().used(), num_pages + total_capacity);
|
||||||
let ((), time) = measure(timer, || store.prepare(1).unwrap());
|
let ((), time) = measure(timer, || store.prepare(1).unwrap());
|
||||||
writeln!(console, "Compaction: {:.1}ms.", time.ms()).unwrap();
|
writeln!(console, "Compaction: {:.1}ms.", time.ms()).unwrap();
|
||||||
stat.compaction_ms = time.ms();
|
|
||||||
assert!(store.lifetime().unwrap().used() > total_capacity + num_pages);
|
assert!(store.lifetime().unwrap().used() > total_capacity + num_pages);
|
||||||
|
|
||||||
(store.extract_storage(), stat)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut with_callback = timer::with_callback(|_, _| {});
|
let mut with_callback = timer::with_callback(|_, _| {});
|
||||||
let timer = with_callback.init().ok().unwrap();
|
let timer = with_callback.init().ok().unwrap();
|
||||||
let storage = take_storage().unwrap();
|
|
||||||
let config = storage_config(&storage);
|
|
||||||
let mut stats = Vec::new();
|
|
||||||
|
|
||||||
writeln!(Console::new(), "\nRunning 2 tests...").unwrap();
|
writeln!(Console::new(), "\nRunning 4 tests...").unwrap();
|
||||||
// Simulate a store full of credentials (of 50 words).
|
// Those non-overwritten 50 words entries simulate credentials.
|
||||||
let (storage, stat) = compute_latency(storage, &timer, config.num_pages, 1, 50);
|
compute_latency(&timer, 3, 1, 50);
|
||||||
stats.push(stat);
|
compute_latency(&timer, 20, 1, 50);
|
||||||
// Simulate a store full of increments of a single counter.
|
// Those overwritten 1 word entries simulate counters.
|
||||||
let (_storage, stat) = compute_latency(storage, &timer, config.num_pages, 0, 1);
|
compute_latency(&timer, 3, 0, 1);
|
||||||
stats.push(stat);
|
compute_latency(&timer, 6, 0, 1);
|
||||||
writeln!(Console::new(), "\nDone.\n").unwrap();
|
writeln!(Console::new(), "\nDone.").unwrap();
|
||||||
|
|
||||||
const HEADERS: &[&str] = &[
|
// Results on nrf52840dk:
|
||||||
"Overwrite",
|
//
|
||||||
"Length",
|
// | Pages | Overwrite | Length | Boot | Compaction | Insert | Remove |
|
||||||
"Boot",
|
// | ----- | --------- | --------- | ------- | ---------- | ------ | ------- |
|
||||||
"Compaction",
|
// | 3 | no | 50 words | 2.0 ms | 132.5 ms | 4.8 ms | 1.2 ms |
|
||||||
"Insert",
|
// | 20 | no | 50 words | 7.4 ms | 135.5 ms | 10.2 ms | 3.9 ms |
|
||||||
"Remove",
|
// | 3 | yes | 1 word | 21.9 ms | 94.5 ms | 12.4 ms | 5.9 ms |
|
||||||
];
|
// | 6 | yes | 1 word | 55.2 ms | 100.8 ms | 24.8 ms | 12.1 ms |
|
||||||
let mut matrix = vec![HEADERS.iter().map(|x| x.to_string()).collect()];
|
|
||||||
for stat in stats {
|
|
||||||
matrix.push(vec![
|
|
||||||
if stat.key_increment == 0 { "yes" } else { "no" }.to_string(),
|
|
||||||
format!("{} words", stat.entry_length),
|
|
||||||
format!("{:.1} ms", stat.boot_ms),
|
|
||||||
format!("{:.1} ms", stat.compaction_ms),
|
|
||||||
format!("{:.1} ms", stat.insert_ms),
|
|
||||||
format!("{:.1} ms", stat.remove_ms),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
writeln!(Console::new(), "Copy to examples/store_latency.rs:\n").unwrap();
|
|
||||||
writeln!(Console::new(), "{:?}", config).unwrap();
|
|
||||||
write_matrix(matrix);
|
|
||||||
|
|
||||||
// Results for nrf52840dk_opensk:
|
|
||||||
// StorageConfig { num_pages: 20 }
|
|
||||||
// Overwrite Length Boot Compaction Insert Remove
|
|
||||||
// no 50 words 18.6 ms 145.8 ms 21.0 ms 9.8 ms
|
|
||||||
// yes 1 words 335.8 ms 100.6 ms 11.7 ms 5.7 ms
|
|
||||||
}
|
|
||||||
|
|
||||||
fn align(x: &str, n: usize) {
|
|
||||||
for _ in 0..n.saturating_sub(x.len()) {
|
|
||||||
write!(Console::new(), " ").unwrap();
|
|
||||||
}
|
|
||||||
write!(Console::new(), "{}", x).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_matrix(mut m: Vec<Vec<String>>) {
|
|
||||||
if m.is_empty() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let num_cols = m.iter().map(|r| r.len()).max().unwrap();
|
|
||||||
let mut col_len = vec![0; num_cols];
|
|
||||||
for row in &mut m {
|
|
||||||
row.resize(num_cols, String::new());
|
|
||||||
for col in 0..num_cols {
|
|
||||||
col_len[col] = core::cmp::max(col_len[col], row[col].len());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for row in m {
|
|
||||||
for col in 0..num_cols {
|
|
||||||
align(&row[col], col_len[col] + 2 * (col > 0) as usize);
|
|
||||||
}
|
|
||||||
writeln!(Console::new()).unwrap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
253
fuzz/Cargo.lock
generated
253
fuzz/Cargo.lock
generated
@@ -1,7 +1,5 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.19"
|
version = "0.7.19"
|
||||||
@@ -16,9 +14,6 @@ name = "arbitrary"
|
|||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db55d72333851e17d572bec876e390cd3b11eb1ef53ae821dd9f3b653d2b4569"
|
checksum = "db55d72333851e17d572bec876e390cd3b11eb1ef53ae821dd9f3b653d2b4569"
|
||||||
dependencies = [
|
|
||||||
"derive_arbitrary",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayref"
|
name = "arrayref"
|
||||||
@@ -59,6 +54,10 @@ version = "1.4.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cbor"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.73"
|
version = "1.0.73"
|
||||||
@@ -86,10 +85,12 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayref",
|
"arrayref",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"cbor",
|
||||||
"hex",
|
"hex",
|
||||||
|
"libtock_drivers",
|
||||||
|
"rand",
|
||||||
"regex",
|
"regex",
|
||||||
"ring",
|
"ring",
|
||||||
"rng256",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"subtle",
|
"subtle",
|
||||||
@@ -100,19 +101,14 @@ dependencies = [
|
|||||||
name = "ctap2"
|
name = "ctap2"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arbitrary",
|
|
||||||
"arrayref",
|
"arrayref",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"cbor",
|
||||||
"crypto",
|
"crypto",
|
||||||
"embedded-time",
|
|
||||||
"lang_items",
|
"lang_items",
|
||||||
"libtock_core",
|
"libtock_core",
|
||||||
"libtock_drivers",
|
"libtock_drivers",
|
||||||
"openssl",
|
|
||||||
"persistent_store",
|
"persistent_store",
|
||||||
"rand 0.8.5",
|
|
||||||
"rng256",
|
|
||||||
"sk-cbor",
|
|
||||||
"subtle",
|
"subtle",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
@@ -125,41 +121,6 @@ dependencies = [
|
|||||||
"libfuzzer-sys",
|
"libfuzzer-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "derive_arbitrary"
|
|
||||||
version = "0.4.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b1a012b5e473dc912f0db0546a1c9c6a194ce8494feb66fa0237160926f9e0e6"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "embedded-time"
|
|
||||||
version = "0.12.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d7a4b4d10ac48d08bfe3db7688c402baadb244721f30a77ce360bd24c3dffe58"
|
|
||||||
dependencies = [
|
|
||||||
"num",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "foreign-types"
|
|
||||||
version = "0.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
|
||||||
dependencies = [
|
|
||||||
"foreign-types-shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "foreign-types-shared"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fuchsia-cprng"
|
name = "fuchsia-cprng"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@@ -170,15 +131,12 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
|||||||
name = "fuzz_helper"
|
name = "fuzz_helper"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arbitrary",
|
|
||||||
"arrayref",
|
"arrayref",
|
||||||
|
"cbor",
|
||||||
"crypto",
|
"crypto",
|
||||||
"ctap2",
|
"ctap2",
|
||||||
"embedded-time",
|
|
||||||
"lang_items",
|
"lang_items",
|
||||||
"libtock_drivers",
|
"libtock_drivers",
|
||||||
"rng256",
|
|
||||||
"sk-cbor",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -200,9 +158,9 @@ checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.8"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
@@ -224,9 +182,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.133"
|
version = "0.2.135"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966"
|
checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libfuzzer-sys"
|
name = "libfuzzer-sys"
|
||||||
@@ -282,130 +240,16 @@ version = "2.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f"
|
|
||||||
dependencies = [
|
|
||||||
"num-complex",
|
|
||||||
"num-integer",
|
|
||||||
"num-iter",
|
|
||||||
"num-rational",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-complex"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5"
|
|
||||||
dependencies = [
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-integer"
|
|
||||||
version = "0.1.45"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg 1.1.0",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-iter"
|
|
||||||
version = "0.1.43"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg 1.1.0",
|
|
||||||
"num-integer",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-rational"
|
|
||||||
version = "0.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg 1.1.0",
|
|
||||||
"num-integer",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-traits"
|
|
||||||
version = "0.2.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg 1.1.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.14.0"
|
version = "1.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
|
checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "openssl"
|
|
||||||
version = "0.10.41"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"cfg-if",
|
|
||||||
"foreign-types",
|
|
||||||
"libc",
|
|
||||||
"once_cell",
|
|
||||||
"openssl-macros",
|
|
||||||
"openssl-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "openssl-macros"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "openssl-sys"
|
|
||||||
version = "0.9.75"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg 1.1.0",
|
|
||||||
"cc",
|
|
||||||
"libc",
|
|
||||||
"pkg-config",
|
|
||||||
"vcpkg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "persistent_store"
|
name = "persistent_store"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pkg-config"
|
|
||||||
version = "0.3.25"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ppv-lite86"
|
|
||||||
version = "0.2.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.43"
|
version = "1.0.43"
|
||||||
@@ -432,7 +276,7 @@ checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg 0.1.8",
|
"autocfg 0.1.8",
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha 0.1.1",
|
"rand_chacha",
|
||||||
"rand_core 0.4.2",
|
"rand_core 0.4.2",
|
||||||
"rand_hc",
|
"rand_hc",
|
||||||
"rand_isaac",
|
"rand_isaac",
|
||||||
@@ -443,17 +287,6 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand"
|
|
||||||
version = "0.8.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"rand_chacha 0.3.1",
|
|
||||||
"rand_core 0.6.4",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_chacha"
|
name = "rand_chacha"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@@ -464,16 +297,6 @@ dependencies = [
|
|||||||
"rand_core 0.3.1",
|
"rand_core 0.3.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_chacha"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
|
||||||
dependencies = [
|
|
||||||
"ppv-lite86",
|
|
||||||
"rand_core 0.6.4",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_core"
|
name = "rand_core"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@@ -489,15 +312,6 @@ version = "0.4.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.6.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_hc"
|
name = "rand_hc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -601,15 +415,6 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rng256"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"arrayref",
|
|
||||||
"libtock_drivers",
|
|
||||||
"rand 0.6.5",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.11"
|
version = "1.0.11"
|
||||||
@@ -618,18 +423,18 @@ checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.144"
|
version = "1.0.145"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
|
checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.144"
|
version = "1.0.145"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
|
checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -638,19 +443,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.69"
|
version = "1.0.86"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e466864e431129c7e0d3476b92f20458e5879919a0596c6472738d9fa2d342f8"
|
checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sk-cbor"
|
|
||||||
version = "0.1.2"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spin"
|
name = "spin"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
@@ -665,9 +466,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.100"
|
version = "1.0.101"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e"
|
checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -676,9 +477,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.4"
|
version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
@@ -695,12 +496,6 @@ dependencies = [
|
|||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vcpkg"
|
|
||||||
version = "0.2.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
|||||||
@@ -34,36 +34,18 @@ path = "fuzz_targets/fuzz_target_process_ctap2_client_pin.rs"
|
|||||||
test = false
|
test = false
|
||||||
doc = false
|
doc = false
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "fuzz_target_process_ctap2_client_pin_structured"
|
|
||||||
path = "fuzz_targets/fuzz_target_process_ctap2_client_pin_structured.rs"
|
|
||||||
test = false
|
|
||||||
doc = false
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "fuzz_target_process_ctap2_get_assertion"
|
name = "fuzz_target_process_ctap2_get_assertion"
|
||||||
path = "fuzz_targets/fuzz_target_process_ctap2_get_assertion.rs"
|
path = "fuzz_targets/fuzz_target_process_ctap2_get_assertion.rs"
|
||||||
test = false
|
test = false
|
||||||
doc = false
|
doc = false
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "fuzz_target_process_ctap2_get_assertion_structured"
|
|
||||||
path = "fuzz_targets/fuzz_target_process_ctap2_get_assertion_structured.rs"
|
|
||||||
test = false
|
|
||||||
doc = false
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "fuzz_target_process_ctap2_make_credential"
|
name = "fuzz_target_process_ctap2_make_credential"
|
||||||
path = "fuzz_targets/fuzz_target_process_ctap2_make_credential.rs"
|
path = "fuzz_targets/fuzz_target_process_ctap2_make_credential.rs"
|
||||||
test = false
|
test = false
|
||||||
doc = false
|
doc = false
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "fuzz_target_process_ctap2_make_credential_structured"
|
|
||||||
path = "fuzz_targets/fuzz_target_process_ctap2_make_credential_structured.rs"
|
|
||||||
test = false
|
|
||||||
doc = false
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "fuzz_target_split_assemble"
|
name = "fuzz_target_split_assemble"
|
||||||
path = "fuzz_targets/fuzz_target_split_assemble.rs"
|
path = "fuzz_targets/fuzz_target_split_assemble.rs"
|
||||||
|
|||||||
@@ -7,11 +7,8 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
arrayref = "0.3.6"
|
arrayref = "0.3.6"
|
||||||
embedded-time = "0.12.1"
|
|
||||||
libtock_drivers = { path = "../../third_party/libtock-drivers" }
|
libtock_drivers = { path = "../../third_party/libtock-drivers" }
|
||||||
crypto = { path = "../../libraries/crypto", features = ['std'] }
|
crypto = { path = "../../libraries/crypto", features = ['std'] }
|
||||||
rng256 = { path = "../../libraries/rng256", features = ['std'] }
|
cbor = { path = "../../libraries/cbor", features = ['std'] }
|
||||||
sk-cbor = { path = "../../libraries/cbor" }
|
ctap2 = { path = "../..", features = ['std'] }
|
||||||
ctap2 = { path = "../..", features = ["fuzz"] }
|
|
||||||
lang_items = { path = "../../third_party/lang-items", features = ['std'] }
|
lang_items = { path = "../../third_party/lang-items", features = ['std'] }
|
||||||
arbitrary = { version = "0.4.7", features = ["derive"] }
|
|
||||||
|
|||||||
@@ -16,25 +16,27 @@
|
|||||||
// `libtock_alloc_init` symbol.
|
// `libtock_alloc_init` symbol.
|
||||||
extern crate lang_items;
|
extern crate lang_items;
|
||||||
|
|
||||||
use arbitrary::{Arbitrary, Unstructured};
|
|
||||||
use arrayref::array_ref;
|
use arrayref::array_ref;
|
||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
use ctap2::api::customization::is_valid;
|
use crypto::rng256::ThreadRng256;
|
||||||
use ctap2::clock::CtapInstant;
|
|
||||||
use ctap2::ctap::command::{
|
use ctap2::ctap::command::{
|
||||||
AuthenticatorClientPinParameters, AuthenticatorGetAssertionParameters,
|
AuthenticatorClientPinParameters, AuthenticatorGetAssertionParameters,
|
||||||
AuthenticatorMakeCredentialParameters, Command,
|
AuthenticatorMakeCredentialParameters,
|
||||||
};
|
};
|
||||||
use ctap2::ctap::data_formats::EnterpriseAttestationMode;
|
use ctap2::ctap::hid::receive::MessageAssembler;
|
||||||
use ctap2::ctap::hid::{
|
use ctap2::ctap::hid::send::HidPacketIterator;
|
||||||
ChannelID, CtapHidCommand, HidPacket, HidPacketIterator, Message, MessageAssembler,
|
use ctap2::ctap::hid::{ChannelID, CtapHid, HidPacket, Message};
|
||||||
};
|
use ctap2::ctap::status_code::Ctap2StatusCode;
|
||||||
use ctap2::ctap::{cbor_read, Channel, CtapState};
|
use ctap2::ctap::CtapState;
|
||||||
use ctap2::env::test::customization::TestCustomization;
|
use libtock_drivers::timer::{ClockValue, Timestamp};
|
||||||
use ctap2::env::test::TestEnv;
|
|
||||||
use ctap2::{test_helpers, Ctap, Transport};
|
|
||||||
|
|
||||||
|
const COMMAND_INIT: u8 = 0x06;
|
||||||
const CHANNEL_BROADCAST: ChannelID = [0xFF, 0xFF, 0xFF, 0xFF];
|
const CHANNEL_BROADCAST: ChannelID = [0xFF, 0xFF, 0xFF, 0xFF];
|
||||||
|
const PACKET_TYPE_MASK: u8 = 0x80;
|
||||||
|
|
||||||
|
const CLOCK_FREQUENCY_HZ: usize = 32768;
|
||||||
|
const DUMMY_TIMESTAMP: Timestamp<isize> = Timestamp::from_ms(0);
|
||||||
|
const DUMMY_CLOCK_VALUE: ClockValue = ClockValue::new(0, CLOCK_FREQUENCY_HZ);
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub enum InputType {
|
pub enum InputType {
|
||||||
@@ -44,17 +46,8 @@ pub enum InputType {
|
|||||||
Ctap1,
|
Ctap1,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum FuzzError {
|
fn user_immediately_present(_: ChannelID) -> Result<(), Ctap2StatusCode> {
|
||||||
ArbitraryError(arbitrary::Error),
|
Ok(())
|
||||||
InvalidCustomization,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type FuzzResult<T> = Result<T, FuzzError>;
|
|
||||||
|
|
||||||
impl From<arbitrary::Error> for FuzzError {
|
|
||||||
fn from(err: arbitrary::Error) -> Self {
|
|
||||||
Self::ArbitraryError(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts a byte slice into Message
|
// Converts a byte slice into Message
|
||||||
@@ -64,14 +57,13 @@ fn raw_to_message(data: &[u8]) -> Message {
|
|||||||
cid[..data.len()].copy_from_slice(data);
|
cid[..data.len()].copy_from_slice(data);
|
||||||
Message {
|
Message {
|
||||||
cid,
|
cid,
|
||||||
// Arbitrary command.
|
cmd: 0,
|
||||||
cmd: CtapHidCommand::Cbor,
|
|
||||||
payload: vec![],
|
payload: vec![],
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Message {
|
Message {
|
||||||
cid: array_ref!(data, 0, 4).clone(),
|
cid: array_ref!(data, 0, 4).clone(),
|
||||||
cmd: CtapHidCommand::from(data[4]),
|
cmd: data[4],
|
||||||
payload: data[5..].to_vec(),
|
payload: data[5..].to_vec(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,22 +71,24 @@ fn raw_to_message(data: &[u8]) -> Message {
|
|||||||
|
|
||||||
// Returns an initialized ctap state, hid and the allocated cid
|
// Returns an initialized ctap state, hid and the allocated cid
|
||||||
// after processing the init command.
|
// after processing the init command.
|
||||||
fn initialize(ctap: &mut Ctap<TestEnv>) -> ChannelID {
|
fn initialize<CheckUserPresence>(
|
||||||
|
ctap_state: &mut CtapState<ThreadRng256, CheckUserPresence>,
|
||||||
|
ctap_hid: &mut CtapHid,
|
||||||
|
) -> ChannelID
|
||||||
|
where
|
||||||
|
CheckUserPresence: Fn(ChannelID) -> Result<(), Ctap2StatusCode>,
|
||||||
|
{
|
||||||
let nonce = vec![0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0];
|
let nonce = vec![0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0];
|
||||||
let message = Message {
|
let message = Message {
|
||||||
cid: CHANNEL_BROADCAST,
|
cid: CHANNEL_BROADCAST,
|
||||||
cmd: CtapHidCommand::Init,
|
cmd: COMMAND_INIT,
|
||||||
payload: nonce,
|
payload: nonce,
|
||||||
};
|
};
|
||||||
let mut assembler_reply = MessageAssembler::new();
|
let mut assembler_reply = MessageAssembler::new();
|
||||||
let mut result_cid: ChannelID = Default::default();
|
let mut result_cid: ChannelID = Default::default();
|
||||||
for pkt_request in HidPacketIterator::new(message).unwrap() {
|
for pkt_request in HidPacketIterator::new(message).unwrap() {
|
||||||
for pkt_reply in
|
for pkt_reply in ctap_hid.process_hid_packet(&pkt_request, DUMMY_CLOCK_VALUE, ctap_state) {
|
||||||
ctap.process_hid_packet(&pkt_request, Transport::MainHid, CtapInstant::new(0))
|
if let Ok(Some(result)) = assembler_reply.parse_packet(&pkt_reply, DUMMY_TIMESTAMP) {
|
||||||
{
|
|
||||||
if let Ok(Some(result)) =
|
|
||||||
assembler_reply.parse_packet(ctap.env(), &pkt_reply, CtapInstant::new(0))
|
|
||||||
{
|
|
||||||
result_cid.copy_from_slice(&result.payload[8..12]);
|
result_cid.copy_from_slice(&result.payload[8..12]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +101,7 @@ fn is_type(data: &[u8], input_type: InputType) -> bool {
|
|||||||
if input_type == InputType::Ctap1 {
|
if input_type == InputType::Ctap1 {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
match cbor_read(data) {
|
match cbor::read(data) {
|
||||||
Err(_) => false,
|
Err(_) => false,
|
||||||
Ok(decoded_cbor) => match input_type {
|
Ok(decoded_cbor) => match input_type {
|
||||||
InputType::CborMakeCredentialParameter => {
|
InputType::CborMakeCredentialParameter => {
|
||||||
@@ -126,16 +120,22 @@ fn is_type(data: &[u8], input_type: InputType) -> bool {
|
|||||||
|
|
||||||
// Interprets the raw data as a complete message (with channel id, command type and payload) and
|
// Interprets the raw data as a complete message (with channel id, command type and payload) and
|
||||||
// invokes message splitting, packet processing at CTAP HID level and response assembling.
|
// invokes message splitting, packet processing at CTAP HID level and response assembling.
|
||||||
fn process_message(data: &[u8], ctap: &mut Ctap<TestEnv>) {
|
fn process_message<CheckUserPresence>(
|
||||||
|
data: &[u8],
|
||||||
|
ctap_state: &mut CtapState<ThreadRng256, CheckUserPresence>,
|
||||||
|
ctap_hid: &mut CtapHid,
|
||||||
|
) where
|
||||||
|
CheckUserPresence: Fn(ChannelID) -> Result<(), Ctap2StatusCode>,
|
||||||
|
{
|
||||||
let message = raw_to_message(data);
|
let message = raw_to_message(data);
|
||||||
if let Some(hid_packet_iterator) = HidPacketIterator::new(message) {
|
if let Some(hid_packet_iterator) = HidPacketIterator::new(message) {
|
||||||
let mut assembler_reply = MessageAssembler::new();
|
let mut assembler_reply = MessageAssembler::new();
|
||||||
for pkt_request in hid_packet_iterator {
|
for pkt_request in hid_packet_iterator {
|
||||||
for pkt_reply in
|
for pkt_reply in
|
||||||
ctap.process_hid_packet(&pkt_request, Transport::MainHid, CtapInstant::new(0))
|
ctap_hid.process_hid_packet(&pkt_request, DUMMY_CLOCK_VALUE, ctap_state)
|
||||||
{
|
{
|
||||||
// Only checks for assembling crashes, not for semantics.
|
// Only checks for assembling crashes, not for semantics.
|
||||||
let _ = assembler_reply.parse_packet(ctap.env(), &pkt_reply, CtapInstant::new(0));
|
let _ = assembler_reply.parse_packet(&pkt_reply, DUMMY_TIMESTAMP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,66 +144,30 @@ fn process_message(data: &[u8], ctap: &mut Ctap<TestEnv>) {
|
|||||||
// Interprets the raw data as any ctap command (including the command byte) and
|
// Interprets the raw data as any ctap command (including the command byte) and
|
||||||
// invokes message splitting, packet processing at CTAP HID level and response assembling
|
// invokes message splitting, packet processing at CTAP HID level and response assembling
|
||||||
// using an initialized and allocated channel.
|
// using an initialized and allocated channel.
|
||||||
pub fn process_ctap_any_type(data: &[u8]) -> arbitrary::Result<()> {
|
pub fn process_ctap_any_type(data: &[u8]) {
|
||||||
let mut unstructured = Unstructured::new(data);
|
|
||||||
|
|
||||||
let mut env = TestEnv::new();
|
|
||||||
env.rng().seed_from_u64(u64::arbitrary(&mut unstructured)?);
|
|
||||||
|
|
||||||
let data = unstructured.take_rest();
|
|
||||||
// Initialize ctap state and hid and get the allocated cid.
|
// Initialize ctap state and hid and get the allocated cid.
|
||||||
let mut ctap = Ctap::new(env, CtapInstant::new(0));
|
let mut rng = ThreadRng256 {};
|
||||||
let cid = initialize(&mut ctap);
|
let mut ctap_state = CtapState::new(&mut rng, user_immediately_present, DUMMY_CLOCK_VALUE);
|
||||||
|
let mut ctap_hid = CtapHid::new();
|
||||||
|
let cid = initialize(&mut ctap_state, &mut ctap_hid);
|
||||||
// Wrap input as message with the allocated cid.
|
// Wrap input as message with the allocated cid.
|
||||||
let mut command = cid.to_vec();
|
let mut command = cid.to_vec();
|
||||||
command.extend(data);
|
command.extend(data);
|
||||||
process_message(&command, &mut ctap);
|
process_message(&command, &mut ctap_state, &mut ctap_hid);
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setup_customization(
|
|
||||||
unstructured: &mut Unstructured,
|
|
||||||
customization: &mut TestCustomization,
|
|
||||||
) -> FuzzResult<()> {
|
|
||||||
customization.setup_enterprise_attestation(
|
|
||||||
Option::<EnterpriseAttestationMode>::arbitrary(unstructured)?,
|
|
||||||
// TODO: Generate arbitrary rp_id_list (but with some dummies because content doesn't
|
|
||||||
// matter), and use the rp ids in commands.
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
if !is_valid(customization) {
|
|
||||||
return Err(FuzzError::InvalidCustomization);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setup_state(
|
|
||||||
unstructured: &mut Unstructured,
|
|
||||||
state: &mut CtapState,
|
|
||||||
env: &mut TestEnv,
|
|
||||||
) -> FuzzResult<()> {
|
|
||||||
if bool::arbitrary(unstructured)? {
|
|
||||||
test_helpers::enable_enterprise_attestation(state, env).ok();
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interprets the raw data as of the given input type and
|
// Interprets the raw data as of the given input type and
|
||||||
// invokes message splitting, packet processing at CTAP HID level and response assembling
|
// invokes message splitting, packet processing at CTAP HID level and response assembling
|
||||||
// using an initialized and allocated channel.
|
// using an initialized and allocated channel.
|
||||||
pub fn process_ctap_specific_type(data: &[u8], input_type: InputType) -> arbitrary::Result<()> {
|
pub fn process_ctap_specific_type(data: &[u8], input_type: InputType) {
|
||||||
let mut unstructured = Unstructured::new(data);
|
|
||||||
|
|
||||||
let mut env = TestEnv::new();
|
|
||||||
env.rng().seed_from_u64(u64::arbitrary(&mut unstructured)?);
|
|
||||||
|
|
||||||
let data = unstructured.take_rest();
|
|
||||||
if !is_type(data, input_type) {
|
if !is_type(data, input_type) {
|
||||||
return Ok(());
|
return;
|
||||||
}
|
}
|
||||||
// Initialize ctap state and hid and get the allocated cid.
|
// Initialize ctap state and hid and get the allocated cid.
|
||||||
let mut ctap = Ctap::new(env, CtapInstant::new(0));
|
let mut rng = ThreadRng256 {};
|
||||||
let cid = initialize(&mut ctap);
|
let mut ctap_state = CtapState::new(&mut rng, user_immediately_present, DUMMY_CLOCK_VALUE);
|
||||||
|
let mut ctap_hid = CtapHid::new();
|
||||||
|
let cid = initialize(&mut ctap_state, &mut ctap_hid);
|
||||||
// Wrap input as message with allocated cid and command type.
|
// Wrap input as message with allocated cid and command type.
|
||||||
let mut command = cid.to_vec();
|
let mut command = cid.to_vec();
|
||||||
match input_type {
|
match input_type {
|
||||||
@@ -221,71 +185,24 @@ pub fn process_ctap_specific_type(data: &[u8], input_type: InputType) -> arbitra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
command.extend(data);
|
command.extend(data);
|
||||||
process_message(&command, &mut ctap);
|
process_message(&command, &mut ctap_state, &mut ctap_hid);
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn process_ctap_structured(data: &[u8], input_type: InputType) -> FuzzResult<()> {
|
|
||||||
let unstructured = &mut Unstructured::new(data);
|
|
||||||
|
|
||||||
let mut env = TestEnv::new();
|
|
||||||
env.rng().seed_from_u64(u64::arbitrary(unstructured)?);
|
|
||||||
setup_customization(unstructured, env.customization_mut())?;
|
|
||||||
|
|
||||||
let mut state = CtapState::new(&mut env, CtapInstant::new(0));
|
|
||||||
setup_state(unstructured, &mut state, &mut env)?;
|
|
||||||
|
|
||||||
let command = match input_type {
|
|
||||||
InputType::CborMakeCredentialParameter => Command::AuthenticatorMakeCredential(
|
|
||||||
AuthenticatorMakeCredentialParameters::arbitrary(unstructured)?,
|
|
||||||
),
|
|
||||||
InputType::CborGetAssertionParameter => Command::AuthenticatorGetAssertion(
|
|
||||||
AuthenticatorGetAssertionParameters::arbitrary(unstructured)?,
|
|
||||||
),
|
|
||||||
InputType::CborClientPinParameter => Command::AuthenticatorClientPin(
|
|
||||||
AuthenticatorClientPinParameters::arbitrary(unstructured)?,
|
|
||||||
),
|
|
||||||
InputType::Ctap1 => {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
state
|
|
||||||
.process_parsed_command(
|
|
||||||
&mut env,
|
|
||||||
command,
|
|
||||||
Channel::MainHid(ChannelID::arbitrary(unstructured)?),
|
|
||||||
CtapInstant::new(0),
|
|
||||||
)
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Splits the given data as HID packets and reassembles it, verifying that the original input message is reconstructed.
|
// Splits the given data as HID packets and reassembles it, verifying that the original input message is reconstructed.
|
||||||
pub fn split_assemble_hid_packets(data: &[u8]) -> arbitrary::Result<()> {
|
pub fn split_assemble_hid_packets(data: &[u8]) {
|
||||||
let mut unstructured = Unstructured::new(data);
|
let mut message = raw_to_message(data);
|
||||||
|
|
||||||
let mut env = TestEnv::new();
|
|
||||||
env.rng().seed_from_u64(u64::arbitrary(&mut unstructured)?);
|
|
||||||
|
|
||||||
let data = unstructured.take_rest();
|
|
||||||
let message = raw_to_message(data);
|
|
||||||
if let Some(hid_packet_iterator) = HidPacketIterator::new(message.clone()) {
|
if let Some(hid_packet_iterator) = HidPacketIterator::new(message.clone()) {
|
||||||
let mut assembler = MessageAssembler::new();
|
let mut assembler = MessageAssembler::new();
|
||||||
let packets: Vec<HidPacket> = hid_packet_iterator.collect();
|
let packets: Vec<HidPacket> = hid_packet_iterator.collect();
|
||||||
if let Some((last_packet, first_packets)) = packets.split_last() {
|
if let Some((last_packet, first_packets)) = packets.split_last() {
|
||||||
for packet in first_packets {
|
for packet in first_packets {
|
||||||
assert_eq!(
|
assert_eq!(assembler.parse_packet(packet, DUMMY_TIMESTAMP), Ok(None));
|
||||||
assembler.parse_packet(&mut env, packet, CtapInstant::new(0)),
|
|
||||||
Ok(None)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
message.cmd &= !PACKET_TYPE_MASK;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
assembler.parse_packet(&mut env, last_packet, CtapInstant::new(0)),
|
assembler.parse_packet(last_packet, DUMMY_TIMESTAMP),
|
||||||
Ok(Some(message))
|
Ok(Some(message))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ use libfuzzer_sys::fuzz_target;
|
|||||||
// For a more generic fuzz target including all CTAP commands, you can use
|
// For a more generic fuzz target including all CTAP commands, you can use
|
||||||
// fuzz_target_process_ctap_command.
|
// fuzz_target_process_ctap_command.
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
process_ctap_specific_type(data, InputType::Ctap1).ok();
|
process_ctap_specific_type(data, InputType::Ctap1);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ use libfuzzer_sys::fuzz_target;
|
|||||||
// For a more generic fuzz target including all CTAP commands, you can use
|
// For a more generic fuzz target including all CTAP commands, you can use
|
||||||
// fuzz_target_process_ctap_command.
|
// fuzz_target_process_ctap_command.
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
process_ctap_specific_type(data, InputType::CborClientPinParameter).ok();
|
process_ctap_specific_type(data, InputType::CborClientPinParameter);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
#![no_main]
|
|
||||||
|
|
||||||
use fuzz_helper::{process_ctap_structured, InputType};
|
|
||||||
use libfuzzer_sys::fuzz_target;
|
|
||||||
|
|
||||||
// Fuzz inputs as CTAP2 client pin command parameters.
|
|
||||||
// The inputs will used to construct arbitrary client pin parameters.
|
|
||||||
fuzz_target!(|data: &[u8]| {
|
|
||||||
process_ctap_structured(data, InputType::CborClientPinParameter).ok();
|
|
||||||
});
|
|
||||||
@@ -7,5 +7,5 @@ use libfuzzer_sys::fuzz_target;
|
|||||||
// For a more generic fuzz target including all CTAP commands, you can use
|
// For a more generic fuzz target including all CTAP commands, you can use
|
||||||
// fuzz_target_process_ctap_command.
|
// fuzz_target_process_ctap_command.
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
process_ctap_specific_type(data, InputType::CborGetAssertionParameter).ok();
|
process_ctap_specific_type(data, InputType::CborGetAssertionParameter);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
#![no_main]
|
|
||||||
|
|
||||||
use fuzz_helper::{process_ctap_structured, InputType};
|
|
||||||
use libfuzzer_sys::fuzz_target;
|
|
||||||
|
|
||||||
// Fuzz inputs as CTAP2 get assertion command parameters.
|
|
||||||
// The inputs will used to construct arbitrary get assertion parameters.
|
|
||||||
fuzz_target!(|data: &[u8]| {
|
|
||||||
process_ctap_structured(data, InputType::CborGetAssertionParameter).ok();
|
|
||||||
});
|
|
||||||
@@ -7,5 +7,5 @@ use libfuzzer_sys::fuzz_target;
|
|||||||
// For a more generic fuzz target including all CTAP commands, you can use
|
// For a more generic fuzz target including all CTAP commands, you can use
|
||||||
// fuzz_target_process_ctap_command.
|
// fuzz_target_process_ctap_command.
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
process_ctap_specific_type(data, InputType::CborMakeCredentialParameter).ok();
|
process_ctap_specific_type(data, InputType::CborMakeCredentialParameter);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
#![no_main]
|
|
||||||
|
|
||||||
use fuzz_helper::{process_ctap_structured, InputType};
|
|
||||||
use libfuzzer_sys::fuzz_target;
|
|
||||||
|
|
||||||
// Fuzz inputs as CTAP2 make credential command parameters.
|
|
||||||
// The inputs will used to construct arbitrary make credential parameters.
|
|
||||||
fuzz_target!(|data: &[u8]| {
|
|
||||||
process_ctap_structured(data, InputType::CborMakeCredentialParameter).ok();
|
|
||||||
});
|
|
||||||
@@ -5,5 +5,5 @@ use libfuzzer_sys::fuzz_target;
|
|||||||
|
|
||||||
// Generically fuzz inputs as CTAP commands.
|
// Generically fuzz inputs as CTAP commands.
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
process_ctap_any_type(data).ok();
|
process_ctap_any_type(data);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ use libfuzzer_sys::fuzz_target;
|
|||||||
|
|
||||||
// Fuzzing HID packets splitting and assembling functions.
|
// Fuzzing HID packets splitting and assembling functions.
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
split_assemble_hid_packets(data).ok();
|
split_assemble_hid_packets(data);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
"""Creates a directory containing seed inputs from a json file having
|
|
||||||
the following structure:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"hex": "a901a1182a182a02a3626964781a6d616b655f6261645f7...",
|
|
||||||
"cbor": "{1: h'42', 2: {\"id\": \"make.example.com\", ...",
|
|
||||||
"description": "make credential parameters"
|
|
||||||
},
|
|
||||||
...
|
|
||||||
]
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
- pass the resulting corpus directory path as the first argument
|
|
||||||
- pass the json file path to make the corpus from as the second argument
|
|
||||||
Example:
|
|
||||||
python make_corpus.py ./corpus ./corpus_file.json
|
|
||||||
"""
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
|
# Creates a directory containing seed inputs from a json file having
|
||||||
|
# the following structure:
|
||||||
|
# [
|
||||||
|
# {
|
||||||
|
# "hex": "a901a1182a182a02a3626964781a6d616b655f6261645f7...",
|
||||||
|
# "cbor": "{1: h'42', 2: {\"id\": \"make.example.com\", ...",
|
||||||
|
# "description": "make credential parameters"
|
||||||
|
# },
|
||||||
|
# ...
|
||||||
|
# ]
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# - pass the resulting corpus directory path as the first argument
|
||||||
|
# - pass the json file path to make the corpus from as the second argument
|
||||||
|
# Example:
|
||||||
|
# python make_corpus.py ./corpus ./corpus_file.json
|
||||||
|
|
||||||
|
|
||||||
# Creates a corpus directory to the given path from the given json file.
|
# Creates a corpus directory to the given path from the given json file.
|
||||||
def make_corpus(corpus_dir, corpus_json):
|
def make_corpus(corpus_dir, corpus_json):
|
||||||
|
|||||||
58
layout.ld
58
layout.ld
@@ -14,6 +14,7 @@
|
|||||||
* FLASH (rx) : ORIGIN = 0x10030, LENGTH = 0x0FFD0
|
* FLASH (rx) : ORIGIN = 0x10030, LENGTH = 0x0FFD0
|
||||||
* SRAM (RWX) : ORIGIN = 0x20000, LENGTH = 0x10000
|
* SRAM (RWX) : ORIGIN = 0x20000, LENGTH = 0x10000
|
||||||
* }
|
* }
|
||||||
|
* STACK_SIZE = 2048;
|
||||||
* MPU_MIN_ALIGN = 8K;
|
* MPU_MIN_ALIGN = 8K;
|
||||||
* INCLUDE ../libtock-rs/layout.ld
|
* INCLUDE ../libtock-rs/layout.ld
|
||||||
*/
|
*/
|
||||||
@@ -24,15 +25,9 @@ SECTIONS {
|
|||||||
/* Section for just the app crt0 header.
|
/* Section for just the app crt0 header.
|
||||||
* This must be first so that the app can find it.
|
* This must be first so that the app can find it.
|
||||||
*/
|
*/
|
||||||
/* Runtime setup logic. The crt0_header symbol is used by the entry point
|
.crt0_header :
|
||||||
* assembly. We have to include start here rather than .text because
|
|
||||||
* otherwise elf2tab fails to recognize that the process binary's flash
|
|
||||||
* region should start at the beginning of .start.
|
|
||||||
*/
|
|
||||||
.start :
|
|
||||||
{
|
{
|
||||||
_beginning = .; /* Start of the app in flash. */
|
_beginning = .; /* Start of the app in flash. */
|
||||||
crt0_header = .;
|
|
||||||
/**
|
/**
|
||||||
* Populate the header expected by `crt0`:
|
* Populate the header expected by `crt0`:
|
||||||
*
|
*
|
||||||
@@ -69,41 +64,32 @@ SECTIONS {
|
|||||||
* .rel.data section */
|
* .rel.data section */
|
||||||
LONG(LOADADDR(.endflash) - _beginning);
|
LONG(LOADADDR(.endflash) - _beginning);
|
||||||
/* The size of the stack requested by this application */
|
/* The size of the stack requested by this application */
|
||||||
LONG(_stack_top_aligned - _sstack);
|
LONG(STACK_SIZE);
|
||||||
/* Pad the header out to a multiple of 32 bytes so there is not a gap
|
/* 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,
|
* between the header and subsequent .data section. It's unclear why,
|
||||||
* but LLD is aligning sections to a multiple of 32 bytes. */
|
* but LLD is aligning sections to a multiple of 32 bytes. */
|
||||||
. = ALIGN(32);
|
. = ALIGN(32);
|
||||||
|
} > FLASH =0xFF
|
||||||
*(.start)
|
|
||||||
} > FLASH =0xFFFFFFFF
|
|
||||||
|
|
||||||
/* Text section, Code! */
|
/* Text section, Code! */
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_text = .;
|
_text = .;
|
||||||
|
KEEP (*(.start))
|
||||||
*(.text*)
|
*(.text*)
|
||||||
*(.rodata*)
|
*(.rodata*)
|
||||||
KEEP (*(.syscalls))
|
KEEP (*(.syscalls))
|
||||||
*(.ARM.extab*)
|
*(.ARM.extab*)
|
||||||
. = ALIGN(4); /* Make sure we're word-aligned here */
|
. = ALIGN(4); /* Make sure we're word-aligned here */
|
||||||
_etext = .;
|
_etext = .;
|
||||||
} > FLASH =0xFFFFFFFF
|
} > FLASH =0xFF
|
||||||
|
|
||||||
/* Application stack */
|
/* Application stack */
|
||||||
.stack (NOLOAD) :
|
.stack :
|
||||||
{
|
{
|
||||||
/* elf2tab requires that the `_sram_origin` symbol be present to
|
. = . + STACK_SIZE;
|
||||||
* mark the first address in the SRAM memory. Since ELF files do
|
|
||||||
* not really need to specify this address as they only care about
|
|
||||||
* loading into flash, we need to manually mark this address for
|
|
||||||
* elf2tab. elf2tab will use it to add a fixed address header in the
|
|
||||||
* TBF header if needed.
|
|
||||||
*/
|
|
||||||
_sram_origin = .;
|
|
||||||
_sstack = .;
|
|
||||||
KEEP(*(.stack_buffer))
|
|
||||||
_stack_top_unaligned = .;
|
_stack_top_unaligned = .;
|
||||||
. = ALIGN(8);
|
. = ALIGN(8);
|
||||||
_stack_top_aligned = .;
|
_stack_top_aligned = .;
|
||||||
@@ -118,7 +104,6 @@ SECTIONS {
|
|||||||
. = ALIGN(4); /* Make sure we're word-aligned here */
|
. = ALIGN(4); /* Make sure we're word-aligned here */
|
||||||
_data = .;
|
_data = .;
|
||||||
KEEP(*(.data*))
|
KEEP(*(.data*))
|
||||||
*(.sdata*) /* RISC-V small-pointer data section */
|
|
||||||
. = ALIGN(4); /* Make sure we're word-aligned at the end of flash */
|
. = ALIGN(4); /* Make sure we're word-aligned at the end of flash */
|
||||||
} > SRAM
|
} > SRAM
|
||||||
|
|
||||||
@@ -137,7 +122,7 @@ SECTIONS {
|
|||||||
{
|
{
|
||||||
. = ALIGN(4); /* Make sure we're word-aligned here */
|
. = ALIGN(4); /* Make sure we're word-aligned here */
|
||||||
_bss = .;
|
_bss = .;
|
||||||
KEEP(*(.bss* .sbss*))
|
KEEP(*(.bss*))
|
||||||
*(COMMON)
|
*(COMMON)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
} > SRAM
|
} > SRAM
|
||||||
@@ -147,11 +132,26 @@ SECTIONS {
|
|||||||
{
|
{
|
||||||
} > FLASH
|
} > FLASH
|
||||||
|
|
||||||
/* Sections we do not need. */
|
/* ARM Exception support
|
||||||
/DISCARD/ :
|
*
|
||||||
|
* 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 :
|
||||||
{
|
{
|
||||||
*(.ARM.exidx .eh_frame)
|
/* (C++) Index entries for section unwinding */
|
||||||
}
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > FLASH
|
||||||
|
PROVIDE_HIDDEN (__exidx_end = .);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT((_stack_top_aligned - _stack_top_unaligned) == 0, "
|
ASSERT((_stack_top_aligned - _stack_top_unaligned) == 0, "
|
||||||
|
|||||||
6
libraries/cbor/Cargo.lock
generated
6
libraries/cbor/Cargo.lock
generated
@@ -1,7 +1,5 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sk-cbor"
|
name = "cbor"
|
||||||
version = "0.1.2"
|
version = "0.1.0"
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user