Infineon: Add cyw20829 platform, shared slot feature, json memory map, psoc6 xip
Based in 1.8.0 release of MCUBoot library
This commit adds CYW20829 Infineon platform support with following capabilities:
1. Overwrite and swap upgrade mode support
2. Multi-image with up to 4 images
3. Hardware security counter is supported for CYW20829 platform
Add XIP support for PSOC6 platform - place BOOT slot in external memory and execute it in place using SMIF in XIP mode
and some new features for Infineon devices.
1. Shared upgrade slot feature - use one shared area for upgrade slots of multiple images
2. Memory map defined using JSON file - define memory regions for bootloader and user app in conventional way using JSON file
diff --git a/.github/workflows/fih_tests.yaml b/.github/workflows/fih_tests.yaml
new file mode 100644
index 0000000..d2fef8b
--- /dev/null
+++ b/.github/workflows/fih_tests.yaml
@@ -0,0 +1,49 @@
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+
+name: FIH hardening
+
+jobs:
+ config:
+ strategy:
+ matrix:
+ fih_env:
+ # FIH environment must use the following space separated format:
+ # BUILD_TYPE SKIP_SIZE DAMAGE_TYPE FIH_LEVEL(optional)
+ - "RELEASE 2,4,6,8,10 SIGNATURE"
+ - "RELEASE 2,4,6,8,10 SIGNATURE LOW"
+ - "RELEASE 2,4,6,8,10 SIGNATURE MEDIUM"
+ - "MINSIZEREL 2,4,6 SIGNATURE"
+ - "MINSIZEREL 2,4,6 SIGNATURE LOW"
+ - "MINSIZEREL 2,4,6 SIGNATURE MEDIUM"
+ - "MINSIZEREL 8,10 SIGNATURE"
+ - "MINSIZEREL 8,10 SIGNATURE LOW"
+ - "MINSIZEREL 8,10 SIGNATURE MEDIUM"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ # Uses Mbed TLS from TFM, and nothing else from here.
+ submodules: false
+ - name: Print the environment
+ run: |
+ uname -a
+ lscpu
+ free
+ pwd
+ - name: Signed commit check
+ if: ${{ github.event_name == 'pull_request' }}
+ run: |
+ ./ci/check-signed-off-by.sh
+ - name: FIH hardening test install
+ run: |
+ ./ci/fih-tests_install.sh
+ - name: FIH hardening test run
+ env:
+ FIH_ENV: ${{ matrix.fih_env }}
+ run: |
+ ./ci/fih-tests_run.sh
diff --git a/.github/workflows/imgtool.yaml b/.github/workflows/imgtool.yaml
index c86d9e5..07f660c 100644
--- a/.github/workflows/imgtool.yaml
+++ b/.github/workflows/imgtool.yaml
@@ -1,7 +1,7 @@
on:
push:
branches:
- - master
+ - main
- v*-branch
name: imgtool
diff --git a/.github/workflows/mynewt.yaml b/.github/workflows/mynewt.yaml
index b4f5e07..46f41d6 100644
--- a/.github/workflows/mynewt.yaml
+++ b/.github/workflows/mynewt.yaml
@@ -2,7 +2,7 @@
on:
push:
branches:
- - master
+ - main
pull_request:
name: Mynewt
diff --git a/.github/workflows/sim.yaml b/.github/workflows/sim.yaml
index c866715..df103ac 100644
--- a/.github/workflows/sim.yaml
+++ b/.github/workflows/sim.yaml
@@ -2,7 +2,7 @@
on:
push:
branches:
- - master
+ - main
pull_request:
name: Sim
@@ -15,22 +15,29 @@
- "sig-ecdsa,sig-ecdsa-mbedtls,sig-ed25519,enc-kw,bootstrap"
- "sig-rsa,sig-rsa3072,overwrite-only,validate-primary-slot,swap-move"
- "enc-rsa"
+ - "enc-aes256-rsa"
- "enc-ec256"
+ - "enc-aes256-ec256"
- "enc-x25519"
+ - "enc-aes256-x25519"
- "sig-rsa overwrite-only large-write,sig-ecdsa overwrite-only large-write,sig-ecdsa-mbedtls overwrite-only large-write,multiimage overwrite-only large-write"
- "sig-rsa validate-primary-slot,sig-ecdsa validate-primary-slot,sig-ecdsa-mbedtls validate-primary-slot,sig-rsa multiimage validate-primary-slot"
- "enc-kw overwrite-only large-write,enc-rsa overwrite-only large-write"
+ - "enc-aes256-kw overwrite-only large-write,enc-rsa overwrite-only large-write"
- "sig-rsa enc-rsa validate-primary-slot,swap-move enc-rsa sig-rsa validate-primary-slot bootstrap"
- "sig-rsa enc-kw validate-primary-slot bootstrap,sig-ed25519 enc-x25519 validate-primary-slot"
- "sig-ecdsa enc-kw validate-primary-slot"
- "sig-ecdsa-mbedtls enc-kw validate-primary-slot"
- "sig-rsa validate-primary-slot overwrite-only large-write"
- "sig-ecdsa enc-ec256 validate-primary-slot"
- # ecdsa-mbedtls and enc-ec256 are not currently supported
- # together, as the ec256 code requires only one backend be
- # active.
- # - "sig-ecdsa-mbedtls enc-ec256 validate-primary-slot"
+ - "sig-ecdsa-mbedtls enc-ec256-mbedtls validate-primary-slot"
+ - "sig-ecdsa-mbedtls enc-aes256-ec256 validate-primary-slot"
- "sig-rsa validate-primary-slot overwrite-only downgrade-prevention"
+ - "sig-rsa validate-primary-slot ram-load"
+ - "sig-rsa enc-rsa validate-primary-slot ram-load"
+ - "sig-rsa validate-primary-slot direct-xip"
+ - "sig-rsa validate-primary-slot ram-load multiimage"
+ - "sig-rsa validate-primary-slot direct-xip multiimage"
runs-on: ubuntu-latest
env:
MULTI_FEATURES: ${{ matrix.features }}
diff --git a/.github/workflows/stale_issue.yml b/.github/workflows/stale_issue.yml
new file mode 100644
index 0000000..6dec8b1
--- /dev/null
+++ b/.github/workflows/stale_issue.yml
@@ -0,0 +1,24 @@
+name: "Close stale pull requests/issues"
+on:
+ schedule:
+ - cron: "16 00 * * *"
+
+jobs:
+ stale:
+ name: Find Stale issues and PRs
+ runs-on: ubuntu-latest
+ if: github.repository == 'mcu-tools/mcuboot'
+ steps:
+ - uses: actions/stale@v3
+ with:
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
+ stale-pr-message: 'This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time.'
+ stale-issue-message: 'This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.'
+ days-before-stale: 180
+ days-before-close: 14
+ stale-issue-label: 'stale'
+ stale-pr-label: 'stale'
+ exempt-issue-labels: 'someday'
+ # exempt-pr-labels: 'Blocked,In progress'
+ # exempt-issue-labels: 'In progress,Enhancement,Feature,Feature Request,RFC,Meta'
+ operations-per-run: 400
diff --git a/.gitignore b/.gitignore
index 4169afc..7986688 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,6 @@
# Python egg metadata, regenerated from source files by setuptools.
/scripts/*.egg-info
/scripts/*.egg
+
+# The target directory from Rust development
+/target/
diff --git a/.gitmodules b/.gitmodules
index 1e4e333..8137634 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,24 +1,21 @@
[submodule "sim/mbedtls"]
path = ext/mbedtls
url = https://github.com/ARMmbed/mbedtls
-[submodule "boot/cypress/libs/mtb-pdl-cat1"]
- path = boot/cypress/libs/mtb-pdl-cat1
- url = https://github.com/cypresssemiconductorco/mtb-pdl-cat1.git
-[submodule "boot/cypress/libs/pdl/psoc6pdl"]
- path = boot/cypress/libs/pdl/psoc6pdl
- url = https://github.com/cypresssemiconductorco/psoc6pdl.git
-[submodule "boot/cypress/libs/retarget-io"]
- path = boot/cypress/libs/retarget-io
- url = https://github.com/cypresssemiconductorco/retarget-io.git
-[submodule "boot/cypress/libs/core-lib"]
- path = boot/cypress/libs/core-lib
- url = https://github.com/cypresssemiconductorco/core-lib.git
-[submodule "boot/cypress/libs/psoc6hal"]
- path = boot/cypress/libs/psoc6hal
- url = https://github.com/cypresssemiconductorco/psoc6hal.git
[submodule "boot/cypress/libs/cy-mbedtls-acceleration"]
path = boot/cypress/libs/cy-mbedtls-acceleration
url = https://github.com/cypresssemiconductorco/cy-mbedtls-acceleration.git
-[submodule "boot/boot_serial/src/cddl_gen"]
- path = ext/cddl_gen
- url = https://github.com/oyvindronningstad/cddl_gen.git
+[submodule "ext/cddl-gen"]
+ path = ext/cddl-gen
+ url = https://github.com/NordicSemiconductor/cddl-gen.git
+[submodule "boot/cypress/libs/mtb-pdl-cat1"]
+ path = boot/cypress/libs/mtb-pdl-cat1
+ url = https://github.com/Infineon/mtb-pdl-cat1.git
+[submodule "boot/cypress/libs/mtb-hal-cat1"]
+ path = boot/cypress/libs/mtb-hal-cat1
+ url = https://github.com/Infineon/mtb-hal-cat1.git
+[submodule "boot/cypress/libs/core-lib"]
+ path = boot/cypress/libs/core-lib
+ url = https://github.com/Infineon/core-lib.git
+[submodule "boot/cypress/libs/retarget-io"]
+ path = boot/cypress/libs/retarget-io
+ url = https://github.com/Infineon/retarget-io.git
diff --git a/.mbedignore b/.mbedignore
index bd68385..06a173e 100644
--- a/.mbedignore
+++ b/.mbedignore
@@ -2,6 +2,8 @@
boot/mynewt/*
boot/zephyr/*
boot/cypress/*
+boot/espressif/*
+boot/nuttx/*
ci/*
docs/*
ptest/*
@@ -16,4 +18,4 @@
ext/nrf/*
ext/tinycrypt/tests/*
ext/tinycrypt/*
-ext/tinycrypt-sha512/*
\ No newline at end of file
+ext/tinycrypt-sha512/*
diff --git a/.travis.yml b/.travis.yml-disabled
similarity index 100%
rename from .travis.yml
rename to .travis.yml-disabled
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..51bb693
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,134 @@
+
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, caste, color, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+mcuboot@groups.io.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
+
+Community Impact Guidelines were inspired by
+[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
+
+For answers to common questions about this code of conduct, see the FAQ at
+[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
+at [https://www.contributor-covenant.org/translations][translations].
+
+[homepage]: https://www.contributor-covenant.org
+[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
+[Mozilla CoC]: https://github.com/mozilla/diversity
+[FAQ]: https://www.contributor-covenant.org/faq
+[translations]: https://www.contributor-covenant.org/translations
+
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..b44b24b
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,612 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "aes"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "495ee669413bfbe9e8cace80f4d3d78e6d8c8d99579f97fb93bde351b185f2d4"
+dependencies = [
+ "cfg-if",
+ "cipher",
+ "cpufeatures",
+ "ctr",
+ "opaque-debug",
+]
+
+[[package]]
+name = "aho-corasick"
+version = "0.7.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "base64"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
+
+[[package]]
+name = "bootsim"
+version = "0.1.0"
+dependencies = [
+ "aes",
+ "base64",
+ "byteorder",
+ "cipher",
+ "docopt",
+ "env_logger",
+ "libc",
+ "log",
+ "mcuboot-sys",
+ "pem",
+ "rand 0.8.4",
+ "ring",
+ "serde",
+ "serde_derive",
+ "simflash",
+ "typenum",
+ "untrusted 0.9.0",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "cc"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "cipher"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "cpufeatures"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "ctr"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a232f92a03f37dd7d7dd2adc67166c77e9cd88de5b019b9a9eecfaeaf7bfd481"
+dependencies = [
+ "cipher",
+]
+
+[[package]]
+name = "docopt"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f3f119846c823f9eafcf953a8f6ffb6ed69bf6240883261a7f13b634579a51f"
+dependencies = [
+ "lazy_static",
+ "regex",
+ "serde",
+ "strsim",
+]
+
+[[package]]
+name = "env_logger"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
+dependencies = [
+ "atty",
+ "humantime",
+ "log",
+ "regex",
+ "termcolor",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.9.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.10.2+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
+[[package]]
+name = "js-sys"
+version = "0.3.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.99"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765"
+
+[[package]]
+name = "log"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "mcuboot-sys"
+version = "0.1.0"
+dependencies = [
+ "cc",
+ "libc",
+ "log",
+ "simflash",
+]
+
+[[package]]
+name = "memchr"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
+
+[[package]]
+name = "once_cell"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
+
+[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
+[[package]]
+name = "pem"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb"
+dependencies = [
+ "base64",
+ "once_cell",
+ "regex",
+]
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+dependencies = [
+ "getrandom 0.1.16",
+ "libc",
+ "rand_chacha 0.2.2",
+ "rand_core 0.5.1",
+ "rand_hc 0.2.0",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
+dependencies = [
+ "libc",
+ "rand_chacha 0.3.1",
+ "rand_core 0.6.3",
+ "rand_hc 0.3.1",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.5.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.3",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+dependencies = [
+ "getrandom 0.1.16",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
+dependencies = [
+ "getrandom 0.2.3",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+dependencies = [
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
+dependencies = [
+ "rand_core 0.6.3",
+]
+
+[[package]]
+name = "regex"
+version = "1.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
+
+[[package]]
+name = "ring"
+version = "0.16.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+dependencies = [
+ "cc",
+ "libc",
+ "once_cell",
+ "spin",
+ "untrusted 0.7.1",
+ "web-sys",
+ "winapi",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.127"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.127"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "simflash"
+version = "0.1.0"
+dependencies = [
+ "log",
+ "rand 0.7.3",
+ "thiserror",
+]
+
+[[package]]
+name = "spin"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "syn"
+version = "1.0.74"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "typenum"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
+
+[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
+[[package]]
+name = "untrusted"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+
+[[package]]
+name = "version_check"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
+
+[[package]]
+name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+
+[[package]]
+name = "wasi"
+version = "0.10.2+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.76"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.76"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041"
+dependencies = [
+ "bumpalo",
+ "lazy_static",
+ "log",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.76"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.76"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.76"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29"
+
+[[package]]
+name = "web-sys"
+version = "0.3.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..46b8a67
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,13 @@
+[workspace]
+members = ["sim"]
+exclude = ["ptest"]
+
+# The simulator runs very slowly without optimization. A value of 1
+# compiles in about half the time, but runs about 5-6 times slower. 2
+# and 3 are hardly different in either compile time or performance.
+# Use 2 in case that makes the code slightly more debuggable.
+[profile.test]
+opt-level = 2
+
+[profile.dev]
+opt-level = 2
diff --git a/NOTICE b/NOTICE
index 0b3435b..ce203c1 100644
--- a/NOTICE
+++ b/NOTICE
@@ -8,4 +8,4 @@
Runtime Inc, copyright 2015.
Portions of this software were developed at
-Arm Limited, copyright 2019-2020.
+Arm Limited, copyright 2019-2021.
diff --git a/README.md b/README.md
index d7c0674..861c4d1 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
[][sim]
[][mynewt]
[][imgtool]
-[][travis]
+[][travis]
[][license]
[pypi]: https://pypi.org/project/imgtool/
@@ -14,9 +14,9 @@
[mynewt]: https://github.com/mcu-tools/mcuboot/actions?query=workflow:Mynewt
[imgtool]: https://github.com/mcu-tools/mcuboot/actions?query=workflow:imgtool
[travis]: https://travis-ci.org/mcu-tools/mcuboot
-[license]: https://github.com/mcu-tools/mcuboot/blob/master/LICENSE
+[license]: https://github.com/mcu-tools/mcuboot/blob/main/LICENSE
-This is mcuboot version 1.8.0-dev
+This is mcuboot version 1.8.0
MCUboot is a secure bootloader for 32-bit MCUs. The goal of MCUboot is to
define a common infrastructure for the bootloader, system flash layout on
@@ -36,6 +36,8 @@
- [Mynewt](docs/readme-mynewt.md)
- [RIOT](docs/readme-riot.md)
- [Mbed-OS](docs/readme-mbed.md)
+- [NuttX](docs/readme-nuttx.md)
+- [Espressif IDF](docs/readme-espressif.md)
- [Simulator](sim/README.rst)
## Roadmap
@@ -62,6 +64,8 @@
- [boot/boot\_serial](boot/boot_serial): Support for serial upgrade within the bootloader itself.
- [boot/zephyr](boot/zephyr): Port of the bootloader to Zephyr
- [boot/mynewt](boot/mynewt): Mynewt bootloader app
+- [boot/nuttx](boot/nuttx): Bootloader application and port of MCUboot interfaces for NuttX.
+- [boot/espressif](boot/espressif): Bootloader application and MCUboot port for Espressif SoCs.
- [imgtool](scripts/imgtool.py): A tool to securely sign firmware images for booting by mcuboot.
- [sim](sim): A bootloader simulator for testing and regression
diff --git a/boot/boot_serial/pkg.yml b/boot/boot_serial/pkg.yml
index f1431c7..19f9a32 100644
--- a/boot/boot_serial/pkg.yml
+++ b/boot/boot_serial/pkg.yml
@@ -28,7 +28,6 @@
pkg.deps:
- "@apache-mynewt-core/hw/hal"
- "@apache-mynewt-core/kernel/os"
- - "@apache-mynewt-core/encoding/tinycbor"
- "@apache-mynewt-core/encoding/base64"
- "@mcuboot/boot/mynewt/flash_map_backend"
- "@mcuboot/boot/mynewt/boot_uart"
diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c
index d0f0eb0..914167e 100644
--- a/boot/boot_serial/src/boot_serial.c
+++ b/boot/boot_serial/src/boot_serial.c
@@ -25,6 +25,7 @@
#include "sysflash/sysflash.h"
#include "bootutil/bootutil_log.h"
+#include "cbor_encode.h"
#ifdef __ZEPHYR__
#include <power/reboot.h>
@@ -33,8 +34,6 @@
#include <drivers/flash.h>
#include <sys/crc.h>
#include <sys/base64.h>
-#include <tinycbor/cbor.h>
-#include <tinycbor/cbor_buf_reader.h>
#else
#include <bsp/bsp.h>
#include <hal/hal_system.h>
@@ -42,7 +41,6 @@
#include <os/os_cputime.h>
#include <crc/crc16.h>
#include <base64/base64.h>
-#include <tinycbor/cbor.h>
#endif /* __ZEPHYR__ */
#include <flash_map_backend/flash_map_backend.h>
@@ -56,16 +54,21 @@
#include "boot_serial/boot_serial.h"
#include "boot_serial_priv.h"
-#ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
+#ifdef MCUBOOT_ERASE_PROGRESSIVELY
#include "bootutil_priv.h"
#endif
#include "serial_recovery_cbor.h"
+#include "bootutil/boot_hooks.h"
-MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
+BOOT_LOG_MODULE_DECLARE(mcuboot);
+
+#ifndef BOOT_IMAGE_NUMBER
+#define BOOT_IMAGE_NUMBER MCUBOOT_IMAGE_NUMBER
+#endif
#define BOOT_SERIAL_INPUT_MAX 512
-#define BOOT_SERIAL_OUT_MAX 128
+#define BOOT_SERIAL_OUT_MAX (128 * MCUBOOT_IMAGE_NUMBER)
#ifdef __ZEPHYR__
/* base64 lib encodes data to null-terminated string */
@@ -78,10 +81,6 @@
#define htons(x) sys_cpu_to_be16(x)
#endif
-#ifndef BOOT_IMAGE_NUMBER
-#define BOOT_IMAGE_NUMBER MCUBOOT_IMAGE_NUMBER
-#endif
-
#if (BOOT_IMAGE_NUMBER > 1)
#define IMAGES_ITER(x) for ((x) = 0; (x) < BOOT_IMAGE_NUMBER; ++(x))
#else
@@ -97,28 +96,28 @@
static char bs_obuf[BOOT_SERIAL_OUT_MAX];
-static int bs_cbor_writer(struct cbor_encoder_writer *, const char *data,
- int len);
static void boot_serial_output(void);
-static struct cbor_encoder_writer bs_writer = {
- .write = bs_cbor_writer
+static cbor_state_backups_t dummy_backups;
+static cbor_state_t cbor_state = {
+ .backups = &dummy_backups
};
-static CborEncoder bs_root;
-static CborEncoder bs_rsp;
-int
-bs_cbor_writer(struct cbor_encoder_writer *cew, const char *data, int len)
-{
- if (cew->bytes_written + len > sizeof(bs_obuf)) {
- return CborErrorOutOfMemory;
- }
-
- memcpy(&bs_obuf[cew->bytes_written], data, len);
- cew->bytes_written += len;
-
- return 0;
-}
+/**
+ * Function that processes MGMT_GROUP_ID_PERUSER mcumgr group and may be
+ * used to process any groups that have not been processed by generic boot
+ * serial implementation.
+ *
+ * @param[in] hdr -- the decoded header of mcumgr message;
+ * @param[in] buffer -- buffer with first mcumgr message;
+ * @param[in] len -- length of of data in buffer;
+ * @param[out] *cs -- object with encoded response.
+ *
+ * @return 0 on success; non-0 error code otherwise.
+ */
+extern int bs_peruser_system_specific(const struct nmgr_hdr *hdr,
+ const char *buffer,
+ int len, cbor_state_t *cs);
/*
* Convert version into string without use of snprintf().
@@ -172,17 +171,15 @@
static void
bs_list(char *buf, int len)
{
- CborEncoder images;
- CborEncoder image;
struct image_header hdr;
uint8_t tmpbuf[64];
- int slot, area_id;
+ uint32_t slot, area_id;
const struct flash_area *fap;
uint8_t image_index;
- cbor_encoder_create_map(&bs_root, &bs_rsp, CborIndefiniteLength);
- cbor_encode_text_stringz(&bs_rsp, "images");
- cbor_encoder_create_array(&bs_rsp, &images, CborIndefiniteLength);
+ map_start_encode(&cbor_state, 1);
+ tstrx_put(&cbor_state, "images");
+ list_start_encode(&cbor_state, 5);
image_index = 0;
IMAGES_ITER(image_index) {
for (slot = 0; slot < 2; slot++) {
@@ -191,34 +188,51 @@
continue;
}
- flash_area_read(fap, 0, &hdr, sizeof(hdr));
-
- if (hdr.ih_magic != IMAGE_MAGIC ||
- bootutil_img_validate(NULL, 0, &hdr, fap, tmpbuf, sizeof(tmpbuf),
- NULL, 0, NULL)) {
- flash_area_close(fap);
- continue;
+ int rc = BOOT_HOOK_CALL(boot_read_image_header_hook,
+ BOOT_HOOK_REGULAR, image_index, slot, &hdr);
+ if (rc == BOOT_HOOK_REGULAR)
+ {
+ flash_area_read(fap, 0, &hdr, sizeof(hdr));
}
+
+ fih_int fih_rc = FIH_FAILURE;
+
+ if (hdr.ih_magic == IMAGE_MAGIC)
+ {
+ BOOT_HOOK_CALL_FIH(boot_image_check_hook,
+ fih_int_encode(BOOT_HOOK_REGULAR),
+ fih_rc, image_index, slot);
+ if (fih_eq(fih_rc, BOOT_HOOK_REGULAR))
+ {
+ FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr, fap, tmpbuf, sizeof(tmpbuf),
+ NULL, 0, NULL);
+ }
+ }
+
flash_area_close(fap);
- cbor_encoder_create_map(&images, &image, CborIndefiniteLength);
+ if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ continue;
+ }
+
+ map_start_encode(&cbor_state, 20);
#if (BOOT_IMAGE_NUMBER > 1)
- cbor_encode_text_stringz(&image, "image");
- cbor_encode_int(&image, image_index);
+ tstrx_put(&cbor_state, "image");
+ uintx32_put(&cbor_state, image_index);
#endif
- cbor_encode_text_stringz(&image, "slot");
- cbor_encode_int(&image, slot);
- cbor_encode_text_stringz(&image, "version");
+ tstrx_put(&cbor_state, "slot");
+ uintx32_put(&cbor_state, slot);
+ tstrx_put(&cbor_state, "version");
bs_list_img_ver((char *)tmpbuf, sizeof(tmpbuf), &hdr.ih_ver);
- cbor_encode_text_stringz(&image, (char *)tmpbuf);
- cbor_encoder_close_container(&images, &image);
+ tstrx_put_term(&cbor_state, (char *)tmpbuf);
+ map_end_encode(&cbor_state, 20);
}
}
- cbor_encoder_close_container(&bs_rsp, &images);
- cbor_encoder_close_container(&bs_root, &bs_rsp);
+ list_end_encode(&cbor_state, 5);
+ map_end_encode(&cbor_state, 1);
boot_serial_output();
}
@@ -229,15 +243,15 @@
bs_upload(char *buf, int len)
{
const uint8_t *img_data = NULL;
- long long int off = UINT_MAX;
+ long long int off = UINT64_MAX;
size_t img_blen = 0;
uint8_t rem_bytes;
- long long int data_len = UINT_MAX;
+ long long int data_len = UINT64_MAX;
int img_num;
size_t slen;
const struct flash_area *fap = NULL;
int rc;
-#ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
+#ifdef MCUBOOT_ERASE_PROGRESSIVELY
static off_t off_last = -1;
struct flash_sector sector;
#endif
@@ -254,13 +268,16 @@
* }
*/
- Upload_t upload;
- if (!cbor_decode_Upload((const uint8_t *)buf, len, &upload)) {
+ struct Upload upload;
+ uint32_t decoded_len;
+ bool result = cbor_decode_Upload((const uint8_t *)buf, len, &upload, &decoded_len);
+
+ if (!result || (len != decoded_len)) {
goto out_invalid_data;
}
for (int i = 0; i < upload._Upload_members_count; i++) {
- _Member_t *member = &upload._Upload_members[i];
+ struct Member_ *member = &upload._Upload_members[i];
switch(member->_Member_choice) {
case _Member_image:
img_num = member->_Member_image;
@@ -283,14 +300,18 @@
}
}
- if (off == UINT_MAX || img_data == NULL) {
+ if (off == UINT64_MAX || img_data == NULL) {
/*
* Offset must be set in every block.
*/
goto out_invalid_data;
}
+#if !defined(MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD)
rc = flash_area_open(flash_area_id_from_multi_image_slot(img_num, 0), &fap);
+#else
+ rc = flash_area_open(flash_area_id_from_direct_image(img_num), &fap);
+#endif
if (rc) {
rc = MGMT_ERR_EINVAL;
goto out;
@@ -298,11 +319,11 @@
if (off == 0) {
curr_off = 0;
- if (data_len > fap->fa_size) {
+ if (data_len > flash_area_get_size(fap)) {
goto out_invalid_data;
}
-#ifndef CONFIG_BOOT_ERASE_PROGRESSIVELY
- rc = flash_area_erase(fap, 0, fap->fa_size);
+#ifndef MCUBOOT_ERASE_PROGRESSIVELY
+ rc = flash_area_erase(fap, 0, flash_area_get_size(fap));
if (rc) {
goto out_invalid_data;
}
@@ -326,16 +347,17 @@
rem_bytes = 0;
}
-#ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
+#ifdef MCUBOOT_ERASE_PROGRESSIVELY
rc = flash_area_sector_from_off(curr_off + img_blen, §or);
if (rc) {
BOOT_LOG_ERR("Unable to determine flash sector size");
goto out;
}
- if (off_last != sector.fs_off) {
- off_last = sector.fs_off;
- BOOT_LOG_INF("Erasing sector at offset 0x%x", sector.fs_off);
- rc = flash_area_erase(fap, sector.fs_off, sector.fs_size);
+ if (off_last != flash_sector_get_off(§or)) {
+ off_last = flash_sector_get_off(§or);
+ BOOT_LOG_INF("Erasing sector at offset 0x%x", flash_sector_get_off(§or));
+ rc = flash_area_erase(fap, flash_sector_get_off(§or),
+ flash_sector_get_size(§or));
if (rc) {
BOOT_LOG_ERR("Error %d while erasing sector", rc);
goto out;
@@ -372,8 +394,8 @@
if (rc == 0) {
curr_off += img_blen;
-#ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
if (curr_off == img_size) {
+#ifdef MCUBOOT_ERASE_PROGRESSIVELY
/* get the last sector offset */
rc = flash_area_sector_from_off(boot_status_off(fap), §or);
if (rc) {
@@ -383,16 +405,24 @@
}
/* Assure that sector for image trailer was erased. */
/* Check whether it was erased during previous upload. */
- if (off_last < sector.fs_off) {
- BOOT_LOG_INF("Erasing sector at offset 0x%x", sector.fs_off);
- rc = flash_area_erase(fap, sector.fs_off, sector.fs_size);
+ if (off_last < flash_sector_get_off(§or)) {
+ BOOT_LOG_INF("Erasing sector at offset 0x%x",
+ flash_sector_get_off(§or));
+ rc = flash_area_erase(fap, flash_sector_get_off(§or),
+ flash_sector_get_size(§or));
if (rc) {
BOOT_LOG_ERR("Error %d while erasing sector", rc);
goto out;
}
}
- }
#endif
+ rc = BOOT_HOOK_CALL(boot_serial_uploaded_hook, 0, img_num, fap,
+ img_size);
+ if (rc) {
+ BOOT_LOG_ERR("Error %d post upload hook", rc);
+ goto out;
+ }
+ }
} else {
out_invalid_data:
rc = MGMT_ERR_EINVAL;
@@ -400,14 +430,14 @@
out:
BOOT_LOG_INF("RX: 0x%x", rc);
- cbor_encoder_create_map(&bs_root, &bs_rsp, CborIndefiniteLength);
- cbor_encode_text_stringz(&bs_rsp, "rc");
- cbor_encode_int(&bs_rsp, rc);
+ map_start_encode(&cbor_state, 10);
+ tstrx_put(&cbor_state, "rc");
+ uintx32_put(&cbor_state, rc);
if (rc == 0) {
- cbor_encode_text_stringz(&bs_rsp, "off");
- cbor_encode_uint(&bs_rsp, curr_off);
+ tstrx_put(&cbor_state, "off");
+ uintx32_put(&cbor_state, curr_off);
}
- cbor_encoder_close_container(&bs_root, &bs_rsp);
+ map_end_encode(&cbor_state, 10);
boot_serial_output();
flash_area_close(fap);
@@ -419,10 +449,10 @@
static void
bs_empty_rsp(char *buf, int len)
{
- cbor_encoder_create_map(&bs_root, &bs_rsp, CborIndefiniteLength);
- cbor_encode_text_stringz(&bs_rsp, "rc");
- cbor_encode_int(&bs_rsp, 0);
- cbor_encoder_close_container(&bs_root, &bs_rsp);
+ map_start_encode(&cbor_state, 10);
+ tstrx_put(&cbor_state, "rc");
+ uintx32_put(&cbor_state, 0);
+ map_end_encode(&cbor_state, 10);
boot_serial_output();
}
@@ -436,7 +466,11 @@
bs_empty_rsp(buf, len);
#ifdef __ZEPHYR__
+#ifdef CONFIG_MULTITHREADING
k_sleep(K_MSEC(250));
+#else
+ k_busy_wait(250000);
+#endif
sys_reboot(SYS_REBOOT_COLD);
#else
os_cputime_delay_usecs(250000);
@@ -465,8 +499,9 @@
buf += sizeof(*hdr);
len -= sizeof(*hdr);
- bs_writer.bytes_written = 0;
- cbor_encoder_init(&bs_root, &bs_writer, 0);
+ cbor_state.payload_mut = (uint8_t *)bs_obuf;
+ cbor_state.payload_end = (const uint8_t *)bs_obuf
+ + sizeof(bs_obuf);
/*
* Limited support for commands.
@@ -494,6 +529,10 @@
default:
break;
}
+ } else if (MCUBOOT_PERUSER_MGMT_GROUP_ENABLED == 1) {
+ if (bs_peruser_system_specific(hdr, buf, len, &cbor_state) == 0) {
+ boot_serial_output();
+ }
}
}
@@ -509,7 +548,7 @@
char encoded_buf[BASE64_ENCODE_SIZE(BOOT_SERIAL_OUT_MAX)];
data = bs_obuf;
- len = bs_writer.bytes_written;
+ len = (uint32_t)cbor_state.payload_mut - (uint32_t)bs_obuf;
bs_hdr->nh_op++;
bs_hdr->nh_flags = 0;
@@ -624,6 +663,7 @@
off = 0;
while (1) {
+ MCUBOOT_CPU_IDLE();
rc = f->read(in_buf + off, sizeof(in_buf) - off, &full_line);
if (rc <= 0 && !full_line) {
continue;
diff --git a/boot/boot_serial/src/boot_serial_priv.h b/boot/boot_serial/src/boot_serial_priv.h
index 9275f3f..5e0211c 100644
--- a/boot/boot_serial/src/boot_serial_priv.h
+++ b/boot/boot_serial/src/boot_serial_priv.h
@@ -36,13 +36,17 @@
/*
* From newtmgr.h
*/
+#define MGMT_ERR_OK 0
+#define MGMT_ERR_EUNKNOWN 2
#define MGMT_ERR_EINVAL 3
+#define MGMT_ERR_ENOTSUP 8
#define NMGR_OP_READ 0
#define NMGR_OP_WRITE 2
#define MGMT_GROUP_ID_DEFAULT 0
#define MGMT_GROUP_ID_IMAGE 1
+#define MGMT_GROUP_ID_PERUSER 64
#define NMGR_ID_CONS_ECHO_CTRL 1
#define NMGR_ID_RESET 5
@@ -65,6 +69,19 @@
void boot_serial_input(char *buf, int len);
extern const struct boot_uart_funcs *boot_uf;
+/**
+ * @brief Selects direct image to upload according to the "image"
+ * parameter of the mcumgr update frame.
+ *
+ * @param[in] image_id the value of the "image" parameter of the
+ * mcumgr update frame to be translated.
+ *
+ * @return flash area ID for the image if defined;
+ * -EINVAL when flash area for given image number has not been
+ * defined.
+ */
+extern int flash_area_id_from_direct_image(int image_id);
+
#ifdef __cplusplus
}
#endif
diff --git a/boot/boot_serial/src/cbor_common.c b/boot/boot_serial/src/cbor_common.c
new file mode 100644
index 0000000..8a4cd9c
--- /dev/null
+++ b/boot/boot_serial/src/cbor_common.c
@@ -0,0 +1,125 @@
+/*
+ * This file has been copied from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
+ */
+
+/*
+ * Copyright (c) 2020 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "cbor_common.h"
+
+_Static_assert((sizeof(size_t) == sizeof(void *)),
+ "This code needs size_t to be the same length as pointers.");
+
+bool new_backup(cbor_state_t *state, uint32_t new_elem_count)
+{
+ if ((state->backups->current_backup + 1)
+ >= state->backups->num_backups) {
+ FAIL();
+ }
+
+ uint32_t i = ++(state->backups->current_backup);
+ memcpy(&state->backups->backup_list[i], state,
+ sizeof(cbor_state_t));
+
+ state->elem_count = new_elem_count;
+
+ return true;
+}
+
+
+bool restore_backup(cbor_state_t *state, uint32_t flags,
+ uint32_t max_elem_count)
+{
+ const uint8_t *payload = state->payload;
+ const uint32_t elem_count = state->elem_count;
+
+ if (state->backups->current_backup == 0) {
+ FAIL();
+ }
+
+ if (flags & FLAG_RESTORE) {
+ uint32_t i = state->backups->current_backup;
+
+ memcpy(state, &state->backups->backup_list[i],
+ sizeof(cbor_state_t));
+ }
+
+ if (flags & FLAG_DISCARD) {
+ state->backups->current_backup--;
+ }
+
+ if (elem_count > max_elem_count) {
+ cbor_print("elem_count: %d (expected max %d)\r\n",
+ elem_count, max_elem_count);
+ FAIL();
+ }
+
+ if (flags & FLAG_TRANSFER_PAYLOAD) {
+ state->payload = payload;
+ }
+
+ return true;
+}
+
+
+bool union_start_code(cbor_state_t *state)
+{
+ if (!new_backup(state, state->elem_count)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+bool union_elem_code(cbor_state_t *state)
+{
+ if (!restore_backup(state, FLAG_RESTORE, state->elem_count)) {
+ FAIL();
+ }
+ return true;
+}
+
+bool union_end_code(cbor_state_t *state)
+{
+ if (!restore_backup(state, FLAG_DISCARD, state->elem_count)) {
+ FAIL();
+ }
+ return true;
+}
+
+bool entry_function(const uint8_t *payload, uint32_t payload_len,
+ const void *struct_ptr, uint32_t *payload_len_out,
+ cbor_encoder_t func, uint32_t elem_count, uint32_t num_backups)
+{
+ cbor_state_t state = {
+ .payload = payload,
+ .payload_end = payload + payload_len,
+ .elem_count = elem_count,
+ };
+
+ cbor_state_t state_backups[num_backups + 1];
+
+ cbor_state_backups_t backups = {
+ .backup_list = state_backups,
+ .current_backup = 0,
+ .num_backups = num_backups + 1,
+ };
+
+ state.backups = &backups;
+
+ bool result = func(&state, struct_ptr);
+
+ if (result && (payload_len_out != NULL)) {
+ *payload_len_out = MIN(payload_len,
+ (size_t)state.payload - (size_t)payload);
+ }
+ return result;
+}
diff --git a/boot/boot_serial/src/cbor_common.h b/boot/boot_serial/src/cbor_common.h
new file mode 100644
index 0000000..e652908
--- /dev/null
+++ b/boot/boot_serial/src/cbor_common.h
@@ -0,0 +1,145 @@
+/*
+ * This file has been copied from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
+ */
+
+/*
+ * Copyright (c) 2020 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef CBOR_COMMON_H__
+#define CBOR_COMMON_H__
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+
+/** Convenience type that allows pointing to strings directly inside the payload
+ * without the need to copy out.
+ */
+typedef struct
+{
+ const uint8_t *value;
+ uint32_t len;
+} cbor_string_type_t;
+
+#ifdef CDDL_CBOR_VERBOSE
+#include <sys/printk.h>
+#define cbor_trace() (printk("bytes left: %d, byte: 0x%x, elem_count: 0x%zx, %s:%d\n",\
+ (uint32_t)state->payload_end - (uint32_t)state->payload, *state->payload, state->elem_count,\
+ __FILE__, __LINE__))
+#define cbor_assert(expr, ...) \
+do { \
+ if (!(expr)) { \
+ printk("ASSERTION \n \"" #expr \
+ "\"\nfailed at %s:%d with message:\n ", \
+ __FILE__, __LINE__); \
+ printk(__VA_ARGS__);\
+ return false; \
+ } \
+} while(0)
+#define cbor_print(...) printk(__VA_ARGS__)
+#else
+#define cbor_trace() ((void)state)
+#define cbor_assert(...)
+#define cbor_print(...)
+#endif
+
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+
+struct cbor_state_backups_s;
+
+typedef struct cbor_state_backups_s cbor_state_backups_t;
+
+typedef struct{
+union {
+ uint8_t *payload_mut;
+ uint8_t const *payload; /**< The current place in the payload. Will be
+ updated when an element is correctly
+ processed. */
+};
+ uint8_t const *payload_bak; /**< Temporary backup of payload. */
+ uint32_t elem_count; /**< The current element is part of a LIST or a MAP,
+ and this keeps count of how many elements are
+ expected. This will be checked before processing
+ and decremented if the element is correctly
+ processed. */
+ uint8_t const *payload_end; /**< The end of the payload. This will be
+ checked against payload before
+ processing each element. */
+ cbor_state_backups_t *backups;
+} cbor_state_t;
+
+struct cbor_state_backups_s{
+ cbor_state_t *backup_list;
+ uint32_t current_backup;
+ uint32_t num_backups;
+};
+
+/** Function pointer type used with multi_decode.
+ *
+ * This type is compatible with all decoding functions here and in the generated
+ * code, except for multi_decode.
+ */
+typedef bool(cbor_encoder_t)(cbor_state_t *, const void *);
+typedef bool(cbor_decoder_t)(cbor_state_t *, void *);
+
+/** Enumeration representing the major types available in CBOR.
+ *
+ * The major type is represented in the 3 first bits of the header byte.
+ */
+typedef enum
+{
+ CBOR_MAJOR_TYPE_PINT = 0, ///! Positive Integer
+ CBOR_MAJOR_TYPE_NINT = 1, ///! Negative Integer
+ CBOR_MAJOR_TYPE_BSTR = 2, ///! Byte String
+ CBOR_MAJOR_TYPE_TSTR = 3, ///! Text String
+ CBOR_MAJOR_TYPE_LIST = 4, ///! List
+ CBOR_MAJOR_TYPE_MAP = 5, ///! Map
+ CBOR_MAJOR_TYPE_TAG = 6, ///! Semantic Tag
+ CBOR_MAJOR_TYPE_PRIM = 7, ///! Primitive Type
+} cbor_major_type_t;
+
+/** Shorthand macro to check if a result is within min/max constraints.
+ */
+#define PTR_VALUE_IN_RANGE(type, res, min, max) \
+ (((min == NULL) || (*(type *)res >= *(type *)min)) \
+ && ((max == NULL) || (*(type *)res <= *(type *)max)))
+
+#define FAIL() \
+do {\
+ cbor_trace(); \
+ return false; \
+} while(0)
+
+
+#define VALUE_IN_HEADER 23 /**! For values below this, the value is encoded
+ directly in the header. */
+
+#define BOOL_TO_PRIM 20 ///! In CBOR, false/true have the values 20/21
+
+#define FLAG_RESTORE 1UL
+#define FLAG_DISCARD 2UL
+#define FLAG_TRANSFER_PAYLOAD 4UL
+
+bool new_backup(cbor_state_t *state, uint32_t new_elem_count);
+
+bool restore_backup(cbor_state_t *state, uint32_t flags,
+ uint32_t max_elem_count);
+
+bool union_start_code(cbor_state_t *state);
+
+bool union_elem_code(cbor_state_t *state);
+
+bool union_end_code(cbor_state_t *state);
+
+bool entry_function(const uint8_t *payload, uint32_t payload_len,
+ const void *struct_ptr, uint32_t *payload_len_out,
+ cbor_encoder_t func, uint32_t elem_count, uint32_t num_backups);
+
+#endif /* CBOR_COMMON_H__ */
diff --git a/boot/boot_serial/src/cbor_decode.c b/boot/boot_serial/src/cbor_decode.c
index 9d27bbb..9707729 100644
--- a/boot/boot_serial/src/cbor_decode.c
+++ b/boot/boot_serial/src/cbor_decode.c
@@ -1,6 +1,6 @@
/*
- * This file has been copied from the cddl_gen submodule.
- * Commit 9d911cf0c7c9f13b5a9fdd5ed6c1012df21e5576
+ * This file has been copied from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
*/
/*
@@ -14,22 +14,8 @@
#include <stddef.h>
#include <string.h>
#include "cbor_decode.h"
+#include "cbor_common.h"
-/** Enumeration representing the major types available in CBOR.
- *
- * The major type is represented in the 3 first bits of the header byte.
- */
-typedef enum
-{
- CBOR_MAJOR_TYPE_PINT = 0, ///! Positive Integer
- CBOR_MAJOR_TYPE_NINT = 1, ///! Negative Integer
- CBOR_MAJOR_TYPE_BSTR = 2, ///! Byte String
- CBOR_MAJOR_TYPE_TSTR = 3, ///! Text String
- CBOR_MAJOR_TYPE_LIST = 4, ///! List
- CBOR_MAJOR_TYPE_MAP = 5, ///! Map
- CBOR_MAJOR_TYPE_TAG = 6, ///! Semantic Tag
- CBOR_MAJOR_TYPE_PRIM = 7, ///! Primitive Type
-} cbor_major_type_t;
/** Return value length from additional value.
*/
@@ -52,122 +38,126 @@
/** Extract the additional info, i.e. the last 5 bits of the header byte. */
#define ADDITIONAL(header_byte) ((header_byte) & 0x1F)
-/** Shorthand macro to check if a result is within min/max constraints.
- */
-#define PTR_VALUE_IN_RANGE(type, p_res, p_min, p_max) \
- (((p_min == NULL) || (*(type *)p_res >= *(type *)p_min)) \
- && ((p_max == NULL) || (*(type *)p_res <= *(type *)p_max)))
-
-#define FAIL() \
-do {\
- cbor_decode_trace(); \
- return false; \
-} while(0)
#define FAIL_AND_DECR_IF(expr) \
do {\
if (expr) { \
- (p_state->p_payload)--; \
+ (state->payload)--; \
FAIL(); \
} \
} while(0)
-#define VALUE_IN_HEADER 23 /**! For values below this, the value is encoded
- directly in the header. */
+#define FAIL_IF(expr) \
+do {\
+ if (expr) { \
+ FAIL(); \
+ } \
+} while(0)
-#define BOOL_TO_PRIM 20 ///! In CBOR, false/true have the values 20/21
+
+#define FAIL_RESTORE() \
+ state->payload = state->payload_bak; \
+ state->elem_count++; \
+ FAIL()
/** Get a single value.
*
- * @details @p pp_payload must point to the header byte. This function will
+ * @details @p ppayload must point to the header byte. This function will
* retrieve the value (either from within the additional info, or from
* the subsequent bytes) and return it in the result. The result can
* have arbitrary length.
*
* The function will also validate
* - Min/max constraints on the value.
- * - That @p pp_payload doesn't overrun past @p p_payload_end.
- * - That @p p_elem_count has not been exhausted.
+ * - That @p payload doesn't overrun past @p payload_end.
+ * - That @p elem_count has not been exhausted.
*
- * @p pp_payload and @p p_elem_count are updated if the function
+ * @p ppayload and @p elem_count are updated if the function
* succeeds. If not, they are left unchanged.
*
* CBOR values are always big-endian, so this function converts from
* big to little-endian if necessary (@ref CONFIG_BIG_ENDIAN).
*/
-static bool value_extract(cbor_decode_state_t * p_state,
- void * const p_result, size_t result_len)
+static bool value_extract(cbor_state_t *state,
+ void *const result, uint32_t result_len)
{
- cbor_decode_trace();
- cbor_decode_assert(result_len != 0, "0-length result not supported.\n");
+ cbor_trace();
+ cbor_assert(result_len != 0, "0-length result not supported.\n");
+ cbor_assert(result != NULL, NULL);
- FAIL_AND_DECR_IF(p_state->elem_count == 0);
- FAIL_AND_DECR_IF(p_state->p_payload >= p_state->p_payload_end);
+ FAIL_IF((state->elem_count == 0) \
+ || (state->payload >= state->payload_end));
- uint8_t *p_u8_result = (uint8_t *)p_result;
- uint8_t additional = ADDITIONAL(*p_state->p_payload);
+ uint8_t *u8_result = (uint8_t *)result;
+ uint8_t additional = ADDITIONAL(*state->payload);
- (p_state->p_payload)++;
+ state->payload_bak = state->payload;
+ (state->payload)++;
- memset(p_result, 0, result_len);
+ memset(result, 0, result_len);
if (additional <= VALUE_IN_HEADER) {
#ifdef CONFIG_BIG_ENDIAN
- p_u8_result[result_len - 1] = additional;
+ u8_result[result_len - 1] = additional;
#else
- p_u8_result[0] = additional;
+ u8_result[0] = additional;
#endif /* CONFIG_BIG_ENDIAN */
} else {
uint32_t len = additional_len(additional);
FAIL_AND_DECR_IF(len > result_len);
- FAIL_AND_DECR_IF((p_state->p_payload + len)
- > p_state->p_payload_end);
+ FAIL_AND_DECR_IF((state->payload + len)
+ > state->payload_end);
#ifdef CONFIG_BIG_ENDIAN
- memcpy(&p_u8_result[result_len - len], p_state->p_payload, len);
+ memcpy(&u8_result[result_len - len], state->payload, len);
#else
for (uint32_t i = 0; i < len; i++) {
- p_u8_result[i] = (p_state->p_payload)[len - i - 1];
+ u8_result[i] = (state->payload)[len - i - 1];
}
#endif /* CONFIG_BIG_ENDIAN */
- (p_state->p_payload) += len;
+ (state->payload) += len;
}
- (p_state->elem_count)--;
+ (state->elem_count)--;
return true;
}
-static bool int32_decode(cbor_decode_state_t * p_state,
- int32_t *p_result, void *p_min_value, void *p_max_value)
+static bool int32_decode(cbor_state_t *state, int32_t *result)
{
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
+ uint32_t uint_result;
+ int32_t int_result;
- if (!value_extract(p_state, p_result, 4)) {
+ if (!value_extract(state, &uint_result, 4)) {
FAIL();
}
- if (*p_result < 0) {
+
+ cbor_print("uintval: %u\r\n", uint_result);
+ if (uint_result >= (1 << (8*sizeof(uint_result)-1))) {
/* Value is too large to fit in a signed integer. */
- FAIL();
+ FAIL_RESTORE();
}
if (major_type == CBOR_MAJOR_TYPE_NINT) {
- // Convert from CBOR's representation.
- *p_result = 1 - *p_result;
+ /* Convert from CBOR's representation. */
+ int_result = -1 - uint_result;
+ } else {
+ int_result = uint_result;
}
- if (!PTR_VALUE_IN_RANGE(int32_t, p_result, p_min_value, p_max_value)) {
- FAIL();
- }
- cbor_decode_print("val: %d\r\n", *p_result);
+
+ cbor_print("val: %d\r\n", int_result);
+ *result = int_result;
return true;
}
-bool intx32_decode(cbor_decode_state_t * p_state,
- int32_t *p_result, void *p_min_value, void *p_max_value)
+bool intx32_decode(cbor_state_t *state, int32_t *result)
{
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
if (major_type != CBOR_MAJOR_TYPE_PINT
&& major_type != CBOR_MAJOR_TYPE_NINT) {
@@ -175,203 +165,384 @@
FAIL();
}
- if (!int32_decode(p_state,
- p_result, p_min_value,
- p_max_value)){
+ if (!int32_decode(state, result)) {
FAIL();
}
return true;
}
-
-static bool uint32_decode(cbor_decode_state_t * p_state,
- void *p_result, void *p_min_value, void *p_max_value)
+bool intx32_expect(cbor_state_t *state, int32_t result)
{
- if (!value_extract(p_state, p_result, 4)) {
+ int32_t value;
+
+ if (!intx32_decode(state, &value)) {
FAIL();
}
- if (!PTR_VALUE_IN_RANGE(uint32_t, p_result, p_min_value, p_max_value)) {
- FAIL();
+ if (value != result) {
+ cbor_print("%d != %d\r\n", value, result);
+ FAIL_RESTORE();
}
- cbor_decode_print("val: %u\r\n", *(uint32_t *)p_result);
return true;
}
-bool uintx32_decode(cbor_decode_state_t * p_state,
- uint32_t *p_result, void *p_min_value, void *p_max_value)
+static bool uint32_decode(cbor_state_t *state, uint32_t *result)
{
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
+ if (!value_extract(state, result, 4)) {
+ FAIL();
+ }
+
+ return true;
+}
+
+
+bool uintx32_decode(cbor_state_t *state, uint32_t *result)
+{
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
if (major_type != CBOR_MAJOR_TYPE_PINT) {
/* Value to be read doesn't have the right type. */
FAIL();
}
- if (!uint32_decode(p_state, p_result, p_min_value, p_max_value)){
+ if (!uint32_decode(state, result)) {
FAIL();
}
return true;
}
-
-static bool size_decode(cbor_decode_state_t * p_state,
- size_t *p_result, size_t *p_min_value, size_t *p_max_value)
+bool uintx32_expect(cbor_state_t *state, uint32_t result)
{
- _Static_assert((sizeof(size_t) == sizeof(uint32_t)),
- "This code needs size_t to be 4 bytes long.");
- return uint32_decode(p_state,
- p_result, p_min_value, p_max_value);
+ uint32_t value;
+
+ if (!uintx32_decode(state, &value)) {
+ FAIL();
+ }
+ if (value != result) {
+ cbor_print("%u != %u\r\n", value, result);
+ FAIL_RESTORE();
+ }
+ return true;
+}
+
+bool uintx32_expect_union(cbor_state_t *state, uint32_t result)
+{
+ union_elem_code(state);
+ return uintx32_expect(state, result);
}
-bool strx_start_decode(cbor_decode_state_t * p_state,
- cbor_string_type_t *p_result, void *p_min_len, void *p_max_len)
+static bool strx_start_decode(cbor_state_t *state,
+ cbor_string_type_t *result, cbor_major_type_t exp_major_type)
{
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
- cbor_string_type_t *p_str_result = (cbor_string_type_t *)p_result;
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
- if (major_type != CBOR_MAJOR_TYPE_BSTR
- && major_type != CBOR_MAJOR_TYPE_TSTR) {
- /* Value to be read doesn't have the right type. */
+ if (major_type != exp_major_type) {
FAIL();
}
- if (!size_decode(p_state,
- &p_str_result->len, (size_t *)p_min_len,
- (size_t *)p_max_len)) {
+
+ if (!uint32_decode(state, &result->len)) {
FAIL();
}
- p_str_result->value = p_state->p_payload;
+
+ if (result->len > (state->payload_end - state->payload)) {
+ cbor_print("error: 0x%x > 0x%x\r\n",
+ (uint32_t)result->len,
+ (uint32_t)(state->payload_end - state->payload));
+ FAIL_RESTORE();
+ }
+
+ result->value = state->payload;
+ return true;
+}
+
+bool bstrx_cbor_start_decode(cbor_state_t *state, cbor_string_type_t *result)
+{
+ if(!strx_start_decode(state, result, CBOR_MAJOR_TYPE_BSTR)) {
+ FAIL();
+ }
+
+ if (!new_backup(state, 0xFFFFFFFF)) {
+ FAIL_RESTORE();
+ }
+
+ /* Overflow is checked in strx_start_decode() */
+ state->payload_end = result->value + result->len;
+ return true;
+}
+
+bool bstrx_cbor_end_decode(cbor_state_t *state)
+{
+ if (state->payload != state->payload_end) {
+ FAIL();
+ }
+ if (!restore_backup(state,
+ FLAG_RESTORE | FLAG_DISCARD | FLAG_TRANSFER_PAYLOAD,
+ 0xFFFFFFFF)) {
+ FAIL();
+ }
+
return true;
}
-bool strx_decode(cbor_decode_state_t * p_state,
- cbor_string_type_t *p_result, void *p_min_len, void *p_max_len)
+bool strx_decode(cbor_state_t *state, cbor_string_type_t *result,
+ cbor_major_type_t exp_major_type)
{
- if (!strx_start_decode(p_state, p_result,
- p_min_len, p_max_len)) {
- return false;
+ if (!strx_start_decode(state, result, exp_major_type)) {
+ FAIL();
}
- (p_state->p_payload) += p_result->len;
+
+ /* Overflow is checked in strx_start_decode() */
+ (state->payload) += result->len;
return true;
}
-bool list_start_decode(cbor_decode_state_t * p_state,
- size_t *p_result, size_t min_num, size_t max_num)
+bool strx_expect(cbor_state_t *state, cbor_string_type_t *result,
+ cbor_major_type_t exp_major_type)
{
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
+ cbor_string_type_t tmp_result;
- *p_result = p_state->elem_count;
-
- if (major_type != CBOR_MAJOR_TYPE_LIST
- && major_type != CBOR_MAJOR_TYPE_MAP) {
+ if (!strx_decode(state, &tmp_result, exp_major_type)) {
FAIL();
}
- if (!uint32_decode(p_state,
- p_result, &min_num, &max_num)) {
- FAIL();
+ if ((tmp_result.len != result->len)
+ || memcmp(result->value, tmp_result.value, tmp_result.len)) {
+ FAIL_RESTORE();
}
- size_t tmp = *p_result;
- *p_result = p_state->elem_count;
- p_state->elem_count = major_type == CBOR_MAJOR_TYPE_MAP ? tmp * 2 : tmp;
return true;
}
-bool primx_decode(cbor_decode_state_t * p_state,
- uint8_t *p_result, void *p_min_result, void *p_max_result)
+bool bstrx_decode(cbor_state_t *state, cbor_string_type_t *result)
{
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
- uint32_t val;
+ return strx_decode(state, result, CBOR_MAJOR_TYPE_BSTR);
+}
+
+
+bool bstrx_expect(cbor_state_t *state, cbor_string_type_t *result)
+{
+ return strx_expect(state, result, CBOR_MAJOR_TYPE_BSTR);
+}
+
+
+bool tstrx_decode(cbor_state_t *state, cbor_string_type_t *result)
+{
+ return strx_decode(state, result, CBOR_MAJOR_TYPE_TSTR);
+}
+
+
+bool tstrx_expect(cbor_state_t *state, cbor_string_type_t *result)
+{
+ return strx_expect(state, result, CBOR_MAJOR_TYPE_TSTR);
+}
+
+
+static bool list_map_start_decode(cbor_state_t *state,
+ cbor_major_type_t exp_major_type)
+{
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
+ uint32_t new_elem_count;
+
+ if (major_type != exp_major_type) {
+ FAIL();
+ }
+
+ if (!uint32_decode(state, &new_elem_count)) {
+ FAIL();
+ }
+
+ if (!new_backup(state, new_elem_count)) {
+ FAIL_RESTORE();
+ }
+
+ return true;
+}
+
+
+bool list_start_decode(cbor_state_t *state)
+{
+ return list_map_start_decode(state, CBOR_MAJOR_TYPE_LIST);
+}
+
+
+bool map_start_decode(cbor_state_t *state)
+{
+ bool ret = list_map_start_decode(state, CBOR_MAJOR_TYPE_MAP);
+
+ if (ret) {
+ state->elem_count *= 2;
+ }
+ return ret;
+}
+
+
+bool list_map_end_decode(cbor_state_t *state)
+{
+ if (!restore_backup(state,
+ FLAG_RESTORE | FLAG_DISCARD | FLAG_TRANSFER_PAYLOAD,
+ 0)) {
+ FAIL();
+ }
+
+ return true;
+}
+
+
+bool list_end_decode(cbor_state_t *state)
+{
+ return list_map_end_decode(state);
+}
+
+
+bool map_end_decode(cbor_state_t *state)
+{
+ return list_map_end_decode(state);
+}
+
+
+static bool primx_decode(cbor_state_t *state, uint32_t *result)
+{
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
if (major_type != CBOR_MAJOR_TYPE_PRIM) {
/* Value to be read doesn't have the right type. */
FAIL();
}
- if (!uint32_decode(p_state,
- &val, p_min_result, p_max_result)) {
+ if (!uint32_decode(state, result)) {
FAIL();
}
- if (p_result != NULL) {
- *p_result = val;
+ if (*result > 0xFF) {
+ FAIL_RESTORE();
+ }
+ return true;
+}
+
+static bool primx_expect(cbor_state_t *state, uint32_t result)
+{
+ uint32_t value;
+
+ if (!primx_decode(state, &value)) {
+ FAIL();
+ }
+ if (value != result) {
+ FAIL_RESTORE();
}
return true;
}
-bool boolx_decode(cbor_decode_state_t * p_state,
- bool *p_result, void *p_min_result, void *p_max_result)
+bool nilx_expect(cbor_state_t *state, void *result)
{
- uint8_t min_result = *(uint8_t *)p_min_result + BOOL_TO_PRIM;
- uint8_t max_result = *(uint8_t *)p_max_result + BOOL_TO_PRIM;
-
- if (!primx_decode(p_state,
- (uint8_t *)p_result, &min_result, &max_result)) {
+ if (!primx_expect(state, 22)) {
FAIL();
}
- (*p_result) -= BOOL_TO_PRIM;
return true;
}
-bool double_decode(cbor_decode_state_t * p_state,
- double *p_result, void *p_min_result, void *p_max_result)
+bool boolx_decode(cbor_state_t *state, bool *result)
{
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
+ uint32_t tmp_result;
+
+ if (!primx_decode(state, &tmp_result)) {
+ FAIL();
+ }
+ (*result) = tmp_result - BOOL_TO_PRIM;
+
+ cbor_print("boolval: %u\r\n", *result);
+ return true;
+}
+
+
+bool boolx_expect(cbor_state_t *state, bool result)
+{
+ bool value;
+
+ if (!boolx_decode(state, &value)) {
+ FAIL();
+ }
+ if (value != result) {
+ FAIL_RESTORE();
+ }
+ return true;
+}
+
+
+bool double_decode(cbor_state_t *state, double *result)
+{
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
if (major_type != CBOR_MAJOR_TYPE_PRIM) {
/* Value to be read doesn't have the right type. */
FAIL();
}
- if (!value_extract(p_state, p_result,
- sizeof(*p_result))) {
- FAIL();
- }
-
- if (!PTR_VALUE_IN_RANGE(double, p_result, p_min_result, p_max_result)) {
+ if (!value_extract(state, result,
+ sizeof(*result))) {
FAIL();
}
return true;
}
-bool any_decode(cbor_decode_state_t * p_state,
- void *p_result, void *p_min_result, void *p_max_result)
+bool double_expect(cbor_state_t *state, double *result)
{
- cbor_decode_assert(p_result == NULL,
+ double value;
+
+ if (!double_decode(state, &value)) {
+ FAIL();
+ }
+ if (value != *result) {
+ FAIL_RESTORE();
+ }
+ return true;
+}
+
+
+bool any_decode(cbor_state_t *state, void *result)
+{
+ cbor_assert(result == NULL,
"'any' type cannot be returned, only skipped.\n");
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
uint32_t value;
- size_t num_decode;
- void *p_null_result = NULL;
- size_t temp_elem_count;
+ uint32_t num_decode;
+ void *null_result = NULL;
+ uint32_t temp_elem_count;
+ uint8_t const *payload_bak;
- if (!value_extract(p_state, &value, sizeof(value))) {
- /* Can happen because of p_elem_count (or p_payload_end) */
+ if (!value_extract(state, &value, sizeof(value))) {
+ /* Can happen because of elem_count (or payload_end) */
FAIL();
}
switch (major_type) {
case CBOR_MAJOR_TYPE_BSTR:
case CBOR_MAJOR_TYPE_TSTR:
- (p_state->p_payload) += value;
+ (state->payload) += value;
break;
case CBOR_MAJOR_TYPE_MAP:
value *= 2; /* Because all members have a key. */
/* Fallthrough */
case CBOR_MAJOR_TYPE_LIST:
- temp_elem_count = p_state->elem_count;
- p_state->elem_count = value;
- if (!multi_decode(value, value, &num_decode, any_decode,
- p_state,
- &p_null_result, NULL, NULL, 0)) {
- p_state->elem_count = temp_elem_count;
+ temp_elem_count = state->elem_count;
+ payload_bak = state->payload;
+ state->elem_count = value;
+ if (!multi_decode(value, value, &num_decode,
+ (void *)any_decode, state,
+ &null_result, 0)) {
+ state->elem_count = temp_elem_count;
+ state->payload = payload_bak;
FAIL();
}
- p_state->elem_count = temp_elem_count;
+ state->elem_count = temp_elem_count;
break;
default:
/* Do nothing */
@@ -382,36 +553,77 @@
}
-bool multi_decode(size_t min_decode,
- size_t max_decode,
- size_t *p_num_decode,
- decoder_t decoder,
- cbor_decode_state_t * p_state,
- void *p_result,
- void *p_min_result,
- void *p_max_result,
- size_t result_len)
+bool tag_decode(cbor_state_t *state, uint32_t *result)
{
- for (size_t i = 0; i < max_decode; i++) {
- uint8_t const *p_payload_bak = p_state->p_payload;
- size_t elem_count_bak = p_state->elem_count;
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
- if (!decoder(p_state,
- (uint8_t *)p_result + i*result_len,
- p_min_result,
- p_max_result)) {
- *p_num_decode = i;
- p_state->p_payload = p_payload_bak;
- p_state->elem_count = elem_count_bak;
+ if (major_type != CBOR_MAJOR_TYPE_TAG) {
+ /* Value to be read doesn't have the right type. */
+ FAIL();
+ }
+ if (!uint32_decode(state, result)) {
+ FAIL();
+ }
+ state->elem_count++;
+ return true;
+}
+
+
+bool tag_expect(cbor_state_t *state, uint32_t result)
+{
+ uint32_t tag_val;
+
+ if (!tag_decode(state, &tag_val)) {
+ FAIL();
+ }
+ if (tag_val != result) {
+ FAIL_RESTORE();
+ }
+ return true;
+}
+
+
+bool multi_decode(uint32_t min_decode,
+ uint32_t max_decode,
+ uint32_t *num_decode,
+ cbor_decoder_t decoder,
+ cbor_state_t *state,
+ void *result,
+ uint32_t result_len)
+{
+ for (uint32_t i = 0; i < max_decode; i++) {
+ uint8_t const *payload_bak = state->payload;
+ uint32_t elem_count_bak = state->elem_count;
+
+ if (!decoder(state,
+ (uint8_t *)result + i*result_len)) {
+ *num_decode = i;
+ state->payload = payload_bak;
+ state->elem_count = elem_count_bak;
if (i < min_decode) {
FAIL();
} else {
- cbor_decode_print("Found %zu elements.\n", i);
+ cbor_print("Found %zu elements.\n", i);
}
return true;
}
}
- cbor_decode_print("Found %zu elements.\n", max_decode);
- *p_num_decode = max_decode;
+ cbor_print("Found %zu elements.\n", max_decode);
+ *num_decode = max_decode;
return true;
}
+
+
+bool present_decode(uint32_t *present,
+ cbor_decoder_t decoder,
+ cbor_state_t *state,
+ void *result)
+{
+ uint32_t num_decode;
+ bool retval = multi_decode(0, 1, &num_decode, decoder, state, result, 0);
+ if (retval) {
+ *present = num_decode;
+ }
+ return retval;
+}
diff --git a/boot/boot_serial/src/cbor_decode.h b/boot/boot_serial/src/cbor_decode.h
index cd466cd..5bdc800 100644
--- a/boot/boot_serial/src/cbor_decode.h
+++ b/boot/boot_serial/src/cbor_decode.h
@@ -1,6 +1,6 @@
/*
- * This file has been copied from the cddl_gen submodule.
- * Commit 9d911cf0c7c9f13b5a9fdd5ed6c1012df21e5576
+ * This file has been copied from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
*/
/*
@@ -9,35 +9,33 @@
* SPDX-License-Identifier: Apache-2.0
*/
-#ifndef CDDL_CBOR_H__
-#define CDDL_CBOR_H__
+#ifndef CBOR_DECODE_H__
+#define CBOR_DECODE_H__
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
+#include "cbor_common.h"
/** The cbor_decode library provides functions for decoding CBOR data elements.
*
* This library is primarily meant to be called from code generated by
- * $CDDL_GEN_BASE/scripts/cddl_gen.py
+ * $CDDL_GEN_BASE/cddl_gen/cddl_gen.py script, or its equivalent cddl_gen
+ * command line executable.
*
* Some details to notice about this library:
- * - Integers are all 32 bits (uint32_t and size_t). This means that CBOR's
- * 64 bit values are not supported. This applies to integer types, as well as
- * lengths for other types.
+ * - Integers are all 32 bits (uint32_t). This means that CBOR's 64 bit values
+ * are not supported, even when the code is running on a 64 bit architecture.
+ * This applies to integer types, as well as lengths for other types.
* - Strings are kept in the container type cbor_string_type_t, which is a
* pointer and a length.
* - When a function returns false, it only means that decoding that particular
* value failed. If a value is allowed to take multiple different values,
- * another decoding function can be called if the first fails. All functions
- * are designed to reset pp_payload and p_elem_count to their original values
- * if they return false.
+ * another decoding function can be called if the first fails.
* - There is some type casting going on under the hood to make the code
- * generator friendly. See especially the decoder_t type which is compatible
+ * generator friendly. See especially the processor_t type which is compatible
* with all functions except multi_decode, but the compiler doesn't "know"
* this because they are defined with different pointer types. It also means
* any usage of multi_decode must be made with care for function types.
- * - This library has no function for semantic tags.
- * - This library doesn't distinguish lists from maps.
*
*
* CBOR's format is described well on Wikipedia
@@ -54,7 +52,11 @@
*
* The available major types can be seen in @ref cbor_major_type_t.
*
- * PINT, NINT, TAG, and PRIM elements have no payload, only Value.
+ * For all types, Values 0-23 are encoded directly in the "Additional info",
+ * meaning that the "Value" field is 0 bytes long. If "Additional info" is 24,
+ * 25, 26, or 27, the "Value" field is 1, 2, 4, or 8 bytes long, respectively.
+ *
+ * Major types PINT, NINT, TAG, and PRIM elements have no payload, only Value.
* PINT: Interpret the Value as a positive integer.
* NINT: Interpret the Value as a positive integer, then multiply by -1 and
* subtract 1.
@@ -65,7 +67,7 @@
* 21: "true"
* 22: "null"
* 23: "undefined"
- * >256: Interpret as IEEE 754 float with given precision
+ * >=0x10000: Interpret as IEEE 754 float with given precision
*
* For BSTR, TSTR, LIST, and MAP, the Value describes the length of the payload.
* For BSTR and TSTR, the length is in bytes, for LIST, the length is in number
@@ -74,148 +76,105 @@
* For LIST and MAP, sub elements are regular CBOR elements with their own
* Header, Value and Payload. LISTs and MAPs can be recursively encoded.
*
- * For all types, Values 0-23 are encoded directly in the "Additional info",
- * meaning that the "Value" field is 0 bytes long. If "Additional info" is 24,
- * 25, 26, or 27, the "Value" field is 1, 2, 4, or 8 bytes long, respectively.
- *
* The additional info means slightly different things for different major
* types.
*/
-
-/** Convenience type that allows pointing to strings directly inside the payload
- * without the need to copy out.
- */
-typedef struct
-{
- const uint8_t *value;
- size_t len;
-} cbor_string_type_t;
-
-#ifdef CDDL_CBOR_VERBOSE
-#include <sys/printk.h>
-#define cbor_decode_trace() (printk("p_state->p_payload: 0x%x, "\
- "*p_state->p_payload: 0x%x, p_state->elem_count: 0x%zx, %s:%d\n",\
- (uint32_t)p_state->p_payload, *p_state->p_payload, p_state->elem_count,\
- __FILE__, __LINE__))
-#define cbor_decode_assert(expr, ...) \
-do { \
- if (!(expr)) { \
- printk("ASSERTION \n \"" #expr \
- "\"\nfailed at %s:%d with message:\n ", \
- __FILE__, __LINE__); \
- printk(__VA_ARGS__);\
- return false; \
- } \
-} while(0)
-#define cbor_decode_print(...) printk(__VA_ARGS__)
-#else
-#define cbor_decode_trace()
-#define cbor_decode_assert(...)
-#define cbor_decode_print(...)
-#endif
-
-typedef struct {
- uint8_t const *p_payload;
- uint8_t const *p_payload_end;
- size_t elem_count;
-} cbor_decode_state_t;
-
-/** Function pointer type used with multi_decode.
- *
- * This type is compatible with all decoding functions here and in the generated
- * code, except for multi_decode.
- */
-typedef bool(decoder_t)(cbor_decode_state_t *, void *, void *, void *);
-
/** Decode a PINT/NINT into a int32_t.
*
- * @param[inout] pp_payload The current place in the payload. Will be
- * updated if the element is correctly decoded.
- * @param[in] p_payload_end The end of the payload. This will be checked
- * against pp_payload before decoding.
- * @param[inout] p_elem_count The current element is part of a LIST or a MAP,
- * and this keeps count of how many elements are
- * expected. This will be checked before decoding
- * decremented if the element is correctly decoded.
- * @param[out] p_result Where to place the decoded value.
- * @param[in] p_min_value The minimum acceptable value. This is checked
- * after decoding, and if the decoded value is
- * outside the range, the decoding will fail.
- * A NULL value here means there is no restriction.
- * @param[in] p_max_value The maximum acceptable value. This is checked
- * after decoding, and if the decoded value is
- * outside the range, the decoding will fail.
- * A NULL value here means there is no restriction.
+ * @param[inout] state The current state of the decoding.
+ * @param[out] result Where to place the decoded value.
*
* @retval true If the value was decoded correctly.
* @retval false If the value has the wrong type, the payload overflowed, the
- * element count was exhausted, the value was not within the
- * acceptable range, or the value was larger than can fit in the
- * result variable.
+ * element count was exhausted, or the value was larger than can
+ * fit in the result variable.
*/
-bool intx32_decode(cbor_decode_state_t * p_state, int32_t *p_result, void *p_min_value, void *p_max_value);
+bool intx32_decode(cbor_state_t *state, int32_t *result);
-/** Decode a PINT into a uint32_t.
+/** Expect a PINT/NINT with a certain value. Uses intx32_decode internally.
*
- * @details See @ref intx32_decode for information about parameters and return
- * values.
+ * @param[inout] state The current state of the decoding.
+ * @param[in] result The expected value
+ *
+ * @retval true If the result was decoded correctly and has the expected value.
+ * @retval false If intx32_decode failed or the result doesn't have the
+ * expected value.
*/
-bool uintx32_decode(cbor_decode_state_t * p_state, uint32_t *p_result, void *p_min_value, void *p_max_value);
+bool intx32_expect(cbor_state_t *state, int32_t result);
-/** Decode a BSTR or TSTR, but leave pp_payload pointing at the payload.
- *
- * @details See @ref intx32_decode for information about parameters and return
- * values. For strings, the value refers to the length of the string.
- */
-bool strx_start_decode(cbor_decode_state_t * p_state, cbor_string_type_t *p_result, void *p_min_len, void *p_max_len);
+/** Decode a PINT. */
+bool uintx32_decode(cbor_state_t *state, uint32_t *result);
+bool uintx32_expect(cbor_state_t *state, uint32_t result);
+bool uintx32_expect_union(cbor_state_t *state, uint32_t result);
-/** Decode a BSTR or TSTR, and move pp_payload to after the payload.
+/** Decode and consume a BSTR header.
*
- * @details See @ref intx32_decode for information about parameters and return
- * values. For strings, the value refers to the length of the string.
+ * The rest of the string can be decoded as CBOR.
+ * A state backup is created to keep track of the element count.
+ *
+ * @retval true Header decoded correctly
+ * @retval false Header decoded incorrectly, or backup failed.
*/
-bool strx_decode(cbor_decode_state_t * p_state, cbor_string_type_t *p_result, void *p_min_len, void *p_max_len);
+bool bstrx_cbor_start_decode(cbor_state_t *state, cbor_string_type_t *result);
-/** Decode a LIST or MAP, but leave pp_payload pointing at the payload.
+/** Finalize decoding a CBOR-encoded bstr.
*
- * @details See @ref intx32_decode for information about parameters and return
- * values. For lists and maps, the value refers to the number of
- * elements.
+ * Restore element count from backup.
*/
-bool list_start_decode(cbor_decode_state_t * p_state, size_t *p_result, size_t min_num, size_t max_num);
+bool bstrx_cbor_end_decode(cbor_state_t *state);
-/** Decode a primitive value.
- *
- * @details See @ref intx32_decode for information about parameters and return
- * values.
- */
-bool primx_decode(cbor_decode_state_t * p_state, uint8_t *p_result, void *p_min_result, void *p_max_result);
+/** Decode and consume a BSTR */
+bool bstrx_decode(cbor_state_t *state, cbor_string_type_t *result);
+bool bstrx_expect(cbor_state_t *state, cbor_string_type_t *result);
-/** Decode a boolean primitive value.
- *
- * @details See @ref intx32_decode for information about parameters and return
- * values. The result is translated internally from the primitive
- * values for true/false (20/21) to 0/1.
- */
-bool boolx_decode(cbor_decode_state_t * p_state, bool *p_result, void *p_min_result, void *p_max_result);
+/** Decode and consume a TSTR */
+bool tstrx_decode(cbor_state_t *state, cbor_string_type_t *result);
+bool tstrx_expect(cbor_state_t *state, cbor_string_type_t *result);
-/** Decode a float
+/** Decode and consume a LIST header.
*
- * @warning This function has not been tested, and likely doesn't work.
+ * The contents of the list can be decoded via subsequent function calls.
+ * A state backup is created to keep track of the element count.
*
- * @details See @ref intx32_decode for information about parameters and return
- * values.
+ * @retval true Header decoded correctly
+ * @retval false Header decoded incorrectly, or backup failed.
*/
-bool float_decode(cbor_decode_state_t * p_state, double *p_result, void *p_min_result, void *p_max_result);
+bool list_start_decode(cbor_state_t *state);
-/** Skip a single element, regardless of type and value.
+/** Decode and consume a MAP header. */
+bool map_start_decode(cbor_state_t *state);
+
+/** Finalize decoding a LIST
*
- * @details See @ref intx32_decode for information about parameters and return
- * values. @p p_result, @p p_min_result, and @p p_max_result must be
- * NULL.
+ * Check that the list had the correct number of elements, and restore previous
+ * element count from backup.
+ *
+ * @retval true Everything ok.
+ * @retval false Element count not correct.
*/
-bool any_decode(cbor_decode_state_t * p_state, void *p_result, void *p_min_result, void *p_max_result);
+bool list_end_decode(cbor_state_t *state);
+
+/** Finalize decoding a MAP */
+bool map_end_decode(cbor_state_t *state);
+
+/** Decode a "nil" primitive value. */
+bool nilx_expect(cbor_state_t *state, void *result);
+
+/** Decode a boolean primitive value. */
+bool boolx_decode(cbor_state_t *state, bool *result);
+bool boolx_expect(cbor_state_t *state, bool result);
+
+/** Decode a float */
+bool float_decode(cbor_state_t *state, double *result);
+bool float_expect(cbor_state_t *state, double *result);
+
+/** Skip a single element, regardless of type and value. */
+bool any_decode(cbor_state_t *state, void *result);
+
+/** Decode a tag. */
+bool tag_decode(cbor_state_t *state, uint32_t *result);
+bool tag_expect(cbor_state_t *state, uint32_t result);
/** Decode 0 or more elements with the same type and constraints.
*
@@ -224,46 +183,52 @@
* with length 8, that could be done with:
*
* @code{c}
- * size_t elem_count = 5;
* uint32_t int_min = 0;
* uint32_t int_max = 100;
- * size_t bstr_size = 8;
+ * uint32_t bstr_size = 8;
* uint32_t ints[3];
* cbor_string_type_t bstrs[2];
+ * bool res;
*
- * list_start_decode(pp_payload, p_payload_end, &parent_elem_count,
- * &elem_count, NULL, NULL);
- * multi_decode(3, 3, &num_decode, uintx32_decode, pp_payload,
- * p_payload_end, ints, &int_min, &int_max, 4);
- * multi_decode(0, 2, &num_decode, strx_decode, pp_payload,
- * p_payload_end, bstrs, &bstr_size, &bstr_size,
+ * res = list_start_encode(state, 3, 5);
+ * // check res
+ * res = multi_encode(3, 3, &num_encode, uintx32_encode, state,
+ * ints, &int_min, &int_max, 4);
+ * // check res
+ * res = multi_encode(0, 2, &num_encode, strx_encode, state,
+ * bstrs, &bstr_size, &bstr_size,
* sizeof(cbor_string_type_t));
+ * // check res
+ * res = list_end_encode(state, 3, 5);
+ * // check res
* @endcode
*
- * See @ref intx32_decode for information about the undocumented
- * parameters.
- *
* @param[in] min_decode The minimum acceptable number of elements.
* @param[in] max_decode The maximum acceptable number of elements.
- * @param[out] p_num_decode The actual number of elements.
+ * @param[out] num_decode The actual number of elements.
* @param[in] decoder The decoder function to call under the hood. This
* function will be called with the provided arguments
* repeatedly until the function fails (returns false)
* or until it has been called @p max_decode times.
- * p_result is moved @p result_len bytes for each call
- * to @p decoder, i.e. @p p_result refers to an array
+ * result is moved @p result_len bytes for each call
+ * to @p decoder, i.e. @p result refers to an array
* of result variables.
- * @param[out] p_result Where to place the decoded values. Must be an array
+ * @param[out] result Where to place the decoded values. Must be an array
* of length at least @p max_decode.
* @param[in] result_len The length of the result variables. Must be the
- * length expected by the @p decoder.
+ * length matching the elements of @p result.
*
* @retval true If at least @p min_decode variables were correctly decoded.
* @retval false If @p decoder failed before having decoded @p min_decode
* values.
*/
-bool multi_decode(size_t min_decode, size_t max_decode, size_t *p_num_decode,
- decoder_t decoder, cbor_decode_state_t * p_state, void *p_result, void *p_min_result, void *p_max_result,
- size_t result_len);
+bool multi_decode(uint32_t min_decode, uint32_t max_decode, uint32_t *num_decode,
+ cbor_decoder_t decoder, cbor_state_t *state, void *result,
+ uint32_t result_len);
-#endif
+bool present_decode(uint32_t *present,
+ cbor_decoder_t decoder,
+ cbor_state_t *state,
+ void *result);
+
+#endif /* CBOR_DECODE_H__ */
diff --git a/boot/boot_serial/src/cbor_encode.c b/boot/boot_serial/src/cbor_encode.c
new file mode 100644
index 0000000..d12dc94
--- /dev/null
+++ b/boot/boot_serial/src/cbor_encode.c
@@ -0,0 +1,466 @@
+/*
+ * This file has been copied from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
+ */
+
+/*
+ * Copyright (c) 2020 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include "cbor_encode.h"
+#include "cbor_common.h"
+
+_Static_assert((sizeof(size_t) == sizeof(void *)),
+ "This code needs size_t to be the same length as pointers.");
+
+uint8_t get_additional(uint32_t len, uint8_t value0)
+{
+ switch(len) {
+ case 0: return value0;
+ case 1: return 24;
+ case 2: return 25;
+ case 3: return 25;
+ case 4: return 26;
+ case 5: return 26;
+ case 6: return 26;
+ case 7: return 26;
+ case 8: return 27;
+ }
+
+ cbor_assert(false, NULL);
+ return 0;
+}
+
+static bool encode_header_byte(cbor_state_t *state,
+ cbor_major_type_t major_type, uint8_t additional)
+{
+ if ((state->payload + 1) > state->payload_end) {
+ FAIL();
+ }
+
+ cbor_assert(additional < 32, NULL);
+
+ *(state->payload_mut++) = (major_type << 5) | (additional & 0x1F);
+ return true;
+}
+
+/** Encode a single value.
+ */
+static bool value_encode_len(cbor_state_t *state, cbor_major_type_t major_type,
+ const void *const input, uint32_t result_len)
+{
+ uint8_t *u8_result = (uint8_t *)input;
+
+ if ((state->payload + 1 + result_len) > state->payload_end) {
+ FAIL();
+ }
+
+ if (!encode_header_byte(state, major_type,
+ get_additional(result_len, u8_result[0]))) {
+ FAIL();
+ }
+ state->payload_mut--;
+ cbor_trace();
+ state->payload_mut++;
+
+#ifdef CONFIG_BIG_ENDIAN
+ memcpy(state->payload_mut, u8_result, result_len);
+ state->payload_mut += result_len;
+#else
+ for (; result_len > 0; result_len--) {
+ *(state->payload_mut++) = u8_result[result_len - 1];
+ }
+#endif
+
+ state->elem_count++;
+ return true;
+}
+
+
+static uint32_t get_result_len(const void *const input, uint32_t max_result_len)
+{
+ uint8_t *u8_result = (uint8_t *)input;
+ size_t i;
+
+ for (i = 0; i < max_result_len; i++) {
+#ifdef CONFIG_BIG_ENDIAN
+ size_t idx = i;
+#else
+ size_t idx = max_result_len - 1 - i;
+#endif
+ if (u8_result[idx] != 0) {
+ break;
+ }
+ }
+ max_result_len -= i;
+
+ /* According to specification result length can be encoded on 1, 2, 4
+ * or 8 bytes.
+ */
+ cbor_assert(max_result_len <= 8, "Up to 8 bytes can be used to encode length.\n");
+ size_t encode_byte_cnt = 1;
+
+ for (size_t i = 0; i <= 3; i++) {
+ if (max_result_len <= encode_byte_cnt) {
+ max_result_len = encode_byte_cnt;
+ break;
+ }
+
+ encode_byte_cnt *= 2;
+ }
+
+ if ((max_result_len == 1) && (u8_result[0] <= VALUE_IN_HEADER)) {
+ max_result_len = 0;
+ }
+
+ return max_result_len;
+}
+
+
+static bool value_encode(cbor_state_t *state, cbor_major_type_t major_type,
+ const void *const input, uint32_t max_result_len)
+{
+ cbor_assert(max_result_len != 0, "0-length result not supported.\n");
+ return value_encode_len(state, major_type, input,
+ get_result_len(input, max_result_len));
+}
+
+
+bool intx32_put(cbor_state_t *state, int32_t input)
+{
+ cbor_major_type_t major_type;
+
+ if (input < 0) {
+ major_type = CBOR_MAJOR_TYPE_NINT;
+ /* Convert from CBOR's representation. */
+ input = -1 - input;
+ } else {
+ major_type = CBOR_MAJOR_TYPE_PINT;
+ input = input;
+ }
+
+ if (!value_encode(state, major_type, &input, 4)) {
+ FAIL();
+ }
+
+ return true;
+}
+
+bool intx32_encode(cbor_state_t *state, const int32_t *input)
+{
+ return intx32_put(state, *input);
+}
+
+
+static bool uint32_encode(cbor_state_t *state, const uint32_t *input,
+ cbor_major_type_t major_type)
+{
+ if (!value_encode(state, major_type, input, 4)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+bool uintx32_encode(cbor_state_t *state, const uint32_t *input)
+{
+ if (!uint32_encode(state, input, CBOR_MAJOR_TYPE_PINT)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+bool uintx32_put(cbor_state_t *state, uint32_t input)
+{
+ if (!uint32_encode(state, &input, CBOR_MAJOR_TYPE_PINT)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+static bool strx_start_encode(cbor_state_t *state,
+ const cbor_string_type_t *input, cbor_major_type_t major_type)
+{
+ if (input->value && ((get_result_len(&input->len, sizeof(input->len))
+ + 1 + input->len + (size_t)state->payload)
+ > (size_t)state->payload_end)) {
+ FAIL();
+ }
+ if (!uint32_encode(state, &input->len, major_type)) {
+ FAIL();
+ }
+
+ return true;
+}
+
+
+static bool primx_encode(cbor_state_t *state, uint32_t input)
+{
+ if (!uint32_encode(state, &input, CBOR_MAJOR_TYPE_PRIM)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+static uint32_t remaining_str_len(cbor_state_t *state)
+{
+ uint32_t max_len = (size_t)state->payload_end - (size_t)state->payload;
+ uint32_t result_len = get_result_len(&max_len, sizeof(uint32_t));
+ return max_len - result_len - 1;
+}
+
+
+bool bstrx_cbor_start_encode(cbor_state_t *state, const cbor_string_type_t *result)
+{
+ if (!new_backup(state, 0)) {
+ FAIL();
+ }
+
+ uint32_t max_len = remaining_str_len(state);
+
+ /* Encode a dummy header */
+ if (!uint32_encode(state, &max_len,
+ CBOR_MAJOR_TYPE_BSTR)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+bool bstrx_cbor_end_encode(cbor_state_t *state)
+{
+ const uint8_t *payload = state->payload;
+
+ if (!restore_backup(state, FLAG_RESTORE | FLAG_DISCARD, 0xFFFFFFFF)) {
+ FAIL();
+ }
+ cbor_string_type_t value;
+
+ value.value = state->payload_end - remaining_str_len(state);
+ value.len = (size_t)payload - (size_t)value.value;
+
+ /* Reencode header of list now that we know the number of elements. */
+ if (!bstrx_encode(state, &value)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+static bool strx_encode(cbor_state_t *state,
+ const cbor_string_type_t *input, cbor_major_type_t major_type)
+{
+ if (!strx_start_encode(state, input, major_type)) {
+ FAIL();
+ }
+ if (input->len > (state->payload_end - state->payload)) {
+ FAIL();
+ }
+ if (state->payload_mut != input->value) {
+ memmove(state->payload_mut, input->value, input->len);
+ }
+ state->payload += input->len;
+ return true;
+}
+
+
+bool bstrx_encode(cbor_state_t *state, const cbor_string_type_t *input)
+{
+ return strx_encode(state, input, CBOR_MAJOR_TYPE_BSTR);
+}
+
+
+bool tstrx_encode(cbor_state_t *state, const cbor_string_type_t *input)
+{
+ return strx_encode(state, input, CBOR_MAJOR_TYPE_TSTR);
+}
+
+
+static bool list_map_start_encode(cbor_state_t *state, uint32_t max_num,
+ cbor_major_type_t major_type)
+{
+#ifdef CDDL_CBOR_CANONICAL
+ if (!new_backup(state, 0)) {
+ FAIL();
+ }
+
+ /* Encode dummy header with max number of elements. */
+ if (!uint32_encode(state, &max_num, major_type)) {
+ FAIL();
+ }
+ state->elem_count--; /* Because of dummy header. */
+#else
+ if (!encode_header_byte(state, major_type, 31)) {
+ FAIL();
+ }
+#endif
+ return true;
+}
+
+
+bool list_start_encode(cbor_state_t *state, uint32_t max_num)
+{
+ return list_map_start_encode(state, max_num, CBOR_MAJOR_TYPE_LIST);
+}
+
+
+bool map_start_encode(cbor_state_t *state, uint32_t max_num)
+{
+ return list_map_start_encode(state, max_num, CBOR_MAJOR_TYPE_MAP);
+}
+
+
+bool list_map_end_encode(cbor_state_t *state, uint32_t max_num,
+ cbor_major_type_t major_type)
+{
+#ifdef CDDL_CBOR_CANONICAL
+ uint32_t list_count = ((major_type == CBOR_MAJOR_TYPE_LIST) ?
+ state->elem_count
+ : (state->elem_count / 2));
+
+ const uint8_t *payload = state->payload;
+ uint32_t max_header_len = get_result_len(&max_num, 4);
+ uint32_t header_len = get_result_len(&list_count, 4);
+
+ if (!restore_backup(state, FLAG_RESTORE | FLAG_DISCARD, 0xFFFFFFFF)) {
+ FAIL();
+ }
+
+ cbor_print("list_count: %d\r\n", list_count);
+
+ /* Reencode header of list now that we know the number of elements. */
+ if (!(uint32_encode(state, &list_count, major_type))) {
+ FAIL();
+ }
+
+ if (max_header_len != header_len) {
+ const uint8_t *start = state->payload + max_header_len - header_len;
+ uint32_t body_size = payload - start;
+ memmove(state->payload_mut,
+ state->payload + max_header_len - header_len,
+ body_size);
+ /* Reset payload pointer to end of list */
+ state->payload += body_size;
+ } else {
+ /* Reset payload pointer to end of list */
+ state->payload = payload;
+ }
+#else
+ if (!encode_header_byte(state, CBOR_MAJOR_TYPE_PRIM, 31)) {
+ FAIL();
+ }
+#endif
+ return true;
+}
+
+
+bool list_end_encode(cbor_state_t *state, uint32_t max_num)
+{
+ return list_map_end_encode(state, max_num, CBOR_MAJOR_TYPE_LIST);
+}
+
+
+bool map_end_encode(cbor_state_t *state, uint32_t max_num)
+{
+ return list_map_end_encode(state, max_num, CBOR_MAJOR_TYPE_MAP);
+}
+
+
+bool nilx_put(cbor_state_t *state, const void *input)
+{
+ (void)input;
+ return primx_encode(state, 22);
+}
+
+
+bool boolx_encode(cbor_state_t *state, const bool *input)
+{
+ if (!primx_encode(state, *input + BOOL_TO_PRIM)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+bool boolx_put(cbor_state_t *state, bool input)
+{
+ if (!primx_encode(state, input + BOOL_TO_PRIM)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+bool double_encode(cbor_state_t *state, double *input)
+{
+ if (!value_encode(state, CBOR_MAJOR_TYPE_PRIM, input,
+ sizeof(*input))) {
+ FAIL();
+ }
+
+ return true;
+}
+
+
+bool double_put(cbor_state_t *state, double input)
+{
+ return double_encode(state, &input);
+}
+
+
+bool any_encode(cbor_state_t *state, void *input)
+{
+ return nilx_put(state, input);
+}
+
+
+bool tag_encode(cbor_state_t *state, uint32_t tag)
+{
+ if (!value_encode(state, CBOR_MAJOR_TYPE_TAG, &tag, sizeof(tag))) {
+ FAIL();
+ }
+ state->elem_count--;
+
+ return true;
+}
+
+
+bool multi_encode(uint32_t min_encode,
+ uint32_t max_encode,
+ const uint32_t *num_encode,
+ cbor_encoder_t encoder,
+ cbor_state_t *state,
+ const void *input,
+ uint32_t result_len)
+{
+ if (!PTR_VALUE_IN_RANGE(uint32_t, num_encode, NULL, &max_encode)) {
+ FAIL();
+ }
+ for (uint32_t i = 0; i < *num_encode; i++) {
+ if (!encoder(state, (const uint8_t *)input + i*result_len)) {
+ FAIL();
+ }
+ }
+ cbor_print("Found %zu elements.\n", *num_encode);
+ return true;
+}
+
+
+bool present_encode(const uint32_t *present,
+ cbor_encoder_t encoder,
+ cbor_state_t *state,
+ const void *input)
+{
+ uint32_t num_encode = *present;
+ bool retval = multi_encode(0, 1, &num_encode, encoder, state, input, 0);
+ return retval;
+}
diff --git a/boot/boot_serial/src/cbor_encode.h b/boot/boot_serial/src/cbor_encode.h
new file mode 100644
index 0000000..4c53d45
--- /dev/null
+++ b/boot/boot_serial/src/cbor_encode.h
@@ -0,0 +1,150 @@
+/*
+ * This file has been copied from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
+ */
+
+/*
+ * Copyright (c) 2020 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef CBOR_ENCODE_H__
+#define CBOR_ENCODE_H__
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "cbor_common.h"
+
+
+/** Encode a PINT/NINT into a int32_t.
+ *
+ * @param[inout] state The current state of the decoding.
+ * @param[out] result Where to place the encoded value.
+ *
+ * @retval true Everything is ok.
+ * @retval false If the payload is exhausted.
+ */
+bool intx32_encode(cbor_state_t *state, const int32_t *input);
+bool intx32_put(cbor_state_t *state, int32_t result);
+
+/** Encode a PINT into a uint32_t. */
+bool uintx32_encode(cbor_state_t *state, const uint32_t *result);
+bool uintx32_put(cbor_state_t *state, uint32_t result);
+
+/** Encode a BSTR header.
+ *
+ * The rest of the string can be encoded as CBOR.
+ * A state backup is created to keep track of the element count.
+ *
+ * @retval true Header encoded correctly
+ * @retval false Header encoded incorrectly, or backup failed.
+ */
+bool bstrx_cbor_start_encode(cbor_state_t *state, const cbor_string_type_t *result);
+
+/** Finalize encoding a CBOR-encoded BSTR.
+ *
+ * Restore element count from backup.
+ */
+bool bstrx_cbor_end_encode(cbor_state_t *state);
+
+/** Encode a BSTR, */
+bool bstrx_encode(cbor_state_t *state, const cbor_string_type_t *result);
+
+/** Encode a TSTR. */
+bool tstrx_encode(cbor_state_t *state, const cbor_string_type_t *result);
+
+#define tstrx_put(state, string) \
+ tstrx_encode(state, &(cbor_string_type_t){.value = (const uint8_t *)string, .len = (sizeof(string) - 1)})
+
+#define tstrx_put_term(state, string) \
+ tstrx_encode(state, &(cbor_string_type_t){.value = (const uint8_t *)string, .len = strlen((const char *)string)})
+
+/** Encode a LIST header.
+ *
+ * The contents of the list can be decoded via subsequent function calls.
+ * A state backup is created to keep track of the element count.
+ */
+bool list_start_encode(cbor_state_t *state, uint32_t max_num);
+
+/** Encode a MAP header. */
+bool map_start_encode(cbor_state_t *state, uint32_t max_num);
+
+/** Encode end of a LIST. Do some checks and deallocate backup. */
+bool list_end_encode(cbor_state_t *state, uint32_t max_num);
+
+/** Encode end of a MAP. Do some checks and deallocate backup. */
+bool map_end_encode(cbor_state_t *state, uint32_t max_num);
+
+/** Encode a "nil" primitive value. result should be NULL. */
+bool nilx_put(cbor_state_t *state, const void *result);
+
+/** Encode a boolean primitive value. */
+bool boolx_encode(cbor_state_t *state, const bool *result);
+bool boolx_put(cbor_state_t *state, bool result);
+
+/** Encode a float */
+bool float_encode(cbor_state_t *state, double *result);
+bool float_put(cbor_state_t *state, double result);
+
+/** Dummy encode "any": Encode a "nil". input should be NULL. */
+bool any_encode(cbor_state_t *state, void *input);
+
+/** Encode a tag. */
+bool tag_encode(cbor_state_t *state, uint32_t tag);
+
+/** Encode 0 or more elements with the same type and constraints.
+ *
+ * @details This must not necessarily encode all elements in a list. E.g. if
+ * the list contains 3 INTS between 0 and 100 followed by 0 to 2 BSTRs
+ * with length 8, that could be done with:
+ *
+ * @code{c}
+ * uint32_t int_min = 0;
+ * uint32_t int_max = 100;
+ * uint32_t bstr_size = 8;
+ * uint32_t ints[3];
+ * cbor_string_type_t bstrs[2] = <initialize here>;
+ * bool res;
+ *
+ * res = list_start_encode(state, 5);
+ * // check res
+ * res = multi_encode(3, 3, &num_encode, uintx32_encode, state,
+ * ints, 4);
+ * // check res
+ * res = multi_encode(0, 2, &num_encode, strx_encode, state,
+ * bstrs, sizeof(cbor_string_type_t));
+ * // check res
+ * res = list_end_encode(state, 5);
+ * // check res
+ * @endcode
+ *
+ * @param[in] min_encode The minimum acceptable number of elements.
+ * @param[in] max_encode The maximum acceptable number of elements.
+ * @param[in] num_encode The actual number of elements.
+ * @param[in] encoder The encoder function to call under the hood. This
+ * function will be called with the provided arguments
+ * repeatedly until the function fails (returns false)
+ * or until it has been called @p max_encode times.
+ * result is moved @p result_len bytes for each call
+ * to @p encoder, i.e. @p result refers to an array
+ * of result variables.
+ * @param[in] input Source of the encoded values. Must be an array
+ * of length at least @p max_encode.
+ * @param[in] result_len The length of the result variables. Must be the
+ * length of the elements in result.
+ *
+ * @retval true If at least @p min_encode variables were correctly encoded.
+ * @retval false If @p encoder failed before having encoded @p min_encode
+ * values.
+ */
+bool multi_encode(uint32_t min_encode, uint32_t max_encode, const uint32_t *num_encode,
+ cbor_encoder_t encoder, cbor_state_t *state, const void *input,
+ uint32_t result_len);
+
+bool present_encode(const uint32_t *present,
+ cbor_encoder_t encoder,
+ cbor_state_t *state,
+ const void *input);
+
+#endif /* CBOR_ENCODE_H__ */
diff --git a/boot/boot_serial/src/regenerate_serial_recovery_cbor.sh b/boot/boot_serial/src/regenerate_serial_recovery_cbor.sh
index 79cb6e9..08d1220 100755
--- a/boot/boot_serial/src/regenerate_serial_recovery_cbor.sh
+++ b/boot/boot_serial/src/regenerate_serial_recovery_cbor.sh
@@ -1,19 +1,19 @@
#!/bin/bash
if [ "$1" == "--help" ] || [ "$1" == "" ]; then
- echo "Regenerate serial_recovery_cbor.c|h if the cddl_gen submodule is updated."
+ echo "Regenerate serial_recovery_cbor.c|h if the cddl-gen submodule is updated."
echo "Usage: $0 <copyright>"
- echo " e.g. $0 \"2020 Nordic Semiconductor ASA\""
+ echo " e.g. $0 \"2021 Nordic Semiconductor ASA\""
exit -1
fi
add_copy_notice() {
echo "$(printf '/*
- * This file has been %s from the cddl_gen submodule.
+ * This file has been %s from the cddl-gen submodule.
* Commit %s
*/
-' "$2" "$(git -C ../../../ext/cddl_gen rev-parse HEAD)"; cat $1;)" > $1
+' "$2" "$(git -C ../../../ext/cddl-gen rev-parse HEAD)"; cat $1;)" > $1
}
echo "Copying cbor_decode.c|h"
@@ -22,11 +22,15 @@
add_copy_notice $2 "copied"
}
-copy_with_copy_notice ../../../ext/cddl_gen/src/cbor_decode.c cbor_decode.c
-copy_with_copy_notice ../../../ext/cddl_gen/include/cbor_decode.h cbor_decode.h cbor_decode.h
+copy_with_copy_notice ../../../ext/cddl-gen/src/cbor_decode.c cbor_decode.c
+copy_with_copy_notice ../../../ext/cddl-gen/src/cbor_encode.c cbor_encode.c
+copy_with_copy_notice ../../../ext/cddl-gen/src/cbor_common.c cbor_common.c
+copy_with_copy_notice ../../../ext/cddl-gen/include/cbor_decode.h cbor_decode.h
+copy_with_copy_notice ../../../ext/cddl-gen/include/cbor_encode.h cbor_encode.h
+copy_with_copy_notice ../../../ext/cddl-gen/include/cbor_common.h cbor_common.h
echo "Generating serial_recovery_cbor.c|h"
-python3 ../../../ext/cddl_gen/scripts/cddl_gen.py -i serial_recovery.cddl -t Upload --oc serial_recovery_cbor.c --oh serial_recovery_cbor.h --time-header
+python3 ../../../ext/cddl-gen/cddl_gen/cddl_gen.py -c serial_recovery.cddl code -d -t Upload --oc serial_recovery_cbor.c --oh serial_recovery_cbor.h --time-header
add_copyright() {
echo "$(printf '/*
@@ -42,3 +46,4 @@
add_copyright serial_recovery_cbor.h "$1"
add_copy_notice serial_recovery_cbor.c "generated"
add_copy_notice serial_recovery_cbor.h "generated"
+add_copy_notice types_serial_recovery_cbor.h "generated"
diff --git a/boot/boot_serial/src/serial_recovery_cbor.c b/boot/boot_serial/src/serial_recovery_cbor.c
index 45634ef..2561b70 100644
--- a/boot/boot_serial/src/serial_recovery_cbor.c
+++ b/boot/boot_serial/src/serial_recovery_cbor.c
@@ -1,16 +1,18 @@
/*
- * This file has been generated from the cddl_gen submodule.
- * Commit 9d911cf0c7c9f13b5a9fdd5ed6c1012df21e5576
+ * This file has been generated from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
*/
/*
- * Copyright (c) 2020 Nordic Semiconductor ASA
+ * Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
-/* Generated with cddl_gen.py (https://github.com/oyvindronningstad/cddl_gen)
- * at: 2020-05-13 12:19:04
+/*
+ * Generated with cddl_gen.py (https://github.com/NordicSemiconductor/cddl-gen)
+ * at: 2021-08-02 17:09:42
+ * Generated with a default_max_qty of 3
*/
#include <stdint.h>
@@ -20,65 +22,73 @@
#include "cbor_decode.h"
#include "serial_recovery_cbor.h"
+#if DEFAULT_MAX_QTY != 3
+#error "The type file was generated with a different default_max_qty than this file"
+#endif
+
static bool decode_Member(
- cbor_decode_state_t *p_state, void * p_result, void * p_min_value,
- void * p_max_value)
+ cbor_state_t *state, struct Member_ *result)
{
- cbor_decode_print("decode_Member\n");
- uint8_t const * p_payload_bak;
- size_t elem_count_bak;
- _Member_t* p_type_result = (_Member_t*)p_result;
+ cbor_print("%s\n", __func__);
+ cbor_string_type_t tmp_str;
+ bool int_res;
- bool result = (((p_payload_bak = p_state->p_payload) && ((elem_count_bak = p_state->elem_count) || 1) && ((((strx_decode(p_state, &((*p_type_result)._Member_image_key), NULL, NULL))&& !memcmp("image", (*p_type_result)._Member_image_key.value, (*p_type_result)._Member_image_key.len)
- && (intx32_decode(p_state, &((*p_type_result)._Member_image), NULL, NULL))) && (((*p_type_result)._Member_choice = _Member_image) || 1))
- || ((p_state->p_payload = p_payload_bak) && ((p_state->elem_count = elem_count_bak) || 1) && (((strx_decode(p_state, &((*p_type_result)._Member_data_key), NULL, NULL))&& !memcmp("data", (*p_type_result)._Member_data_key.value, (*p_type_result)._Member_data_key.len)
- && (strx_decode(p_state, &((*p_type_result)._Member_data), NULL, NULL))) && (((*p_type_result)._Member_choice = _Member_data) || 1)))
- || ((p_state->p_payload = p_payload_bak) && ((p_state->elem_count = elem_count_bak) || 1) && (((strx_decode(p_state, &((*p_type_result)._Member_len_key), NULL, NULL))&& !memcmp("len", (*p_type_result)._Member_len_key.value, (*p_type_result)._Member_len_key.len)
- && (intx32_decode(p_state, &((*p_type_result)._Member_len), NULL, NULL))) && (((*p_type_result)._Member_choice = _Member_len) || 1)))
- || ((p_state->p_payload = p_payload_bak) && ((p_state->elem_count = elem_count_bak) || 1) && (((strx_decode(p_state, &((*p_type_result)._Member_off_key), NULL, NULL))&& !memcmp("off", (*p_type_result)._Member_off_key.value, (*p_type_result)._Member_off_key.len)
- && (intx32_decode(p_state, &((*p_type_result)._Member_off), NULL, NULL))) && (((*p_type_result)._Member_choice = _Member_off) || 1)))
- || ((p_state->p_payload = p_payload_bak) && ((p_state->elem_count = elem_count_bak) || 1) && (((strx_decode(p_state, &((*p_type_result)._Member_sha_key), NULL, NULL))&& !memcmp("sha", (*p_type_result)._Member_sha_key.value, (*p_type_result)._Member_sha_key.len)
- && (strx_decode(p_state, &((*p_type_result)._Member_sha), NULL, NULL))) && (((*p_type_result)._Member_choice = _Member_sha) || 1))))));
+ bool tmp_result = (((union_start_code(state) && (int_res = (((((tstrx_expect(state, ((tmp_str.value = (const uint8_t *)"image",
+ tmp_str.len = sizeof("image") - 1, &tmp_str)))))
+ && (intx32_decode(state, (&(*result)._Member_image)))) && (((*result)._Member_choice = _Member_image) || 1))
+ || (union_elem_code(state) && ((((tstrx_expect(state, ((tmp_str.value = (const uint8_t *)"data",
+ tmp_str.len = sizeof("data") - 1, &tmp_str)))))
+ && (bstrx_decode(state, (&(*result)._Member_data)))) && (((*result)._Member_choice = _Member_data) || 1)))
+ || (union_elem_code(state) && ((((tstrx_expect(state, ((tmp_str.value = (const uint8_t *)"len",
+ tmp_str.len = sizeof("len") - 1, &tmp_str)))))
+ && (intx32_decode(state, (&(*result)._Member_len)))) && (((*result)._Member_choice = _Member_len) || 1)))
+ || (union_elem_code(state) && ((((tstrx_expect(state, ((tmp_str.value = (const uint8_t *)"off",
+ tmp_str.len = sizeof("off") - 1, &tmp_str)))))
+ && (intx32_decode(state, (&(*result)._Member_off)))) && (((*result)._Member_choice = _Member_off) || 1)))
+ || (union_elem_code(state) && ((((tstrx_expect(state, ((tmp_str.value = (const uint8_t *)"sha",
+ tmp_str.len = sizeof("sha") - 1, &tmp_str)))))
+ && (bstrx_decode(state, (&(*result)._Member_sha)))) && (((*result)._Member_choice = _Member_sha) || 1)))), union_end_code(state), int_res))));
- if (!result)
- {
- cbor_decode_trace();
- }
+ if (!tmp_result)
+ cbor_trace();
- return result;
+ return tmp_result;
}
static bool decode_Upload(
- cbor_decode_state_t *p_state, void * p_result, void * p_min_value,
- void * p_max_value)
+ cbor_state_t *state, struct Upload *result)
{
- cbor_decode_print("decode_Upload\n");
- size_t temp_elem_counts[2];
- size_t *p_temp_elem_count = temp_elem_counts;
- Upload_t* p_type_result = (Upload_t*)p_result;
+ cbor_print("%s\n", __func__);
+ bool int_res;
- bool result = (((list_start_decode(p_state, &(*(p_temp_elem_count++)), 1, 5))
- && multi_decode(1, 5, &(*p_type_result)._Upload_members_count, (void*)decode_Member, p_state, &((*p_type_result)._Upload_members), NULL, NULL, sizeof(_Member_t))
- && ((p_state->elem_count = *(--p_temp_elem_count)) || 1)));
+ bool tmp_result = (((map_start_decode(state) && (int_res = (multi_decode(1, 5, &(*result)._Upload_members_count, (void *)decode_Member, state, (&(*result)._Upload_members), sizeof(struct Member_))), ((map_end_decode(state)) && int_res)))));
- if (!result)
- {
- cbor_decode_trace();
- }
+ if (!tmp_result)
+ cbor_trace();
- p_state->elem_count = temp_elem_counts[0];
- return result;
+ return tmp_result;
}
-bool cbor_decode_Upload(const uint8_t * p_payload, size_t payload_len, Upload_t * p_result)
-{
- cbor_decode_state_t state = {
- .p_payload = p_payload,
- .p_payload_end = p_payload + payload_len,
- .elem_count = 1
- };
- return decode_Upload(&state, p_result, NULL, NULL);
+__attribute__((unused)) static bool type_test_decode_Upload(
+ struct Upload *result)
+{
+ /* This function should not be called, it is present only to test that
+ * the types of the function and struct match, since this information
+ * is lost with the casts in the entry function.
+ */
+ return decode_Upload(NULL, result);
+}
+
+
+bool cbor_decode_Upload(
+ const uint8_t *payload, uint32_t payload_len,
+ struct Upload *result,
+ uint32_t *payload_len_out)
+{
+ return entry_function(payload, payload_len, (const void *)result,
+ payload_len_out, (void *)decode_Upload,
+ 1, 2);
}
diff --git a/boot/boot_serial/src/serial_recovery_cbor.h b/boot/boot_serial/src/serial_recovery_cbor.h
index aa14f5c..f167d9b 100644
--- a/boot/boot_serial/src/serial_recovery_cbor.h
+++ b/boot/boot_serial/src/serial_recovery_cbor.h
@@ -1,16 +1,18 @@
/*
- * This file has been generated from the cddl_gen submodule.
- * Commit 9d911cf0c7c9f13b5a9fdd5ed6c1012df21e5576
+ * This file has been generated from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
*/
/*
- * Copyright (c) 2020 Nordic Semiconductor ASA
+ * Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
-/* Generated with cddl_gen.py (https://github.com/oyvindronningstad/cddl_gen)
- * at: 2020-05-13 12:19:04
+/*
+ * Generated with cddl_gen.py (https://github.com/NordicSemiconductor/cddl-gen)
+ * at: 2021-08-02 17:09:42
+ * Generated with a default_max_qty of 3
*/
#ifndef SERIAL_RECOVERY_CBOR_H__
@@ -21,45 +23,17 @@
#include <stddef.h>
#include <string.h>
#include "cbor_decode.h"
+#include "types_serial_recovery_cbor.h"
+
+#if DEFAULT_MAX_QTY != 3
+#error "The type file was generated with a different default_max_qty than this file"
+#endif
-typedef struct {
- union {
- struct {
- cbor_string_type_t _Member_image_key;
- int32_t _Member_image;
- };
- struct {
- cbor_string_type_t _Member_data_key;
- cbor_string_type_t _Member_data;
- };
- struct {
- cbor_string_type_t _Member_len_key;
- int32_t _Member_len;
- };
- struct {
- cbor_string_type_t _Member_off_key;
- int32_t _Member_off;
- };
- struct {
- cbor_string_type_t _Member_sha_key;
- cbor_string_type_t _Member_sha;
- };
- };
- enum {
- _Member_image,
- _Member_data,
- _Member_len,
- _Member_off,
- _Member_sha,
- } _Member_choice;
-} _Member_t;
+bool cbor_decode_Upload(
+ const uint8_t *payload, uint32_t payload_len,
+ struct Upload *result,
+ uint32_t *payload_len_out);
-typedef struct {
- _Member_t _Upload_members[5];
- size_t _Upload_members_count;
-} Upload_t;
-bool cbor_decode_Upload(const uint8_t * p_payload, size_t payload_len, Upload_t * p_result);
-
-#endif // SERIAL_RECOVERY_CBOR_H__
+#endif /* SERIAL_RECOVERY_CBOR_H__ */
diff --git a/boot/boot_serial/src/types_serial_recovery_cbor.h b/boot/boot_serial/src/types_serial_recovery_cbor.h
new file mode 100644
index 0000000..8856017
--- /dev/null
+++ b/boot/boot_serial/src/types_serial_recovery_cbor.h
@@ -0,0 +1,56 @@
+/*
+ * This file has been generated from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
+ */
+
+/*
+ * Generated with cddl_gen.py (https://github.com/NordicSemiconductor/cddl-gen)
+ * at: 2021-08-02 17:09:42
+ * Generated with a default_max_qty of 3
+ */
+
+#ifndef TYPES_SERIAL_RECOVERY_CBOR_H__
+#define TYPES_SERIAL_RECOVERY_CBOR_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include "cbor_decode.h"
+
+#define DEFAULT_MAX_QTY 3
+
+struct Member_ {
+ union {
+ struct {
+ int32_t _Member_image;
+ };
+ struct {
+ cbor_string_type_t _Member_data;
+ };
+ struct {
+ int32_t _Member_len;
+ };
+ struct {
+ int32_t _Member_off;
+ };
+ struct {
+ cbor_string_type_t _Member_sha;
+ };
+ };
+ enum {
+ _Member_image,
+ _Member_data,
+ _Member_len,
+ _Member_off,
+ _Member_sha,
+ } _Member_choice;
+};
+
+struct Upload {
+ struct Member_ _Upload_members[5];
+ uint32_t _Upload_members_count;
+};
+
+
+#endif /* TYPES_SERIAL_RECOVERY_CBOR_H__ */
diff --git a/boot/boot_serial/test/src/testcases/boot_serial_upload_bigger_image.c b/boot/boot_serial/test/src/testcases/boot_serial_upload_bigger_image.c
index 53a7199..83ba50a 100644
--- a/boot/boot_serial/test/src/testcases/boot_serial_upload_bigger_image.c
+++ b/boot/boot_serial/test/src/testcases/boot_serial_upload_bigger_image.c
@@ -18,7 +18,6 @@
*/
#include <flash_map_backend/flash_map_backend.h>
-#include <tinycbor/cborconstants_p.h>
#include "boot_test.h"
diff --git a/boot/bootutil/include/bootutil/boot_hooks.h b/boot/bootutil/include/bootutil/boot_hooks.h
new file mode 100644
index 0000000..61de3c4
--- /dev/null
+++ b/boot/bootutil/include/bootutil/boot_hooks.h
@@ -0,0 +1,160 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Copyright (c) 2021 Nordic Semiconductor ASA
+ *
+ * Original license:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+ * @file
+ * @brief Hooks definition implementation API
+ *
+ * This file contains API interface definition for hooks which can be
+ * implemented to overide or to amend some of MCUboot's native routines.
+ */
+
+#ifndef H_BOOTUTIL_HOOKS
+#define H_BOOTUTIL_HOOKS
+
+#ifdef MCUBOOT_IMAGE_ACCESS_HOOKS
+
+#define BOOT_HOOK_CALL(f, ret_default, ...) f(__VA_ARGS__)
+
+#define BOOT_HOOK_CALL_FIH(f, fih_ret_default, fih_rc, ...) \
+ do { \
+ FIH_CALL(f, fih_rc, __VA_ARGS__); \
+ } while(0);
+
+#else
+
+#define BOOT_HOOK_CALL(f, ret_default, ...) ret_default
+
+#define BOOT_HOOK_CALL_FIH(f, fih_ret_default, fih_rc, ...) \
+ do { \
+ fih_rc = fih_ret_default; \
+ } while(0);
+
+#endif
+
+/** Hook for provide image header data.
+ *
+ * This Hook may be used to overide image header read implementation or doing
+ * a custom action before.
+ *
+ * @param img_index the index of the image pair
+ * @param slot slot number
+ * @param img_head image header structure to be populated
+ *
+ * @retval 0: header was read/populated, skip direct header data read
+ * BOOT_HOOK_REGULAR: follow the normal execution path,
+ * otherwise an error-code value.
+ */
+int boot_read_image_header_hook(int img_index, int slot,
+ struct image_header *img_head);
+
+/** Hook for Validate image hash/signature
+ *
+ * This Hook may be used to overide image validation procedure or doing
+ * a custom action before.
+ *
+ * @param img_index the index of the image pair
+ * @param slot slot number
+ *
+ * @retval FIH_SUCCESS: image is valid, skip direct validation
+ * FIH_FAILURE: image is invalid, skip direct validation
+ * fih encoded BOOT_HOOK_REGULAR: follow the normal execution path.
+ */
+fih_int boot_image_check_hook(int img_index, int slot);
+
+/** Hook for implement image update
+ *
+ * This hook is for for implementing an alternative mechanism of image update or
+ * doing a custom action before.
+ *
+ * @param img_index the index of the image pair
+ * @param img_head the image header of the secondary image
+ * @param area the flash area of the secondary image.
+ *
+ * @retval 0: update was done, skip performing the update
+ * BOOT_HOOK_REGULAR: follow the normal execution path,
+ * otherwise an error-code value.
+ */
+int boot_perform_update_hook(int img_index, struct image_header *img_head,
+ const struct flash_area *area);
+
+/** Hook for implement image's post copying action
+ *
+ * This hook is for implement action which might be done right after image was
+ * copied to the primary slot. This hook is called in MCUBOOT_OVERWRITE_ONLY
+ * mode only.
+ *
+ * @param img_index the index of the image pair
+ * @param area the flash area of the primary image.
+ * @param size size of copied image.
+ *
+ * @retval 0: success, mcuboot will follow normal code execution flow after
+ * execution of this call.
+ * non-zero: an error, mcuboot will return from
+ * boot_copy_image() with error.
+ * Update will be undone so might be resume on the next boot.
+ */
+int boot_copy_region_post_hook(int img_index, const struct flash_area *area,
+ size_t size);
+
+/** Hook for implement image's post recovery upload action
+ *
+ * This hook is for implement action which might be done right after image was
+ * copied to the primary slot. This hook is called in serial recovery upload
+ * operation.
+ *
+ * @param img_index the index of the image pair
+ * @param area the flash area of the primary image.
+ * @param size size of copied image.
+ *
+ * @retval 0: success, mcuboot will follow normal code execution flow after
+ * execution of this call.
+ * non-zero: an error, will be transferred as part of comand response
+ * as "rc" entry.
+ */
+int boot_serial_uploaded_hook(int img_index, const struct flash_area *area,
+ size_t size);
+
+/** Hook for implement the image's slot installation status fetch operation for
+ * the MGMT custom command.
+ *
+ * The image's slot installation status is custom property. It's detailed
+ * definition depends on user implementation. It is only defined that the status
+ * will be set to 0 if this hook not provides another value.
+ *
+ * @param img_index the index of the image pair
+ * @param slot slot number
+ * @param img_install_stat the image installation status to be populated
+ *
+ * @retval 0: the installaton status was fetched successfully,
+ * BOOT_HOOK_REGULAR: follow the normal execution path, status will be
+ * set to 0
+ * otherwise an error-code value. Error-code is ignored, but it is up to
+ * the implementation to reflect this error in img_install_stat.
+ */
+int boot_img_install_stat_hook(int image_index, int slot,
+ int *img_install_stat);
+
+#endif /*H_BOOTUTIL_HOOKS*/
diff --git a/boot/bootutil/include/bootutil/boot_public_hooks.h b/boot/bootutil/include/bootutil/boot_public_hooks.h
new file mode 100644
index 0000000..453edf2
--- /dev/null
+++ b/boot/bootutil/include/bootutil/boot_public_hooks.h
@@ -0,0 +1,52 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Copyright (c) 2021 Nordic Semiconductor ASA
+ *
+ * Original license:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+ * @file
+ * @brief Hooks definition implementation API
+ *
+ * This file contains API interface definition for hooks which can be
+ * implemented for overide some of MCUboot's native routines.
+ */
+
+#ifndef H_BOOTUTIL_PUBLIC_HOOKS
+#define H_BOOTUTIL_PUBLIC_HOOKS
+
+#include "bootutil/boot_hooks.h"
+
+/** Hook for provide primary image swap state.
+ *
+ * @param img_index the index of the image pair
+ * @param state image swap state structure to be populated
+ *
+ * @retval 0: header was read/populated
+ * FIH_FAILURE: image is invalid,
+ * BOOT_HOOK_REGULAR if hook not implemented for the image-slot,
+ * othervise an error-code value.
+ */
+int boot_read_swap_state_primary_slot_hook(int image_index,
+ struct boot_swap_state *state);
+
+#endif /*H_BOOTUTIL_PUBLIC_HOOKS*/
diff --git a/boot/bootutil/include/bootutil/boot_record.h b/boot/bootutil/include/bootutil/boot_record.h
index 933a8ea..e6aaa71 100644
--- a/boot/bootutil/include/bootutil/boot_record.h
+++ b/boot/bootutil/include/bootutil/boot_record.h
@@ -18,6 +18,7 @@
#define __BOOT_RECORD_H__
#include <stdint.h>
+#include <stddef.h>
#include "bootutil/image.h"
#ifdef __cplusplus
diff --git a/boot/bootutil/include/bootutil/bootutil.h b/boot/bootutil/include/bootutil/bootutil.h
index cf08a59..6ea66ff 100644
--- a/boot/bootutil/include/bootutil/bootutil.h
+++ b/boot/bootutil/include/bootutil/bootutil.h
@@ -51,6 +51,11 @@
*/
uint8_t br_flash_dev_id;
uint32_t br_image_off;
+
+#ifdef MCUBOOT_ENC_IMAGES_XIP
+ uint32_t xip_key[BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE/4];
+ uint32_t xip_iv[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE/4];
+#endif
};
/* This is not actually used by mcuboot's code but can be used by apps
@@ -72,12 +77,6 @@
struct boot_loader_state;
fih_int context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp);
-int boot_swap_type_multi(int image_index);
-int boot_swap_type(void);
-
-int boot_set_pending(int permanent);
-int boot_set_confirmed(void);
-
#define SPLIT_GO_OK (0)
#define SPLIT_GO_NON_MATCHING (-1)
#define SPLIT_GO_ERR (-2)
@@ -88,4 +87,4 @@
}
#endif
-#endif
+#endif
\ No newline at end of file
diff --git a/boot/bootutil/include/bootutil/bootutil_log.h b/boot/bootutil/include/bootutil/bootutil_log.h
index 0ce8a53..f2c70b9 100644
--- a/boot/bootutil/include/bootutil/bootutil_log.h
+++ b/boot/bootutil/include/bootutil/bootutil_log.h
@@ -26,9 +26,9 @@
#endif
#include <mcuboot_config/mcuboot_config.h>
-#include <mcuboot_config/mcuboot_logging.h>
#ifdef MCUBOOT_HAVE_LOGGING
+#include <mcuboot_config/mcuboot_logging.h>
#define BOOT_LOG_ERR(...) MCUBOOT_LOG_ERR(__VA_ARGS__)
#define BOOT_LOG_WRN(...) MCUBOOT_LOG_WRN(__VA_ARGS__)
@@ -36,6 +36,9 @@
#define BOOT_LOG_DBG(...) MCUBOOT_LOG_DBG(__VA_ARGS__)
#define BOOT_LOG_SIM(...) MCUBOOT_LOG_SIM(__VA_ARGS__)
+#define BOOT_LOG_MODULE_DECLARE(module) MCUBOOT_LOG_MODULE_DECLARE(module)
+#define BOOT_LOG_MODULE_REGISTER(module) MCUBOOT_LOG_MODULE_REGISTER(module)
+
#else
#define BOOT_LOG_ERR(...) IGNORE(__VA_ARGS__)
@@ -44,6 +47,9 @@
#define BOOT_LOG_DBG(...) IGNORE(__VA_ARGS__)
#define BOOT_LOG_SIM(...) IGNORE(__VA_ARGS__)
+#define BOOT_LOG_MODULE_DECLARE(module)
+#define BOOT_LOG_MODULE_REGISTER(module)
+
#endif /* MCUBOOT_HAVE_LOGGING */
#ifdef __cplusplus
diff --git a/boot/bootutil/include/bootutil/bootutil_public.h b/boot/bootutil/include/bootutil/bootutil_public.h
index d73cc2e..adde43c 100644
--- a/boot/bootutil/include/bootutil/bootutil_public.h
+++ b/boot/bootutil/include/bootutil/bootutil_public.h
@@ -3,8 +3,8 @@
*
* Copyright (c) 2017-2019 Linaro LTD
* Copyright (c) 2016-2019 JUUL Labs
- * Copyright (c) 2019-2020 Arm Limited
- * Copyright (c) 2020 Nordic Semiconductor ASA
+ * Copyright (c) 2019-2021 Arm Limited
+ * Copyright (c) 2020-2021 Nordic Semiconductor ASA
*
* Original license:
*
@@ -41,6 +41,7 @@
#include <inttypes.h>
#include <string.h>
#include <flash_map_backend/flash_map_backend.h>
+#include <mcuboot_config/mcuboot_config.h>
#ifdef __cplusplus
extern "C" {
@@ -70,7 +71,7 @@
/** Swapping encountered an unrecoverable error */
#define BOOT_SWAP_TYPE_PANIC 0xff
-#define BOOT_MAX_ALIGN 8
+#define BOOT_MAX_ALIGN 8U
#define BOOT_MAGIC_GOOD 1
#define BOOT_MAGIC_BAD 2
@@ -96,7 +97,9 @@
#define BOOT_ENOMEM 6
#define BOOT_EBADARGS 7
#define BOOT_EBADVERSION 8
+#define BOOT_EFLASH_SEC 9
+#define BOOT_HOOK_REGULAR 1
/*
* Extract the swap type and image number from image trailers's swap_info
* filed.
@@ -115,8 +118,10 @@
#include "mcuboot_config/mcuboot_assert.h"
#else
#include <assert.h>
+#ifndef ASSERT
#define ASSERT assert
#endif
+#endif
struct boot_swap_state {
uint8_t magic; /* One of the BOOT_MAGIC_[...] values. */
@@ -147,25 +152,54 @@
int boot_swap_type(void);
/**
- * Marks the image in the secondary slot as pending. On the next reboot,
- * the system will perform a one-time boot of the the secondary slot image.
+ * Marks the image with the given index in the secondary slot as pending. On the
+ * next reboot, the system will perform a one-time boot of the the secondary
+ * slot image.
*
- * @param permanent Whether the image should be used permanently or
- * only tested once:
- * 0=run image once, then confirm or revert.
- * 1=run image forever.
+ * @param image_index Image pair index.
*
- * @return 0 on success; nonzero on failure.
+ * @param permanent Whether the image should be used permanently or
+ * only tested once:
+ * 0=run image once, then confirm or revert.
+ * 1=run image forever.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+int boot_set_pending_multi(int image_index, int permanent);
+
+/**
+ * Marks the image with index 0 in the secondary slot as pending. On the next
+ * reboot, the system will perform a one-time boot of the the secondary slot
+ * image. Note that this API is kept for compatibility. The
+ * boot_set_pending_multi() API is recommended.
+ *
+ * @param permanent Whether the image should be used permanently or
+ * only tested once:
+ * 0=run image once, then confirm or revert.
+ * 1=run image forever.
+ *
+ * @return 0 on success; nonzero on failure.
*/
int boot_set_pending(int permanent);
/**
- * @brief Marks the image in the primary slot as confirmed.
+ * Marks the image with the given index in the primary slot as confirmed. The
+ * system will continue booting into the image in the primary slot until told to
+ * boot from a different slot.
*
- * The system will continue booting into the image in the primary slot until
- * told to boot from a different slot.
+ * @param image_index Image pair index.
*
- * @return 0 on success; nonzero on failure.
+ * @return 0 on success; nonzero on failure.
+ */
+int boot_set_confirmed_multi(int image_index);
+
+/**
+ * Marks the image with index 0 in the primary slot as confirmed. The system
+ * will continue booting into the image in the primary slot until told to boot
+ * from a different slot. Note that this API is kept for compatibility. The
+ * boot_set_confirmed_multi() API is recommended.
+ *
+ * @return 0 on success; nonzero on failure.
*/
int boot_set_confirmed(void);
@@ -194,18 +228,25 @@
/**
* @brief Read the image swap state
*
- * @param flash_area_id Id of flash parttition from which trailer will be read.
- * @param state Struture for holding swap state.
+ * @param flash_area_id id of flash partition from which state will be read;
+ * @param state pointer to structure for storing swap state.
*
- * @return 0 on success, nonzero errno code on fail.
+ * @return 0 on success; non-zero error code on failure;
*/
int
boot_read_swap_state_by_id(int flash_area_id, struct boot_swap_state *state);
-#define BOOT_MAGIC_ARR_SZ \
- (sizeof boot_img_magic / sizeof boot_img_magic[0])
-
-extern const uint32_t boot_img_magic[4];
+/**
+ * @brief Read the image swap state
+ *
+ * @param fa pointer to flash_area object;
+ * @param state pointer to structure for storing swap state.
+ *
+ * @return 0 on success; non-zero error code on failure.
+ */
+int
+boot_read_swap_state(const struct flash_area *fap,
+ struct boot_swap_state *state);
#ifdef __cplusplus
}
diff --git a/boot/bootutil/include/bootutil/caps.h b/boot/bootutil/include/bootutil/caps.h
index 77182a1..ca68279 100644
--- a/boot/bootutil/include/bootutil/caps.h
+++ b/boot/bootutil/include/bootutil/caps.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2017 Linaro Limited
+ * Copyright (c) 2021 Arm Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,7 +48,12 @@
#define BOOTUTIL_CAP_DOWNGRADE_PREVENTION (1<<12)
#define BOOTUTIL_CAP_ENC_X25519 (1<<13)
#define BOOTUTIL_CAP_BOOTSTRAP (1<<14)
-#define BOOTUTIL_CAP_SWAP_USING_STATUS (1<<15)
+#define BOOTUTIL_CAP_AES256 (1<<15)
+#define BOOTUTIL_CAP_RAM_LOAD (1<<16)
+#define BOOTUTIL_CAP_DIRECT_XIP (1<<17)
+
+//Sep-12 2021 capabilities 15-17 already used in github mainline
+#define BOOTUTIL_CAP_SWAP_USING_STATUS (1<<18)
/*
* Query the number of images this bootloader is configured for. This
diff --git a/boot/bootutil/include/bootutil/crypto/aes_ctr.h b/boot/bootutil/include/bootutil/crypto/aes_ctr.h
index 8422f45..3758ca8 100644
--- a/boot/bootutil/include/bootutil/crypto/aes_ctr.h
+++ b/boot/bootutil/include/bootutil/crypto/aes_ctr.h
@@ -7,8 +7,8 @@
* one of these defined.
*/
-#ifndef __BOOTUTIL_CRYPTO_AES_CTR_H_
-#define __BOOTUTIL_CRYPTO_AES_CTR_H_
+#ifndef BOOTUTIL_CRYPTO_AES_CTR_H
+#define BOOTUTIL_CRYPTO_AES_CTR_H
#include <string.h>
@@ -21,11 +21,15 @@
#if defined(MCUBOOT_USE_MBED_TLS)
#include <mbedtls/aes.h>
- #define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE (16)
- #define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE (16)
+ #include "bootutil/enc_key_public.h"
+ #define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE BOOT_ENC_KEY_SIZE
+ #define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE (16U)
#endif /* MCUBOOT_USE_MBED_TLS */
#if defined(MCUBOOT_USE_TINYCRYPT)
+ #if defined(MCUBOOT_AES_256)
+ #error "Cannot use AES-256 for encryption with Tinycrypt library."
+ #endif
#include <string.h>
#include <tinycrypt/aes.h>
#include <tinycrypt/ctr_mode.h>
@@ -62,12 +66,14 @@
static inline int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *m, uint32_t mlen, size_t blk_off, uint8_t *c)
{
uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
+ (void)memset(&stream_block, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
return mbedtls_aes_crypt_ctr(ctx, mlen, &blk_off, counter, stream_block, m, c);
}
static inline int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *c, uint32_t clen, size_t blk_off, uint8_t *m)
{
uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
+ (void)memset(&stream_block, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
return mbedtls_aes_crypt_ctr(ctx, clen, &blk_off, counter, stream_block, c, m);
}
#endif /* MCUBOOT_USE_MBED_TLS */
@@ -119,4 +125,4 @@
}
#endif
-#endif /* __BOOTUTIL_CRYPTO_AES_CTR_H_ */
+#endif /* BOOTUTIL_CRYPTO_AES_CTR_H */
diff --git a/boot/bootutil/include/bootutil/crypto/aes_kw.h b/boot/bootutil/include/bootutil/crypto/aes_kw.h
index 925f46a..cf3194f 100644
--- a/boot/bootutil/include/bootutil/crypto/aes_kw.h
+++ b/boot/bootutil/include/bootutil/crypto/aes_kw.h
@@ -23,6 +23,9 @@
#endif /* MCUBOOT_USE_MBED_TLS */
#if defined(MCUBOOT_USE_TINYCRYPT)
+ #if defined(MCUBOOT_AES_256)
+ #error "Cannot use AES-256 for encryption with Tinycrypt library."
+ #endif
#include <tinycrypt/aes.h>
#include <tinycrypt/constants.h>
#endif /* MCUBOOT_USE_TINYCRYPT */
diff --git a/boot/bootutil/include/bootutil/crypto/common.h b/boot/bootutil/include/bootutil/crypto/common.h
new file mode 100644
index 0000000..e02c4de
--- /dev/null
+++ b/boot/bootutil/include/bootutil/crypto/common.h
@@ -0,0 +1,19 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Copyright (c) 2021 Arm Limited
+ */
+
+#ifndef __BOOTUTIL_CRYPTO_COMMON_H__
+#define __BOOTUTIL_CRYPTO_COMMON_H__
+
+/* TODO May need to update this in a future 3.x version of Mbed TLS.
+ * Extract a member of the mbedtls context structure.
+ */
+#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+#define MBEDTLS_CONTEXT_MEMBER(X) MBEDTLS_PRIVATE(X)
+#else
+#define MBEDTLS_CONTEXT_MEMBER(X) X
+#endif
+
+#endif /* __BOOTUTIL_CRYPTO_COMMON_H__ */
\ No newline at end of file
diff --git a/boot/bootutil/include/bootutil/crypto/ecdh_p256.h b/boot/bootutil/include/bootutil/crypto/ecdh_p256.h
index a37d50a..962535c 100644
--- a/boot/bootutil/include/bootutil/crypto/ecdh_p256.h
+++ b/boot/bootutil/include/bootutil/crypto/ecdh_p256.h
@@ -68,6 +68,12 @@
#endif /* MCUBOOT_USE_TINYCRYPT */
#if defined(MCUBOOT_USE_MBED_TLS)
+#define NUM_ECC_BYTES 32
+
+#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+static int fake_rng(void *p_rng, unsigned char *output, size_t len);
+#endif
+
typedef struct bootutil_ecdh_p256_context {
mbedtls_ecp_group grp;
mbedtls_ecp_point P;
@@ -120,13 +126,21 @@
mbedtls_mpi_read_binary(&ctx->d, sk, NUM_ECC_BYTES);
+#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+ rc = mbedtls_ecdh_compute_shared(&ctx->grp,
+ &ctx->z,
+ &ctx->P,
+ &ctx->d,
+ fake_rng,
+ NULL);
+#else
rc = mbedtls_ecdh_compute_shared(&ctx->grp,
&ctx->z,
&ctx->P,
&ctx->d,
NULL,
NULL);
-
+#endif
mbedtls_mpi_write_binary(&ctx->z, z, NUM_ECC_BYTES);
return rc;
diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa_p256.h b/boot/bootutil/include/bootutil/crypto/ecdsa_p256.h
index fa26ffd..6b5b315 100644
--- a/boot/bootutil/include/bootutil/crypto/ecdsa_p256.h
+++ b/boot/bootutil/include/bootutil/crypto/ecdsa_p256.h
@@ -31,6 +31,7 @@
#if defined(MCUBOOT_USE_MBED_TLS)
#include <mbedtls/ecdsa.h>
+ #include "bootutil/crypto/common.h"
#define BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE (4 * 8)
#endif
@@ -132,17 +133,17 @@
(void)sig;
(void)hash;
- rc = mbedtls_ecp_group_load(&ctx->grp, MBEDTLS_ECP_DP_SECP256R1);
+ rc = mbedtls_ecp_group_load(&ctx->MBEDTLS_CONTEXT_MEMBER(grp), MBEDTLS_ECP_DP_SECP256R1);
if (rc) {
return -1;
}
- rc = mbedtls_ecp_point_read_binary(&ctx->grp, &ctx->Q, pk, pk_len);
+ rc = mbedtls_ecp_point_read_binary(&ctx->MBEDTLS_CONTEXT_MEMBER(grp), &ctx->MBEDTLS_CONTEXT_MEMBER(Q), pk, pk_len);
if (rc) {
return -1;
}
- rc = mbedtls_ecp_check_pubkey(&ctx->grp, &ctx->Q);
+ rc = mbedtls_ecp_check_pubkey(&ctx->MBEDTLS_CONTEXT_MEMBER(grp), &ctx->MBEDTLS_CONTEXT_MEMBER(Q));
if (rc) {
return -1;
}
diff --git a/boot/bootutil/include/bootutil/crypto/hmac_sha256.h b/boot/bootutil/include/bootutil/crypto/hmac_sha256.h
index 49d372a..e684018 100644
--- a/boot/bootutil/include/bootutil/crypto/hmac_sha256.h
+++ b/boot/bootutil/include/bootutil/crypto/hmac_sha256.h
@@ -22,7 +22,6 @@
#include <stddef.h>
#include <mbedtls/cmac.h>
#include <mbedtls/md.h>
- #include <mbedtls/md_internal.h>
#endif /* MCUBOOT_USE_MBED_TLS */
#if defined(MCUBOOT_USE_TINYCRYPT)
diff --git a/boot/bootutil/include/bootutil/crypto/sha256.h b/boot/bootutil/include/bootutil/crypto/sha256.h
index 00c3218..b45cd63 100644
--- a/boot/bootutil/include/bootutil/crypto/sha256.h
+++ b/boot/bootutil/include/bootutil/crypto/sha256.h
@@ -3,6 +3,7 @@
*
* Copyright (c) 2017-2019 Linaro LTD
* Copyright (c) 2017-2019 JUUL Labs
+ * Copyright (c) 2021 Arm Limited
*/
/*
@@ -27,6 +28,10 @@
#if defined(MCUBOOT_USE_MBED_TLS)
#include <mbedtls/sha256.h>
+ #include <mbedtls/version.h>
+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000
+ #include <mbedtls/compat-2.x.h>
+ #endif
#define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64)
#define BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE (32)
#endif /* MCUBOOT_USE_MBED_TLS */
diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h
index 1de6f81..449d9ec 100644
--- a/boot/bootutil/include/bootutil/enc_key.h
+++ b/boot/bootutil/include/bootutil/enc_key.h
@@ -45,7 +45,7 @@
struct enc_key_data {
uint8_t valid;
- uint8_t aes_iv[BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE];
+ uint8_t aes_iv[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
bootutil_aes_ctr_context aes_ctr;
};
@@ -62,7 +62,7 @@
int boot_enc_decrypt(const uint8_t *buf, uint8_t *enckey, uint32_t sz, uint8_t *enciv);
bool boot_enc_valid(struct enc_key_data *enc_state, int image_index,
const struct flash_area *fap);
-void boot_encrypt(struct enc_key_data *enc_state, int image_index,
+int boot_encrypt(struct enc_key_data *enc_state, int image_index,
const struct flash_area *fap, uint32_t off, uint32_t sz,
uint32_t blk_off, uint8_t *buf);
void boot_enc_zeroize(struct enc_key_data *enc_state);
diff --git a/boot/bootutil/include/bootutil/enc_key_public.h b/boot/bootutil/include/bootutil/enc_key_public.h
index 634f842..9ca16ac 100644
--- a/boot/bootutil/include/bootutil/enc_key_public.h
+++ b/boot/bootutil/include/bootutil/enc_key_public.h
@@ -2,7 +2,7 @@
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2018-2019 JUUL Labs
- * Copyright (c) 2019 Arm Limited
+ * Copyright (c) 2019-2021 Arm Limited
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* Original license:
@@ -32,12 +32,16 @@
extern "C" {
#endif
-#define BOOT_ENC_KEY_SIZE 16
+#ifdef MCUBOOT_AES_256
+#define BOOT_ENC_KEY_SIZE 32U
+#else
+#define BOOT_ENC_KEY_SIZE 16U
+#endif
-#define TLV_ENC_RSA_SZ 256
-#define TLV_ENC_KW_SZ 24
-#define TLV_ENC_EC256_SZ (65 + 32 + 16)
-#define TLV_ENC_X25519_SZ (32 + 32 + 16)
+#define TLV_ENC_RSA_SZ 256U
+#define TLV_ENC_KW_SZ BOOT_ENC_KEY_SIZE + 8U
+#define TLV_ENC_EC256_SZ (65U + 32U + BOOT_ENC_KEY_SIZE)
+#define TLV_ENC_X25519_SZ (32U + 32U + BOOT_ENC_KEY_SIZE)
#if defined(MCUBOOT_ENCRYPT_RSA)
#define BOOT_ENC_TLV_SIZE TLV_ENC_RSA_SZ
@@ -53,4 +57,4 @@
}
#endif
-#endif /* BOOTUTIL_ENC_KEY_PUBLIC_H */
\ No newline at end of file
+#endif /* BOOTUTIL_ENC_KEY_PUBLIC_H */
diff --git a/boot/bootutil/include/bootutil/fault_injection_hardening.h b/boot/bootutil/include/bootutil/fault_injection_hardening.h
index 05ec6c2..a9c58ec 100644
--- a/boot/bootutil/include/bootutil/fault_injection_hardening.h
+++ b/boot/bootutil/include/bootutil/fault_injection_hardening.h
@@ -4,8 +4,8 @@
* Copyright (c) 2020 Arm Limited
*/
-#ifndef __FAULT_INJECTION_HARDENING_H__
-#define __FAULT_INJECTION_HARDENING_H__
+#ifndef FAULT_INJECTION_HARDENING_H
+#define FAULT_INJECTION_HARDENING_H
/* Fault injection mitigation library.
*
@@ -54,6 +54,7 @@
* fail causing a panic.
*/
+#include <stdbool.h>
#include "mcuboot_config/mcuboot_config.h"
#if defined(MCUBOOT_FIH_PROFILE_HIGH)
@@ -103,7 +104,7 @@
* another xor. The mask value doesn't _really_ matter that much, as long as
* it has reasonably high hamming weight.
*/
-#define _FIH_MASK_VALUE 0xBEEF
+#define FIH_MASK_VALUE 0xBEEF
#ifdef FIH_ENABLE_DOUBLE_VARS
@@ -111,14 +112,21 @@
* XORed with the mask.
*/
extern volatile int _fih_mask;
+
typedef volatile struct {
volatile int val;
volatile int msk;
} fih_int;
+typedef volatile struct {
+ volatile unsigned int val;
+ volatile unsigned int msk;
+} fih_uint;
+
#else
typedef int fih_int;
+typedef unsigned int fih_uint;
#endif /* FIH_ENABLE_DOUBLE_VARS */
@@ -133,7 +141,7 @@
void fih_panic_loop(void);
#define FIH_PANIC fih_panic_loop()
#else
-#define FIH_PANIC while (1) {}
+#define FIH_PANIC while (true) {}
#endif /* FIH_ENABLE_GLOBAL_FAIL */
/* NOTE: For functions to be inlined outside their compilation unit they have to
@@ -143,7 +151,7 @@
#ifdef FIH_ENABLE_DELAY
/* Delaying logic, with randomness from a CSPRNG */
-__attribute__((always_inline)) inline
+__attribute__((always_inline)) static inline
int fih_delay(void)
{
unsigned char delay;
@@ -166,13 +174,13 @@
#else
-__attribute__((always_inline)) inline
+__attribute__((always_inline)) static inline
int fih_delay_init(void)
{
return 1;
}
-__attribute__((always_inline)) inline
+__attribute__((always_inline)) static inline
int fih_delay(void)
{
return 1;
@@ -181,7 +189,8 @@
#ifdef FIH_ENABLE_DOUBLE_VARS
-__attribute__((always_inline)) inline
+/* Validate fih_int for tampering. */
+__attribute__((always_inline)) static inline
void fih_int_validate(fih_int x)
{
if (x.val != (x.msk ^ _fih_mask)) {
@@ -190,7 +199,7 @@
}
/* Convert a fih_int to an int. Validate for tampering. */
-__attribute__((always_inline)) inline
+__attribute__((always_inline)) static inline
int fih_int_decode(fih_int x)
{
fih_int_validate(x);
@@ -198,15 +207,15 @@
}
/* Convert an int to a fih_int, can be used to encode specific error codes. */
-__attribute__((always_inline)) inline
+__attribute__((always_inline)) static inline
fih_int fih_int_encode(int x)
{
fih_int ret = {x, x ^ _fih_mask};
return ret;
}
-/* Standard equality. If A == B then 1, else 0 */
-__attribute__((always_inline)) inline
+/* Standard equality for fih_int type. If A == B then 1, else 0 */
+__attribute__((always_inline)) static inline
int fih_eq(fih_int x, fih_int y)
{
fih_int_validate(x);
@@ -214,7 +223,8 @@
return (x.val == y.val) && fih_delay() && (x.msk == y.msk);
}
-__attribute__((always_inline)) inline
+/* Standard non equality for fih_int type. If A != B then 1, else 0 */
+__attribute__((always_inline)) static inline
int fih_not_eq(fih_int x, fih_int y)
{
fih_int_validate(x);
@@ -222,10 +232,53 @@
return (x.val != y.val) && fih_delay() && (x.msk != y.msk);
}
+/* Validate fih_uint for tampering. */
+__attribute__((always_inline)) static inline
+void fih_uint_validate(fih_uint x)
+{
+ if (x.val != (x.msk ^ _fih_mask)) {
+ FIH_PANIC;
+ }
+}
+
+/* Convert a fih_uint to an unsigned int. Validate for tampering. */
+__attribute__((always_inline)) static inline
+unsigned int fih_uint_decode(fih_uint x)
+{
+ fih_uint_validate(x);
+ return x.val;
+}
+
+/* Convert an unsigned int to a fih_uint, can be used to encode specific error codes. */
+__attribute__((always_inline)) static inline
+fih_uint fih_uint_encode(unsigned int x)
+{
+ fih_uint ret = {x, x ^ _fih_mask};
+ return ret;
+}
+
+/* Standard equality for fih_uint type. If A == B then 1, else 0 */
+__attribute__((always_inline)) static inline
+bool fih_uint_eq(fih_uint x, fih_uint y)
+{
+ fih_uint_validate(x);
+ fih_uint_validate(y);
+ return (x.val == y.val) && fih_delay() && (x.msk == y.msk);
+}
+
+/* Standard non equality for fih_uint type. If A != B then 1, else 0 */
+__attribute__((always_inline)) static inline
+bool fih_uint_not_eq(fih_uint x, fih_uint y)
+{
+ fih_uint_validate(x);
+ fih_uint_validate(y);
+ return (x.val != y.val) && fih_delay() && (x.msk != y.msk);
+}
+
#else
/* NOOP */
-__attribute__((always_inline)) inline
+__attribute__((always_inline)) static inline
void fih_int_validate(fih_int x)
{
(void) x;
@@ -233,27 +286,61 @@
}
/* NOOP */
-__attribute__((always_inline)) inline
+__attribute__((always_inline)) static inline
int fih_int_decode(fih_int x)
{
return x;
}
/* NOOP */
-__attribute__((always_inline)) inline
+__attribute__((always_inline)) static inline
fih_int fih_int_encode(int x)
{
return x;
}
-__attribute__((always_inline)) inline
+__attribute__((always_inline)) static inline
int fih_eq(fih_int x, fih_int y)
{
+ return (int) (x == y);
+}
+
+__attribute__((always_inline)) static inline
+int fih_not_eq(fih_int x, fih_int y)
+{
+ return (int) (x != y);
+}
+
+/* NOOP */
+__attribute__((always_inline)) static inline
+void fih_uint_validate(fih_uint x)
+{
+ (void) x;
+ return;
+}
+
+/* NOOP */
+__attribute__((always_inline)) static inline
+unsigned int fih_uint_decode(fih_uint x)
+{
+ return x;
+}
+
+/* NOOP */
+__attribute__((always_inline)) static inline
+fih_uint fih_uint_encode(unsigned int x)
+{
+ return x;
+}
+
+__attribute__((always_inline)) static inline
+bool fih_uint_eq(fih_uint x, fih_uint y)
+{
return x == y;
}
-__attribute__((always_inline)) inline
-int fih_not_eq(fih_int x, fih_int y)
+__attribute__((always_inline)) static inline
+bool fih_uint_not_eq(fih_uint x, fih_uint y)
{
return x != y;
}
@@ -263,10 +350,10 @@
* errors. This function converts 0 to FIH_SUCCESS and any other number to a
* value that is not FIH_SUCCESS
*/
-__attribute__((always_inline)) inline
+__attribute__((always_inline)) static inline
fih_int fih_int_encode_zero_equality(int x)
{
- if (x) {
+ if (x != 0) {
return FIH_FAILURE;
} else {
return FIH_SUCCESS;
@@ -313,12 +400,12 @@
FIH_LABEL("FIH_CALL_START", l, c); \
FIH_CFI_PRECALL_BLOCK; \
ret = FIH_FAILURE; \
- if (fih_delay()) { \
+ if (fih_delay() != 0) { \
ret = f(__VA_ARGS__); \
} \
FIH_CFI_POSTCALL_BLOCK; \
FIH_LABEL("FIH_CALL_END", l, c); \
- } while (0)
+ } while (false)
#else
@@ -326,13 +413,13 @@
do { \
FIH_LABEL("FIH_CALL_START"); \
FIH_CFI_PRECALL_BLOCK; \
- ret = FIH_FAILURE; \
- if (fih_delay()) { \
- ret = f(__VA_ARGS__); \
+ (ret) = FIH_FAILURE; \
+ if (fih_delay() != 0) { \
+ (ret) = (f)(__VA_ARGS__); \
} \
FIH_CFI_POSTCALL_BLOCK; \
FIH_LABEL("FIH_CALL_END"); \
- } while (0)
+ } while (false)
#endif
/* FIH return changes the state of the internal state machine. If you do a
@@ -343,7 +430,7 @@
do { \
FIH_CFI_PRERET; \
return ret; \
- } while (0)
+ } while (false)
#ifdef FIH_ENABLE_CFI
@@ -374,4 +461,4 @@
}
#endif /* __cplusplus */
-#endif /* __FAULT_INJECTION_HARDENING_H__ */
+#endif /* FAULT_INJECTION_HARDENING_H */
diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h
index 38304f0..103e6b7 100644
--- a/boot/bootutil/include/bootutil/image.h
+++ b/boot/bootutil/include/bootutil/image.h
@@ -3,7 +3,7 @@
*
* Copyright (c) 2016-2019 Linaro LTD
* Copyright (c) 2016-2019 JUUL Labs
- * Copyright (c) 2019-2020 Arm Limited
+ * Copyright (c) 2019-2021 Arm Limited
*
* Original license:
*
@@ -38,9 +38,9 @@
struct flash_area;
-#define IMAGE_MAGIC 0x96f3b83d
-#define IMAGE_MAGIC_V1 0x96f3b83c
-#define IMAGE_MAGIC_NONE 0xffffffff
+#define IMAGE_MAGIC 0x96f3b83dU
+#define IMAGE_MAGIC_V1 0x96f3b83cU
+#define IMAGE_MAGIC_NONE 0xffffffffU
#define IMAGE_TLV_INFO_MAGIC 0x6907
#define IMAGE_TLV_PROT_INFO_MAGIC 0x6908
@@ -49,21 +49,22 @@
/*
* Image header flags.
*/
-#define IMAGE_F_PIC 0x00000001 /* Not supported. */
-#define IMAGE_F_ENCRYPTED 0x00000004 /* Encrypted. */
-#define IMAGE_F_NON_BOOTABLE 0x00000010 /* Split image app. */
+#define IMAGE_F_PIC 0x00000001U /* Not supported. */
+#define IMAGE_F_ENCRYPTED_AES128 0x00000004U /* Encrypted using AES128. */
+#define IMAGE_F_ENCRYPTED_AES256 0x00000008U /* Encrypted using AES256. */
+#define IMAGE_F_NON_BOOTABLE 0x00000010U /* Split image app. */
/*
* Indicates that this image should be loaded into RAM instead of run
* directly from flash. The address to load should be in the
* ih_load_addr field of the header.
*/
-#define IMAGE_F_RAM_LOAD 0x00000020
+#define IMAGE_F_RAM_LOAD 0x00000020U
/*
* Indicates that ih_load_addr stores information on flash/ROM address the
* image has been built for.
*/
-#define IMAGE_F_ROM_FIXED 0x00000100
+#define IMAGE_F_ROM_FIXED 0x00000100U
/*
* ECSDA224 is with NIST P-224
@@ -89,11 +90,12 @@
#define IMAGE_TLV_RSA3072_PSS 0x23 /* RSA3072 of hash output */
#define IMAGE_TLV_ED25519 0x24 /* ed25519 of hash output */
#define IMAGE_TLV_ENC_RSA2048 0x30 /* Key encrypted with RSA-OAEP-2048 */
-#define IMAGE_TLV_ENC_KW128 0x31 /* Key encrypted with AES-KW-128 */
+#define IMAGE_TLV_ENC_KW 0x31 /* Key encrypted with AES-KW 128 or 256*/
#define IMAGE_TLV_ENC_EC256 0x32 /* Key encrypted with ECIES-EC256 */
#define IMAGE_TLV_ENC_X25519 0x33 /* Key encrypted with ECIES-X25519 */
#define IMAGE_TLV_DEPENDENCY 0x40 /* Image depends on other image */
#define IMAGE_TLV_SEC_CNT 0x50 /* security counter */
+#define IMAGE_TLV_PROV_PACK 0x51 /* Reprovisioning packet */
#define IMAGE_TLV_BOOT_RECORD 0x60 /* measured boot record */
/*
* vendor reserved TLVs at xxA0-xxFF,
@@ -107,6 +109,11 @@
*/
#define IMAGE_TLV_ANY 0xffff /* Used to iterate over all TLV */
+#ifdef CYW20829
+#define REPROV_PACK_SIZE 796
+#define HW_ROLLBACK_CNT_VALID 0x00002134
+#define REPROV_PACK_VALID 0x57AC0000
+#endif /* CYW20829 */
struct image_version {
uint8_t iv_major;
uint8_t iv_minor;
@@ -148,9 +155,14 @@
uint16_t it_len; /* Data length (not including TLV header). */
};
-#define IS_ENCRYPTED(hdr) ((hdr)->ih_flags & IMAGE_F_ENCRYPTED)
+#define IS_ENCRYPTED(hdr) (IMAGE_F_ENCRYPTED_AES128 == ((hdr)->ih_flags & IMAGE_F_ENCRYPTED_AES128) \
+ || IMAGE_F_ENCRYPTED_AES256 == ((hdr)->ih_flags & IMAGE_F_ENCRYPTED_AES256))
+#ifdef MCUBOOT_ENC_IMAGES_XIP
+#define MUST_DECRYPT(fap, idx, hdr) (IS_ENCRYPTED(hdr))
+#else
#define MUST_DECRYPT(fap, idx, hdr) \
- ((fap)->fa_id == FLASH_AREA_IMAGE_SECONDARY(idx) && IS_ENCRYPTED(hdr))
+ (flash_area_get_id(fap) == FLASH_AREA_IMAGE_SECONDARY(idx) && IS_ENCRYPTED(hdr))
+#endif
_Static_assert(sizeof(struct image_header) == IMAGE_HEADER_SIZE,
"struct image_header not required size");
@@ -182,7 +194,11 @@
int32_t bootutil_get_img_security_cnt(struct image_header *hdr,
const struct flash_area *fap,
uint32_t *security_cnt);
-
+#ifdef CYW20829
+int32_t bootutil_get_img_reprov_packet(struct image_header *hdr,
+ const struct flash_area *fap,
+ uint8_t *reprov_packet);
+#endif /* CYW20829 */
#ifdef __cplusplus
}
#endif
diff --git a/boot/bootutil/include/bootutil/ramload.h b/boot/bootutil/include/bootutil/ramload.h
new file mode 100644
index 0000000..03513b0
--- /dev/null
+++ b/boot/bootutil/include/bootutil/ramload.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __RAMLOAD_H__
+#define __RAMLOAD_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef MULTIPLE_EXECUTABLE_RAM_REGIONS
+/**
+ * Provides information about the Executable RAM for a given image ID.
+ *
+ * @param image_id Index of the image (from 0).
+ * @param exec_ram_start Pointer to store the start address of the exec RAM
+ * @param exec_ram_size Pointer to store the size of the exec RAM
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+int boot_get_image_exec_ram_info(uint32_t image_id,
+ uint32_t *exec_ram_start,
+ uint32_t *exec_ram_size);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RAMLOAD_H__ */
\ No newline at end of file
diff --git a/boot/bootutil/include/bootutil/security_cnt.h b/boot/bootutil/include/bootutil/security_cnt.h
index b0f9f11..9c12ed3 100644
--- a/boot/bootutil/include/bootutil/security_cnt.h
+++ b/boot/bootutil/include/bootutil/security_cnt.h
@@ -1,11 +1,12 @@
/*
* Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2021 Infineon Technologies AG
*
* SPDX-License-Identifier: Apache-2.0
*/
-#ifndef __SECURITY_CNT_H__
-#define __SECURITY_CNT_H__
+#ifndef SECURITY_CNT_H
+#define SECURITY_CNT_H
/**
* @file security_cnt.h
@@ -47,7 +48,7 @@
*
* @return FIH_SUCCESS on success
*/
-fih_int boot_nv_security_counter_get(uint32_t image_id, fih_int *security_cnt);
+fih_int boot_nv_security_counter_get(uint32_t image_id, fih_uint *security_cnt);
/**
* Updates the stored value of a given image's security counter with a new
@@ -57,14 +58,17 @@
* @param img_security_cnt New security counter value. The new value must be
* between 0 and UINT32_MAX and it must be greater than
* or equal to the current security counter value.
+ * @param custom_data Pointer a custom data, which may be required by various
+ * platforms
*
* @return 0 on success; nonzero on failure.
*/
int32_t boot_nv_security_counter_update(uint32_t image_id,
- uint32_t img_security_cnt);
+ uint32_t img_security_cnt,
+ void * custom_data);
#ifdef __cplusplus
}
#endif
-#endif /* __SECURITY_CNT_H__ */
+#endif /* SECURITY_CNT_H */
diff --git a/boot/bootutil/include/bootutil/sign_key.h b/boot/bootutil/include/bootutil/sign_key.h
index 584a90a..f3d85c9 100644
--- a/boot/bootutil/include/bootutil/sign_key.h
+++ b/boot/bootutil/include/bootutil/sign_key.h
@@ -19,12 +19,15 @@
* under the License.
*/
-#ifndef __BOOTUTIL_SIGN_KEY_H_
-#define __BOOTUTIL_SIGN_KEY_H_
+#ifndef BOOTUTIL_SIGN_KEY_H
+#define BOOTUTIL_SIGN_KEY_H
#include <stddef.h>
#include <stdint.h>
+/* mcuboot_config.h is needed for MCUBOOT_HW_KEY to work */
+#include "mcuboot_config/mcuboot_config.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -65,4 +68,4 @@
}
#endif
-#endif /* __BOOTUTIL_SIGN_KEY_H_ */
+#endif /* BOOTUTIL_SIGN_KEY_H */
diff --git a/boot/bootutil/src/boot_record.c b/boot/bootutil/src/boot_record.c
index 3fb1fcc..e3a2208 100644
--- a/boot/bootutil/src/boot_record.c
+++ b/boot/bootutil/src/boot_record.c
@@ -35,6 +35,7 @@
#define SHARED_MEMORY_OVERFLOW (1)
#define SHARED_MEMORY_OVERWRITE (2)
#define SHARED_MEMORY_GEN_ERROR (3)
+#define SHARED_MEMORY_CORRUPTED (4)
/**
* @var shared_memory_init_done
@@ -52,6 +53,7 @@
const uint8_t *data)
{
struct shared_data_tlv_entry tlv_entry = {0};
+ uint16_t type = SET_TLV_TYPE(major_type, minor_type);
struct shared_boot_data *boot_data;
uint16_t boot_data_size;
uintptr_t tlv_end, offset;
@@ -60,6 +62,7 @@
return SHARED_MEMORY_GEN_ERROR;
}
+ assert(((uintptr_t)MCUBOOT_SHARED_DATA_BASE & 3u) == 0u);
boot_data = (struct shared_boot_data *)MCUBOOT_SHARED_DATA_BASE;
/* Check whether first time to call this function. If does then initialise
@@ -71,6 +74,10 @@
boot_data->header.tlv_tot_len = SHARED_DATA_HEADER_SIZE;
shared_memory_init_done = true;
}
+ else if (boot_data->header.tlv_magic != SHARED_DATA_TLV_INFO_MAGIC ||
+ boot_data->header.tlv_tot_len != SHARED_DATA_HEADER_SIZE) {
+ return SHARED_MEMORY_CORRUPTED;
+ }
/* Check whether TLV entry is already added.
* Get the boundaries of TLV section
@@ -84,8 +91,7 @@
while (offset < tlv_end) {
/* Create local copy to avoid unaligned access */
memcpy(&tlv_entry, (const void *)offset, SHARED_DATA_ENTRY_HEADER_SIZE);
- if (GET_MAJOR(tlv_entry.tlv_type) == major_type &&
- GET_MINOR(tlv_entry.tlv_type) == minor_type) {
+ if (tlv_entry.tlv_type == type) {
return SHARED_MEMORY_OVERWRITE;
}
@@ -93,7 +99,7 @@
}
/* Add TLV entry */
- tlv_entry.tlv_type = SET_TLV_TYPE(major_type, minor_type);
+ tlv_entry.tlv_type = type;
tlv_entry.tlv_len = size;
if (!boot_u16_safe_add(&boot_data_size, boot_data->header.tlv_tot_len,
@@ -107,12 +113,12 @@
}
offset = tlv_end;
- memcpy((void *)offset, &tlv_entry, SHARED_DATA_ENTRY_HEADER_SIZE);
+ (void)memcpy((void *)offset, &tlv_entry, SHARED_DATA_ENTRY_HEADER_SIZE);
offset += SHARED_DATA_ENTRY_HEADER_SIZE;
- memcpy((void *)offset, data, size);
+ (void)memcpy((void *)offset, data, size);
- boot_data->header.tlv_tot_len += SHARED_DATA_ENTRY_SIZE(size);
+ boot_data->header.tlv_tot_len = boot_data_size;
return SHARED_MEMORY_OK;
}
@@ -132,12 +138,16 @@
uint16_t type;
uint16_t ias_minor;
size_t record_len = 0;
- uint8_t image_hash[32]; /* SHA256 - 32 Bytes */
+ uint8_t image_hash[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
uint8_t buf[MAX_BOOT_RECORD_SZ];
bool boot_record_found = false;
bool hash_found = false;
int rc;
+ if (NULL == hdr || NULL == fap) {
+ return -1;
+ }
+
/* Manifest data is concatenated to the end of the image.
* It is encoded in TLV format.
*/
@@ -172,7 +182,7 @@
} else if (type == IMAGE_TLV_SHA256) {
/* Get the image's hash value from the manifest section. */
- if (len > sizeof(image_hash)) {
+ if (len != BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE) {
return -1;
}
rc = flash_area_read(fap, offset, image_hash, len);
@@ -204,11 +214,15 @@
* part of the boot record TLV). For this reason this field has been
* filled with zeros during the image signing process.
*/
+ if (record_len < sizeof(image_hash)) {
+ return -1;
+ }
+
offset = record_len - sizeof(image_hash);
/* The size of 'buf' has already been checked when
* the BOOT_RECORD TLV was read, it won't overflow.
*/
- memcpy(buf + offset, image_hash, sizeof(image_hash));
+ (void)memcpy(buf + offset, image_hash, sizeof(image_hash));
/* Add the CBOR encoded boot record to the shared data area. */
ias_minor = SET_IAS_MINOR(sw_module, SW_BOOT_RECORD);
diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c
index 221d8a6..75e53d3 100644
--- a/boot/bootutil/src/bootutil_misc.c
+++ b/boot/bootutil/src/bootutil_misc.c
@@ -129,12 +129,12 @@
boot_status_entries(int image_index, const struct flash_area *fap)
{
#if MCUBOOT_SWAP_USING_SCRATCH
- if (fap->fa_id == FLASH_AREA_IMAGE_SCRATCH) {
+ if (flash_area_get_id(fap) == FLASH_AREA_IMAGE_SCRATCH) {
return BOOT_STATUS_STATE_COUNT;
} else
#endif
- if (fap->fa_id == FLASH_AREA_IMAGE_PRIMARY(image_index) ||
- fap->fa_id == FLASH_AREA_IMAGE_SECONDARY(image_index)) {
+ if (flash_area_get_id(fap) == FLASH_AREA_IMAGE_PRIMARY(image_index) ||
+ flash_area_get_id(fap) == FLASH_AREA_IMAGE_SECONDARY(image_index)) {
return BOOT_STATUS_STATE_COUNT * BOOT_STATUS_MAX_ENTRIES;
}
return -1;
@@ -145,21 +145,22 @@
boot_status_off(const struct flash_area *fap)
{
uint32_t off_from_end;
- uint8_t elem_sz;
+ size_t elem_sz;
elem_sz = flash_area_align(fap);
+ assert(elem_sz != 0u);
off_from_end = boot_trailer_sz(elem_sz);
- assert(off_from_end <= fap->fa_size);
- return fap->fa_size - off_from_end;
+ assert(off_from_end <= flash_area_get_size(fap));
+ return flash_area_get_size(fap) - off_from_end;
}
#endif
static inline uint32_t
boot_magic_off(const struct flash_area *fap)
{
- return fap->fa_size - BOOT_MAGIC_SZ;
+ return flash_area_get_size(fap) - BOOT_MAGIC_SZ;
}
#ifndef MCUBOOT_SWAP_USING_STATUS
@@ -275,26 +276,20 @@
{
uint32_t off;
const struct flash_area *fap;
-#if MCUBOOT_SWAP_SAVE_ENCTLV
- int i;
-#endif
int rc;
rc = boot_find_status(image_index, &fap);
- if (rc == 0) {
+ if (0 == rc) {
off = boot_enc_key_off(fap, slot);
#if MCUBOOT_SWAP_SAVE_ENCTLV
- uint8_t aes_iv[BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE];
+ uint8_t aes_iv[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
rc = flash_area_read(fap, off, bs->enctlv[slot], BOOT_ENC_TLV_ALIGN_SIZE);
- if (rc == 0) {
- for (i = 0; i < BOOT_ENC_TLV_ALIGN_SIZE; i++) {
- if (bs->enctlv[slot][i] != 0xff) {
- break;
- }
- }
- /* Only try to decrypt non-erased TLV metadata */
- if (i != BOOT_ENC_TLV_ALIGN_SIZE) {
+ if (0 == rc) {
+ /* Only try to decrypt initialized TLV metadata */
+ if (!bootutil_buffer_is_filled(bs->enctlv[slot],
+ BOOT_UNINITIALIZED_TLV_FILL,
+ BOOT_ENC_TLV_ALIGN_SIZE)) {
rc = boot_enc_decrypt(bs->enctlv[slot], bs->enckey[slot], 0, aes_iv);
}
}
@@ -316,9 +311,9 @@
uint32_t off;
off = boot_copy_done_off(fap);
- BOOT_LOG_DBG("writing copy_done; fa_id=%d off=0x%lx (0x%lx)",
- fap->fa_id, (unsigned long)off,
- (unsigned long)(fap->fa_off + off));
+ BOOT_LOG_DBG("writing copy_done; fa_id=%u off=0x%" PRIx32
+ " (0x%" PRIx32 ")", (unsigned)flash_area_get_id(fap),
+ off, flash_area_get_off(fap) + off);
return boot_write_trailer_flag(fap, off, BOOT_FLAG_SET);
}
@@ -328,9 +323,9 @@
uint32_t off;
off = boot_swap_size_off(fap);
- BOOT_LOG_DBG("writing swap_size; fa_id=%d off=0x%lx (0x%lx)",
- fap->fa_id, (unsigned long)off,
- (unsigned long)fap->fa_off + off);
+ BOOT_LOG_DBG("writing swap_size; fa_id=%u off=0x%" PRIx32
+ " (0x%" PRIx32 ")", (unsigned)flash_area_get_id(fap),
+ off, flash_area_get_off(fap) + off);
return boot_write_trailer(fap, off, (const uint8_t *) &swap_size, 4);
}
@@ -345,9 +340,9 @@
int rc;
off = boot_enc_key_off(fap, slot);
- BOOT_LOG_DBG("writing enc_key; fa_id=%d off=0x%lx (0x%lx)",
- fap->fa_id, (unsigned long)off,
- (unsigned long)fap->fa_off + off);
+ BOOT_LOG_DBG("writing enc_key; fa_id=%u off=0x%" PRIx32
+ " (0x%" PRIx32 ")", (unsigned)flash_area_get_id(fap),
+ off, flash_area_get_off(fap) + off);
#if MCUBOOT_SWAP_SAVE_ENCTLV
rc = flash_area_write(fap, off, bs->enctlv[slot], BOOT_ENC_TLV_ALIGN_SIZE);
#else
diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h
index 37a9350..ac40a6e 100644
--- a/boot/bootutil/src/bootutil_priv.h
+++ b/boot/bootutil/src/bootutil_priv.h
@@ -3,7 +3,7 @@
*
* Copyright (c) 2017-2020 Linaro LTD
* Copyright (c) 2017-2019 JUUL Labs
- * Copyright (c) 2019-2020 Arm Limited
+ * Copyright (c) 2019-2021 Arm Limited
*
* Original license:
*
@@ -28,6 +28,7 @@
#ifndef H_BOOTUTIL_PRIV_
#define H_BOOTUTIL_PRIV_
+#include <inttypes.h>
#include <string.h>
#include "sysflash/sysflash.h"
@@ -82,15 +83,17 @@
uint8_t swap_type; /* The type of swap in effect */
uint32_t swap_size; /* Total size of swapped image */
#ifdef MCUBOOT_ENC_IMAGES
+#define BOOT_UNINITIALIZED_KEY_FILL 0xFF
uint8_t enckey[BOOT_NUM_SLOTS][BOOT_ENC_KEY_SIZE];
-#if MCUBOOT_SWAP_SAVE_ENCTLV
+#ifdef MCUBOOT_SWAP_SAVE_ENCTLV
+#define BOOT_UNINITIALIZED_TLV_FILL 0xFF
uint8_t enctlv[BOOT_NUM_SLOTS][BOOT_ENC_TLV_ALIGN_SIZE];
#endif
#endif
int source; /* Which slot contains swap status metadata */
};
-#define BOOT_STATUS_IDX_0 1
+#define BOOT_STATUS_IDX_0 1U
#define BOOT_STATUS_STATE_0 1
#define BOOT_STATUS_STATE_1 2
@@ -143,21 +146,19 @@
#else
#define ARE_SLOTS_EQUIVALENT() 1
-#if (BOOT_IMAGE_NUMBER != 1)
-#error "The MCUBOOT_DIRECT_XIP and MCUBOOT_RAM_LOAD mode only supports single-image boot (MCUBOOT_IMAGE_NUMBER=1)."
-#endif
-#ifdef MCUBOOT_ENC_IMAGES
-#error "Image encryption (MCUBOOT_ENC_IMAGES) is not supported when MCUBOOT_DIRECT_XIP or MCUBOOT_RAM_LOAD mode is selected."
-#endif
+#if defined(MCUBOOT_DIRECT_XIP) && defined(MCUBOOT_ENC_IMAGES)
+#error "Image encryption (MCUBOOT_ENC_IMAGES) is not supported when MCUBOOT_DIRECT_XIP is selected."
+#endif /* MCUBOOT_DIRECT_XIP && MCUBOOT_ENC_IMAGES */
#endif /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
#define BOOT_MAX_IMG_SECTORS MCUBOOT_MAX_IMG_SECTORS
#define BOOT_LOG_IMAGE_INFO(slot, hdr) \
- BOOT_LOG_INF("%-9s slot: version=%u.%u.%u+%u", \
+ BOOT_LOG_INF("%-9s slot: " \
+ "version=%u.%u.%" PRIu16 "+%" PRIu32, \
((slot) == BOOT_PRIMARY_SLOT) ? "Primary" : "Secondary", \
- (hdr)->ih_ver.iv_major, \
- (hdr)->ih_ver.iv_minor, \
+ (unsigned)(hdr)->ih_ver.iv_major, \
+ (unsigned)(hdr)->ih_ver.iv_minor, \
(hdr)->ih_ver.iv_revision, \
(hdr)->ih_ver.iv_build_num)
@@ -172,7 +173,7 @@
#error "Too few sectors, please increase BOOT_MAX_IMG_SECTORS to at least 32"
#endif
-#if MCUBOOT_SWAP_USING_MOVE
+#if defined(MCUBOOT_SWAP_USING_MOVE)
#define BOOT_STATUS_MOVE_STATE_COUNT 1
#define BOOT_STATUS_SWAP_STATE_COUNT 2
#define BOOT_STATUS_STATE_COUNT (BOOT_STATUS_MOVE_STATE_COUNT + BOOT_STATUS_SWAP_STATE_COUNT)
@@ -210,14 +211,14 @@
size_t num_sectors;
} imgs[BOOT_IMAGE_NUMBER][BOOT_NUM_SLOTS];
-#if MCUBOOT_SWAP_USING_SCRATCH
+#if defined(MCUBOOT_SWAP_USING_SCRATCH)
struct {
const struct flash_area *area;
boot_sector_t *sectors;
size_t num_sectors;
} scratch;
#endif
-#if MCUBOOT_SWAP_USING_STATUS
+#if defined(MCUBOOT_SWAP_USING_STATUS)
struct {
const struct flash_area *area;
boot_sector_t *sectors;
@@ -242,16 +243,11 @@
fih_int boot_fih_memequal(const void *s1, const void *s2, size_t n);
-int boot_magic_compatible_check(uint8_t tbl_val, uint8_t val);
+bool boot_magic_compatible_check(uint8_t tbl_val, uint8_t val);
uint32_t boot_status_sz(uint32_t min_write_sz);
uint32_t boot_trailer_sz(uint32_t min_write_sz);
int boot_status_entries(int image_index, const struct flash_area *fap);
uint32_t boot_status_off(const struct flash_area *fap);
-uint32_t boot_swap_info_off(const struct flash_area *fap);
-int boot_read_swap_state(const struct flash_area *fap,
- struct boot_swap_state *state);
-int boot_read_swap_state_by_id(int flash_area_id,
- struct boot_swap_state *state);
int boot_write_magic(const struct flash_area *fap);
int boot_write_status(const struct boot_loader_state *state, struct boot_status *bs);
int boot_write_copy_done(const struct flash_area *fap);
@@ -265,7 +261,7 @@
uint8_t flag_val);
int boot_read_swap_size(int image_index, uint32_t *swap_size);
int boot_slots_compatible(struct boot_loader_state *state);
-uint32_t boot_status_internal_off(const struct boot_status *bs, int elem_sz);
+uint32_t boot_status_internal_off(const struct boot_status *bs, uint32_t elem_sz);
int boot_read_image_header(struct boot_loader_state *state, int slot,
struct image_header *out_hdr, struct boot_status *bs);
int boot_copy_region(struct boot_loader_state *state,
@@ -289,11 +285,19 @@
#endif
/**
+ * Checks that a buffer is filled by the specified value.
+ *
+ * @returns true if all bytes in the buffer are equal to `fill`; false if any
+ * of the bytes does not match, or when buffer is NULL, or when len == 0.
+ */
+bool bootutil_buffer_is_filled(const void *buffer, uint8_t fill, size_t len);
+
+/**
* Checks that a buffer is erased according to what the erase value for the
* flash device provided in `flash_area` is.
*
* @returns true if the buffer is erased; false if any of the bytes is not
- * erased, or when buffer is NULL, or when len == 0.
+ * erased, or when area is NULL, or when buffer is NULL, or when len == 0.
*/
bool bootutil_buffer_is_erased(const struct flash_area *area,
const void *buffer, size_t len);
@@ -324,11 +328,11 @@
*/
static inline bool boot_u16_safe_add(uint16_t *dest, uint16_t a, uint16_t b)
{
- uint32_t tmp = a + b;
+ uint32_t tmp = (uint32_t)a + b;
if (tmp > UINT16_MAX) {
return false;
} else {
- *dest = tmp;
+ *dest = (uint16_t) tmp;
return true;
}
}
@@ -336,18 +340,17 @@
/*
* Accessors for the contents of struct boot_loader_state.
*/
-
-/* These are macros so they can be used as lvalues. */
#if (BOOT_IMAGE_NUMBER > 1)
#define BOOT_CURR_IMG(state) ((state)->curr_img_idx)
#else
-#define BOOT_CURR_IMG(state) 0
+#define BOOT_CURR_IMG(state) 0u
#endif
#ifdef MCUBOOT_ENC_IMAGES
#define BOOT_CURR_ENC(state) ((state)->enc[BOOT_CURR_IMG(state)])
#else
#define BOOT_CURR_ENC(state) NULL
#endif
+/* These are macros so they can be used as lvalues. */
#define BOOT_IMG(state, slot) ((state)->imgs[BOOT_CURR_IMG(state)][(slot)])
#define BOOT_IMG_AREA(state, slot) (BOOT_IMG(state, slot).area)
#define BOOT_WRITE_SZ(state) ((state)->write_sz)
@@ -377,7 +380,7 @@
static inline uint32_t
boot_img_slot_off(struct boot_loader_state *state, size_t slot)
{
- return BOOT_IMG(state, slot).area->fa_off;
+ return flash_area_get_off(BOOT_IMG(state, slot).area);
}
#ifndef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
@@ -386,7 +389,7 @@
boot_img_sector_size(const struct boot_loader_state *state,
size_t slot, size_t sector)
{
- return BOOT_IMG(state, slot).sectors[sector].fa_size;
+ return flash_area_get_size(&BOOT_IMG(state, slot).sectors[sector]);
}
/*
@@ -397,8 +400,8 @@
boot_img_sector_off(const struct boot_loader_state *state, size_t slot,
size_t sector)
{
- return BOOT_IMG(state, slot).sectors[sector].fa_off -
- BOOT_IMG(state, slot).sectors[0].fa_off;
+ return flash_area_get_off(&BOOT_IMG(state, slot).sectors[sector]) -
+ flash_area_get_off(&BOOT_IMG(state, slot).sectors[0]);
}
#else /* defined(MCUBOOT_USE_FLASH_AREA_GET_SECTORS) */
@@ -407,24 +410,47 @@
boot_img_sector_size(const struct boot_loader_state *state,
size_t slot, size_t sector)
{
- return BOOT_IMG(state, slot).sectors[sector].fs_size;
+ return flash_sector_get_size(&BOOT_IMG(state, slot).sectors[sector]);
}
static inline uint32_t
boot_img_sector_off(const struct boot_loader_state *state, size_t slot,
size_t sector)
{
- return BOOT_IMG(state, slot).sectors[sector].fs_off -
- BOOT_IMG(state, slot).sectors[0].fs_off;
+ return flash_sector_get_off(&BOOT_IMG(state, slot).sectors[sector]) -
+ flash_sector_get_off(&BOOT_IMG(state, slot).sectors[0]);
}
#endif /* !defined(MCUBOOT_USE_FLASH_AREA_GET_SECTORS) */
#ifdef MCUBOOT_RAM_LOAD
+# ifdef __BOOTSIM__
+
+/* Query for the layout of a RAM buffer appropriate for holding the
+ * image. This will be per-test-thread, and therefore must be queried
+ * through this call. */
+struct bootsim_ram_info {
+ uint32_t start;
+ uint32_t size;
+ uintptr_t base;
+};
+struct bootsim_ram_info *bootsim_get_ram_info(void);
+
+#define IMAGE_GET_FIELD(field) (bootsim_get_ram_info()->field)
+#define IMAGE_RAM_BASE IMAGE_GET_FIELD(base)
+#define IMAGE_EXECUTABLE_RAM_START IMAGE_GET_FIELD(start)
+#define IMAGE_EXECUTABLE_RAM_SIZE IMAGE_GET_FIELD(size)
+
+# else
+# define IMAGE_RAM_BASE ((uintptr_t)0)
+# endif
+
#define LOAD_IMAGE_DATA(hdr, fap, start, output, size) \
- (memcpy((output),(void*)((hdr)->ih_load_addr + (start)), \
+ (memcpy((output),(void*)(IMAGE_RAM_BASE + (hdr)->ih_load_addr + (start)), \
(size)), 0)
#else
+#define IMAGE_RAM_BASE ((uintptr_t)0)
+
#define LOAD_IMAGE_DATA(hdr, fap, start, output, size) \
(flash_area_read((fap), (start), (output), (size)))
#endif /* MCUBOOT_RAM_LOAD */
diff --git a/boot/bootutil/src/bootutil_public.c b/boot/bootutil/src/bootutil_public.c
index 6057b41..f045fae 100644
--- a/boot/bootutil/src/bootutil_public.c
+++ b/boot/bootutil/src/bootutil_public.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2017-2019 Linaro LTD
* Copyright (c) 2016-2019 JUUL Labs
- * Copyright (c) 2019-2020 Arm Limited
+ * Copyright (c) 2019-2021 Arm Limited
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* Original license:
@@ -51,10 +51,12 @@
#include "bootutil/enc_key_public.h"
#endif
+#include "bootutil/boot_public_hooks.h"
+
#ifdef CONFIG_MCUBOOT
-MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
+BOOT_LOG_MODULE_DECLARE(mcuboot);
#else
-MCUBOOT_LOG_MODULE_REGISTER(mcuboot_util);
+BOOT_LOG_MODULE_REGISTER(mcuboot_util);
#endif
const uint32_t boot_img_magic[] = {
@@ -142,7 +144,7 @@
static inline uint32_t
boot_magic_off(const struct flash_area *fap)
{
- return fap->fa_size - BOOT_MAGIC_SZ;
+ return flash_area_get_size(fap) - BOOT_MAGIC_SZ;
}
static inline uint32_t
@@ -172,15 +174,14 @@
* @param val The magic value in a trailer, encoded as a
* BOOT_MAGIC_[...].
*
- * @return 1 if the two values are compatible;
- * 0 otherwise.
+ * @return true - if the two values are compatible;
+ * false - otherwise.
*/
-int
-boot_magic_compatible_check(uint8_t tbl_val, uint8_t val)
+bool boot_magic_compatible_check(uint8_t tbl_val, uint8_t val)
{
switch (tbl_val) {
case BOOT_MAGIC_ANY:
- return 1;
+ return true;
case BOOT_MAGIC_NOTGOOD:
return val != BOOT_MAGIC_GOOD;
@@ -190,20 +191,16 @@
}
}
-bool bootutil_buffer_is_erased(const struct flash_area *area,
- const void *buffer, size_t len)
+bool bootutil_buffer_is_filled(const void *buffer, uint8_t fill, size_t len)
{
- size_t i;
- uint8_t *u8b;
- uint8_t erased_val;
+ uint8_t *p;
if (buffer == NULL || len == 0) {
return false;
}
- erased_val = flash_area_erased_val(area);
- for (i = 0, u8b = (uint8_t *)buffer; i < len; i++) {
- if (u8b[i] != erased_val) {
+ for (p = (uint8_t *)buffer; len-- > 0; p++) {
+ if (*p != fill) {
return false;
}
}
@@ -211,16 +208,30 @@
return true;
}
+bool bootutil_buffer_is_erased(const struct flash_area *area,
+ const void *buffer, size_t len)
+{
+ uint8_t erased_val;
+
+ if (area == NULL) {
+ return false;
+ }
+
+ erased_val = flash_area_erased_val(area);
+
+ return bootutil_buffer_is_filled(buffer, erased_val, len);
+}
+
static int
boot_read_flag(const struct flash_area *fap, uint8_t *flag, uint32_t off)
{
int rc;
rc = flash_area_read(fap, off, flag, sizeof *flag);
- if (rc < 0) {
+ if (rc != 0) {
return BOOT_EFLASH;
}
- if (bootutil_buffer_is_erased(fap, flag, sizeof *flag)) {
+ if (*flag == flash_area_erased_val(fap)) {
*flag = BOOT_FLAG_UNSET;
} else {
*flag = boot_flag_decode(*flag);
@@ -248,7 +259,7 @@
off = boot_magic_off(fap);
rc = flash_area_read(fap, off, magic, BOOT_MAGIC_SZ);
- if (rc < 0) {
+ if (rc != 0) {
return BOOT_EFLASH;
}
if (bootutil_buffer_is_erased(fap, magic, BOOT_MAGIC_SZ)) {
@@ -259,7 +270,7 @@
off = boot_swap_info_off(fap);
rc = flash_area_read(fap, off, &swap_info, sizeof swap_info);
- if (rc < 0) {
+ if (rc != 0) {
return BOOT_EFLASH;
}
@@ -267,14 +278,14 @@
state->swap_type = BOOT_GET_SWAP_TYPE(swap_info);
state->image_num = BOOT_GET_IMAGE_NUM(swap_info);
- if (bootutil_buffer_is_erased(fap, &swap_info, sizeof swap_info) ||
+ if (swap_info == flash_area_erased_val(fap) ||
state->swap_type > BOOT_SWAP_TYPE_REVERT) {
state->swap_type = BOOT_SWAP_TYPE_NONE;
state->image_num = 0;
}
rc = boot_read_copy_done(fap, &state->copy_done);
- if (rc) {
+ if (rc != 0) {
return BOOT_EFLASH;
}
@@ -286,7 +297,7 @@
int
boot_read_swap_state_by_id(int flash_area_id, struct boot_swap_state *state)
{
- const struct flash_area *fap;
+ const struct flash_area *fap = NULL;
int rc;
rc = flash_area_open(flash_area_id, &fap);
@@ -309,9 +320,9 @@
off = boot_magic_off(fap);
- BOOT_LOG_DBG("writing magic; fa_id=%d off=0x%lx (0x%lx)",
- fap->fa_id, (unsigned long)off,
- (unsigned long)(fap->fa_off + off));
+ BOOT_LOG_DBG("writing magic; fa_id=%u off=0x%" PRIx32
+ " (0x%" PRIx32 ")", (unsigned)flash_area_get_id(fap),
+ off, flash_area_get_off(fap) + off);
rc = flash_area_write(fap, off, boot_img_magic, BOOT_MAGIC_SZ);
if (rc != 0) {
return BOOT_EFLASH;
@@ -330,11 +341,14 @@
const uint8_t *inbuf, uint8_t inlen)
{
uint8_t buf[BOOT_MAX_ALIGN];
- uint8_t align;
+ size_t align;
uint8_t erased_val;
int rc;
align = flash_area_align(fap);
+ if (align == 0u) {
+ return BOOT_EFLASH;
+ }
align = (inlen + align - 1) & ~(align - 1);
if (align > BOOT_MAX_ALIGN) {
return -1;
@@ -368,9 +382,9 @@
uint32_t off;
off = boot_image_ok_off(fap);
- BOOT_LOG_DBG("writing image_ok; fa_id=%d off=0x%lx (0x%lx)",
- fap->fa_id, (unsigned long)off,
- (unsigned long)(fap->fa_off + off));
+ BOOT_LOG_DBG("writing image_ok; fa_id=%u off=0x%" PRIx32
+ " (0x%" PRIx32 ")", (unsigned)flash_area_get_id(fap),
+ off, flash_area_get_off(fap) + off);
return boot_write_trailer_flag(fap, off, BOOT_FLAG_SET);
}
@@ -394,23 +408,23 @@
BOOT_SET_SWAP_INFO(swap_info, image_num, swap_type);
off = boot_swap_info_off(fap);
- BOOT_LOG_DBG("writing swap_info; fa_id=%d off=0x%lx (0x%lx), swap_type=0x%x"
- " image_num=0x%x",
- fap->fa_id, (unsigned long)off,
- (unsigned long)(fap->fa_off + off), swap_type, image_num);
+ BOOT_LOG_DBG("writing swap_info; fa_id=%u off=0x%" PRIx32
+ " (0x%" PRIx32 "), swap_type=0x%x image_num=0x%x",
+ (unsigned)flash_area_get_id(fap), off,
+ flash_area_get_off(fap) + off,
+ (unsigned)swap_type, (unsigned)image_num);
return boot_write_trailer(fap, off, (const uint8_t *) &swap_info, 1);
}
-#define BOOT_LOG_SWAP_STATE(area, state) \
- BOOT_LOG_INF("%s: magic=%s, swap_type=0x%x, copy_done=0x%x, " \
- "image_ok=0x%x", \
- (area), \
- ((state)->magic == BOOT_MAGIC_GOOD ? "good" : \
- (state)->magic == BOOT_MAGIC_UNSET ? "unset" : \
- "bad"), \
- (state)->swap_type, \
- (state)->copy_done, \
- (state)->image_ok)
+#define BOOT_LOG_SWAP_STATE(area, state) \
+ BOOT_LOG_INF("%s: magic=%s, swap_type=0x%x, copy_done=0x%x, image_ok=0x%x", \
+ (area), \
+ ((state)->magic == BOOT_MAGIC_GOOD ? "good" : \
+ (state)->magic == BOOT_MAGIC_UNSET ? "unset" : \
+ "bad"), \
+ (unsigned)(state)->swap_type, \
+ (unsigned)(state)->copy_done, \
+ (unsigned)(state)->image_ok)
int
boot_swap_type_multi(int image_index)
@@ -421,15 +435,28 @@
int rc;
size_t i;
- rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_PRIMARY(image_index),
- &primary_slot);
+ rc = BOOT_HOOK_CALL(boot_read_swap_state_primary_slot_hook,
+ BOOT_HOOK_REGULAR, image_index, &primary_slot);
+ if (rc == BOOT_HOOK_REGULAR)
+ {
+ rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_PRIMARY(image_index),
+ &primary_slot);
+ }
if (rc) {
return BOOT_SWAP_TYPE_PANIC;
}
rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_SECONDARY(image_index),
&secondary_slot);
- if (rc) {
+ if (rc == BOOT_EFLASH) {
+ BOOT_LOG_INF("Secondary image of image pair (%d.) "
+ "is unreachable. Treat it as empty", image_index);
+ secondary_slot.magic = BOOT_MAGIC_UNSET;
+ secondary_slot.swap_type = BOOT_SWAP_TYPE_NONE;
+ secondary_slot.copy_done = BOOT_FLAG_UNSET;
+ secondary_slot.image_ok = BOOT_FLAG_UNSET;
+ secondary_slot.image_num = 0;
+ } else if (rc) {
return BOOT_SWAP_TYPE_PANIC;
}
@@ -478,42 +505,44 @@
}
/**
- * Marks the image in the secondary slot as pending. On the next reboot,
- * the system will perform a one-time boot of the the secondary slot image.
+ * Marks the image with the given index in the secondary slot as pending. On the
+ * next reboot, the system will perform a one-time boot of the the secondary
+ * slot image.
+ *
+ * @param image_index Image pair index.
*
* @param permanent Whether the image should be used permanently or
- * only tested once:
- * 0=run image once, then confirm or revert.
- * 1=run image forever.
+ * only tested once:
+ * 0=run image once, then confirm or revert.
+ * 1=run image forever.
*
* @return 0 on success; nonzero on failure.
*/
int
-boot_set_pending(int permanent)
+boot_set_pending_multi(int image_index, int permanent)
{
- const struct flash_area *fap;
- struct boot_swap_state state_secondary_slot;
+ const struct flash_area *fap = NULL;
+ struct boot_swap_state state_secondary_slot = {0};
uint8_t swap_type;
int rc;
- rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_SECONDARY(0),
- &state_secondary_slot);
+ rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image_index), &fap);
if (rc != 0) {
- return rc;
+ return BOOT_EFLASH;
+ }
+
+ rc = boot_read_swap_state(fap, &state_secondary_slot);
+ if (rc != 0) {
+ goto done;
}
switch (state_secondary_slot.magic) {
case BOOT_MAGIC_GOOD:
/* Swap already scheduled. */
- return 0;
+ break;
case BOOT_MAGIC_UNSET:
- rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(0), &fap);
- if (rc != 0) {
- rc = BOOT_EFLASH;
- } else {
- rc = boot_write_magic(fap);
- }
+ rc = boot_write_magic(fap);
if (rc == 0 && permanent) {
rc = boot_write_image_ok(fap);
@@ -528,46 +557,69 @@
rc = boot_write_swap_info(fap, swap_type, 0);
}
- flash_area_close(fap);
- return rc;
+ break;
case BOOT_MAGIC_BAD:
/* The image slot is corrupt. There is no way to recover, so erase the
* slot to allow future upgrades.
*/
- rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(0), &fap);
- if (rc != 0) {
- return BOOT_EFLASH;
- }
-
- flash_area_erase(fap, 0, fap->fa_size);
- flash_area_close(fap);
- return BOOT_EBADIMAGE;
+ flash_area_erase(fap, 0, flash_area_get_size(fap));
+ rc = BOOT_EBADIMAGE;
+ break;
default:
assert(0);
- return BOOT_EBADIMAGE;
+ rc = BOOT_EBADIMAGE;
}
+
+done:
+ flash_area_close(fap);
+ return rc;
}
/**
- * Marks the image in the primary slot as confirmed. The system will continue
- * booting into the image in the primary slot until told to boot from a
- * different slot.
+ * Marks the image with index 0 in the secondary slot as pending. On the next
+ * reboot, the system will perform a one-time boot of the the secondary slot
+ * image. Note that this API is kept for compatibility. The
+ * boot_set_pending_multi() API is recommended.
+ *
+ * @param permanent Whether the image should be used permanently or
+ * only tested once:
+ * 0=run image once, then confirm or revert.
+ * 1=run image forever.
*
* @return 0 on success; nonzero on failure.
*/
int
-boot_set_confirmed(void)
+boot_set_pending(int permanent)
{
- const struct flash_area *fap;
- struct boot_swap_state state_primary_slot;
+ return boot_set_pending_multi(0, permanent);
+}
+
+/**
+ * Marks the image with the given index in the primary slot as confirmed. The
+ * system will continue booting into the image in the primary slot until told to
+ * boot from a different slot.
+ *
+ * @param image_index Image pair index.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+int
+boot_set_confirmed_multi(int image_index)
+{
+ const struct flash_area *fap = NULL;
+ struct boot_swap_state state_primary_slot = {0};
int rc;
- rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_PRIMARY(0),
- &state_primary_slot);
+ rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index), &fap);
if (rc != 0) {
- return rc;
+ return BOOT_EFLASH;
+ }
+
+ rc = boot_read_swap_state(fap, &state_primary_slot);
+ if (rc != 0) {
+ goto done;
}
switch (state_primary_slot.magic) {
@@ -577,25 +629,19 @@
case BOOT_MAGIC_UNSET:
/* Already confirmed. */
- return 0;
+ goto done;
case BOOT_MAGIC_BAD:
/* Unexpected state. */
- return BOOT_EBADVECT;
- }
-
- rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(0), &fap);
- if (rc) {
- rc = BOOT_EFLASH;
- goto done;
- }
-
- if (state_primary_slot.copy_done == BOOT_FLAG_UNSET) {
- /* Swap never completed. This is unexpected. */
rc = BOOT_EBADVECT;
goto done;
}
+ /* Intentionally do not check copy_done flag
+ * so can confirm a padded image which was programed using a programing
+ * interface.
+ */
+
if (state_primary_slot.image_ok != BOOT_FLAG_UNSET) {
/* Already confirmed. */
goto done;
@@ -607,3 +653,17 @@
flash_area_close(fap);
return rc;
}
+
+/**
+ * Marks the image with index 0 in the primary slot as confirmed. The system
+ * will continue booting into the image in the primary slot until told to boot
+ * from a different slot. Note that this API is kept for compatibility. The
+ * boot_set_confirmed_multi() API is recommended.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+int
+boot_set_confirmed(void)
+{
+ return boot_set_confirmed_multi(0);
+}
diff --git a/boot/bootutil/src/caps.c b/boot/bootutil/src/caps.c
index 2033056..4944f46 100644
--- a/boot/bootutil/src/caps.c
+++ b/boot/bootutil/src/caps.c
@@ -2,6 +2,7 @@
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2017 Linaro Limited
+ * Copyright (c) 2021 Arm Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -70,6 +71,15 @@
#if defined(MCUBOOT_BOOTSTRAP)
res |= BOOTUTIL_CAP_BOOTSTRAP;
#endif
+#if defined(MCUBOOT_AES_256)
+ res |= BOOTUTIL_CAP_AES256;
+#endif
+#if defined(MCUBOOT_RAM_LOAD)
+ res |= BOOTUTIL_CAP_RAM_LOAD;
+#endif
+#if defined(MCUBOOT_DIRECT_XIP)
+ res |= BOOTUTIL_CAP_DIRECT_XIP;
+#endif
return res;
}
diff --git a/boot/bootutil/src/crc32c.h b/boot/bootutil/src/crc32c.h
index 329b9d3..3a45663 100644
--- a/boot/bootutil/src/crc32c.h
+++ b/boot/bootutil/src/crc32c.h
@@ -22,11 +22,11 @@
* specific language governing permissions and limitations
* under the License.
*/
-#ifndef H_CRC32C_
-#define H_CRC32C_
+#ifndef CRC32C_H
+#define CRC32C_H
#include <stdint.h>
uint32_t crc32c_checksum(const uint8_t *address, uint32_t length);
-#endif /* H_CRC32C_ */
+#endif /* CRC32C_H */
diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c
index 12c0a9c..73e1f1f 100644
--- a/boot/bootutil/src/encrypted.c
+++ b/boot/bootutil/src/encrypted.c
@@ -2,7 +2,7 @@
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2018-2019 JUUL Labs
- * Copyright (c) 2019 Arm Limited
+ * Copyright (c) 2019-2021 Arm Limited
*/
#include "mcuboot_config/mcuboot_config.h"
@@ -14,7 +14,11 @@
#if defined(MCUBOOT_ENCRYPT_RSA)
#include "mbedtls/rsa.h"
+#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+#include "rsa_alt_helpers.h"
+#else
#include "mbedtls/rsa_internal.h"
+#endif
#include "mbedtls/asn1.h"
#endif
@@ -40,6 +44,7 @@
#include "bootutil/image.h"
#include "bootutil/enc_key.h"
#include "bootutil/sign_key.h"
+#include "bootutil/crypto/common.h"
#include "bootutil_priv.h"
@@ -74,15 +79,11 @@
bootutil_aes_kw_init(&aes_kw);
rc = bootutil_aes_kw_set_unwrap_key(&aes_kw, bootutil_enc_key.key, *bootutil_enc_key.len);
- if (rc != 0) {
- goto done;
- }
- rc = bootutil_aes_kw_unwrap(&aes_kw, wrapped, TLV_ENC_KW_SZ, enckey, BOOT_ENC_KEY_SIZE);
- if (rc != 0) {
- goto done;
+
+ if (rc == 0) {
+ rc = bootutil_aes_kw_unwrap(&aes_kw, wrapped, TLV_ENC_KW_SZ, enckey, BOOT_ENC_KEY_SIZE);
}
-done:
bootutil_aes_kw_drop(&aes_kw);
return rc;
}
@@ -105,16 +106,16 @@
/* Non-optional fields. */
if ( /* version */
- mbedtls_asn1_get_int(p, end, &ctx->ver) != 0 ||
+ mbedtls_asn1_get_int(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(ver)) != 0 ||
/* public modulus */
- mbedtls_asn1_get_mpi(p, end, &ctx->N) != 0 ||
+ mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(N)) != 0 ||
/* public exponent */
- mbedtls_asn1_get_mpi(p, end, &ctx->E) != 0 ||
+ mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(E)) != 0 ||
/* private exponent */
- mbedtls_asn1_get_mpi(p, end, &ctx->D) != 0 ||
+ mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(D)) != 0 ||
/* primes */
- mbedtls_asn1_get_mpi(p, end, &ctx->P) != 0 ||
- mbedtls_asn1_get_mpi(p, end, &ctx->Q) != 0) {
+ mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(P)) != 0 ||
+ mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(Q)) != 0) {
return -3;
}
@@ -127,22 +128,26 @@
*/
if (*p < end) {
if ( /* d mod (p-1) and d mod (q-1) */
- mbedtls_asn1_get_mpi(p, end, &ctx->DP) != 0 ||
- mbedtls_asn1_get_mpi(p, end, &ctx->DQ) != 0 ||
+ mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(DP)) != 0 ||
+ mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(DQ)) != 0 ||
/* q ^ (-1) mod p */
- mbedtls_asn1_get_mpi(p, end, &ctx->QP) != 0) {
+ mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(QP)) != 0) {
return -4;
}
} else {
- if (mbedtls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D,
- &ctx->DP, &ctx->DQ, &ctx->QP) != 0) {
+ if (mbedtls_rsa_deduce_crt(&ctx->MBEDTLS_CONTEXT_MEMBER(P),
+ &ctx->MBEDTLS_CONTEXT_MEMBER(Q),
+ &ctx->MBEDTLS_CONTEXT_MEMBER(D),
+ &ctx->MBEDTLS_CONTEXT_MEMBER(DP),
+ &ctx->MBEDTLS_CONTEXT_MEMBER(DQ),
+ &ctx->MBEDTLS_CONTEXT_MEMBER(QP)) != 0) {
return -5;
}
}
#endif
- ctx->len = mbedtls_mpi_size(&ctx->N);
+ ctx->MBEDTLS_CONTEXT_MEMBER(len) = mbedtls_mpi_size(&ctx->MBEDTLS_CONTEXT_MEMBER(N));
if (mbedtls_rsa_check_privkey(ctx) != 0) {
return -6;
@@ -190,12 +195,12 @@
return -5;
}
- if (alg.len != sizeof(ec_pubkey_oid) - 1 ||
- memcmp(alg.p, ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
+ if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 ||
+ memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
return -6;
}
- if (param.len != sizeof(ec_secp256r1_oid) - 1 ||
- memcmp(param.p, ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
+ if (param.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1 ||
+ memcmp(param.MBEDTLS_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
return -7;
}
@@ -267,8 +272,8 @@
return -4;
}
- if (alg.len != sizeof(ec_pubkey_oid) - 1 ||
- memcmp(alg.p, ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
+ if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 ||
+ memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
return -5;
}
@@ -433,25 +438,22 @@
#if defined(MCUBOOT_ENCRYPT_RSA)
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048
-# define EXPECTED_ENC_EXT_LEN EXPECTED_ENC_TLV
#elif defined(MCUBOOT_ENCRYPT_KW)
-# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW128
-# define EXPECTED_ENC_EXT_LEN EXPECTED_ENC_TLV
+# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW
#elif defined(MCUBOOT_ENCRYPT_EC256)
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256
# define EXPECTED_ENC_EXT_LEN (EXPECTED_ENC_LEN + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE)
# define EC_PUBK_INDEX (0)
# define EC_TAG_INDEX (65)
# define EC_CIPHERKEY_INDEX (65 + 32)
-_Static_assert(EC_CIPHERKEY_INDEX + 16 == EXPECTED_ENC_LEN,
+_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN,
"Please fix ECIES-P256 component indexes");
#elif defined(MCUBOOT_ENCRYPT_X25519)
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_X25519
-# define EXPECTED_ENC_EXT_LEN EXPECTED_ENC_TLV
# define EC_PUBK_INDEX (0)
# define EC_TAG_INDEX (32)
# define EC_CIPHERKEY_INDEX (32 + 32)
-_Static_assert(EC_CIPHERKEY_INDEX + 16 == EXPECTED_ENC_LEN,
+_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN,
"Please fix ECIES-X25519 component indexes");
#endif
@@ -459,12 +461,30 @@
#define EXPECTED_ENC_EXT_LEN EXPECTED_ENC_LEN
#endif
+#if defined(MCUBOOT_ENCRYPT_RSA) || \
+ (defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS))
+#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+static int fake_rng(void *p_rng, unsigned char *output, size_t len)
+{
+ size_t i;
+
+ (void)p_rng;
+ for (i = 0; i < len; i++) {
+ output[i] = (char)i;
+ }
+
+ return 0;
+}
+#endif
+#endif /* defined(MCUBOOT_ENCRYPT_RSA) ||
+ defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS) */
+
/*
* Decrypt an encryption key TLV.
*
- * @param buf An encryption TLV buffer red from flash
+ * @param buf An encryption TLV read from flash (build time fixed length)
* @param sz An encryption TLV buffer data size
- * @param enckey An AES-128 key sized buffer to store to plain key.
+ * @param enckey An AES-128 or AES-256 key sized buffer to store to plain key.
*/
int
boot_enc_decrypt(const uint8_t *buf, uint8_t *enckey, uint32_t sz, uint8_t *enciv)
@@ -505,8 +525,12 @@
#if defined(MCUBOOT_ENCRYPT_RSA)
+#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+ mbedtls_rsa_init(&rsa);
+ mbedtls_rsa_set_padding(&rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
+#else
mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
-
+#endif
cp = (uint8_t *)bootutil_enc_key.key;
cpend = cp + *bootutil_enc_key.len;
@@ -515,16 +539,20 @@
mbedtls_rsa_free(&rsa);
return rc;
}
-
+#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+ rc = mbedtls_rsa_rsaes_oaep_decrypt(&rsa, fake_rng, NULL,
+ NULL, 0, &olen, buf, enckey, BOOT_ENC_KEY_SIZE);
+#else
rc = mbedtls_rsa_rsaes_oaep_decrypt(&rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE,
NULL, 0, &olen, buf, enckey, BOOT_ENC_KEY_SIZE);
+#endif
mbedtls_rsa_free(&rsa);
#endif /* defined(MCUBOOT_ENCRYPT_RSA) */
#if defined(MCUBOOT_ENCRYPT_KW)
- assert(*bootutil_enc_key.len == 16);
+ assert(*bootutil_enc_key.len == BOOT_ENC_KEY_SIZE);
rc = key_unwrap(buf, enckey);
#endif /* defined(MCUBOOT_ENCRYPT_KW) */
@@ -592,8 +620,8 @@
*/
/* Prepare for default encryption scheme with zero salt and AES IVs */
- memset(counter, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
- memset(salt, 0, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
+ (void)memset(counter, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
+ (void)memset(salt, 0, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
len = BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE;
@@ -625,13 +653,13 @@
bootutil_hmac_sha256_init(&hmac);
- rc = bootutil_hmac_sha256_set_key(&hmac, &derived_key[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE], BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
+ rc = bootutil_hmac_sha256_set_key(&hmac, &derived_key[BOOT_ENC_KEY_SIZE], BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
if (rc != 0) {
(void)bootutil_hmac_sha256_drop(&hmac);
return -1;
}
- rc = bootutil_hmac_sha256_update(&hmac, &buf[EC_CIPHERKEY_INDEX], BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
+ rc = bootutil_hmac_sha256_update(&hmac, &buf[EC_CIPHERKEY_INDEX], BOOT_ENC_KEY_SIZE);
if (rc != 0) {
(void)bootutil_hmac_sha256_drop(&hmac);
return -1;
@@ -699,16 +727,18 @@
uint8_t slot;
int rc;
- rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
+ rc = flash_area_id_to_multi_image_slot(image_index, flash_area_get_id(fap));
if (rc < 0) {
return rc;
}
slot = rc;
+#ifndef MCUBOOT_ENC_IMAGES_XIP
/* Already loaded... */
if (enc_state[slot].valid) {
return 1;
}
+#endif
/* Initialize the AES context */
boot_enc_init(enc_state, slot);
@@ -729,11 +759,11 @@
#if MCUBOOT_SWAP_SAVE_ENCTLV
buf = bs->enctlv[slot];
- memset(buf, 0xff, BOOT_ENC_TLV_ALIGN_SIZE);
+ (void)memset(buf, BOOT_UNINITIALIZED_TLV_FILL, BOOT_ENC_TLV_ALIGN_SIZE);
#endif
rc = flash_area_read(fap, off, buf, len);
- if (rc) {
+ if (rc != 0) {
return -1;
}
@@ -746,7 +776,7 @@
{
int rc;
- rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
+ rc = flash_area_id_to_multi_image_slot(image_index, flash_area_get_id(fap));
if (rc < 0) {
/* can't get proper slot number - skip encryption, */
/* postpone the error for a upper layer */
@@ -756,7 +786,7 @@
return enc_state[rc].valid;
}
-void
+int
boot_encrypt(struct enc_key_data *enc_state, int image_index,
const struct flash_area *fap, uint32_t off, uint32_t sz,
uint32_t blk_off, uint8_t *buf)
@@ -768,13 +798,23 @@
/* boot_copy_region will call boot_encrypt with sz = 0 when skipping over
the TLVs. */
if (sz == 0) {
- return;
+ return 0;
}
- rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
- if (rc < 0) {
- assert(0);
- return;
+#if MCUBOOT_SWAP_USING_SCRATCH
+/* in this case scratch area contains encrypted source block that was copied
+from secondary slot */
+ if (fap->fa_id == FLASH_AREA_IMAGE_SCRATCH) {
+ rc = 1;
+ }
+ else
+#endif
+ {
+ rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
+ if (rc < 0) {
+ assert(0);
+ return rc;
+ }
}
enc = &enc_state[rc];
@@ -788,7 +828,7 @@
nonce[14] = (uint8_t)(off >> 8);
nonce[15] = (uint8_t)off;
- bootutil_aes_ctr_encrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf);
+ return bootutil_aes_ctr_encrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf);
}
/**
@@ -801,7 +841,7 @@
for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
(void)boot_enc_drop(enc_state, slot);
}
- memset(enc_state, 0, sizeof(struct enc_key_data) * BOOT_NUM_SLOTS);
+ (void)memset(enc_state, 0, sizeof(struct enc_key_data) * BOOT_NUM_SLOTS);
}
#endif /* MCUBOOT_ENC_IMAGES */
diff --git a/boot/bootutil/src/fault_injection_hardening.c b/boot/bootutil/src/fault_injection_hardening.c
index 5ee109c..5e818c6 100644
--- a/boot/bootutil/src/fault_injection_hardening.c
+++ b/boot/bootutil/src/fault_injection_hardening.c
@@ -10,9 +10,9 @@
/* Variable that could be (but isn't) changed at runtime to force the compiler
* not to optimize the double check. Value doesn't matter.
*/
-volatile int _fih_mask = _FIH_MASK_VALUE;
-fih_int FIH_SUCCESS = {FIH_POSITIVE_VALUE, _FIH_MASK_VALUE ^ FIH_POSITIVE_VALUE};
-fih_int FIH_FAILURE = {FIH_NEGATIVE_VALUE, _FIH_MASK_VALUE ^ FIH_NEGATIVE_VALUE};
+volatile int _fih_mask = FIH_MASK_VALUE;
+fih_int FIH_SUCCESS = {FIH_POSITIVE_VALUE, FIH_MASK_VALUE ^ FIH_POSITIVE_VALUE};
+fih_int FIH_FAILURE = {FIH_NEGATIVE_VALUE, FIH_MASK_VALUE ^ FIH_NEGATIVE_VALUE};
#else
fih_int FIH_SUCCESS = {FIH_POSITIVE_VALUE};
fih_int FIH_FAILURE = {FIH_NEGATIVE_VALUE};
@@ -21,7 +21,7 @@
#ifdef FIH_ENABLE_CFI
#ifdef FIH_ENABLE_DOUBLE_VARS
-fih_int _fih_cfi_ctr = {0, 0 ^ _FIH_MASK_VALUE};
+fih_int _fih_cfi_ctr = {0, 0 ^ FIH_MASK_VALUE};
#else
fih_int _fih_cfi_ctr = {0};
#endif /* FIH_ENABLE_DOUBLE_VARS */
diff --git a/boot/bootutil/src/image_ec.c b/boot/bootutil/src/image_ec.c
index a127b74..2d92afb 100644
--- a/boot/bootutil/src/image_ec.c
+++ b/boot/bootutil/src/image_ec.c
@@ -2,6 +2,7 @@
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2016-2018 JUUL Labs
+ * Copyright (C) 2021 Arm Limited
*
* Original license:
*
@@ -34,6 +35,7 @@
#include "mbedtls/oid.h"
#include "mbedtls/asn1.h"
+#include "bootutil/crypto/common.h"
#include "bootutil_priv.h"
/*
@@ -70,7 +72,7 @@
return -4;
}
- if (mbedtls_ecp_group_load(&ctx->grp, MBEDTLS_ECP_DP_SECP224R1)) {
+ if (mbedtls_ecp_group_load(&ctx->MBEDTLS_CONTEXT_MEMBER(grp), MBEDTLS_ECP_DP_SECP224R1)) {
return -5;
}
@@ -81,11 +83,11 @@
return -7;
}
- if (mbedtls_ecp_point_read_binary(&ctx->grp, &ctx->Q, *p, end - *p)) {
+ if (mbedtls_ecp_point_read_binary(&ctx->MBEDTLS_CONTEXT_MEMBER(grp), &ctx->MBEDTLS_CONTEXT_MEMBER(Q), *p, end - *p)) {
return -8;
}
- if (mbedtls_ecp_check_pubkey(&ctx->grp, &ctx->Q)) {
+ if (mbedtls_ecp_check_pubkey(&ctx->MBEDTLS_CONTEXT_MEMBER(grp), &ctx->MBEDTLS_CONTEXT_MEMBER(Q))) {
return -9;
}
return 0;
diff --git a/boot/bootutil/src/image_ec256.c b/boot/bootutil/src/image_ec256.c
index bdd72c6..9f0ed3d 100644
--- a/boot/bootutil/src/image_ec256.c
+++ b/boot/bootutil/src/image_ec256.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 2016-2019 JUUL Labs
* Copyright (c) 2017 Linaro LTD
+ * Copyright (C) 2021 Arm Limited
*
* Original license:
*
@@ -40,6 +41,7 @@
#include "mbedtls/oid.h"
#include "mbedtls/asn1.h"
#include "bootutil/crypto/ecdsa_p256.h"
+#include "bootutil/crypto/common.h"
#include "bootutil_priv.h"
/*
@@ -68,12 +70,12 @@
if (mbedtls_asn1_get_alg(p, end, &alg, ¶m)) {
return -2;
}
- if (alg.len != sizeof(ec_pubkey_oid) - 1 ||
- memcmp(alg.p, ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
+ if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 ||
+ memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
return -3;
}
- if (param.len != sizeof(ec_secp256r1_oid) - 1||
- memcmp(param.p, ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
+ if (param.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1||
+ memcmp(param.MBEDTLS_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
return -4;
}
@@ -116,13 +118,13 @@
return -2;
}
/* id-ecPublicKey (RFC5480) */
- if (alg.len != sizeof(ec_pubkey_oid) - 1 ||
- memcmp(alg.p, ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
+ if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 ||
+ memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
return -3;
}
/* namedCurve (RFC5480) */
- if (param.len != sizeof(ec_secp256r1_oid) - 1 ||
- memcmp(param.p, ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
+ if (param.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1 ||
+ memcmp(param.MBEDTLS_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
return -4;
}
/* ECPoint (RFC5480) */
diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c
index 940c18d..b5838c4 100644
--- a/boot/bootutil/src/image_ed25519.c
+++ b/boot/bootutil/src/image_ed25519.c
@@ -2,6 +2,7 @@
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2019 JUUL Labs
+ * Copyright (c) 2021 Arm Limited
*/
#include <string.h>
@@ -15,6 +16,7 @@
#include "mbedtls/asn1.h"
#include "bootutil_priv.h"
+#include "bootutil/crypto/common.h"
static const uint8_t ed25519_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x65\x70";
#define NUM_ED25519_BYTES 32
@@ -43,8 +45,8 @@
return -2;
}
- if (alg.len != sizeof(ed25519_pubkey_oid) - 1 ||
- memcmp(alg.p, ed25519_pubkey_oid, sizeof(ed25519_pubkey_oid) - 1)) {
+ if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ed25519_pubkey_oid) - 1 ||
+ memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ed25519_pubkey_oid, sizeof(ed25519_pubkey_oid) - 1)) {
return -3;
}
diff --git a/boot/bootutil/src/image_rsa.c b/boot/bootutil/src/image_rsa.c
index 1a1727e..42d2db7 100644
--- a/boot/bootutil/src/image_rsa.c
+++ b/boot/bootutil/src/image_rsa.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2017-2018 Linaro LTD
* Copyright (c) 2017-2019 JUUL Labs
- * Copyright (c) 2020 Arm Limited
+ * Copyright (c) 2020-2021 Arm Limited
*
* Original license:
*
@@ -32,6 +32,7 @@
#ifdef MCUBOOT_SIGN_RSA
#include "bootutil/sign_key.h"
#include "bootutil/crypto/sha256.h"
+#include "bootutil/crypto/common.h"
#include "mbedtls/rsa.h"
#include "mbedtls/asn1.h"
@@ -88,12 +89,12 @@
return -2;
}
- if ((rc = mbedtls_asn1_get_mpi(p, end, &ctx->N)) != 0 ||
- (rc = mbedtls_asn1_get_mpi(p, end, &ctx->E)) != 0) {
+ if ((rc = mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(N))) != 0 ||
+ (rc = mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(E))) != 0) {
return -3;
}
- ctx->len = mbedtls_mpi_size(&ctx->N);
+ ctx->MBEDTLS_CONTEXT_MEMBER(len) = mbedtls_mpi_size(&ctx->MBEDTLS_CONTEXT_MEMBER(N));
if (*p != end) {
return -4;
@@ -101,7 +102,8 @@
/* The mbedtls version is more than 2.6.1 */
#if MBEDTLS_VERSION_NUMBER > 0x02060100
- rc = mbedtls_rsa_import(ctx, &ctx->N, NULL, NULL, NULL, &ctx->E);
+ rc = mbedtls_rsa_import(ctx, &ctx->MBEDTLS_CONTEXT_MEMBER(N), NULL,
+ NULL, NULL, &ctx->MBEDTLS_CONTEXT_MEMBER(E));
if (rc != 0) {
return -5;
}
@@ -112,7 +114,7 @@
return -6;
}
- ctx->len = mbedtls_mpi_size(&ctx->N);
+ ctx->MBEDTLS_CONTEXT_MEMBER(len) = mbedtls_mpi_size(&ctx->MBEDTLS_CONTEXT_MEMBER(N));
return 0;
}
@@ -171,7 +173,8 @@
int rc = 0;
fih_int fih_rc = FIH_FAILURE;
- if (ctx->len != PSS_EMLEN || PSS_EMLEN > MBEDTLS_MPI_MAX_SIZE) {
+ if (ctx->MBEDTLS_CONTEXT_MEMBER(len) != PSS_EMLEN ||
+ PSS_EMLEN > MBEDTLS_MPI_MAX_SIZE) {
rc = -1;
goto out;
}
@@ -296,13 +299,17 @@
uint8_t *cp;
uint8_t *end;
+#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+ mbedtls_rsa_init(&ctx);
+#else
mbedtls_rsa_init(&ctx, 0, 0);
+#endif
cp = (uint8_t *)bootutil_keys[key_id].key;
end = cp + *bootutil_keys[key_id].len;
rc = bootutil_parse_rsakey(&ctx, &cp, end);
- if (rc || slen != ctx.len) {
+ if (rc || slen != ctx.MBEDTLS_CONTEXT_MEMBER(len)) {
mbedtls_rsa_free(&ctx);
goto out;
}
diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c
index 18967c5..e7cff90 100644
--- a/boot/bootutil/src/image_validate.c
+++ b/boot/bootutil/src/image_validate.c
@@ -4,6 +4,7 @@
* Copyright (c) 2017-2019 Linaro LTD
* Copyright (c) 2016-2019 JUUL Labs
* Copyright (c) 2019-2020 Arm Limited
+ * Copyright (c) 2021 Infineon Technologies AG
*
* Original license:
*
@@ -38,6 +39,8 @@
#include "bootutil/security_cnt.h"
#include "bootutil/fault_injection_hardening.h"
+#include "bootutil/bootutil_log.h"
+
#include "mcuboot_config/mcuboot_config.h"
#ifdef MCUBOOT_ENC_IMAGES
@@ -85,6 +88,9 @@
(void)blk_sz;
(void)off;
(void)rc;
+ (void)fap;
+ (void)tmp_buf;
+ (void)tmp_buf_sz;
#endif
#endif
@@ -113,7 +119,9 @@
size += hdr->ih_protect_tlv_size;
#ifdef MCUBOOT_RAM_LOAD
- bootutil_sha256_update(&sha256_ctx,(void*)(hdr->ih_load_addr), size);
+ bootutil_sha256_update(&sha256_ctx,
+ (void*)(IMAGE_RAM_BASE + hdr->ih_load_addr),
+ size);
#else
for (off = 0; off < size; off += blk_sz) {
blk_sz = size - off;
@@ -143,8 +151,16 @@
/* Only payload is encrypted (area between header and TLVs) */
if (off >= hdr_size && off < tlv_off) {
blk_off = (off - hdr_size) & 0xf;
- boot_encrypt(enc_state, image_index, fap, off - hdr_size,
+#ifdef MCUBOOT_ENC_IMAGES_XIP
+ rc = bootutil_img_encrypt(enc_state, image_index, hdr, fap, off,
blk_sz, blk_off, tmp_buf);
+#else
+ rc = boot_encrypt(enc_state, image_index, fap, off - hdr_size,
+ blk_sz, blk_off, tmp_buf);
+#endif
+ if (rc) {
+ return rc;
+ }
}
}
#endif
@@ -204,9 +220,9 @@
bootutil_sha256_context sha256_ctx;
int i;
const struct bootutil_key *key;
- uint8_t hash[32];
+ uint8_t hash[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
- if (keyhash_len > 32) {
+ if (keyhash_len != BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE) {
return -1;
}
@@ -229,8 +245,8 @@
bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len)
{
bootutil_sha256_context sha256_ctx;
- uint8_t hash[32];
- uint8_t key_hash[32];
+ uint8_t hash[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
+ uint8_t key_hash[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
size_t key_hash_size = sizeof(key_hash);
int rc;
fih_int fih_rc;
@@ -323,6 +339,67 @@
return 0;
}
+#ifdef CYW20829
+/**
+ * Reads the content of an image's reprovisioning packet.
+ *
+ * @param hdr Pointer to the image header structure.
+ * @param fap Pointer to a description structure of the image's
+ * flash area.
+ * @param reprov_packet Pointer to store the reprovisioning packet.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+int32_t
+bootutil_get_img_reprov_packet(struct image_header *hdr,
+ const struct flash_area *fap,
+ uint8_t *reprov_packet)
+{
+ struct image_tlv_iter it;
+ uint32_t off;
+ uint16_t len;
+ int32_t rc;
+
+ if ((hdr == NULL) ||
+ (fap == NULL) ||
+ (reprov_packet == NULL)) {
+ /* Invalid parameter. */
+ return BOOT_EBADARGS;
+ }
+
+ /* The reprovisioning packet TLV is in the protected part of the TLV area. */
+ if (hdr->ih_protect_tlv_size == 0) {
+ return BOOT_EBADIMAGE;
+ }
+
+ rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_PROV_PACK, true);
+ if (rc) {
+ return rc;
+ }
+
+ /* Traverse through the protected TLV area to find
+ * the reprovisioning apcket TLV.
+ */
+
+ rc = bootutil_tlv_iter_next(&it, &off, &len, NULL);
+ if (rc != 0) {
+ /* Reprovisioning packet TLV has not been found. */
+ return -1;
+ }
+
+ if (len != REPROV_PACK_SIZE) {
+ /* Reprovisioning packet is not valid. */
+ return BOOT_EBADIMAGE;
+ }
+
+ rc = LOAD_IMAGE_DATA(hdr, fap, off, reprov_packet, len);
+ if (rc != 0) {
+ return BOOT_EFLASH;
+ }
+
+ return 0;
+}
+#endif /* CYW20289 */
#endif /* MCUBOOT_HW_ROLLBACK_PROT */
/*
@@ -349,12 +426,13 @@
#endif /* EXPECTED_SIG_TLV */
struct image_tlv_iter it;
uint8_t buf[SIG_BUF_SIZE];
- uint8_t hash[32];
+ uint8_t hash[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
int rc = 0;
fih_int fih_rc = FIH_FAILURE;
#ifdef MCUBOOT_HW_ROLLBACK_PROT
- fih_int security_cnt = fih_int_encode(INT_MAX);
+ fih_uint security_cnt = fih_uint_encode(UINT_MAX);
uint32_t img_security_cnt = 0;
+ uint8_t reprov_packet[REPROV_PACK_SIZE];
fih_int security_counter_valid = FIH_FAILURE;
#endif
@@ -365,7 +443,7 @@
}
if (out_hash) {
- memcpy(out_hash, hash, 32);
+ memcpy(out_hash, hash, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
}
rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, false);
@@ -411,7 +489,7 @@
/*
* Determine which key we should be checking.
*/
- if (len > 32) {
+ if (len != BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE) {
rc = -1;
goto out;
}
@@ -484,18 +562,52 @@
goto out;
}
+ BOOT_LOG_DBG("NV Counter read from efuse = %u", fih_uint_decode(security_cnt));
+
+ BOOT_LOG_DBG("NV Counter read from image = %" PRIu32, img_security_cnt);
+
/* Compare the new image's security counter value against the
* stored security counter value.
*/
fih_rc = fih_int_encode_zero_equality(img_security_cnt <
- fih_int_decode(security_cnt));
+ (uint32_t)fih_uint_decode(security_cnt));
if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
/* The image's security counter is not accepted. */
goto out;
}
-
+#ifndef CYW20829
/* The image's security counter has been successfully verified. */
security_counter_valid = fih_rc;
+ }
+#else
+ /* The image's security counter has been successfully verified. */
+ security_counter_valid = fih_int_encode(HW_ROLLBACK_CNT_VALID);
+ } else if (type == IMAGE_TLV_PROV_PACK) {
+
+ if (fih_eq(security_counter_valid, fih_int_encode(HW_ROLLBACK_CNT_VALID))) {
+ /*
+ * Verify the image reprovisioning packet.
+ * This must always be present.
+ */
+ BOOT_LOG_INF("Prov packet length 0x51 TLV = %" PRIu16, len);
+
+ if (len != sizeof(reprov_packet)) {
+ /* Re-provisioning packet is not valid. */
+ rc = -1;
+ goto out;
+ }
+
+ rc = LOAD_IMAGE_DATA(hdr, fap, off, reprov_packet, len);
+ if (rc) {
+ goto out;
+ }
+
+ security_counter_valid = fih_int_encode(fih_int_decode(security_counter_valid) | REPROV_PACK_VALID);
+ }
+ else{
+ goto out;
+ }
+#endif /* CYW20829 */
#endif /* MCUBOOT_HW_ROLLBACK_PROT */
}
}
@@ -509,7 +621,12 @@
FIH_SUCCESS));
#endif
#ifdef MCUBOOT_HW_ROLLBACK_PROT
+#ifdef CYW20829
+ if (fih_not_eq(security_counter_valid, fih_int_encode(REPROV_PACK_VALID | HW_ROLLBACK_CNT_VALID))) {
+ BOOT_LOG_DBG("Reprovisioning packet TLV 0x51 is not present image = %d", image_index);
+#else
if (fih_not_eq(security_counter_valid, FIH_SUCCESS)) {
+#endif /* CYW20829 */
rc = -1;
goto out;
}
diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c
index e4c0a3f..7794b5a 100644
--- a/boot/bootutil/src/loader.c
+++ b/boot/bootutil/src/loader.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2016-2020 Linaro LTD
* Copyright (c) 2016-2019 JUUL Labs
- * Copyright (c) 2019-2020 Arm Limited
+ * Copyright (c) 2019-2021 Arm Limited
*
* Original license:
*
@@ -35,7 +35,6 @@
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
-#include <os/os_malloc.h>
#include "bootutil/bootutil.h"
#include "bootutil/image.h"
#include "bootutil_priv.h"
@@ -44,14 +43,20 @@
#include "bootutil/security_cnt.h"
#include "bootutil/boot_record.h"
#include "bootutil/fault_injection_hardening.h"
+#include "bootutil/ramload.h"
+#include "bootutil/boot_hooks.h"
#ifdef MCUBOOT_ENC_IMAGES
#include "bootutil/enc_key.h"
#endif
+#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
+#include <os/os_malloc.h>
+#endif
+
#include "mcuboot_config/mcuboot_config.h"
-MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
+BOOT_LOG_MODULE_DECLARE(mcuboot);
static struct boot_loader_state boot_data;
@@ -61,6 +66,22 @@
#define IMAGES_ITER(x)
#endif
+#if defined(MCUBOOT_DIRECT_XIP) || defined(MCUBOOT_RAM_LOAD)
+struct slot_usage_t {
+ /* Index of the slot chosen to be loaded */
+ uint32_t active_slot;
+ bool slot_available[BOOT_NUM_SLOTS];
+#if defined(MCUBOOT_RAM_LOAD)
+ /* Image destination and size for the active slot */
+ uint32_t img_dst;
+ uint32_t img_sz;
+#elif defined(MCUBOOT_DIRECT_XIP_REVERT)
+ /* Swap status for the active slot */
+ struct boot_swap_state swap_state;
+#endif
+};
+#endif /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
+
/*
* This macro allows some control on the allocation of local variables.
* When running natively on a target, we don't want to allocated huge
@@ -82,7 +103,12 @@
int i;
for (i = 0; i < BOOT_NUM_SLOTS; i++) {
- rc = boot_read_image_header(state, i, boot_img_hdr(state, i), bs);
+ rc = BOOT_HOOK_CALL(boot_read_image_header_hook, BOOT_HOOK_REGULAR,
+ BOOT_CURR_IMG(state), i, boot_img_hdr(state, i));
+ if (rc == BOOT_HOOK_REGULAR)
+ {
+ rc = boot_read_image_header(state, i, boot_img_hdr(state, i), bs);
+ }
if (rc != 0) {
/* If `require_all` is set, fail on any single fail, otherwise
* if at least the first slot's header was read successfully,
@@ -101,6 +127,101 @@
return 0;
}
+/**
+ * Saves boot status and shared data for current image.
+ *
+ * @param state Boot loader status information.
+ * @param active_slot Index of the slot will be loaded for current image.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+static int
+boot_add_shared_data(struct boot_loader_state *state,
+ uint32_t active_slot)
+{
+#if defined(MCUBOOT_MEASURED_BOOT) || defined(MCUBOOT_DATA_SHARING)
+ int rc;
+
+#ifdef MCUBOOT_MEASURED_BOOT
+ rc = boot_save_boot_status(BOOT_CURR_IMG(state),
+ boot_img_hdr(state, active_slot),
+ BOOT_IMG_AREA(state, active_slot));
+ if (rc != 0) {
+ BOOT_LOG_ERR("Failed to add image data to shared area");
+ return rc;
+ }
+#endif /* MCUBOOT_MEASURED_BOOT */
+
+#ifdef MCUBOOT_DATA_SHARING
+ rc = boot_save_shared_data(boot_img_hdr(state, active_slot),
+ BOOT_IMG_AREA(state, active_slot));
+ if (rc != 0) {
+ BOOT_LOG_ERR("Failed to add data to shared memory area.");
+ return rc;
+ }
+#endif /* MCUBOOT_DATA_SHARING */
+
+ return 0;
+
+#else /* MCUBOOT_MEASURED_BOOT || MCUBOOT_DATA_SHARING */
+ (void) (state);
+ (void) (active_slot);
+
+ return 0;
+#endif
+}
+
+/**
+ * Fills rsp to indicate how booting should occur.
+ *
+ * @param state Boot loader status information.
+ * @param slot_usage Information about the active and available slots.
+ * Only used in MCUBOOT_DIRECT_XIP and MCUBOOT_RAM_LOAD
+ * @param rsp boot_rsp struct to fill.
+ */
+static void
+fill_rsp(struct boot_loader_state *state, void *slot_usage,
+ struct boot_rsp *rsp)
+{
+ uint32_t active_slot;
+
+#if (BOOT_IMAGE_NUMBER > 1)
+ /* Always boot from Image 0. */
+ BOOT_CURR_IMG(state) = 0;
+#endif
+
+#if defined(MCUBOOT_DIRECT_XIP) || defined(MCUBOOT_RAM_LOAD)
+ active_slot = ((struct slot_usage_t *)slot_usage)[BOOT_CURR_IMG(state)].active_slot;
+#else
+ (void) (slot_usage);
+ active_slot = BOOT_PRIMARY_SLOT;
+#endif
+
+ rsp->br_flash_dev_id = flash_area_get_device_id(BOOT_IMG_AREA(state, active_slot));
+ rsp->br_image_off = boot_img_slot_off(state, active_slot);
+ rsp->br_hdr = boot_img_hdr(state, active_slot);
+}
+
+/**
+ * Closes all flash areas.
+ *
+ * @param state Boot loader status information.
+ */
+static void
+close_all_flash_areas(struct boot_loader_state *state)
+{
+ uint32_t slot;
+
+ IMAGES_ITER(BOOT_CURR_IMG(state)) {
+#if MCUBOOT_SWAP_USING_SCRATCH
+ flash_area_close(BOOT_SCRATCH_AREA(state));
+#endif
+ for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
+ flash_area_close(BOOT_IMG_AREA(state, BOOT_NUM_SLOTS - 1 - slot));
+ }
+ }
+}
+
#if !defined(MCUBOOT_DIRECT_XIP)
/*
* Compute the total size of the given image. Includes the size of
@@ -110,7 +231,7 @@
static int
boot_read_image_size(struct boot_loader_state *state, int slot, uint32_t *size)
{
- const struct flash_area *fap;
+ const struct flash_area *fap = NULL;
struct image_tlv_info info;
uint32_t off;
uint32_t protect_tlv_size;
@@ -170,18 +291,22 @@
static uint32_t
boot_write_sz(struct boot_loader_state *state)
{
- uint32_t elem_sz;
+ size_t elem_sz;
#if MCUBOOT_SWAP_USING_SCRATCH
- uint32_t align;
+ size_t align;
#endif
/* Figure out what size to write update status update as. The size depends
* on what the minimum write size is for scratch area, active image slot.
* We need to use the bigger of those 2 values.
*/
+
elem_sz = flash_area_align(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT));
+ assert(elem_sz != 0u);
+
#if MCUBOOT_SWAP_USING_SCRATCH
align = flash_area_align(BOOT_SCRATCH_AREA(state));
+ assert(align != 0u);
if (align > elem_sz) {
elem_sz = align;
}
@@ -190,51 +315,20 @@
return elem_sz;
}
-#ifndef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
static int
boot_initialize_area(struct boot_loader_state *state, int flash_area)
{
- int num_sectors = BOOT_MAX_IMG_SECTORS;
- int rc;
-
- if (flash_area == FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state))) {
- rc = flash_area_to_sectors(flash_area, &num_sectors,
- BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors);
- BOOT_IMG(state, BOOT_PRIMARY_SLOT).num_sectors = (size_t)num_sectors;
-
- } else if (flash_area == FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) {
- rc = flash_area_to_sectors(flash_area, &num_sectors,
- BOOT_IMG(state, BOOT_SECONDARY_SLOT).sectors);
- BOOT_IMG(state, BOOT_SECONDARY_SLOT).num_sectors = (size_t)num_sectors;
-
-#if MCUBOOT_SWAP_USING_SCRATCH
- } else if (flash_area == FLASH_AREA_IMAGE_SCRATCH) {
- rc = flash_area_to_sectors(flash_area, &num_sectors,
- state->scratch.sectors);
- state->scratch.num_sectors = (size_t)num_sectors;
-#endif
-
- } else {
- return BOOT_EFLASH;
- }
-
- return rc;
-}
-#else /* defined(MCUBOOT_USE_FLASH_AREA_GET_SECTORS) */
-static int
-boot_initialize_area(struct boot_loader_state *state, int flash_area)
-{
- uint32_t num_sectors;
- struct flash_sector *out_sectors;
+ uint32_t num_sectors = BOOT_MAX_IMG_SECTORS;
+ boot_sector_t *out_sectors;
size_t *out_num_sectors;
int rc;
num_sectors = BOOT_MAX_IMG_SECTORS;
- if (flash_area == FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state))) {
+ if (flash_area == (int) FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state))) {
out_sectors = BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors;
out_num_sectors = &BOOT_IMG(state, BOOT_PRIMARY_SLOT).num_sectors;
- } else if (flash_area == FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) {
+ } else if (flash_area == (int) FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) {
out_sectors = BOOT_IMG(state, BOOT_SECONDARY_SLOT).sectors;
out_num_sectors = &BOOT_IMG(state, BOOT_SECONDARY_SLOT).num_sectors;
#if MCUBOOT_SWAP_USING_SCRATCH
@@ -251,14 +345,18 @@
return BOOT_EFLASH;
}
+#ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
rc = flash_area_get_sectors(flash_area, &num_sectors, out_sectors);
+#else
+ _Static_assert(sizeof(int) <= sizeof(uint32_t), "Fix needed");
+ rc = flash_area_to_sectors(flash_area, (int *)&num_sectors, out_sectors);
+#endif /* defined(MCUBOOT_USE_FLASH_AREA_GET_SECTORS) */
if (rc != 0) {
return rc;
}
*out_num_sectors = num_sectors;
return 0;
}
-#endif /* !defined(MCUBOOT_USE_FLASH_AREA_GET_SECTORS) */
/**
* Determines the sector layout of both image slots and the scratch area.
@@ -281,7 +379,8 @@
rc = boot_initialize_area(state, FLASH_AREA_IMAGE_SECONDARY(image_index));
if (rc != 0) {
- return BOOT_EFLASH;
+ /* We need to differentiate from the primary image issue */
+ return BOOT_EFLASH_SEC;
}
#if MCUBOOT_SWAP_USING_STATUS
@@ -307,9 +406,11 @@
boot_status_reset(struct boot_status *bs)
{
#ifdef MCUBOOT_ENC_IMAGES
- memset(&bs->enckey, 0xff, BOOT_NUM_SLOTS * BOOT_ENC_KEY_SIZE);
+ (void)memset(&bs->enckey, BOOT_UNINITIALIZED_KEY_FILL,
+ BOOT_NUM_SLOTS * BOOT_ENC_KEY_SIZE);
#if MCUBOOT_SWAP_SAVE_ENCTLV
- memset(&bs->enctlv, 0xff, BOOT_NUM_SLOTS * BOOT_ENC_TLV_ALIGN_SIZE);
+ (void)memset(&bs->enctlv, BOOT_UNINITIALIZED_TLV_FILL,
+ BOOT_NUM_SLOTS * BOOT_ENC_TLV_ALIGN_SIZE);
#endif
#endif /* MCUBOOT_ENC_IMAGES */
@@ -343,12 +444,12 @@
int
boot_write_status(const struct boot_loader_state *state, struct boot_status *bs)
{
- const struct flash_area *fap;
+ const struct flash_area *fap = NULL;
uint32_t off;
int area_id;
int rc;
uint8_t buf[BOOT_MAX_ALIGN];
- uint8_t align;
+ size_t align;
uint8_t erased_val;
/* NOTE: The first sector copied (that is the last sector on slot) contains
@@ -378,8 +479,13 @@
off = boot_status_off(fap) +
boot_status_internal_off(bs, BOOT_WRITE_SZ(state));
align = flash_area_align(fap);
+ if (align == 0u) {
+ rc = BOOT_EFLASH;
+ goto done;
+ }
+
erased_val = flash_area_erased_val(fap);
- memset(buf, erased_val, BOOT_MAX_ALIGN);
+ (void)memset(buf, erased_val, BOOT_MAX_ALIGN);
buf[0] = bs->state;
rc = flash_area_write(fap, off, buf, align);
@@ -421,14 +527,24 @@
image_index = BOOT_CURR_IMG(state);
-#ifdef MCUBOOT_ENC_IMAGES
+/* In the case of ram loading the image has already been decrypted as it is
+ * decrypted when copied in ram */
+#if defined(MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_RAM_LOAD)
if (MUST_DECRYPT(fap, image_index, hdr)) {
- rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap, bs);
+ rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
if (rc < 0) {
FIH_RET(fih_rc);
}
- if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), 1, bs)) {
- FIH_RET(fih_rc);
+ else {
+ uint8_t slot = (uint8_t)rc;
+
+ rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap, bs);
+ if (rc < 0) {
+ FIH_RET(fih_rc);
+ }
+ if (0 == rc && boot_enc_set_key(BOOT_CURR_ENC(state), slot, bs)) {
+ FIH_RET(fih_rc);
+ }
}
}
#endif
@@ -490,7 +606,7 @@
return false;
}
- if (size >= fap->fa_size) {
+ if (size >= flash_area_get_size(fap)) {
return false;
}
@@ -516,7 +632,7 @@
static int
boot_check_header_erased(struct boot_loader_state *state, int slot)
{
- const struct flash_area *fap;
+ const struct flash_area *fap = NULL;
struct image_header *hdr;
uint8_t erased_val;
int area_id;
@@ -542,8 +658,6 @@
#if (BOOT_IMAGE_NUMBER > 1) || \
defined(MCUBOOT_DIRECT_XIP) || \
defined(MCUBOOT_RAM_LOAD) || \
- defined(MCUBOOT_SWAP_USING_SCRATCH) || \
- defined(MCUBOOT_SWAP_USING_MOVE) || \
(defined(MCUBOOT_OVERWRITE_ONLY) && defined(MCUBOOT_DOWNGRADE_PREVENTION))
/**
* Compare image version numbers not including the build number
@@ -597,13 +711,21 @@
* does not match the slot address.
*/
static bool
-boot_rom_address_check(struct boot_loader_state *state, size_t slot)
+boot_rom_address_check(struct boot_loader_state *state,
+ struct slot_usage_t slot_usage[])
{
- const struct image_header *hdr = boot_img_hdr(state, slot);
- uint32_t f_off = boot_img_slot_off(state, slot);
+ uint32_t active_slot;
+ const struct image_header *hdr;
+ uint32_t f_off;
+
+ active_slot = slot_usage[BOOT_CURR_IMG(state)].active_slot;
+ hdr = boot_img_hdr(state, active_slot);
+ f_off = boot_img_slot_off(state, active_slot);
+
if (hdr->ih_flags & IMAGE_F_ROM_FIXED && hdr->ih_load_addr != f_off) {
- BOOT_LOG_WRN("Image in %s slot at 0x%x has been built for offset 0x%x"\
- ", skipping", slot == 0 ? "primary" : "secondary", f_off,
+ BOOT_LOG_WRN("Image in %s slot at 0x%" PRIx32
+ " has been built for offset 0x%" PRIx32 ", skipping",
+ active_slot == 0 ? "primary" : "secondary", f_off,
hdr->ih_load_addr);
/* If there is address mismatch, the image is not bootable from this
@@ -627,7 +749,7 @@
boot_validate_slot(struct boot_loader_state *state, int slot,
struct boot_status *bs)
{
- const struct flash_area *fap;
+ const struct flash_area *fap = NULL;
struct image_header *hdr;
int area_id;
fih_int fih_rc = FIH_FAILURE;
@@ -639,7 +761,7 @@
FIH_RET(fih_rc);
}
- BOOT_LOG_DBG("> boot_validate_slot: fa_id = %d", fap->fa_id);
+ BOOT_LOG_DBG("> boot_validate_slot: fa_id = %u", (unsigned)fap->fa_id);
hdr = boot_img_hdr(state, slot);
if (boot_check_header_erased(state, slot) == 0 ||
@@ -677,7 +799,7 @@
&boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver);
if (rc < 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) {
BOOT_LOG_ERR("insufficient version in secondary slot");
- flash_area_erase(fap, 0, fap->fa_size);
+ flash_area_erase(fap, 0, flash_area_get_size(fap));
/* Image in the secondary slot does not satisfy version requirement.
* Erase the image and continue booting from the primary slot.
*/
@@ -686,12 +808,16 @@
}
}
#endif
-
- FIH_CALL(boot_image_check, fih_rc, state, hdr, fap, bs);
+ BOOT_HOOK_CALL_FIH(boot_image_check_hook, fih_int_encode(BOOT_HOOK_REGULAR),
+ fih_rc, BOOT_CURR_IMG(state), slot);
+ if (fih_eq(fih_rc, fih_int_encode(BOOT_HOOK_REGULAR)))
+ {
+ FIH_CALL(boot_image_check, fih_rc, state, hdr, fap, bs);
+ }
if (!boot_is_header_valid(hdr, fap) || fih_not_eq(fih_rc, FIH_SUCCESS)) {
if ((slot != BOOT_PRIMARY_SLOT) || ARE_SLOTS_EQUIVALENT()) {
BOOT_LOG_DBG(" * Image in the secondary slot is invalid. Erase the image");
- flash_area_erase(fap, 0, fap->fa_size);
+ flash_area_erase(fap, 0, flash_area_get_size(fap));
/* Image is invalid, erase it to prevent further unnecessary
* attempts to validate and boot it.
*/
@@ -732,7 +858,11 @@
{
const struct flash_area *fap = NULL;
uint32_t img_security_cnt;
+ void * custom_data = NULL;
int rc;
+#ifdef CYW20829
+ uint8_t buff[REPROV_PACK_SIZE];
+#endif /* CYW20829 */
rc = flash_area_open(flash_area_id_from_multi_image_slot(image_index, slot),
&fap);
@@ -746,10 +876,13 @@
goto done;
}
- rc = boot_nv_security_counter_update(image_index, img_security_cnt);
- if (rc != 0) {
- goto done;
+#ifdef CYW20829
+ rc = bootutil_get_img_reprov_packet(hdr, fap, buff);
+ if (rc == 0) {
+ custom_data = (void *)buff;
}
+#endif /* CYW20829 */
+ rc = boot_nv_security_counter_update(image_index, img_security_cnt, custom_data);
done:
flash_area_close(fap);
@@ -790,6 +923,7 @@
return swap_type;
}
+#endif
/**
* Erases a region of flash.
@@ -807,6 +941,7 @@
return flash_area_erase(fap, off, sz);
}
+#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
/**
* Copies the contents of one flash region to another. You must erase the
* destination region prior to calling this function.
@@ -830,7 +965,7 @@
uint32_t bytes_copied;
int chunk_sz;
int rc;
-#ifdef MCUBOOT_ENC_IMAGES
+#if defined (MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_ENC_IMAGES_XIP)
uint32_t off;
uint32_t tlv_off;
size_t blk_off;
@@ -840,9 +975,20 @@
uint8_t image_index;
#endif
- TARGET_STATIC uint8_t buf[1024];
+/* NOTE:
+ * Default value 1024 is not suitable for platforms with larger erase size.
+ * Give user ability to define platform tolerant chunk size. In most cases
+ * it would be flash erase alignment.
+ */
+#ifdef MCUBOOT_PLATFORM_CHUNK_SIZE
+ #define MCUBOOT_CHUNK_SIZE MCUBOOT_PLATFORM_CHUNK_SIZE
+#else
+ #define MCUBOOT_CHUNK_SIZE 1024
+#endif
-#if !defined(MCUBOOT_ENC_IMAGES)
+ TARGET_STATIC uint8_t buf[MCUBOOT_CHUNK_SIZE] __attribute__((aligned(4)));
+
+#if !defined(MCUBOOT_ENC_IMAGES) || defined(MCUBOOT_ENC_IMAGES_XIP)
(void)state;
#endif
@@ -859,28 +1005,28 @@
return BOOT_EFLASH;
}
-#ifdef MCUBOOT_ENC_IMAGES
+#if defined(MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_ENC_IMAGES_XIP)
image_index = BOOT_CURR_IMG(state);
- if ((fap_src->fa_id == FLASH_AREA_IMAGE_PRIMARY(image_index) ||
- fap_dst->fa_id == FLASH_AREA_IMAGE_PRIMARY(image_index)) &&
+ if ((flash_area_get_id(fap_src) == FLASH_AREA_IMAGE_PRIMARY(image_index) ||
+ flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_PRIMARY(image_index)) &&
- !(fap_src->fa_id == FLASH_AREA_IMAGE_PRIMARY(image_index) &&
- fap_dst->fa_id == FLASH_AREA_IMAGE_PRIMARY(image_index)) &&
- !(fap_src->fa_id == FLASH_AREA_IMAGE_SECONDARY(image_index) &&
- fap_dst->fa_id == FLASH_AREA_IMAGE_SECONDARY(image_index)))
+ !(flash_area_get_id(fap_src) == FLASH_AREA_IMAGE_PRIMARY(image_index) &&
+ flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_PRIMARY(image_index)) &&
+ !(flash_area_get_id(fap_src) == FLASH_AREA_IMAGE_SECONDARY(image_index) &&
+ flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_SECONDARY(image_index)))
{
/* assume the primary slot as src, needs encryption */
hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT);
#if !defined(MCUBOOT_SWAP_USING_MOVE)
off = off_src;
- if (fap_dst->fa_id == FLASH_AREA_IMAGE_PRIMARY(image_index)) {
+ if (flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_PRIMARY(image_index)) {
/* might need decryption (metadata from the secondary slot) */
hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT);
off = off_dst;
}
#else
off = off_dst;
- if (fap_dst->fa_id == FLASH_AREA_IMAGE_PRIMARY(image_index)) {
+ if (flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_PRIMARY(image_index)) {
hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT);
}
#endif
@@ -909,10 +1055,11 @@
blk_sz = tlv_off - (off + bytes_copied);
}
}
- if(0 != blk_sz) {
- boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src,
- (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz,
- blk_off, &buf[idx]);
+ rc = boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src,
+ (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz,
+ blk_off, &buf[idx]);
+ if (rc != 0) {
+ return rc;
}
}
}
@@ -954,8 +1101,8 @@
size_t size;
size_t this_size;
size_t last_sector;
- const struct flash_area *fap_primary_slot;
- const struct flash_area *fap_secondary_slot;
+ const struct flash_area *fap_primary_slot = NULL;
+ const struct flash_area *fap_secondary_slot = NULL;
uint8_t image_index;
#if defined(MCUBOOT_OVERWRITE_ONLY_FAST)
@@ -987,12 +1134,9 @@
assert (rc == 0);
sect_count = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT);
- BOOT_LOG_DBG(" * primary slot sectors: %d", sect_count);
+ BOOT_LOG_DBG(" * primary slot sectors: %lu", (unsigned long)sect_count);
for (sect = 0, size = 0; sect < sect_count; sect++) {
this_size = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, sect);
- /* BOOT_LOG_DBG(" * primary slot erase region (0x%0lx / 0x%0lx): sector = %d, off = %0x, size = %d",
- fap_primary_slot->fa_off, fap_primary_slot->fa_size,
- sect, size, this_size); */
rc = boot_erase_region(fap_primary_slot, size, this_size);
assert(rc == 0);
@@ -1036,8 +1180,7 @@
}
#endif
- BOOT_LOG_INF("Copying the secondary slot to the primary slot: 0x%x bytes",
- size);
+ BOOT_LOG_INF("Copying the secondary slot to the primary slot: 0x%lx bytes", (unsigned long)size);
rc = boot_copy_region(state, fap_secondary_slot, fap_primary_slot, 0, 0, size);
if (rc != 0) {
return rc;
@@ -1050,6 +1193,12 @@
}
#endif
+ rc = BOOT_HOOK_CALL(boot_copy_region_post_hook, 0, BOOT_CURR_IMG(state),
+ BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT), size);
+ if (rc != 0) {
+ return rc;
+ }
+
#ifdef MCUBOOT_HW_ROLLBACK_PROT
/* Update the stored security counter with the new image's security counter
* value. Both slots hold the new image at this point, but the secondary
@@ -1112,12 +1261,11 @@
#ifdef MCUBOOT_ENC_IMAGES
const struct flash_area *fap;
uint8_t slot;
- uint8_t i;
#endif
uint32_t size;
uint32_t copy_size;
uint8_t image_index;
- int rc;
+ int rc = -1;
/* FIXME: just do this if asked by user? */
@@ -1148,7 +1296,8 @@
rc = 0;
}
} else {
- memset(bs->enckey[0], 0xff, BOOT_ENC_KEY_SIZE);
+ (void)memset(bs->enckey[0], BOOT_UNINITIALIZED_KEY_FILL,
+ BOOT_ENC_KEY_SIZE);
}
#endif
@@ -1172,7 +1321,8 @@
rc = 0;
}
} else {
- memset(bs->enckey[1], 0xff, BOOT_ENC_KEY_SIZE);
+ (void)memset(bs->enckey[1], BOOT_UNINITIALIZED_KEY_FILL,
+ BOOT_ENC_KEY_SIZE);
}
#endif
@@ -1194,16 +1344,14 @@
#ifdef MCUBOOT_ENC_IMAGES
for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
rc = boot_read_enc_key(image_index, slot, bs);
- assert(rc == 0);
+ assert(0 == rc);
- for (i = 0; i < BOOT_ENC_KEY_SIZE; i++) {
- if (bs->enckey[slot][i] != 0xff) {
- break;
- }
- }
-
- if (i != BOOT_ENC_KEY_SIZE) {
- boot_enc_set_key(BOOT_CURR_ENC(state), slot, bs);
+ /* Set only an initialized key */
+ if (!bootutil_buffer_is_filled(bs->enckey[slot],
+ BOOT_UNINITIALIZED_KEY_FILL,
+ BOOT_ENC_KEY_SIZE)) {
+ rc = boot_enc_set_key(BOOT_CURR_ENC(state), slot, bs);
+ assert(rc == 0);
}
}
#endif
@@ -1219,7 +1367,7 @@
}
#endif
- return 0;
+ return rc;
}
#endif
@@ -1368,7 +1516,12 @@
if (rc == 0) {
/* All dependencies've been satisfied, continue with next image. */
BOOT_CURR_IMG(state)++;
- } else if (rc == BOOT_EBADVERSION) {
+ } else {
+#if (USE_SHARED_SLOT == 1)
+ /* Disable an upgrading of this image.*/
+ BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
+ BOOT_CURR_IMG(state)++;
+#else
/* Cannot upgrade due to non-met dependencies, so disable all
* image upgrades.
*/
@@ -1377,9 +1530,7 @@
BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
}
break;
- } else {
- /* Other error happened, images are inconsistent */
- return rc;
+#endif /* (USE_SHARED_SLOT == 1) */
}
}
return rc;
@@ -1401,7 +1552,7 @@
uint8_t swap_type;
#endif
- BOOT_LOG_DBG("> boot_perform_update: bs->idx = %d", bs->idx);
+ BOOT_LOG_DBG("> boot_perform_update: bs->idx = %" PRIu32, bs->idx);
/* At this point there are no aborted swaps. */
#if defined(MCUBOOT_OVERWRITE_ONLY)
@@ -1415,6 +1566,21 @@
rc = boot_check_header_erased(state, BOOT_PRIMARY_SLOT);
FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, bs);
if (rc == 0 || fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ /* Initialize swap status partition for primary slot, because
+ * in swap mode it is needed to properly complete copying the image
+ * to the primary slot.
+ */
+ const struct flash_area *fap_primary_slot = NULL;
+
+ rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state)),
+ &fap_primary_slot);
+ assert(rc == 0);
+
+ rc = swap_status_init(state, fap_primary_slot, bs);
+ assert(rc == 0);
+
+ flash_area_close(fap_primary_slot);
+
rc = boot_copy_image(state, bs);
} else {
rc = boot_swap_image(state, bs);
@@ -1598,27 +1764,33 @@
int rc;
fih_int fih_rc = FIH_FAILURE;
- BOOT_LOG_DBG("> boot_prepare_image_for_update: image = %d", BOOT_CURR_IMG(state));
+ BOOT_LOG_DBG("> boot_prepare_image_for_update: image = %u",
+ (unsigned)BOOT_CURR_IMG(state));
/* Determine the sector layout of the image slots and scratch area. */
rc = boot_read_sectors(state);
if (rc != 0) {
- BOOT_LOG_WRN("Failed reading sectors; BOOT_MAX_IMG_SECTORS=%d"
- " - too small?", BOOT_MAX_IMG_SECTORS);
+ BOOT_LOG_WRN("Failed reading sectors; BOOT_MAX_IMG_SECTORS=%u"
+ " - too small?", (unsigned int) BOOT_MAX_IMG_SECTORS);
/* Unable to determine sector layout, continue with next image
* if there is one.
*/
BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
- return;
+ if (rc == BOOT_EFLASH)
+ {
+ /* Only return on error from the primary image flash */
+ return;
+ }
}
/* Attempt to read an image header from each slot. */
rc = boot_read_image_headers(state, false, NULL);
- BOOT_LOG_DBG(" * Read an image (%d) header from each slot: rc = %d", BOOT_CURR_IMG(state), rc);
+ BOOT_LOG_DBG(" * Read an image (%u) header from each slot: rc = %d",
+ (unsigned)BOOT_CURR_IMG(state), rc);
if (rc != 0) {
/* Continue with next image if there is one. */
BOOT_LOG_WRN("Failed reading image headers; Image=%u",
- BOOT_CURR_IMG(state));
+ (unsigned)BOOT_CURR_IMG(state));
BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
return;
}
@@ -1633,7 +1805,7 @@
rc = swap_read_status(state, bs);
if (rc != 0) {
BOOT_LOG_WRN("Failed reading boot status; Image=%u",
- BOOT_CURR_IMG(state));
+ (unsigned)BOOT_CURR_IMG(state));
/* Continue with next image if there is one. */
BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
return;
@@ -1646,7 +1818,8 @@
* have been updated in the previous function call.
*/
rc = boot_read_image_headers(state, !boot_status_is_reset(bs), bs);
- BOOT_LOG_DBG(" * re-read image(%d) headers: rc = %d.", BOOT_CURR_IMG(state), rc);
+ BOOT_LOG_DBG(" * re-read image(%u) headers: rc = %d.",
+ (unsigned)BOOT_CURR_IMG(state), rc);
#ifdef MCUBOOT_BOOTSTRAP
/* When bootstrapping it's OK to not have image magic in the primary slot */
if (rc != 0 && (BOOT_CURR_IMG(state) != BOOT_PRIMARY_SLOT ||
@@ -1748,6 +1921,50 @@
BOOT_LOG_DBG("< boot_prepare_image_for_update");
}
+/**
+ * Updates the security counter for the current image.
+ *
+ * @param state Boot loader status information.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+static int
+boot_update_hw_rollback_protection(struct boot_loader_state *state)
+{
+#ifdef MCUBOOT_HW_ROLLBACK_PROT
+ int rc;
+
+ /* Update the stored security counter with the active image's security
+ * counter value. It will only be updated if the new security counter is
+ * greater than the stored value.
+ *
+ * In case of a successful image swapping when the swap type is TEST the
+ * security counter can be increased only after a reset, when the swap
+ * type is NONE and the image has marked itself "OK" (the image_ok flag
+ * has been set). This way a "revert" can be performed when it's
+ * necessary.
+ */
+ if (BOOT_SWAP_TYPE(state) == BOOT_SWAP_TYPE_NONE) {
+ rc = boot_update_security_counter(
+ BOOT_CURR_IMG(state),
+ BOOT_PRIMARY_SLOT,
+ boot_img_hdr(state, BOOT_PRIMARY_SLOT));
+ if (rc != 0) {
+ BOOT_LOG_ERR("Security counter update failed after image "
+ "validation.");
+ return rc;
+ }
+ }
+
+ return 0;
+
+#else /* MCUBOOT_HW_ROLLBACK_PROT */
+ (void) (state);
+
+ return 0;
+#endif
+}
+
fih_int
context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
{
@@ -1773,7 +1990,8 @@
TARGET_STATIC boot_sector_t status_sectors[BOOT_MAX_SWAP_STATUS_SECTORS];
#endif
- memset(state, 0, sizeof(struct boot_loader_state));
+ (void)memset(&bs, 0, sizeof(bs));
+ (void)memset(state, 0, sizeof(struct boot_loader_state));
has_upgrade = false;
#if (BOOT_IMAGE_NUMBER == 1)
@@ -1870,7 +2088,7 @@
/* Set the previously determined swap type */
bs.swap_type = BOOT_SWAP_TYPE(state);
- BOOT_LOG_DBG(" * process swap_type = %d", bs.swap_type);
+ BOOT_LOG_DBG(" * process swap_type = %u", (unsigned)bs.swap_type);
switch (BOOT_SWAP_TYPE(state)) {
case BOOT_SWAP_TYPE_NONE:
@@ -1879,8 +2097,14 @@
case BOOT_SWAP_TYPE_TEST: /* fallthrough */
case BOOT_SWAP_TYPE_PERM: /* fallthrough */
case BOOT_SWAP_TYPE_REVERT:
- BOOT_LOG_DBG(" * perform update...", bs.swap_type);
- rc = boot_perform_update(state, &bs);
+ BOOT_LOG_DBG(" * perform update, mode %u...", (unsigned)bs.swap_type);
+ rc = BOOT_HOOK_CALL(boot_perform_update_hook, BOOT_HOOK_REGULAR,
+ BOOT_CURR_IMG(state), &(BOOT_IMG(state, 1).hdr),
+ BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT));
+ if (rc == BOOT_HOOK_REGULAR)
+ {
+ rc = boot_perform_update(state, &bs);
+ }
assert(rc == 0);
break;
@@ -1890,7 +2114,8 @@
* pretending we just reverted back to primary slot.
*/
#ifndef MCUBOOT_OVERWRITE_ONLY
- BOOT_LOG_DBG(" * update failed! Set image_ok manually for image(%d)", BOOT_CURR_IMG(state));
+ BOOT_LOG_DBG(" * update failed! Set image_ok manually for image(%u)",
+ (unsigned)BOOT_CURR_IMG(state));
/* image_ok needs to be explicitly set to avoid a new revert. */
rc = swap_set_image_ok(BOOT_CURR_IMG(state));
if (rc != 0) {
@@ -1933,7 +2158,7 @@
}
#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
- FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, NULL);
+ FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, &bs);
if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
goto out;
}
@@ -1943,57 +2168,33 @@
* the magic number on the image is OK.
*/
if (BOOT_IMG(state, BOOT_PRIMARY_SLOT).hdr.ih_magic != IMAGE_MAGIC) {
- BOOT_LOG_ERR("bad image magic 0x%lx; Image=%u", (unsigned long)
- &boot_img_hdr(state,BOOT_PRIMARY_SLOT)->ih_magic,
- BOOT_CURR_IMG(state));
+ BOOT_LOG_ERR("bad image magic 0x%" PRIx32 "; Image=%u",
+ BOOT_IMG(state, BOOT_PRIMARY_SLOT).hdr.ih_magic,
+ (unsigned)BOOT_CURR_IMG(state));
rc = BOOT_EBADIMAGE;
goto out;
}
#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */
-#ifdef MCUBOOT_HW_ROLLBACK_PROT
- /* Update the stored security counter with the active image's security
- * counter value. It will only be updated if the new security counter is
- * greater than the stored value.
- *
- * In case of a successful image swapping when the swap type is TEST the
- * security counter can be increased only after a reset, when the swap
- * type is NONE and the image has marked itself "OK" (the image_ok flag
- * has been set). This way a "revert" can be performed when it's
- * necessary.
- */
- if (BOOT_SWAP_TYPE(state) == BOOT_SWAP_TYPE_NONE) {
- rc = boot_update_security_counter(
- BOOT_CURR_IMG(state),
- BOOT_PRIMARY_SLOT,
- boot_img_hdr(state, BOOT_PRIMARY_SLOT));
- if (rc != 0) {
- BOOT_LOG_ERR("Security counter update failed after image "
- "validation.");
- goto out;
+#ifdef MCUBOOT_ENC_IMAGES_XIP
+ if (0 == BOOT_CURR_IMG(state)) {
+ if (IS_ENCRYPTED(boot_img_hdr(state, BOOT_PRIMARY_SLOT)))
+ {
+ (void)memcpy((uint8_t*)rsp->xip_iv, BOOT_CURR_ENC(state)->aes_iv, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
+ (void)memcpy((uint8_t*)rsp->xip_key, bs.enckey[BOOT_CURR_IMG(state)], BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE);
}
}
-#endif /* MCUBOOT_HW_ROLLBACK_PROT */
+#endif /* MCUBOOT_ENC_IMAGES_XIP */
-#ifdef MCUBOOT_MEASURED_BOOT
- rc = boot_save_boot_status(BOOT_CURR_IMG(state),
- boot_img_hdr(state, BOOT_PRIMARY_SLOT),
- BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT));
+ rc = boot_update_hw_rollback_protection(state);
if (rc != 0) {
- BOOT_LOG_ERR("Failed to add Image %u data to shared memory area",
- BOOT_CURR_IMG(state));
goto out;
}
-#endif /* MCUBOOT_MEASURED_BOOT */
-#ifdef MCUBOOT_DATA_SHARING
- rc = boot_save_shared_data(boot_img_hdr(state, BOOT_PRIMARY_SLOT),
- BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT));
+ rc = boot_add_shared_data(state, BOOT_PRIMARY_SLOT);
if (rc != 0) {
- BOOT_LOG_ERR("Failed to add data to shared memory area.");
goto out;
}
-#endif /* MCUBOOT_DATA_SHARING */
}
#if (BOOT_IMAGE_NUMBER > 1)
@@ -2001,27 +2202,21 @@
BOOT_CURR_IMG(state) = 0;
#endif
+ rsp->br_flash_dev_id = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)->fa_device_id;
+ rsp->br_image_off = boot_img_slot_off(state, BOOT_PRIMARY_SLOT);
+ rsp->br_hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT);
/*
* Since the boot_status struct stores plaintext encryption keys, reset
* them here to avoid the possibility of jumping into an image that could
* easily recover them.
*/
- memset(&bs, 0, sizeof(struct boot_status));
+ (void)memset(&bs, 0, sizeof(struct boot_status));
- rsp->br_flash_dev_id = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)->fa_device_id;
- rsp->br_image_off = boot_img_slot_off(state, BOOT_PRIMARY_SLOT);
- rsp->br_hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT);
+ fill_rsp(state, NULL, rsp);
fih_rc = FIH_SUCCESS;
out:
- IMAGES_ITER(BOOT_CURR_IMG(state)) {
-#if MCUBOOT_SWAP_USING_SCRATCH
- flash_area_close(BOOT_SCRATCH_AREA(state));
-#endif
- for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
- flash_area_close(BOOT_IMG_AREA(state, BOOT_NUM_SLOTS - 1 - slot));
- }
- }
+ close_all_flash_areas(state);
if (rc) {
fih_rc = fih_int_encode(rc);
@@ -2040,6 +2235,10 @@
int rc;
fih_int fih_rc = FIH_FAILURE;
+ if ((loader_slot < 0) || (split_slot < 0)) {
+ FIH_RET(FIH_FAILURE);
+ }
+
sectors = malloc(BOOT_MAX_IMG_SECTORS * 2 * sizeof *sectors);
if (sectors == NULL) {
FIH_RET(FIH_FAILURE);
@@ -2100,92 +2299,180 @@
#else /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
+#define NO_ACTIVE_SLOT UINT32_MAX
+
/**
- * Iterates over all slots and determines which contain a firmware image.
+ * Opens all flash areas and checks which contain an image with a valid header.
*
- * @param state Boot loader status information.
- * @param slot_usage Pointer to an array, which aim is to carry information
- * about slots that contain an image. After return the
- * corresponding array elements are set to a non-zero
- * value if the given slots are in use (contain a firmware
- * image), otherwise they are set to zero.
- * @param slot_cnt The number of slots, which can contain firmware images.
- * (Equal to or smaller than the size of the
- * slot_usage array.)
+ * @param state Boot loader status information.
+ * @param slot_usage Structure to fill with information about the available
+ * slots.
*
- * @return The number of found images.
+ * @return 0 on success; nonzero on failure.
+ */
+static int
+boot_get_slot_usage(struct boot_loader_state *state,
+ struct slot_usage_t slot_usage[])
+{
+ uint32_t slot;
+ int fa_id;
+ int rc;
+ struct image_header *hdr = NULL;
+
+ IMAGES_ITER(BOOT_CURR_IMG(state)) {
+ /* Open all the slots */
+ for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
+ fa_id = flash_area_id_from_multi_image_slot(
+ BOOT_CURR_IMG(state), slot);
+ rc = flash_area_open(fa_id, &BOOT_IMG_AREA(state, slot));
+ assert(rc == 0);
+ }
+
+ /* Attempt to read an image header from each slot. */
+ rc = boot_read_image_headers(state, false, NULL);
+ if (rc != 0) {
+ BOOT_LOG_WRN("Failed reading image headers.");
+ return rc;
+ }
+
+ /* Check headers in all slots */
+ for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
+ hdr = boot_img_hdr(state, slot);
+
+ if (boot_is_header_valid(hdr, BOOT_IMG_AREA(state, slot))) {
+ slot_usage[BOOT_CURR_IMG(state)].slot_available[slot] = true;
+ BOOT_LOG_IMAGE_INFO(slot, hdr);
+ } else {
+ slot_usage[BOOT_CURR_IMG(state)].slot_available[slot] = false;
+ BOOT_LOG_INF("Image %u %s slot: Image not found",
+ (unsigned)BOOT_CURR_IMG(state),
+ (slot == BOOT_PRIMARY_SLOT)
+ ? "Primary" : "Secondary");
+ }
+ }
+
+ slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
+ }
+
+ return 0;
+}
+
+/**
+ * Finds the slot containing the image with the highest version number for the
+ * current image.
+ *
+ * @param state Boot loader status information.
+ * @param slot_usage Information about the active and available slots.
+ *
+ * @return NO_ACTIVE_SLOT if no available slot found, number of
+ * the found slot otherwise.
*/
static uint32_t
-boot_get_slot_usage(struct boot_loader_state *state, uint8_t slot_usage[],
- uint32_t slot_cnt)
+find_slot_with_highest_version(struct boot_loader_state *state,
+ struct slot_usage_t slot_usage[])
{
- struct image_header *hdr = NULL;
- uint32_t image_cnt = 0;
uint32_t slot;
+ uint32_t candidate_slot = NO_ACTIVE_SLOT;
+ int rc;
- memset(slot_usage, 0, slot_cnt);
-
- for (slot = 0; slot < slot_cnt; slot++) {
- hdr = boot_img_hdr(state, slot);
-
- if (boot_is_header_valid(hdr, BOOT_IMG_AREA(state, slot))) {
- slot_usage[slot] = 1;
- image_cnt++;
- BOOT_LOG_IMAGE_INFO(slot, hdr);
- } else {
- BOOT_LOG_INF("%s slot: Image not found", (slot == BOOT_PRIMARY_SLOT)
- ? "Primary" : "Secondary");
+ for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
+ if (slot_usage[BOOT_CURR_IMG(state)].slot_available[slot]) {
+ if (candidate_slot == NO_ACTIVE_SLOT) {
+ candidate_slot = slot;
+ } else {
+ rc = boot_version_cmp(
+ &boot_img_hdr(state, slot)->ih_ver,
+ &boot_img_hdr(state, candidate_slot)->ih_ver);
+ if (rc == 1) {
+ /* The version of the image being examined is greater than
+ * the version of the current candidate.
+ */
+ candidate_slot = slot;
+ }
+ }
}
}
- return image_cnt;
+ return candidate_slot;
}
-#ifdef MCUBOOT_DIRECT_XIP_REVERT
+#ifdef MCUBOOT_HAVE_LOGGING
/**
- * Checks whether the image in the given slot was previously selected to run.
- * Erases the image if it was selected but its execution failed, otherwise marks
- * it as selected if it has not been before.
+ * Prints the state of the loaded images.
*
- * @param state Image metadata from the image trailer. This function fills
- * this struct with the data read from the image trailer.
- * @param slot Image slot number.
+ * @param state Boot loader status information.
+ * @param slot_usage Information about the active and available slots.
+ */
+static void
+print_loaded_images(struct boot_loader_state *state,
+ struct slot_usage_t slot_usage[])
+{
+ uint32_t active_slot;
+
+ (void)state;
+
+ IMAGES_ITER(BOOT_CURR_IMG(state)) {
+ active_slot = slot_usage[BOOT_CURR_IMG(state)].active_slot;
+
+ BOOT_LOG_INF("Image %u loaded from the %s slot",
+ (unsigned)BOOT_CURR_IMG(state),
+ (active_slot == BOOT_PRIMARY_SLOT) ?
+ "primary" : "secondary");
+ }
+}
+#endif
+
+#if defined(MCUBOOT_DIRECT_XIP) && defined(MCUBOOT_DIRECT_XIP_REVERT)
+/**
+ * Checks whether the active slot of the current image was previously selected
+ * to run. Erases the image if it was selected but its execution failed,
+ * otherwise marks it as selected if it has not been before.
*
- * @return 0 on success; nonzero on failure.
+ * @param state Boot loader status information.
+ * @param slot_usage Information about the active and available slots.
+ *
+ * @return 0 on success; nonzero on failure.
*/
static int
-boot_select_or_erase(struct boot_swap_state *state, uint32_t slot)
+boot_select_or_erase(struct boot_loader_state *state,
+ struct slot_usage_t slot_usage[])
{
const struct flash_area *fap;
int fa_id;
int rc;
+ uint32_t active_slot;
+ struct boot_swap_state* active_swap_state;
- fa_id = flash_area_id_from_image_slot(slot);
+ active_slot = slot_usage[BOOT_CURR_IMG(state)].active_slot;
+
+ fa_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), active_slot);
rc = flash_area_open(fa_id, &fap);
assert(rc == 0);
- memset(state, 0, sizeof(struct boot_swap_state));
- rc = boot_read_swap_state(fap, state);
+ active_swap_state = &(slot_usage[BOOT_CURR_IMG(state)].swap_state);
+
+ (void)memset(active_swap_state, 0, sizeof(struct boot_swap_state));
+ rc = boot_read_swap_state(fap, active_swap_state);
assert(rc == 0);
- if (state->magic != BOOT_MAGIC_GOOD ||
- (state->copy_done == BOOT_FLAG_SET &&
- state->image_ok != BOOT_FLAG_SET)) {
+ if (active_swap_state->magic != BOOT_MAGIC_GOOD ||
+ (active_swap_state->copy_done == BOOT_FLAG_SET &&
+ active_swap_state->image_ok != BOOT_FLAG_SET)) {
/*
* A reboot happened without the image being confirmed at
* runtime or its trailer is corrupted/invalid. Erase the image
* to prevent it from being selected again on the next reboot.
*/
BOOT_LOG_DBG("Erasing faulty image in the %s slot.",
- (slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary");
- rc = flash_area_erase(fap, 0, fap->fa_size);
+ (active_slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary");
+ rc = flash_area_erase(fap, 0, flash_area_get_size(fap));
assert(rc == 0);
flash_area_close(fap);
rc = -1;
} else {
- if (state->copy_done != BOOT_FLAG_SET) {
- if (state->copy_done == BOOT_FLAG_BAD) {
+ if (active_swap_state->copy_done != BOOT_FLAG_SET) {
+ if (active_swap_state->copy_done == BOOT_FLAG_BAD) {
BOOT_LOG_DBG("The copy_done flag had an unexpected value. Its "
"value was neither 'set' nor 'unset', but 'bad'.");
}
@@ -2198,7 +2485,7 @@
rc = boot_write_copy_done(fap);
if (rc != 0) {
BOOT_LOG_WRN("Failed to set copy_done flag of the image in "
- "the %s slot.", (slot == BOOT_PRIMARY_SLOT) ?
+ "the %s slot.", (active_slot == BOOT_PRIMARY_SLOT) ?
"primary" : "secondary");
rc = 0;
}
@@ -2208,29 +2495,54 @@
return rc;
}
-#endif /* MCUBOOT_DIRECT_XIP_REVERT */
+#endif /* MCUBOOT_DIRECT_XIP && MCUBOOT_DIRECT_XIP_REVERT */
#ifdef MCUBOOT_RAM_LOAD
+#ifndef MULTIPLE_EXECUTABLE_RAM_REGIONS
#if !defined(IMAGE_EXECUTABLE_RAM_START) || !defined(IMAGE_EXECUTABLE_RAM_SIZE)
#error "Platform MUST define executable RAM bounds in case of RAM_LOAD"
#endif
+#endif
/**
- * Verifies that the image in a slot will be loaded within the predefined bounds
- * that are allowed to be used by executable images.
+ * Verifies that the active slot of the current image can be loaded within the
+ * predefined bounds that are allowed to be used by executable images.
*
- * @param img_dst The address to which the image is going to be copied.
- * @param img_sz The size of the image.
+ * @param state Boot loader status information.
+ * @param slot_usage Information about the active and available slots.
*
- * @return 0 on success; nonzero on failure.
+ * @return 0 on success; nonzero on failure.
*/
static int
-boot_verify_ram_load_address(uint32_t img_dst, uint32_t img_sz)
+boot_verify_ram_load_address(struct boot_loader_state *state,
+ struct slot_usage_t slot_usage[])
{
+ uint32_t img_dst;
+ uint32_t img_sz;
uint32_t img_end_addr;
+ uint32_t exec_ram_start;
+ uint32_t exec_ram_size;
- if (img_dst < IMAGE_EXECUTABLE_RAM_START) {
+ (void)state;
+
+#ifdef MULTIPLE_EXECUTABLE_RAM_REGIONS
+ int rc;
+
+ rc = boot_get_image_exec_ram_info(BOOT_CURR_IMG(state), &exec_ram_start,
+ &exec_ram_size);
+ if (rc != 0) {
+ return BOOT_EBADSTATUS;
+ }
+#else
+ exec_ram_start = IMAGE_EXECUTABLE_RAM_START;
+ exec_ram_size = IMAGE_EXECUTABLE_RAM_SIZE;
+#endif
+
+ img_dst = slot_usage[BOOT_CURR_IMG(state)].img_dst;
+ img_sz = slot_usage[BOOT_CURR_IMG(state)].img_sz;
+
+ if (img_dst < exec_ram_start) {
return BOOT_EBADIMAGE;
}
@@ -2238,17 +2550,121 @@
return BOOT_EBADIMAGE;
}
- if (img_end_addr > (IMAGE_EXECUTABLE_RAM_START +
- IMAGE_EXECUTABLE_RAM_SIZE)) {
+ if (img_end_addr > (exec_ram_start + exec_ram_size)) {
return BOOT_EBADIMAGE;
}
return 0;
}
+#ifdef MCUBOOT_ENC_IMAGES
+
/**
- * Copies an image from a slot in the flash to an SRAM address.
+ * Copies and decrypts an image from a slot in the flash to an SRAM address.
*
+ * @param state Boot loader status information.
+ * @param slot The flash slot of the image to be copied to SRAM.
+ * @param hdr The image header.
+ * @param src_sz Size of the image.
+ * @param img_dst Pointer to the address at which the image needs to be
+ * copied to SRAM.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+static int
+boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state,
+ uint32_t slot, struct image_header *hdr,
+ uint32_t src_sz, uint32_t img_dst)
+{
+ /* The flow for the decryption and copy of the image is as follows :
+ * 1. The whole image is copied to the RAM (header + payload + TLV).
+ * 2. The encryption key is loaded from the TLV in flash.
+ * 3. The image is then decrypted chunk by chunk in RAM (1 chunk
+ * is 1024 bytes). Only the payload section is decrypted.
+ * 4. The image is authenticated in RAM.
+ */
+ const struct flash_area *fap_src = NULL;
+ struct boot_status bs;
+ uint32_t blk_off;
+ uint32_t tlv_off;
+ uint32_t blk_sz;
+ uint32_t bytes_copied = hdr->ih_hdr_size;
+ uint32_t chunk_sz;
+ uint32_t max_sz = 1024;
+ uint16_t idx;
+ uint8_t image_index;
+ uint8_t * cur_dst;
+ int area_id;
+ int rc;
+ uint8_t * ram_dst = (void *)(IMAGE_RAM_BASE + img_dst);
+
+ image_index = BOOT_CURR_IMG(state);
+ area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot);
+ rc = flash_area_open(area_id, &fap_src);
+ if (rc != 0){
+ return BOOT_EFLASH;
+ }
+
+ tlv_off = BOOT_TLV_OFF(hdr);
+
+ /* Copying the whole image in RAM */
+ rc = flash_area_read(fap_src, 0, ram_dst, src_sz);
+ if (rc != 0) {
+ goto done;
+ }
+
+ rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap_src, &bs);
+ if (rc < 0) {
+ goto done;
+ }
+
+ /* if rc > 0 then the key has already been loaded */
+ if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), slot, &bs)) {
+ goto done;
+ }
+
+ /* Starting at the end of the header as the header section is not encrypted */
+ while (bytes_copied < tlv_off) { /* TLV section copied previously */
+ if (src_sz - bytes_copied > max_sz) {
+ chunk_sz = max_sz;
+ } else {
+ chunk_sz = src_sz - bytes_copied;
+ }
+
+ cur_dst = ram_dst + bytes_copied;
+ blk_sz = chunk_sz;
+ idx = 0;
+ if (bytes_copied + chunk_sz > tlv_off) {
+ /* Going over TLV section
+ * Part of the chunk is encrypted payload */
+ blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf;
+ blk_sz = tlv_off - (bytes_copied);
+ boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src,
+ (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz,
+ blk_off, cur_dst);
+ } else {
+ /* Image encrypted payload section */
+ blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf;
+ boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src,
+ (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz,
+ blk_off, cur_dst);
+ }
+
+ bytes_copied += chunk_sz;
+ }
+ rc = 0;
+
+done:
+ flash_area_close(fap_src);
+
+ return rc;
+}
+
+#endif /* MCUBOOT_ENC_IMAGES */
+/**
+ * Copies a slot of the current image into SRAM.
+ *
+ * @param state Boot loader status information.
* @param slot The flash slot of the image to be copied to SRAM.
* @param img_dst The address at which the image needs to be copied to
* SRAM.
@@ -2257,18 +2673,26 @@
* @return 0 on success; nonzero on failure.
*/
static int
-boot_copy_image_to_sram(int slot, uint32_t img_dst, uint32_t img_sz)
+boot_copy_image_to_sram(struct boot_loader_state *state, int slot,
+ uint32_t img_dst, uint32_t img_sz)
{
int rc;
const struct flash_area *fap_src = NULL;
+ int area_id;
- rc = flash_area_open(flash_area_id_from_image_slot(slot), &fap_src);
+#if (BOOT_IMAGE_NUMBER == 1)
+ (void)state;
+#endif
+
+ area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot);
+
+ rc = flash_area_open(area_id, &fap_src);
if (rc != 0) {
return BOOT_EFLASH;
}
/* Direct copy from flash to its new location in SRAM. */
- rc = flash_area_read(fap_src, 0, (void *)img_dst, img_sz);
+ rc = flash_area_read(fap_src, 0, (void *)(IMAGE_RAM_BASE + img_dst), img_sz);
if (rc != 0) {
BOOT_LOG_INF("Error whilst copying image from Flash to SRAM: %d", rc);
}
@@ -2278,50 +2702,142 @@
return rc;
}
+#if (BOOT_IMAGE_NUMBER > 1)
/**
- * Copies an image from a slot in the flash to an SRAM address. The load
- * address and image size is extracted from the image header.
+ * Checks if two memory regions (A and B) are overlap or not.
*
- * @param state Boot loader status information.
- * @param slot The flash slot of the image to be copied to SRAM.
- * @param hdr Pointer to the image header structure of the image
- * @param img_dst Pointer to the address at which the image needs to be
- * copied to SRAM.
- * @param img_sz Pointer to the size of the image that needs to be
- * copied to SRAM.
+ * @param start_a Start of the A region.
+ * @param end_a End of the A region.
+ * @param start_b Start of the B region.
+ * @param end_b End of the B region.
*
- * @return 0 on success; nonzero on failure.
+ * @return true if there is overlap; false otherwise.
+ */
+static bool
+do_regions_overlap(uint32_t start_a, uint32_t end_a,
+ uint32_t start_b, uint32_t end_b)
+{
+ if (start_b > end_a) {
+ return false;
+ } else if (start_b >= start_a) {
+ return true;
+ } else if (end_b > start_a) {
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Checks if the image we want to load to memory overlap with an already
+ * ramloaded image.
+ *
+ * @param slot_usage Information about the active and available slots.
+ * @param image_id_to_check The ID of the image we would like to load.
+ *
+ * @return 0 if there is no overlap; nonzero otherwise.
*/
static int
-boot_load_image_to_sram(struct boot_loader_state *state, uint32_t slot,
- struct image_header *hdr, uint32_t *img_dst,
- uint32_t *img_sz)
+boot_check_ram_load_overlapping(struct slot_usage_t slot_usage[],
+ uint32_t image_id_to_check)
{
+ uint32_t i;
+
+ uint32_t start_a;
+ uint32_t end_a;
+ uint32_t start_b;
+ uint32_t end_b;
+
+ start_a = slot_usage[image_id_to_check].img_dst;
+ /* Safe to add here, values are already verified in
+ * boot_verify_ram_load_address() */
+ end_a = start_a + slot_usage[image_id_to_check].img_sz;
+
+ for (i = 0; i < BOOT_IMAGE_NUMBER; i++) {
+ if (slot_usage[i].active_slot == NO_ACTIVE_SLOT
+ || i == image_id_to_check) {
+ continue;
+ }
+
+ start_b = slot_usage[i].img_dst;
+ /* Safe to add here, values are already verified in
+ * boot_verify_ram_load_address() */
+ end_b = start_b + slot_usage[i].img_sz;
+
+ if (do_regions_overlap(start_a, end_a, start_b, end_b)) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+#endif
+
+/**
+ * Loads the active slot of the current image into SRAM. The load address and
+ * image size is extracted from the image header.
+ *
+ * @param state Boot loader status information.
+ * @param slot_usage Information about the active and available slots.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+static int
+boot_load_image_to_sram(struct boot_loader_state *state,
+ struct slot_usage_t slot_usage[])
+{
+ uint32_t active_slot;
+ struct image_header *hdr = NULL;
+ uint32_t img_dst;
+ uint32_t img_sz;
int rc;
+ active_slot = slot_usage[BOOT_CURR_IMG(state)].active_slot;
+ hdr = boot_img_hdr(state, active_slot);
+
if (hdr->ih_flags & IMAGE_F_RAM_LOAD) {
- *img_dst = hdr->ih_load_addr;
+ img_dst = hdr->ih_load_addr;
- rc = boot_read_image_size(state, slot, img_sz);
+ rc = boot_read_image_size(state, active_slot, &img_sz);
if (rc != 0) {
return rc;
}
- rc = boot_verify_ram_load_address(*img_dst, *img_sz);
+ slot_usage[BOOT_CURR_IMG(state)].img_dst = img_dst;
+ slot_usage[BOOT_CURR_IMG(state)].img_sz = img_sz;
+
+ rc = boot_verify_ram_load_address(state, slot_usage);
if (rc != 0) {
- BOOT_LOG_INF("Image RAM load address 0x%x is invalid.", *img_dst);
+ BOOT_LOG_INF("Image RAM load address 0x%" PRIx32 " is invalid.", img_dst);
return rc;
}
+#if (BOOT_IMAGE_NUMBER > 1)
+ rc = boot_check_ram_load_overlapping(slot_usage, BOOT_CURR_IMG(state));
+ if (rc != 0) {
+ BOOT_LOG_INF("Image RAM loading to address 0x%" PRIx32
+ " would overlap with another image.", img_dst);
+ return rc;
+ }
+#endif
+#ifdef MCUBOOT_ENC_IMAGES
+ /* decrypt image if encrypted and copy it to RAM */
+ if (IS_ENCRYPTED(hdr)) {
+ rc = boot_decrypt_and_copy_image_to_sram(state, active_slot, hdr, img_sz, img_dst);
+ } else {
+ rc = boot_copy_image_to_sram(state, active_slot, img_dst, img_sz);
+ }
+#else
/* Copy image to the load address from where it currently resides in
* flash.
*/
- rc = boot_copy_image_to_sram(slot, *img_dst, *img_sz);
+ rc = boot_copy_image_to_sram(state, active_slot, img_dst, img_sz);
+#endif
if (rc != 0) {
- BOOT_LOG_INF("RAM loading to 0x%x is failed.", *img_dst);
+ BOOT_LOG_INF("RAM loading to 0x%" PRIx32 " is failed.", img_dst);
} else {
- BOOT_LOG_INF("RAM loading to 0x%x is succeeded.", *img_dst);
+ BOOT_LOG_INF("RAM loading to 0x%" PRIx32 " is succeeded.", img_dst);
}
} else {
/* Only images that support IMAGE_F_RAM_LOAD are allowed if
@@ -2330,114 +2846,277 @@
rc = BOOT_EBADIMAGE;
}
+ if (rc != 0) {
+ slot_usage[BOOT_CURR_IMG(state)].img_dst = 0;
+ slot_usage[BOOT_CURR_IMG(state)].img_sz = 0;
+ }
+
return rc;
}
/**
* Removes an image from SRAM, by overwriting it with zeros.
*
- * @param img_dst The address of the image that needs to be removed from
- * SRAM.
- * @param img_sz The size of the image that needs to be removed from
- * SRAM.
+ * @param state Boot loader status information.
+ * @param slot_usage Information about the active and available slots.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+static inline int
+boot_remove_image_from_sram(struct boot_loader_state *state,
+ struct slot_usage_t slot_usage[])
+{
+ (void)state;
+
+ BOOT_LOG_INF("Removing image from SRAM at address 0x%" PRIx32,
+ slot_usage[BOOT_CURR_IMG(state)].img_dst);
+
+ memset((void*)(IMAGE_RAM_BASE + slot_usage[BOOT_CURR_IMG(state)].img_dst),
+ 0, slot_usage[BOOT_CURR_IMG(state)].img_sz);
+
+ slot_usage[BOOT_CURR_IMG(state)].img_dst = 0;
+ slot_usage[BOOT_CURR_IMG(state)].img_sz = 0;
+
+ return 0;
+}
+
+/**
+ * Removes an image from flash by erasing the corresponding flash area
+ *
+ * @param state Boot loader status information.
+ * @param slot The flash slot of the image to be erased.
*
* @return 0 on success; nonzero on failure.
*/
static inline int
-boot_remove_image_from_sram(uint32_t img_dst, uint32_t img_sz)
+boot_remove_image_from_flash(struct boot_loader_state *state, uint32_t slot)
{
- BOOT_LOG_INF("Removing image from SRAM at address 0x%x", img_dst);
- memset((void*)img_dst, 0, img_sz);
+ int area_id;
+ int rc;
+ const struct flash_area *fap;
- return 0;
+ (void)state;
+
+ BOOT_LOG_INF("Removing image %u slot %" PRIu32 " from flash",
+ (unsigned)BOOT_CURR_IMG(state), slot);
+ area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot);
+ rc = flash_area_open(area_id, &fap);
+ if (rc == 0) {
+ flash_area_erase(fap, 0, flash_area_get_size(fap));
+ }
+
+ return rc;
}
#endif /* MCUBOOT_RAM_LOAD */
-fih_int
-context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
+#if (BOOT_IMAGE_NUMBER > 1)
+/**
+ * Checks the image dependency whether it is satisfied.
+ *
+ * @param state Boot loader status information.
+ * @param slot_usage Information about the active and available slots.
+ * @param dep Image dependency which has to be verified.
+ *
+ * @return 0 if dependencies are met; nonzero otherwise.
+ */
+static int
+boot_verify_slot_dependency(struct boot_loader_state *state,
+ struct slot_usage_t slot_usage[],
+ struct image_dependency *dep)
{
- struct image_header *hdr = NULL;
- struct image_header *selected_image_header = NULL;
- uint8_t slot_usage[BOOT_NUM_SLOTS];
- uint32_t selected_slot;
- uint32_t slot;
- uint32_t img_cnt;
- uint32_t i;
- int fa_id;
+ struct image_version *dep_version;
+ uint32_t dep_slot;
int rc;
-#ifdef MCUBOOT_RAM_LOAD
- uint32_t img_dst;
- uint32_t img_sz;
- uint32_t img_loaded = 0;
-#endif /* MCUBOOT_RAM_LOAD */
-#ifdef MCUBOOT_DIRECT_XIP_REVERT
- struct boot_swap_state slot_state;
-#endif /* MCUBOOT_DIRECT_XIP_REVERT */
- fih_int fih_rc = FIH_FAILURE;
- memset(state, 0, sizeof(struct boot_loader_state));
-
- /* Open primary and secondary image areas for the duration
- * of this call.
+ /* Determine the source of the image which is the subject of
+ * the dependency and get it's version.
*/
- for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
- fa_id = flash_area_id_from_image_slot(slot);
- rc = flash_area_open(fa_id, &BOOT_IMG_AREA(state, slot));
- assert(rc == 0);
+ dep_slot = slot_usage[dep->image_id].active_slot;
+ dep_version = &state->imgs[dep->image_id][dep_slot].hdr.ih_ver;
+
+ rc = boot_version_cmp(dep_version, &dep->image_min_version);
+ if (rc >= 0) {
+ /* Dependency satisfied. */
+ rc = 0;
}
- /* Attempt to read an image header from each slot. */
- rc = boot_read_image_headers(state, false, NULL);
+ return rc;
+}
+
+/**
+ * Reads all dependency TLVs of an image and verifies one after another to see
+ * if they are all satisfied.
+ *
+ * @param state Boot loader status information.
+ * @param slot_usage Information about the active and available slots.
+ *
+ * @return 0 if dependencies are met; nonzero otherwise.
+ */
+static int
+boot_verify_slot_dependencies(struct boot_loader_state *state,
+ struct slot_usage_t slot_usage[])
+{
+ uint32_t active_slot;
+ const struct flash_area *fap;
+ struct image_tlv_iter it;
+ struct image_dependency dep;
+ uint32_t off;
+ uint16_t len;
+ int area_id;
+ int rc;
+
+ active_slot = slot_usage[BOOT_CURR_IMG(state)].active_slot;
+
+ area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state),
+ active_slot);
+ rc = flash_area_open(area_id, &fap);
if (rc != 0) {
- BOOT_LOG_WRN("Failed reading image headers.");
- goto out;
+ rc = BOOT_EFLASH;
+ goto done;
}
- img_cnt = boot_get_slot_usage(state, slot_usage,
- sizeof(slot_usage)/sizeof(slot_usage[0]));
+ rc = bootutil_tlv_iter_begin(&it, boot_img_hdr(state, active_slot), fap,
+ IMAGE_TLV_DEPENDENCY, true);
+ if (rc != 0) {
+ goto done;
+ }
- if (img_cnt) {
- /* Select the newest and valid image. */
- for (i = 0; i < img_cnt; i++) {
- selected_slot = 0;
+ while (true) {
+ rc = bootutil_tlv_iter_next(&it, &off, &len, NULL);
+ if (rc < 0) {
+ return -1;
+ } else if (rc > 0) {
+ rc = 0;
+ break;
+ }
- /* Iterate over all the slots that are in use (contain an image)
- * and select the one that holds the newest image.
- */
- for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
- if (slot_usage[slot]) {
- hdr = boot_img_hdr(state, slot);
- if (selected_image_header != NULL) {
- rc = boot_version_cmp(&hdr->ih_ver,
- &selected_image_header->ih_ver);
- if (rc < 1) {
- /* The version of the image being examined wasn't
- * greater than the currently selected image's
- * version.
- */
- continue;
- }
- }
- /* Check if image has IMAGE_F_ROM_FIXED flag set and
- * is in proper slot.
- */
- if (boot_rom_address_check(state, slot) != 0) {
- continue;
- }
- selected_slot = slot;
- selected_image_header = hdr;
- }
+ if (len != sizeof(dep)) {
+ rc = BOOT_EBADIMAGE;
+ goto done;
+ }
+
+ rc = LOAD_IMAGE_DATA(boot_img_hdr(state, active_slot),
+ fap, off, &dep, len);
+ if (rc != 0) {
+ rc = BOOT_EFLASH;
+ goto done;
+ }
+
+ if (dep.image_id >= BOOT_IMAGE_NUMBER) {
+ rc = BOOT_EBADARGS;
+ goto done;
+ }
+
+ rc = boot_verify_slot_dependency(state, slot_usage, &dep);
+ if (rc != 0) {
+ /* Dependency not satisfied. */
+ goto done;
+ }
+ }
+
+done:
+ flash_area_close(fap);
+ return rc;
+}
+
+/**
+ * Checks the dependency of all the active slots. If an image found with
+ * invalid or not satisfied dependencies the image is removed from SRAM (in
+ * case of MCUBOOT_RAM_LOAD strategy) and its slot is set to unavailable.
+ *
+ * @param state Boot loader status information.
+ * @param slot_usage Information about the active and available slots.
+ *
+ * @return 0 if dependencies are met; nonzero otherwise.
+ */
+static int
+boot_verify_dependencies(struct boot_loader_state *state,
+ struct slot_usage_t slot_usage[])
+{
+ int rc = -1;
+ uint32_t active_slot;
+
+ IMAGES_ITER(BOOT_CURR_IMG(state)) {
+ rc = boot_verify_slot_dependencies(state, slot_usage);
+ if (rc != 0) {
+ /* Dependencies not met or invalid dependencies. */
+
+#ifdef MCUBOOT_RAM_LOAD
+ boot_remove_image_from_sram(state, slot_usage);
+#endif /* MCUBOOT_RAM_LOAD */
+
+ active_slot = slot_usage[BOOT_CURR_IMG(state)].active_slot;
+ slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
+ slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
+
+ return rc;
+ }
+ }
+
+ return rc;
+}
+#endif /* (BOOT_IMAGE_NUMBER > 1) */
+
+/**
+ * Tries to load a slot for all the images with validation.
+ *
+ * @param state Boot loader status information.
+ * @param slot_usage Information about the active and available slots.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+fih_int
+boot_load_and_validate_images(struct boot_loader_state *state,
+ struct slot_usage_t slot_usage[])
+{
+ uint32_t active_slot;
+ int rc;
+ fih_int fih_rc;
+
+ /* Go over all the images and try to load one */
+ IMAGES_ITER(BOOT_CURR_IMG(state)) {
+ /* All slots tried until a valid image found. Breaking from this loop
+ * means that a valid image found or already loaded. If no slot is
+ * found the function returns with error code. */
+ while (true) {
+
+ /* Go over all the slots and try to load one */
+ active_slot = slot_usage[BOOT_CURR_IMG(state)].active_slot;
+ if (active_slot != NO_ACTIVE_SLOT){
+ /* A slot is already active, go to next image. */
+ break;
+ }
+
+ active_slot = find_slot_with_highest_version(state,
+ slot_usage);
+ if (active_slot == NO_ACTIVE_SLOT) {
+ BOOT_LOG_INF("No slot to load for image %u",
+ (unsigned)BOOT_CURR_IMG(state));
+ FIH_RET(FIH_FAILURE);
+ }
+
+ /* Save the number of the active slot. */
+ slot_usage[BOOT_CURR_IMG(state)].active_slot = active_slot;
+
+#ifdef MCUBOOT_DIRECT_XIP
+ rc = boot_rom_address_check(state, slot_usage);
+ if (rc != 0) {
+ /* The image is placed in an unsuitable slot. */
+ slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
+ slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
+ continue;
}
#ifdef MCUBOOT_DIRECT_XIP_REVERT
- rc = boot_select_or_erase(&slot_state, selected_slot);
+ rc = boot_select_or_erase(state, slot_usage);
if (rc != 0) {
/* The selected image slot has been erased. */
- slot_usage[selected_slot] = 0;
- selected_image_header = NULL;
+ slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
+ slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
continue;
}
#endif /* MCUBOOT_DIRECT_XIP_REVERT */
+#endif /* MCUBOOT_DIRECT_XIP */
#ifdef MCUBOOT_RAM_LOAD
/* Image is first loaded to RAM and authenticated there in order to
@@ -2445,111 +3124,146 @@
* when loading images from external (untrusted) flash to internal
* (trusted) RAM and image is authenticated before copying.
*/
- rc = boot_load_image_to_sram(state, selected_slot,
- selected_image_header, &img_dst,
- &img_sz);
+ rc = boot_load_image_to_sram(state, slot_usage);
if (rc != 0 ) {
- /* Image loading failed try the next one. */
- slot_usage[selected_slot] = 0;
- selected_image_header = NULL;
+ /* Image cannot be ramloaded. */
+ boot_remove_image_from_flash(state, active_slot);
+ slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
+ slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
continue;
- } else {
- img_loaded = 1;
}
#endif /* MCUBOOT_RAM_LOAD */
- FIH_CALL(boot_validate_slot, fih_rc, state, selected_slot, NULL);
- if (fih_eq(fih_rc, FIH_SUCCESS)) {
- /* If a valid image is found then there is no reason to check
- * the rest of the images, as each of them has a smaller version
- * number.
- */
- break;
- }
+
+ FIH_CALL(boot_validate_slot, fih_rc, state, active_slot, NULL);
+ if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ /* Image is invalid. */
#ifdef MCUBOOT_RAM_LOAD
- else if (img_loaded) {
- /* If an image is found to be invalid then it is removed from
- * RAM to prevent it being a shellcode vector.
- */
- boot_remove_image_from_sram(img_dst, img_sz);
- img_loaded = 0;
- }
+ boot_remove_image_from_sram(state, slot_usage);
#endif /* MCUBOOT_RAM_LOAD */
- /* The selected image is invalid, mark its slot as "unused"
- * and start over.
- */
- slot_usage[selected_slot] = 0;
- selected_image_header = NULL;
- }
-
- if (fih_not_eq(fih_rc, FIH_SUCCESS) || (selected_image_header == NULL)) {
- /* If there was no valid image at all */
- goto out;
- }
-
-#ifdef MCUBOOT_HW_ROLLBACK_PROT
- /* Update the stored security counter with the newer (active) image's
- * security counter value.
- */
-#ifdef MCUBOOT_DIRECT_XIP_REVERT
- /* When the 'revert' mechanism is enabled in direct-xip mode, the
- * security counter can be increased only after reboot, if the image
- * has been confirmed at runtime (the image_ok flag has been set).
- * This way a 'revert' can be performed when it's necessary.
- */
- if (slot_state.image_ok == BOOT_FLAG_SET) {
-#endif
- rc = boot_update_security_counter(0, selected_slot,
- selected_image_header);
- if (rc != 0) {
- BOOT_LOG_ERR("Security counter update failed after image "
- "validation.");
- goto out;
+ slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
+ slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
+ continue;
}
-#ifdef MCUBOOT_DIRECT_XIP_REVERT
+
+ /* Valid image loaded from a slot, go to next image. */
+ break;
}
+ }
+
+ FIH_RET(FIH_SUCCESS);
+}
+
+/**
+ * Updates the security counter for the current image.
+ *
+ * @param state Boot loader status information.
+ * @param slot_usage Information about the active and available slots.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+static int
+boot_update_hw_rollback_protection(struct boot_loader_state *state,
+ const struct slot_usage_t slot_usage[])
+{
+#ifdef MCUBOOT_HW_ROLLBACK_PROT
+ int rc;
+
+ /* Update the stored security counter with the newer (active) image's
+ * security counter value.
+ */
+#if defined(MCUBOOT_DIRECT_XIP) && defined(MCUBOOT_DIRECT_XIP_REVERT)
+ /* When the 'revert' mechanism is enabled in direct-xip mode, the
+ * security counter can be increased only after reboot, if the image
+ * has been confirmed at runtime (the image_ok flag has been set).
+ * This way a 'revert' can be performed when it's necessary.
+ */
+ if (slot_usage[BOOT_CURR_IMG(state)].swap_state.image_ok == BOOT_FLAG_SET) {
#endif
-#endif /* MCUBOOT_HW_ROLLBACK_PROT */
-
-#ifdef MCUBOOT_MEASURED_BOOT
- rc = boot_save_boot_status(0, selected_image_header,
- BOOT_IMG_AREA(state, selected_slot));
+ rc = boot_update_security_counter(BOOT_CURR_IMG(state),
+ slot_usage[BOOT_CURR_IMG(state)].active_slot,
+ boot_img_hdr(state, slot_usage[BOOT_CURR_IMG(state)].active_slot));
if (rc != 0) {
- BOOT_LOG_ERR("Failed to add image data to shared area");
+ BOOT_LOG_ERR("Security counter update failed after image "
+ "validation.");
+ return rc;
}
-#endif /* MCUBOOT_MEASURED_BOOT */
+#if defined(MCUBOOT_DIRECT_XIP) && defined(MCUBOOT_DIRECT_XIP_REVERT)
+ }
+#endif
-#ifdef MCUBOOT_DATA_SHARING
- rc = boot_save_shared_data(selected_image_header,
- BOOT_IMG_AREA(state, selected_slot));
- if (rc != 0) {
- BOOT_LOG_ERR("Failed to add data to shared memory area.");
- }
-#endif /* MCUBOOT_DATA_SHARING */
+ return 0;
- BOOT_LOG_INF("Booting image from the %s slot",
- (selected_slot == BOOT_PRIMARY_SLOT) ?
- "primary" : "secondary");
+#else /* MCUBOOT_HW_ROLLBACK_PROT */
+ (void) (state);
+ (void) (slot_usage);
+ return 0;
+#endif
+}
- rsp->br_flash_dev_id =
- BOOT_IMG_AREA(state, selected_slot)->fa_device_id;
- rsp->br_image_off = boot_img_slot_off(state, selected_slot);
- rsp->br_hdr = selected_image_header;
- } else {
- /* No candidate image available */
- rc = BOOT_EBADIMAGE;
+fih_int
+context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
+{
+ struct slot_usage_t slot_usage[BOOT_IMAGE_NUMBER];
+ int rc;
+ fih_int fih_rc = fih_int_encode(0);
+
+ memset(state, 0, sizeof(struct boot_loader_state));
+ memset(slot_usage, 0, sizeof(struct slot_usage_t) * BOOT_IMAGE_NUMBER);
+
+ rc = boot_get_slot_usage(state, slot_usage);
+ if (rc != 0) {
goto out;
}
+#if (BOOT_IMAGE_NUMBER > 1)
+ while (true) {
+#endif
+ FIH_CALL(boot_load_and_validate_images, fih_rc, state, slot_usage);
+ if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ goto out;
+ }
+
+#if (BOOT_IMAGE_NUMBER > 1)
+ rc = boot_verify_dependencies(state, slot_usage);
+ if (rc != 0) {
+ /* Dependency check failed for an image, it has been removed from
+ * SRAM in case of MCUBOOT_RAM_LOAD strategy, and set to
+ * unavailable. Try to load an image from another slot.
+ */
+ continue;
+ }
+ /* Dependency check was successful. */
+ break;
+ }
+#endif
+
+ IMAGES_ITER(BOOT_CURR_IMG(state)) {
+ rc = boot_update_hw_rollback_protection(state, slot_usage);
+ if (rc != 0) {
+ goto out;
+ }
+
+ rc = boot_add_shared_data(state, slot_usage[BOOT_CURR_IMG(state)].active_slot);
+ if (rc != 0) {
+ goto out;
+ }
+ }
+
+ /* All image loaded successfully. */
+#ifdef MCUBOOT_HAVE_LOGGING
+ print_loaded_images(state, slot_usage);
+#endif
+
+ fill_rsp(state, slot_usage, rsp);
+
out:
- for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
- flash_area_close(BOOT_IMG_AREA(state, BOOT_NUM_SLOTS - 1 - slot));
- }
+ close_all_flash_areas(state);
- if (rc) {
- fih_rc = fih_int_encode(rc);
- }
+ if (fih_eq(fih_rc, FIH_SUCCESS)) {
+ fih_rc = fih_int_encode(rc);
+ }
- FIH_RET(fih_rc);
+ FIH_RET(fih_rc);
}
#endif /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
diff --git a/boot/bootutil/src/swap_misc.c b/boot/bootutil/src/swap_misc.c
index 42ae7a4..13af238 100644
--- a/boot/bootutil/src/swap_misc.c
+++ b/boot/bootutil/src/swap_misc.c
@@ -28,7 +28,7 @@
#include "mcuboot_config/mcuboot_config.h"
-MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
+BOOT_LOG_MODULE_DECLARE(mcuboot);
#if defined(MCUBOOT_SWAP_USING_SCRATCH) || defined(MCUBOOT_SWAP_USING_MOVE)
@@ -49,7 +49,7 @@
uint8_t image_index;
int rc;
- BOOT_LOG_DBG("erasing trailer; fa_id=%d", fap->fa_id);
+ BOOT_LOG_DBG("erasing trailer; fa_id=%u", (unsigned)flash_area_get_id(fap));
image_index = BOOT_CURR_IMG(state);
fa_id_primary = flash_area_id_from_multi_image_slot(image_index,
@@ -57,9 +57,9 @@
fa_id_secondary = flash_area_id_from_multi_image_slot(image_index,
BOOT_SECONDARY_SLOT);
- if (fap->fa_id == fa_id_primary) {
+ if (flash_area_get_id(fap) == fa_id_primary) {
slot = BOOT_PRIMARY_SLOT;
- } else if (fap->fa_id == fa_id_secondary) {
+ } else if (flash_area_get_id(fap) == fa_id_secondary) {
slot = BOOT_SECONDARY_SLOT;
} else {
return BOOT_EFLASH;
@@ -97,7 +97,7 @@
image_index = BOOT_CURR_IMG(state);
- BOOT_LOG_DBG("initializing status; fa_id=%d", fap->fa_id);
+ BOOT_LOG_DBG("initializing status; fa_id=%u", (unsigned)flash_area_get_id(fap));
rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_SECONDARY(image_index),
&swap_state);
@@ -167,12 +167,12 @@
rc = swap_read_status_bytes(fap, state, bs);
if (rc == 0) {
off = boot_swap_info_off(fap);
- rc = flash_area_read(fap, off, &swap_info, sizeof swap_info);
+ rc = flash_area_read(fap, off, &swap_info, sizeof swap_info);
if (rc != 0) {
return BOOT_EFLASH;
}
- if (bootutil_buffer_is_erased(fap, &swap_info, sizeof swap_info)) {
+ if (swap_info == flash_area_erased_val(fap)) {
BOOT_SET_SWAP_INFO(swap_info, 0, BOOT_SWAP_TYPE_NONE);
rc = 0;
}
@@ -190,11 +190,10 @@
int
swap_set_copy_done(uint8_t image_index)
{
- const struct flash_area *fap;
+ const struct flash_area *fap = NULL;
int rc;
- rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index),
- &fap);
+ rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index), &fap);
if (rc != 0) {
return BOOT_EFLASH;
}
@@ -207,12 +206,11 @@
int
swap_set_image_ok(uint8_t image_index)
{
- const struct flash_area *fap;
- struct boot_swap_state state;
+ const struct flash_area *fap = NULL;
+ struct boot_swap_state state = {0};
int rc;
- rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index),
- &fap);
+ rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index), &fap);
if (rc != 0) {
return BOOT_EFLASH;
}
diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c
index 8fe0b44..08c21da 100644
--- a/boot/bootutil/src/swap_move.c
+++ b/boot/bootutil/src/swap_move.c
@@ -31,7 +31,7 @@
#include "mcuboot_config/mcuboot_config.h"
-MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
+BOOT_LOG_MODULE_DECLARE(mcuboot);
#ifdef MCUBOOT_SWAP_USING_MOVE
@@ -128,7 +128,7 @@
uint8_t status;
int max_entries;
int found_idx;
- uint8_t write_sz;
+ uint32_t write_sz;
int move_entries;
int rc;
int last_rc;
@@ -152,7 +152,7 @@
return BOOT_EFLASH;
}
- if (bootutil_buffer_is_erased(fap, &status, 1)) {
+ if (flash_area_erased_val(fap) == status) {
if (rc != last_rc) {
erased_sections++;
}
@@ -197,7 +197,7 @@
}
uint32_t
-boot_status_internal_off(const struct boot_status *bs, int elem_sz)
+boot_status_internal_off(const struct boot_status *bs, uint32_t elem_sz)
{
uint32_t off;
int idx_sz;
@@ -228,7 +228,7 @@
num_sectors_sec = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT);
if (num_sectors_sec == 0) {
- BOOT_LOG_WRN("Upgrade disabled for image %d", BOOT_CURR_IMG(state));
+ BOOT_LOG_WRN("Upgrade disabled for image %u", (unsigned)BOOT_CURR_IMG(state));
return 0;
}
@@ -262,16 +262,15 @@
return 1;
}
-#define BOOT_LOG_SWAP_STATE(area, state) \
- BOOT_LOG_INF("%s: magic=%s, swap_type=0x%x, copy_done=0x%x, " \
- "image_ok=0x%x", \
- (area), \
- ((state)->magic == BOOT_MAGIC_GOOD ? "good" : \
- (state)->magic == BOOT_MAGIC_UNSET ? "unset" : \
- "bad"), \
- (state)->swap_type, \
- (state)->copy_done, \
- (state)->image_ok)
+#define BOOT_LOG_SWAP_STATE(area, state) \
+ BOOT_LOG_INF("%s: magic=%s, swap_type=0x%x, copy_done=0x%x, image_ok=0x%x", \
+ (area), \
+ ((state)->magic == BOOT_MAGIC_GOOD ? "good" : \
+ (state)->magic == BOOT_MAGIC_UNSET ? "unset" : \
+ "bad"), \
+ (unsigned)(state)->swap_type, \
+ (unsigned)(state)->copy_done, \
+ (unsigned)(state)->image_ok)
int
swap_status_source(struct boot_loader_state *state)
@@ -412,7 +411,7 @@
*/
void
fixup_revert(const struct boot_loader_state *state, struct boot_status *bs,
- const struct flash_area *fap_sec, uint8_t sec_id)
+ const struct flash_area *fap_sec)
{
struct boot_swap_state swap_state;
int rc;
@@ -428,7 +427,7 @@
return;
}
- rc = boot_read_swap_state_by_id(sec_id, &swap_state);
+ rc = boot_read_swap_state(fap_sec, &swap_state);
assert(rc == 0);
BOOT_LOG_SWAP_STATE("Secondary image", &swap_state);
@@ -509,7 +508,7 @@
rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image_index), &fap_sec);
assert (rc == 0);
- fixup_revert(state, bs, fap_sec, FLASH_AREA_IMAGE_SECONDARY(image_index));
+ fixup_revert(state, bs, fap_sec);
if (bs->op == BOOT_STATUS_OP_MOVE) {
idx = g_last_idx;
diff --git a/boot/bootutil/src/swap_priv.h b/boot/bootutil/src/swap_priv.h
index 9cf5777..86d0b72 100644
--- a/boot/bootutil/src/swap_priv.h
+++ b/boot/bootutil/src/swap_priv.h
@@ -95,7 +95,7 @@
static inline size_t boot_scratch_area_size(const struct boot_loader_state *state)
{
- return BOOT_SCRATCH_AREA(state)->fa_size;
+ return flash_area_get_size(BOOT_SCRATCH_AREA(state));
}
#endif
diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c
index 9b9228a..fea6ce1 100644
--- a/boot/bootutil/src/swap_scratch.c
+++ b/boot/bootutil/src/swap_scratch.c
@@ -31,7 +31,7 @@
#include "mcuboot_config/mcuboot_config.h"
-MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
+BOOT_LOG_MODULE_DECLARE(mcuboot);
#ifndef MCUBOOT_SWAP_USING_MOVE
@@ -54,7 +54,7 @@
boot_read_image_header(struct boot_loader_state *state, int slot,
struct image_header *out_hdr, struct boot_status *bs)
{
- const struct flash_area *fap;
+ const struct flash_area *fap = NULL;
int area_id;
int rc;
@@ -74,9 +74,21 @@
}
else if (bs->state == BOOT_STATUS_STATE_2) {
if (slot == 0) {
+#if MCUBOOT_SWAP_USING_SCRATCH
+ /* encrypted scratch partition needs area wrapper */
+ uint32_t image_proc_size = boot_scratch_area_size(state) * bs->idx;
+ uint32_t primary_img_size = boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_img_size;
+ uint32_t secondary_img_size = boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_img_size;
+ slot = 2;
+
+ if (secondary_img_size >= primary_img_size &&
+ secondary_img_size - primary_img_size < image_proc_size) {
+ slot = 1;
+ }
+#else
slot = 1;
- }
- else {
+#endif
+ } else {
slot = 2;
}
}
@@ -89,16 +101,12 @@
goto done;
}
- rc = flash_area_read_is_empty(fap, 0, out_hdr, sizeof *out_hdr);
+ rc = flash_area_read(fap, 0, out_hdr, sizeof *out_hdr);
if (rc < 0) {
rc = BOOT_EFLASH;
goto done;
}
- if (rc == 1) {
- memset(out_hdr, 0, sizeof(*out_hdr));
- }
-
/* We only know where the headers are located when bs is valid */
if (bs != NULL && out_hdr->ih_magic != IMAGE_MAGIC) {
@@ -170,7 +178,7 @@
return BOOT_EFLASH;
}
- if (bootutil_buffer_is_erased(fap, &status, 1)) {
+ if (status == flash_area_erased_val(fap)) {
if (found && !found_idx) {
found_idx = i;
}
@@ -210,7 +218,7 @@
}
uint32_t
-boot_status_internal_off(const struct boot_status *bs, int elem_sz)
+boot_status_internal_off(const struct boot_status *bs, uint32_t elem_sz)
{
int idx_sz;
@@ -244,15 +252,17 @@
num_sectors_secondary = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT);
if (num_sectors_secondary == 0) {
- BOOT_LOG_WRN("Upgrade disabled for image %d", BOOT_CURR_IMG(state));
+ BOOT_LOG_WRN("Upgrade disabled for image %u", (unsigned)BOOT_CURR_IMG(state));
return 0;
}
if ((num_sectors_primary > BOOT_MAX_IMG_SECTORS) ||
(num_sectors_secondary > BOOT_MAX_IMG_SECTORS)) {
BOOT_LOG_WRN("Cannot upgrade: more sectors than allowed");
- BOOT_LOG_DBG("sectors_primary (%d) or sectors_secondary (%d) > BOOT_MAX_IMG_SECTORS (%d)",
- num_sectors_primary, num_sectors_secondary, BOOT_MAX_IMG_SECTORS);
+ BOOT_LOG_DBG("sectors_primary (%lu) or sectors_secondary (%lu) > BOOT_MAX_IMG_SECTORS (%lu)",
+ (unsigned long)num_sectors_primary,
+ (unsigned long)num_sectors_secondary,
+ (unsigned long)BOOT_MAX_IMG_SECTORS);
return 0;
}
@@ -325,16 +335,15 @@
return 1;
}
-#define BOOT_LOG_SWAP_STATE(area, state) \
- BOOT_LOG_INF("%s: magic=%s, swap_type=0x%x, copy_done=0x%x, " \
- "image_ok=0x%x", \
- (area), \
- ((state)->magic == BOOT_MAGIC_GOOD ? "good" : \
- (state)->magic == BOOT_MAGIC_UNSET ? "unset" : \
- "bad"), \
- (state)->swap_type, \
- (state)->copy_done, \
- (state)->image_ok)
+#define BOOT_LOG_SWAP_STATE(area, state) \
+ BOOT_LOG_INF("%s: magic=%s, swap_type=0x%x, copy_done=0x%x, image_ok=0x%x", \
+ (area), \
+ ((state)->magic == BOOT_MAGIC_GOOD ? "good" : \
+ (state)->magic == BOOT_MAGIC_UNSET ? "unset" : \
+ "bad"), \
+ (unsigned)(state)->swap_type, \
+ (unsigned)(state)->copy_done, \
+ (unsigned)(state)->image_ok)
struct boot_status_table {
uint8_t bst_magic_primary_slot;
@@ -427,7 +436,9 @@
swap_status_source(struct boot_loader_state *state)
{
const struct boot_status_table *table;
+#if MCUBOOT_SWAP_USING_SCRATCH
struct boot_swap_state state_scratch;
+#endif
struct boot_swap_state state_primary_slot;
int rc;
size_t i;
@@ -443,26 +454,33 @@
&state_primary_slot);
assert(rc == 0);
+#if MCUBOOT_SWAP_USING_SCRATCH
rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_SCRATCH, &state_scratch);
assert(rc == 0);
+#endif
+
+ (void)rc;
BOOT_LOG_SWAP_STATE("Primary image", &state_primary_slot);
+#if MCUBOOT_SWAP_USING_SCRATCH
BOOT_LOG_SWAP_STATE("Scratch", &state_scratch);
-
+#endif
for (i = 0; i < BOOT_STATUS_TABLES_COUNT; i++) {
table = &boot_status_tables[i];
if (boot_magic_compatible_check(table->bst_magic_primary_slot,
state_primary_slot.magic) &&
+#if MCUBOOT_SWAP_USING_SCRATCH
boot_magic_compatible_check(table->bst_magic_scratch,
state_scratch.magic) &&
+#endif
(table->bst_copy_done_primary_slot == BOOT_FLAG_ANY ||
table->bst_copy_done_primary_slot == state_primary_slot.copy_done))
{
source = table->bst_status_source;
-#if (BOOT_IMAGE_NUMBER > 1)
- /* In case of multi image boot it can happen that if boot status
+#if (BOOT_IMAGE_NUMBER > 1) && MCUBOOT_SWAP_USING_SCRATCH
+ /* In case of multi-image boot it can happen that if boot status
* info is found on scratch area then it does not belong to the
* currently examined image.
*/
@@ -546,14 +564,14 @@
boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state,
struct boot_status *bs)
{
- const struct flash_area *fap_primary_slot;
- const struct flash_area *fap_secondary_slot;
- const struct flash_area *fap_scratch;
+ const struct flash_area *fap_primary_slot = NULL;
+ const struct flash_area *fap_secondary_slot = NULL;
+ const struct flash_area *fap_scratch = NULL;
uint32_t copy_sz;
uint32_t trailer_sz;
uint32_t img_off;
uint32_t scratch_trailer_off;
- struct boot_swap_state swap_state;
+ struct boot_swap_state swap_state = {0};
size_t last_sector;
bool erase_scratch;
uint8_t image_index;
@@ -563,8 +581,12 @@
img_off = boot_img_sector_off(state, BOOT_PRIMARY_SLOT, idx);
copy_sz = sz;
- // trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state)); // TODO: fixme for status use case
- trailer_sz = BOOT_WRITE_SZ(state);
+
+#ifdef MCUBOOT_SWAP_USING_STATUS
+ trailer_sz = BOOT_WRITE_SZ(state); // TODO: deep investigation in swap_status use case
+#else
+ trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state));
+#endif
/* sz in this function is always sized on a multiple of the sector size.
* The check against the start offset of the last sector
@@ -598,7 +620,7 @@
if (bs->state == BOOT_STATUS_STATE_0) {
BOOT_LOG_DBG("erasing scratch area");
- rc = boot_erase_region(fap_scratch, 0, fap_scratch->fa_size);
+ rc = boot_erase_region(fap_scratch, 0, flash_area_get_size(fap_scratch));
assert(rc == 0);
if (bs->idx == BOOT_STATUS_IDX_0) {
@@ -622,7 +644,8 @@
/* Erase the temporary trailer from the scratch area. */
#ifndef MCUBOOT_SWAP_USING_STATUS
- rc = boot_erase_region(fap_scratch, 0, fap_scratch->fa_size);
+ rc = boot_erase_region(fap_scratch, 0,
+ flash_area_get_size(fap_scratch));
assert(rc == 0);
#else
rc = swap_erase_trailer_sectors(state, fap_scratch);
@@ -681,8 +704,7 @@
(BOOT_STATUS_STATE_COUNT - 1) * BOOT_WRITE_SZ(state));
BOOT_STATUS_ASSERT(rc == 0);
- rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_SCRATCH,
- &swap_state);
+ rc = boot_read_swap_state(fap_scratch, &swap_state);
assert(rc == 0);
if (swap_state.image_ok == BOOT_FLAG_SET) {
diff --git a/boot/bootutil/src/swap_status.c b/boot/bootutil/src/swap_status.c
index 6b9d33b..7f7e065 100644
--- a/boot/bootutil/src/swap_status.c
+++ b/boot/bootutil/src/swap_status.c
@@ -37,6 +37,7 @@
#include "swap_priv.h"
#include "swap_status.h"
#include "bootutil/bootutil_log.h"
+#include "bootutil/fault_injection_hardening.h"
#include "mcuboot_config/mcuboot_config.h"
@@ -49,18 +50,25 @@
swap_read_status_bytes(const struct flash_area *fap,
struct boot_loader_state *state, struct boot_status *bs)
{
+ const struct flash_area *fap_stat = NULL;
uint32_t off;
uint8_t status = 0;
- uint8_t last_status = 0xff;
- int max_entries;
+ uint8_t erased_val;
+ uint8_t last_status;
+ uint32_t max_entries;
int32_t found_idx;
bool found;
bool invalid;
int rc;
- int i;
+ uint32_t i;
(void)state;
- BOOT_LOG_DBG("> STATUS: swap_read_status_bytes: fa_id = %d", fap->fa_id);
+ BOOT_LOG_DBG("> STATUS: swap_read_status_bytes: fa_id = %u", (unsigned)fap->fa_id);
+
+ rc = flash_area_open(FLASH_AREA_IMAGE_SWAP_STATUS, &fap_stat);
+ if (rc != 0) {
+ return -1;
+ }
if (fap->fa_id == FLASH_AREA_IMAGE_SCRATCH) {
max_entries = 1;
@@ -68,22 +76,25 @@
max_entries = BOOT_STATUS_MAX_ENTRIES;
}
+ erased_val = flash_area_erased_val(fap_stat);
+
off = boot_status_off(fap);
found = false;
found_idx = -1;
invalid = false;
+ last_status = erased_val;
for (i = 0; i < max_entries; i++) {
rc = swap_status_retrieve(fap->fa_id, off + i, &status, 1);
if (rc < 0) {
- return BOOT_EFLASH;
+ flash_area_close(fap_stat);
+ return -1;
}
- // if (status != flash_area_erased_val(fap)) { // TODO: fixup for external memory fap's
- if (status == 0) {
+ if (status == erased_val) {
if (found && (found_idx == -1)) {
- found_idx = i;
+ found_idx = (int)i;
}
} else {
last_status = status;
@@ -93,6 +104,8 @@
} else if (found_idx > 0) {
invalid = true;
break;
+ } else {
+ /* No action required */
}
}
}
@@ -109,7 +122,7 @@
/* With validation of the primary slot disabled, there is no way
* to be sure the swapped primary slot is OK, so abort!
*/
- assert(0);
+ FIH_PANIC;
#endif
}
@@ -120,7 +133,8 @@
uint8_t image_index = BOOT_CURR_IMG(state);
rc = boot_read_swap_size((int32_t)image_index, &bs->swap_size);
if (rc < 0) {
- return BOOT_EFLASH;
+ flash_area_close(fap_stat);
+ return -1;
}
#ifdef MCUBOOT_SWAP_USING_MOVE
@@ -137,7 +151,7 @@
{
/* resume swap sectors operation */
last_status++;
- if (last_status > BOOT_STATUS_STATE_COUNT) {
+ if (last_status > (uint8_t)BOOT_STATUS_STATE_COUNT) {
last_status = BOOT_STATUS_STATE_0;
found_idx++;
}
@@ -148,14 +162,16 @@
}
}
+ flash_area_close(fap_stat);
+
return 0;
}
/* this is internal offset in swap status area */
uint32_t
-boot_status_internal_off(const struct boot_status *bs, int elem_sz)
+boot_status_internal_off(const struct boot_status *bs, uint32_t elem_sz)
{
- uint32_t off = (bs->idx - BOOT_STATUS_IDX_0) * (uint32_t)elem_sz;
+ uint32_t off = (bs->idx - BOOT_STATUS_IDX_0) * elem_sz;
return off;
}
diff --git a/boot/bootutil/src/swap_status.h b/boot/bootutil/src/swap_status.h
index dc27d64..cd96856 100644
--- a/boot/bootutil/src/swap_status.h
+++ b/boot/bootutil/src/swap_status.h
@@ -37,30 +37,29 @@
#ifdef MCUBOOT_SWAP_USING_STATUS
-#define BOOT_LOG_SWAP_STATE_M(area, state) \
- BOOT_LOG_DBG("%s: magic=%s, swap_type=0x%x, copy_done=0x%x, " \
- "image_ok=0x%x", \
- (area), \
- ((state)->magic == (uint8_t)BOOT_MAGIC_GOOD ? "good" :\
- (state)->magic == (uint8_t)BOOT_MAGIC_UNSET ? "unset" :\
- "bad"), \
- (state)->swap_type, \
- (state)->copy_done, \
- (state)->image_ok)
+#define BOOT_LOG_SWAP_STATE_M(area, state) \
+ BOOT_LOG_DBG("%s: magic=%s, swap_type=0x%x, copy_done=0x%x, image_ok=0x%x", \
+ (area), \
+ ((state)->magic == (uint8_t)BOOT_MAGIC_GOOD ? "good" : \
+ (state)->magic == (uint8_t)BOOT_MAGIC_UNSET ? "unset" : \
+ "bad"), \
+ (unsigned)(state)->swap_type, \
+ (unsigned)(state)->copy_done, \
+ (unsigned)(state)->image_ok)
-#define BOOT_SET_SWAP_INFO_M(swap_info, image, type) { \
- assert((int)((image) < 0xFu)); \
- assert((int)((type) < 0xFu)); \
- (swap_info) = (image) << 4u \
- | (type); \
- }
+#define BOOT_SET_SWAP_INFO_M(swap_info, image, type) do { \
+ assert((image) < 0xFu); \
+ assert((type) < 0xFu); \
+ (swap_info) = (image) << 4u \
+ | (type); \
+ } while (false)
-#define BOOT_GET_SWAP_TYPE_M(swap_info) ((swap_info) & 0x0Fu)
-#define BOOT_GET_IMAGE_NUM_M(swap_info) ((swap_info) >> 4u)
+#define BOOT_GET_SWAP_TYPE_M(swap_info) ((swap_info) & 0x0Fu)
+#define BOOT_GET_IMAGE_NUM_M(swap_info) ((swap_info) >> 4u)
extern const uint32_t stat_part_magic[1];
-#define BOOT_SWAP_STATUS_MAGIC (0xDEADBEAFu)
+#define BOOT_SWAP_STATUS_MAGIC (0xDEADBEEFu)
#define BOOT_SWAP_STATUS_ENCK1_SZ 16UL
#define BOOT_SWAP_STATUS_ENCK2_SZ 16UL
@@ -90,9 +89,9 @@
/* agreed to name it "a record" */
#define BOOT_SWAP_STATUS_PAYLD_SZ (BOOT_SWAP_STATUS_ROW_SZ -\
- BOOT_SWAP_STATUS_MGCREC_SZ - \
- BOOT_SWAP_STATUS_CNT_SZ - \
- BOOT_SWAP_STATUS_CRC_SZ)
+ BOOT_SWAP_STATUS_MGCREC_SZ - \
+ BOOT_SWAP_STATUS_CNT_SZ - \
+ BOOT_SWAP_STATUS_CRC_SZ)
#define BOOT_SWAP_STATUS_ROW_SZ_MIN 16UL
/* INFO: defining record structure for better understanding */
@@ -133,13 +132,13 @@
/* the size of one copy of status area */
#define BOOT_SWAP_STATUS_D_SIZE (BOOT_SWAP_STATUS_ROW_SZ * \
- (BOOT_SWAP_STATUS_SECT_ROWS_NUM + \
- BOOT_SWAP_STATUS_TRAIL_ROWS_NUM))
+ (BOOT_SWAP_STATUS_SECT_ROWS_NUM + \
+ BOOT_SWAP_STATUS_TRAIL_ROWS_NUM))
/* the size of one copy of status area without cnt and crc fields */
#define BOOT_SWAP_STATUS_D_SIZE_RAW (BOOT_SWAP_STATUS_PAYLD_SZ * \
- (BOOT_SWAP_STATUS_SECT_ROWS_NUM + \
- BOOT_SWAP_STATUS_TRAIL_ROWS_NUM))
+ (BOOT_SWAP_STATUS_SECT_ROWS_NUM + \
+ BOOT_SWAP_STATUS_TRAIL_ROWS_NUM))
/* multiplier which defines how many blocks will be used to reduce Flash wear
* 1 is for single write wear, 2 - twice less wear, 3 - three times less wear, etc */
@@ -153,14 +152,15 @@
#define BOOT_SWAP_STATUS_OFFS_PRIM 0UL
#define BOOT_SWAP_STATUS_OFFS_SEC (BOOT_SWAP_STATUS_OFFS_PRIM + \
- BOOT_SWAP_STATUS_SZ_PRIM)
+ BOOT_SWAP_STATUS_SZ_PRIM)
-int32_t swap_status_init_offset(uint32_t area_id);
-int swap_status_update(uint32_t target_area_id, uint32_t offs, const void *data, uint32_t len);
-int swap_status_retrieve(uint32_t target_area_id, uint32_t offs, void *data, uint32_t len);
+/* size Limit for primary slot trailer buffer */
+#define MAX_TRAILER_BUF_SIZE CY_FLASH_ALIGN
-int boot_write_trailer(const struct flash_area *fap, uint32_t off,
- const uint8_t *inbuf, uint8_t inlen);
+int32_t swap_status_init_offset(uint8_t area_id);
+int swap_status_update(uint8_t target_area_id, uint32_t offs, const void *data, uint32_t len);
+int swap_status_retrieve(uint8_t target_area_id, uint32_t offs, void *data, uint32_t len);
+int swap_status_to_image_trailer(const struct flash_area *fap);
#endif /* MCUBOOT_SWAP_USING_STATUS */
diff --git a/boot/bootutil/src/swap_status_misc.c b/boot/bootutil/src/swap_status_misc.c
index c8f8f95..8512b02 100644
--- a/boot/bootutil/src/swap_status_misc.c
+++ b/boot/bootutil/src/swap_status_misc.c
@@ -69,50 +69,36 @@
return BOOT_FLAG_SET;
}
-static inline size_t
-boot_status_sector_size(const struct boot_loader_state *state, size_t sector)
-{
- return state->status.sectors[sector].fs_size;
-}
-
-static inline uint32_t
-boot_status_sector_off(const struct boot_loader_state *state,
- size_t sector)
-{
- return state->status.sectors[sector].fs_off -
- state->status.sectors[0].fs_off;
-}
-
/* Offset Section */
static inline uint32_t
boot_magic_off(const struct flash_area *fap)
{
(void)fap;
- return ((uint32_t)BOOT_SWAP_STATUS_D_SIZE_RAW - (uint32_t)BOOT_MAGIC_SZ);
+ return (uint32_t)BOOT_SWAP_STATUS_D_SIZE_RAW - (uint32_t)BOOT_MAGIC_SZ;
}
uint32_t
boot_image_ok_off(const struct flash_area *fap)
{
- return (uint32_t)(boot_magic_off(fap) - 1u);
+ return boot_magic_off(fap) - BOOT_SWAP_STATUS_IMG_OK_SZ;
}
uint32_t
boot_copy_done_off(const struct flash_area *fap)
{
- return (uint32_t)(boot_image_ok_off(fap) - 1u);
+ return boot_image_ok_off(fap) - BOOT_SWAP_STATUS_COPY_DONE_SZ;
}
uint32_t
boot_swap_info_off(const struct flash_area *fap)
{
- return (uint32_t)(boot_copy_done_off(fap) - 1u);
+ return boot_copy_done_off(fap) - BOOT_SWAP_STATUS_SWAPINF_SZ;
}
uint32_t
boot_swap_size_off(const struct flash_area *fap)
{
- return (uint32_t)(boot_swap_info_off(fap) - 4u);
+ return boot_swap_info_off(fap) - BOOT_SWAP_STATUS_SWAPSZ_SZ;
}
uint32_t
@@ -130,9 +116,9 @@
{
#ifdef MCUBOOT_SWAP_SAVE_ENCTLV
/* suggest encryption key is also stored in status partition */
- return (uint32_t)(boot_swap_size_off(fap) - (uint32_t)((slot + 1u) * (uint32_t)BOOT_ENC_TLV_SIZE));
+ return boot_swap_size_off(fap) - (((uint32_t)slot + 1UL) * (uint32_t)BOOT_ENC_TLV_SIZE);
#else
- return (uint32_t)(boot_swap_size_off(fap) - (uint32_t)((slot + 1u) * (uint32_t)BOOT_ENC_KEY_SIZE));
+ return boot_swap_size_off(fap) - (((uint32_t)slot + 1UL) * (uint32_t)BOOT_ENC_KEY_SIZE);
#endif
}
#endif
@@ -140,7 +126,7 @@
/**
* Write trailer data; status bytes, swap_size, etc
*
- * @returns 0 on success, != 0 on error.
+ * @returns 0 on success, -1 on error.
*/
int
boot_write_trailer(const struct flash_area *fap, uint32_t off,
@@ -148,10 +134,23 @@
{
int rc;
- rc = swap_status_update(fap->fa_id, off, (uint8_t *)inbuf, inlen);
+ /* copy status part trailer to primary image before set copy_done flag */
+ if (boot_copy_done_off(fap) == off &&
+ fap->fa_id == FLASH_AREA_IMAGE_PRIMARY(0u) &&
+ BOOT_SWAP_STATUS_COPY_DONE_SZ == inlen) {
+
+ BOOT_LOG_DBG("copy status part trailer to primary image slot");
+ rc = swap_status_to_image_trailer(fap);
+ if (rc != 0) {
+ BOOT_LOG_ERR("trailer copy failed");
+ return -1;
+ }
+ }
+
+ rc = swap_status_update(fap->fa_id, off, inbuf, inlen);
if (rc != 0) {
- return BOOT_EFLASH;
+ return -1;
}
return rc;
}
@@ -167,14 +166,14 @@
off = boot_enc_key_off(fap, slot);
#ifdef MCUBOOT_SWAP_SAVE_ENCTLV
rc = swap_status_update(fap->fa_id, off,
- (uint8_t *) bs->enctlv[slot], BOOT_ENC_TLV_ALIGN_SIZE);
+ bs->enctlv[slot], BOOT_ENC_TLV_ALIGN_SIZE);
#else
rc = swap_status_update(fap->fa_id, off,
- (uint8_t *) bs->enckey[slot], BOOT_ENC_KEY_SIZE);
+ bs->enckey[slot], BOOT_ENC_KEY_SIZE);
#endif
- if (rc != 0) {
- return BOOT_EFLASH;
- }
+ if (rc != 0) {
+ return -1;
+ }
return 0;
}
@@ -184,25 +183,21 @@
{
uint32_t off;
const struct flash_area *fap;
-#ifdef MCUBOOT_SWAP_SAVE_ENCTLV
- int i;
-#endif
int rc;
rc = boot_find_status(image_index, &fap);
- if (rc == 0) {
+ if (0 == rc) {
off = boot_enc_key_off(fap, slot);
#ifdef MCUBOOT_SWAP_SAVE_ENCTLV
rc = swap_status_retrieve(fap->fa_id, off, bs->enctlv[slot], BOOT_ENC_TLV_ALIGN_SIZE);
- if (rc == 0) {
- for (i = 0; i < BOOT_ENC_TLV_ALIGN_SIZE; i++) {
- if (bs->enctlv[slot][i] != 0xff) {
- break;
- }
- }
- /* Only try to decrypt non-erased TLV metadata */
- if (i != BOOT_ENC_TLV_ALIGN_SIZE) {
- rc = boot_enc_decrypt(bs->enctlv[slot], bs->enckey[slot]);
+ if (0 == rc) {
+ uint8_t aes_iv[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
+
+ /* Only try to decrypt initialized TLV metadata */
+ if (!bootutil_buffer_is_filled(bs->enctlv[slot],
+ BOOT_UNINITIALIZED_TLV_FILL,
+ BOOT_ENC_TLV_ALIGN_SIZE)) {
+ rc = boot_enc_decrypt(bs->enctlv[slot], bs->enckey[slot], 0, aes_iv);
}
}
#else
@@ -225,19 +220,14 @@
off = boot_magic_off(fap);
rc = swap_status_update(fap->fa_id, off,
- (uint8_t *) boot_img_magic, BOOT_MAGIC_SZ);
+ boot_img_magic, BOOT_MAGIC_SZ);
if (rc != 0) {
- return BOOT_EFLASH;
+ return -1;
}
return 0;
}
-int boot_status_num_sectors(const struct boot_loader_state *state)
-{
- return (int)(BOOT_SWAP_STATUS_SIZE / boot_status_sector_size(state, 0));
-}
-
/**
* Writes the supplied boot status to the flash file system. The boot status
* contains the current state of an in-progress image copy operation.
@@ -251,10 +241,13 @@
{
const struct flash_area *fap = NULL;
uint32_t off;
- int area_id;
+ uint8_t area_id;
int rc;
(void)state;
+ if (bs->idx < BOOT_STATUS_IDX_0) {
+ return BOOT_EFLASH;
+ }
/* NOTE: The first sector copied (that is the last sector on slot) contains
* the trailer. Since in the last step the primary slot is erased, the
* first two status writes go to the scratch which will be copied to
@@ -262,17 +255,17 @@
*/
#ifdef MCUBOOT_SWAP_USING_SCRATCH
- if (bs->use_scratch) {
+ if (bs->use_scratch != 0U) {
/* Write to scratch status. */
- area_id = FLASH_AREA_IMAGE_SCRATCH;
+ area_id = (uint8_t)FLASH_AREA_IMAGE_SCRATCH;
} else
#endif
{
/* Write to the primary slot. */
- area_id = (int)FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state));
+ area_id = FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state));
}
- rc = flash_area_open((uint8_t)area_id, &fap);
+ rc = flash_area_open(area_id, &fap);
if (rc != 0) {
rc = BOOT_EFLASH;
goto done;
@@ -294,20 +287,6 @@
}
int
-boot_read_data_empty(const struct flash_area *fap, void *data, uint32_t len)
-{
- uint8_t *buf;
-
- buf = (uint8_t *)data;
- for (uint32_t i = 0; i < len; i++) {
- if (buf[i] != flash_area_erased_val(fap)) {
- return 0;
- }
- }
- return 1;
-}
-
-int
boot_read_swap_state(const struct flash_area *fap,
struct boot_swap_state *state)
{
@@ -317,54 +296,64 @@
uint8_t swap_info = 0U;
int rc;
uint32_t erase_trailer = 0;
+ bool buf_is_clean = false;
+ bool is_primary = false;
+ bool is_secondary = false;
+ uint32_t i;
const struct flash_area *fap_stat = NULL;
rc = flash_area_open(FLASH_AREA_IMAGE_SWAP_STATUS, &fap_stat);
if (rc != 0) {
- return BOOT_EFLASH;
+ return -1;
}
off = boot_magic_off(fap);
/* retrieve value for magic field from status partition area */
rc = swap_status_retrieve(fap->fa_id, off, magic, BOOT_MAGIC_SZ);
if (rc < 0) {
- return BOOT_EFLASH;
+ return -1;
}
- rc = boot_read_data_empty(fap_stat, magic, BOOT_MAGIC_SZ);
- if (rc < 0) {
- return BOOT_EFLASH;
- }
- /* fill magic number value if equal to expected */
- if (rc == 1) {
+ for (i = 0u; i < (uint32_t)BOOT_IMAGE_NUMBER; i++) {
+ if (fap->fa_id == FLASH_AREA_IMAGE_PRIMARY(i)) {
+ is_primary = true;
+ break;
+ }
+ if (fap->fa_id == FLASH_AREA_IMAGE_SECONDARY(i)) {
+ is_secondary = true;
+ break;
+ }
+ }
+
+ /* fill magic number value if equal to expected */
+ if (bootutil_buffer_is_erased(fap_stat, magic, BOOT_MAGIC_SZ)) {
state->magic = BOOT_MAGIC_UNSET;
/* attempt to find magic in upgrade img slot trailer */
- if (fap->fa_id == FLASH_AREA_IMAGE_1 ||
- fap->fa_id == FLASH_AREA_IMAGE_3) {
+ if (is_secondary) {
+ trailer_off = fap->fa_size - BOOT_MAGIC_SZ;
- trailer_off = fap->fa_size - BOOT_MAGIC_SZ;
-
- rc = flash_area_read_is_empty(fap, trailer_off, magic, BOOT_MAGIC_SZ);
+ rc = flash_area_read(fap, trailer_off, magic, BOOT_MAGIC_SZ);
+ if (rc != 0) {
+ return -1;
+ }
+ buf_is_clean = bootutil_buffer_is_erased(fap, magic, BOOT_MAGIC_SZ);
+ if (buf_is_clean) {
+ state->magic = BOOT_MAGIC_UNSET;
+ } else {
+ state->magic = (uint8_t)boot_magic_decode(magic);
+ /* put magic to status partition for upgrade slot*/
+ if ((uint32_t)BOOT_MAGIC_GOOD == state->magic) {
+ rc = swap_status_update(fap->fa_id, off,
+ (uint8_t *) magic, BOOT_MAGIC_SZ);
+ }
if (rc < 0) {
- return BOOT_EFLASH;
- }
- if (rc == 1) {
- state->magic = BOOT_MAGIC_UNSET;
+ return -1;
} else {
- state->magic = (uint8_t)boot_magic_decode(magic);
- /* put magic to status partition for upgrade slot*/
- if (state->magic == (uint32_t)BOOT_MAGIC_GOOD) {
- rc = swap_status_update(fap->fa_id, off,
- (uint8_t *) magic, BOOT_MAGIC_SZ);
- }
- if (rc < 0) {
- return BOOT_EFLASH;
- } else {
- erase_trailer = 1;
- }
+ erase_trailer = 1;
}
+ }
}
} else {
state->magic = (uint8_t)boot_magic_decode(magic);
@@ -373,13 +362,10 @@
off = boot_swap_info_off(fap);
rc = swap_status_retrieve(fap->fa_id, off, &swap_info, sizeof swap_info);
if (rc < 0) {
- return BOOT_EFLASH;
+ return -1;
}
- rc = boot_read_data_empty(fap_stat, &swap_info, sizeof swap_info);
- if (rc < 0) {
- return BOOT_EFLASH;
- }
- if (rc == 1 || state->swap_type > (uint8_t)BOOT_SWAP_TYPE_REVERT) {
+ if (bootutil_buffer_is_erased(fap_stat, &swap_info, sizeof swap_info) ||
+ state->swap_type >= (uint8_t)BOOT_SWAP_TYPE_FAIL) {
state->swap_type = (uint8_t)BOOT_SWAP_TYPE_NONE;
state->image_num = 0;
}
@@ -392,14 +378,10 @@
off = boot_copy_done_off(fap);
rc = swap_status_retrieve(fap->fa_id, off, &state->copy_done, sizeof state->copy_done);
if (rc < 0) {
- return BOOT_EFLASH;
+ return -1;
}
- rc = boot_read_data_empty(fap_stat, &state->copy_done, sizeof state->copy_done);
/* need to check swap_info was empty */
- if (rc < 0) {
- return BOOT_EFLASH;
- }
- if (rc == 1) {
+ if (bootutil_buffer_is_erased(fap_stat, &state->copy_done, sizeof state->copy_done)) {
state->copy_done = BOOT_FLAG_UNSET;
} else {
state->copy_done = (uint8_t)boot_flag_decode(state->copy_done);
@@ -408,58 +390,40 @@
off = boot_image_ok_off(fap);
rc = swap_status_retrieve(fap->fa_id, off, &state->image_ok, sizeof state->image_ok);
if (rc < 0) {
- return BOOT_EFLASH;
+ return -1;
}
- rc = boot_read_data_empty(fap_stat, &state->image_ok, sizeof state->image_ok);
/* need to check swap_info was empty */
- if (rc < 0) {
- return BOOT_EFLASH;
- }
- if (rc == 1) {
+ if (bootutil_buffer_is_erased(fap_stat, &state->image_ok, sizeof state->image_ok)) {
/* assign img_ok unset */
state->image_ok = BOOT_FLAG_UNSET;
/* attempt to read img_ok value in upgrade img slots trailer area
* it is set when image in slot for upgrade is signed for swap_type permanent
*/
- uint32_t process_image_ok = 0;
- switch (fap->fa_id) {
- case FLASH_AREA_IMAGE_0:
- case FLASH_AREA_IMAGE_2:
- {
- if (state->copy_done == (uint8_t)BOOT_FLAG_SET)
- process_image_ok = 1;
- }
- break;
- case FLASH_AREA_IMAGE_1:
- case FLASH_AREA_IMAGE_3:
- {
- process_image_ok = 1;
- }
- break;
- case FLASH_AREA_IMAGE_SCRATCH:
- {
- BOOT_LOG_DBG(" * selected SCRATCH area, copy_done = %d", state->copy_done);
- {
- if (state->copy_done == (uint8_t)BOOT_FLAG_SET)
- process_image_ok = 1;
- }
- }
- break;
- default:
- {
- return BOOT_EFLASH;
- }
- break;
+ bool process_image_ok = (uint8_t)BOOT_FLAG_SET == state->copy_done;
+ if (fap->fa_id == FLASH_AREA_IMAGE_SCRATCH) {
+ BOOT_LOG_DBG(" * selected SCRATCH area, copy_done = %u", (unsigned)state->copy_done);
}
- if (process_image_ok != 0u) {
+ else if (is_secondary) {
+ process_image_ok = true;
+ }
+ else if (!is_primary) {
+ process_image_ok = false;
+ rc = -1;
+ }
+ else {
+ /* Fix MISRA Rule 15.7 */
+ }
+ if (process_image_ok) {
trailer_off = fap->fa_size - (uint8_t)BOOT_MAGIC_SZ - (uint8_t)BOOT_MAX_ALIGN;
- rc = flash_area_read_is_empty(fap, trailer_off, &state->image_ok, sizeof state->image_ok);
- if (rc < 0) {
- return BOOT_EFLASH;
+ rc = flash_area_read(fap, trailer_off, &state->image_ok, sizeof state->image_ok);
+ if (rc != 0) {
+ return -1;
}
- if (rc == 1) {
+
+ buf_is_clean = bootutil_buffer_is_erased(fap, &state->image_ok, sizeof state->image_ok);
+ if (buf_is_clean) {
state->image_ok = BOOT_FLAG_UNSET;
} else {
state->image_ok = (uint8_t)boot_flag_decode(state->image_ok);
@@ -470,24 +434,25 @@
&state->image_ok, sizeof state->image_ok);
}
if (rc < 0) {
- return BOOT_EFLASH;
+ return -1;
}
- /* mark img trailer needs to be erased */
- erase_trailer = 1;
+ /* don't erase trailer, just move img_ok to status part */
+ erase_trailer = 0;
}
}
} else {
state->image_ok = (uint8_t)boot_flag_decode(state->image_ok);
}
- if ((erase_trailer != 0u) && (fap->fa_id != FLASH_AREA_IMAGE_SCRATCH)) {
+ if ((erase_trailer != 0u) && (fap->fa_id != FLASH_AREA_IMAGE_SCRATCH) && (0 == rc)) {
/* erase magic from upgrade img trailer */
rc = flash_area_erase(fap, trailer_off, BOOT_MAGIC_SZ);
- if (rc != 0)
+ if (rc != 0) {
return rc;
+ }
}
- return 0;
+ return rc;
}
/**
@@ -504,10 +469,15 @@
{
uint32_t magic[BOOT_MAGIC_ARR_SZ] = {0};
uint32_t off;
-
- /* the status is always in status partition */
- uint8_t area = FLASH_AREA_IMAGE_PRIMARY((uint32_t)image_index);
int rc = -1;
+ uint8_t area = FLASH_AREA_ERROR;
+
+ if ((image_index < 0) || (image_index >= MCUBOOT_IMAGE_NUMBER)) {
+ return rc;
+ }
+ /* the status is always in status partition */
+ area = FLASH_AREA_IMAGE_PRIMARY((uint32_t)image_index);
+
/*
* In the middle a swap, tries to locate the area that is currently
@@ -523,7 +493,7 @@
off = boot_magic_off(*fap);
rc = swap_status_retrieve(area, off, magic, BOOT_MAGIC_SZ);
- if (rc == 0) {
+ if (0 == rc) {
rc = memcmp(magic, boot_img_magic, BOOT_MAGIC_SZ);
}
@@ -539,7 +509,7 @@
int rc;
rc = boot_find_status(image_index, &fap);
- if (rc == 0) {
+ if (0 == rc) {
off = boot_swap_size_off(fap);
rc = swap_status_retrieve(fap->fa_id, off, swap_size, sizeof *swap_size);
@@ -551,48 +521,58 @@
swap_erase_trailer_sectors(const struct boot_loader_state *state,
const struct flash_area *fap)
{
- uint32_t sub_offs, trailer_offs;
- uint32_t sz;
+ int32_t sub_offs;
+ uint32_t trailer_offs;
uint8_t fa_id_primary;
uint8_t fa_id_secondary;
uint8_t image_index;
int rc;
(void)state;
- BOOT_LOG_INF("Erasing trailer; fa_id=%d", fap->fa_id);
+ BOOT_LOG_INF("Erasing trailer; fa_id=%u", (unsigned)fap->fa_id);
/* trailer is located in status-partition */
const struct flash_area *fap_stat = NULL;
rc = flash_area_open(FLASH_AREA_IMAGE_SWAP_STATUS, &fap_stat);
if (rc != 0) {
- return BOOT_EFLASH;
+ return -1;
}
- if (fap->fa_id != FLASH_AREA_IMAGE_SCRATCH)
- {
+ if (fap->fa_id != FLASH_AREA_IMAGE_SCRATCH) {
image_index = BOOT_CURR_IMG(state);
- fa_id_primary = (uint8_t)flash_area_id_from_multi_image_slot((int32_t)image_index,
+ rc = flash_area_id_from_multi_image_slot((int32_t)image_index,
BOOT_PRIMARY_SLOT);
- fa_id_secondary = (uint8_t)flash_area_id_from_multi_image_slot((int32_t)image_index,
+ if (rc < 0) {
+ return -1;
+ }
+ fa_id_primary = (uint8_t)rc;
+
+ rc = flash_area_id_from_multi_image_slot((int32_t)image_index,
BOOT_SECONDARY_SLOT);
+ if (rc < 0) {
+ return -1;
+ }
+ fa_id_secondary = (uint8_t)rc;
/* skip if Flash Area is not recognizable */
if ((fap->fa_id != fa_id_primary) && (fap->fa_id != fa_id_secondary)) {
- return BOOT_EFLASH;
+ return -1;
}
}
- sub_offs = (uint32_t)swap_status_init_offset(fap->fa_id);
+ sub_offs = swap_status_init_offset(fap->fa_id);
+ if (sub_offs < 0) {
+ return -1;
+ }
/* delete starting from last sector and moving to beginning */
/* calculate last sector of status sub-area */
- sz = (uint32_t)BOOT_SWAP_STATUS_SIZE;
+ rc = flash_area_erase(fap_stat, (uint32_t)sub_offs, (uint32_t)BOOT_SWAP_STATUS_SIZE);
+ if (rc != 0) {
+ return -1;
+ }
- rc = flash_area_erase(fap_stat, sub_offs, sz);
- assert((int)(rc == 0));
-
- if (fap->fa_id != FLASH_AREA_IMAGE_SCRATCH)
- {
+ if (fap->fa_id != FLASH_AREA_IMAGE_SCRATCH) {
/*
* it is also needed to erase trailer area in slots since they may contain
* data, which is already cleared in corresponding status partition
@@ -621,37 +601,37 @@
image_index = BOOT_CURR_IMG(state);
- BOOT_LOG_DBG("initializing status; fa_id=%d", fap->fa_id);
+ BOOT_LOG_DBG("initializing status; fa_id=%u", (unsigned)fap->fa_id);
rc = boot_read_swap_state_by_id((int32_t)FLASH_AREA_IMAGE_SECONDARY(image_index),
&swap_state);
- assert((int)(rc == 0));
+ assert(0 == rc);
if (bs->swap_type != (uint8_t)BOOT_SWAP_TYPE_NONE) {
rc = boot_write_swap_info(fap, bs->swap_type, image_index);
- assert((int)(rc == 0));
+ assert(0 == rc);
}
- if (swap_state.image_ok == (uint8_t)BOOT_FLAG_SET) {
+ if ((uint8_t)BOOT_FLAG_SET == swap_state.image_ok) {
rc = boot_write_image_ok(fap);
- assert((int)(rc == 0));
+ assert(0 == rc);
}
rc = boot_write_swap_size(fap, bs->swap_size);
- assert((int)(rc == 0));
+ assert(0 == rc);
#ifdef MCUBOOT_ENC_IMAGES
rc = boot_write_enc_key(fap, 0, bs);
- assert((int)(rc == 0));
+ assert(0 == rc);
rc = boot_write_enc_key(fap, 1, bs);
- assert((int)(rc == 0));
+ assert(0 == rc);
#endif
rc = boot_write_magic(fap);
- assert((int)(rc == 0));
+ assert(0 == rc);
- return 0;
+ return rc;
}
int
@@ -661,46 +641,42 @@
const struct flash_area *fap_stat = NULL;
uint32_t off;
uint8_t swap_info = 0;
- int area_id;
+ uint8_t area_id;
int rc = 0;
bs->source = swap_status_source(state);
- if (bs->source == BOOT_STATUS_SOURCE_NONE) {
+ if (BOOT_STATUS_SOURCE_NONE == bs->source) {
return 0;
}
-
- if (bs->source == BOOT_STATUS_SOURCE_PRIMARY_SLOT) {
- area_id = (int32_t)FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state));
- } else if (bs->source == BOOT_STATUS_SOURCE_SCRATCH) {
+ else if (BOOT_STATUS_SOURCE_PRIMARY_SLOT == bs->source) {
+ area_id = FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state));
+ }
+ else if (BOOT_STATUS_SOURCE_SCRATCH == bs->source) {
area_id = FLASH_AREA_IMAGE_SCRATCH;
- } else {
- return BOOT_EBADARGS;
+ }
+ else {
+ return -1;
}
- rc = flash_area_open((uint8_t)area_id, &fap);
+ rc = flash_area_open(area_id, &fap);
if (rc != 0) {
- return BOOT_EFLASH;
+ return -1;
}
rc = flash_area_open(FLASH_AREA_IMAGE_SWAP_STATUS, &fap_stat);
if (rc != 0) {
- return BOOT_EFLASH;
+ return -1;
}
rc = swap_read_status_bytes(fap, state, bs);
- if (rc == 0) {
+ if (0 == rc) {
off = boot_swap_info_off(fap);
rc = swap_status_retrieve((uint8_t)area_id, off, &swap_info, sizeof swap_info);
if (rc < 0) {
- return BOOT_EFLASH;
+ return -1;
}
- rc = boot_read_data_empty(fap_stat, &swap_info, sizeof swap_info);
- if (rc < 0) {
- return BOOT_EFLASH;
- }
-
- if (rc == 1) {
+ if (bootutil_buffer_is_erased(fap_stat, &swap_info, sizeof swap_info)) {
BOOT_SET_SWAP_INFO_M(swap_info, 0u, (uint8_t)BOOT_SWAP_TYPE_NONE);
rc = 0;
}
diff --git a/boot/bootutil/src/swap_status_part.c b/boot/bootutil/src/swap_status_part.c
index a2899a9..f6be047 100644
--- a/boot/bootutil/src/swap_status_part.c
+++ b/boot/bootutil/src/swap_status_part.c
@@ -26,97 +26,83 @@
* under the License.
*/
-#include <assert.h>
#include "crc32c.h"
#include <string.h>
+#include <stdlib.h>
#include "swap_status.h"
#ifdef MCUBOOT_SWAP_USING_STATUS
-#define IMAGE_0_STATUS_OFFS 0
-#define IMAGE_0_STATUS_SIZE (BOOT_SWAP_STATUS_SIZE)
-
-#define IMAGE_1_STATUS_OFFS (IMAGE_0_STATUS_OFFS + IMAGE_0_STATUS_SIZE)
-#define IMAGE_1_STATUS_SIZE (BOOT_SWAP_STATUS_SIZE)
-
-#define SCRATCH_STATUS_OFFS (IMAGE_1_STATUS_OFFS + BOOT_SWAP_STATUS_SIZE)
-#ifdef MCUBOOT_SWAP_USING_SCRATCH
-#define SCRATCH_STATUS_SIZE (BOOT_SWAP_STATUS_SIZE)
-#else
-#define SCRATCH_STATUS_SIZE 0
-#endif
-
-#if (MCUBOOT_IMAGE_NUMBER == 2)
-#define IMAGE_2_STATUS_OFFS (SCRATCH_STATUS_OFFS + SCRATCH_STATUS_SIZE)
-#define IMAGE_2_STATUS_SIZE (BOOT_SWAP_STATUS_SIZE)
-
-#define IMAGE_3_STATUS_OFFS (IMAGE_2_STATUS_OFFS + IMAGE_2_STATUS_SIZE)
-#define IMAGE_3_STATUS_SIZE (BOOT_SWAP_STATUS_SIZE)
-#endif
+static uint8_t record_buff[BOOT_SWAP_STATUS_ROW_SZ];
+static uint8_t status_buff[BOOT_SWAP_STATUS_PAYLD_SZ];
const uint32_t stat_part_magic[] = {
BOOT_SWAP_STATUS_MAGIC
};
-uint32_t calc_rec_idx(uint32_t value)
+static inline uint32_t calc_rec_idx(uint32_t value)
{
- uint32_t rec_idx;
-
- rec_idx = value/BOOT_SWAP_STATUS_PAYLD_SZ;
-
- return rec_idx;
+ return value / BOOT_SWAP_STATUS_PAYLD_SZ;
}
-uint32_t calc_record_offs(uint32_t offs)
+static inline uint32_t calc_record_offs(uint32_t offs)
{
- uint32_t rec_offs;
-
- rec_offs = BOOT_SWAP_STATUS_ROW_SZ*calc_rec_idx(offs);
-
- return rec_offs;
+ return BOOT_SWAP_STATUS_ROW_SZ * calc_rec_idx(offs);
}
-uint32_t calc_record_crc(const uint8_t *data, uint32_t length)
+static inline uint32_t calc_record_crc(const uint8_t *data, uint32_t length)
{
- uint32_t crc;
-
- crc = crc32c_checksum(data, length);
-
- return crc;
+ return crc32c_checksum(data, length);
}
-int32_t swap_status_init_offset(uint32_t area_id)
+static inline uint32_t pack_bytes_u32(const uint8_t *data)
{
- int32_t offset = -1;
- /* calculate an offset caused by area type: primary_x/secondary_x */
- switch (area_id) {
- case FLASH_AREA_IMAGE_0:
- offset = (int)IMAGE_0_STATUS_OFFS;
- break;
- case FLASH_AREA_IMAGE_1:
- offset = (int)IMAGE_1_STATUS_OFFS;
- break;
+ uint32_t result = 0U;
+
+ result = ((uint32_t)data[3U] << 24U) | ((uint32_t)data[2U] << 16U) |
+ ((uint32_t)data[1U] << 8U) | (uint32_t)data[0U];
+
+ return result;
+}
+
+int32_t swap_status_init_offset(uint8_t area_id)
+{
+ uint8_t order[] = {
+ FLASH_AREA_IMAGE_PRIMARY(0U)
+ , FLASH_AREA_IMAGE_SECONDARY(0U)
#ifdef MCUBOOT_SWAP_USING_SCRATCH
- case FLASH_AREA_IMAGE_SCRATCH:
- offset = (int)SCRATCH_STATUS_OFFS;
- break;
-#endif
-#if (MCUBOOT_IMAGE_NUMBER == 2)
- case FLASH_AREA_IMAGE_2:
- offset = (int)IMAGE_2_STATUS_OFFS;
- break;
- case FLASH_AREA_IMAGE_3:
- offset = (int)IMAGE_3_STATUS_OFFS;
- break;
-#endif
- default:
- offset = -1;
- break;
+ , FLASH_AREA_IMAGE_SCRATCH
+#endif /* MCUBOOT_SWAP_USING_SCRATCH */
+#if BOOT_IMAGE_NUMBER >= 2
+ , FLASH_AREA_IMAGE_PRIMARY(1U)
+ , FLASH_AREA_IMAGE_SECONDARY(1U)
+#endif /* BOOT_IMAGE_NUMBER >= 2 */
+#if BOOT_IMAGE_NUMBER >= 3
+ , FLASH_AREA_IMAGE_PRIMARY(2U)
+ , FLASH_AREA_IMAGE_SECONDARY(2U)
+#endif /* BOOT_IMAGE_NUMBER >= 3 */
+#if BOOT_IMAGE_NUMBER == 4
+ , FLASH_AREA_IMAGE_PRIMARY(3U)
+ , FLASH_AREA_IMAGE_SECONDARY(3U)
+#endif /* BOOT_IMAGE_NUMBER == 4 */
+ };
+
+ int32_t result = -1;
+ int32_t offset = 0;
+ uint32_t i;
+
+ for (i = 0U; i < sizeof(order) / sizeof(order[0U]); i++) {
+ if (order[i] == area_id) {
+ result = offset;
+ break;
+ }
+ offset += BOOT_SWAP_STATUS_SIZE;
}
- return offset;
+
+ return result;
}
-int swap_status_read_record(uint32_t rec_offset, uint8_t *data, uint32_t *copy_counter)
+static int swap_status_read_record(uint32_t rec_offset, uint8_t *data, uint32_t *copy_counter, uint32_t *max_idx)
{ /* returns BOOT_SWAP_STATUS_PAYLD_SZ of data */
int rc = -1;
@@ -127,60 +113,56 @@
uint32_t magic_fail = 0;
uint32_t max_cnt = 0;
- int32_t max_idx = 0;
-
- uint8_t buff[BOOT_SWAP_STATUS_ROW_SZ];
-
const struct flash_area *fap_stat = NULL;
rc = flash_area_open(FLASH_AREA_IMAGE_SWAP_STATUS, &fap_stat);
if (rc != 0) {
- return BOOT_EFLASH;
+ return -1;
}
+ else {
+ /* loop over copies/duplicates */
+ for (uint32_t i = 0; i < BOOT_SWAP_STATUS_MULT; i++) {
+ /* calculate final duplicate offset */
+ fin_offset = rec_offset + i * BOOT_SWAP_STATUS_D_SIZE;
- /* loop over copies/duplicates */
- for(uint32_t i = 0; i<BOOT_SWAP_STATUS_MULT; i++) {
- /* calculate final duplicate offset */
- fin_offset = rec_offset + i*BOOT_SWAP_STATUS_D_SIZE;
-
- rc = flash_area_read(fap_stat, fin_offset, buff, sizeof(buff));
- if (rc != 0) {
- return BOOT_EFLASH;
- }
- /* read magic value to know if area was pre-erased */
- magic = *((uint32_t *)&buff[BOOT_SWAP_STATUS_ROW_SZ -\
- BOOT_SWAP_STATUS_MGCREC_SZ -\
- BOOT_SWAP_STATUS_CNT_SZ-\
- BOOT_SWAP_STATUS_CRC_SZ]);
- if (magic == BOOT_SWAP_STATUS_MAGIC) { /* read CRC */
- crc = *((uint32_t *)&buff[BOOT_SWAP_STATUS_ROW_SZ -\
- BOOT_SWAP_STATUS_CRC_SZ]);
- /* check record data integrity first */
- if (crc == calc_record_crc(buff, BOOT_SWAP_STATUS_ROW_SZ-BOOT_SWAP_STATUS_CRC_SZ)) {
- /* look for counter */
- counter = *((uint32_t *)&buff[BOOT_SWAP_STATUS_ROW_SZ -\
- BOOT_SWAP_STATUS_CNT_SZ - \
- BOOT_SWAP_STATUS_CRC_SZ]);
- /* find out counter max */
- if (counter >= max_cnt) {
- max_cnt = counter;
- max_idx = (int32_t)i;
- data_offset = fin_offset;
+ rc = flash_area_read(fap_stat, fin_offset, record_buff, sizeof(record_buff));
+ if (rc != 0) {
+ return -1;
+ }
+ else {
+ /* read magic value to know if area was pre-erased */
+ magic = pack_bytes_u32(&record_buff[BOOT_SWAP_STATUS_PAYLD_SZ]);
+ if (magic == BOOT_SWAP_STATUS_MAGIC) { /* read CRC */
+ crc = pack_bytes_u32(&record_buff[BOOT_SWAP_STATUS_ROW_SZ -
+ BOOT_SWAP_STATUS_CRC_SZ]);
+ /* check record data integrity first */
+ if (crc == calc_record_crc(record_buff, BOOT_SWAP_STATUS_ROW_SZ-BOOT_SWAP_STATUS_CRC_SZ)) {
+ /* look for counter */
+ counter = pack_bytes_u32(&record_buff[BOOT_SWAP_STATUS_ROW_SZ -
+ BOOT_SWAP_STATUS_CNT_SZ -
+ BOOT_SWAP_STATUS_CRC_SZ]);
+ /* find out counter max */
+ if (counter >= max_cnt) {
+ max_cnt = counter;
+ *max_idx = i;
+ data_offset = fin_offset;
+ }
+ }
+ /* if crc != calculated() */
+ else {
+ crc_fail++;
+ }
+ }
+ else {
+ magic_fail++;
}
}
- /* if crc != calculated() */
- else {
- crc_fail++;
- }
- }
- else {
- magic_fail++;
}
}
/* no magic found - status area is pre-erased, start from scratch */
if (magic_fail == BOOT_SWAP_STATUS_MULT) {
/* emulate last index was received, so next will start from beginning */
- max_idx = (int32_t)(BOOT_SWAP_STATUS_MULT-1U);
+ *max_idx = BOOT_SWAP_STATUS_MULT - 1U;
*copy_counter = 0;
/* return all erased values */
(void)memset(data, (int32_t)flash_area_erased_val(fap_stat), BOOT_SWAP_STATUS_PAYLD_SZ);
@@ -188,21 +170,21 @@
else {
/* no valid CRC found - status pre-read failure */
if (crc_fail == BOOT_SWAP_STATUS_MULT) {
- max_idx = -1;
+ rc = -1;
}
else {
*copy_counter = max_cnt;
/* read payload data */
rc = flash_area_read(fap_stat, data_offset, data, BOOT_SWAP_STATUS_PAYLD_SZ);
- if (rc != 0) {
- return BOOT_EFLASH;
- }
+ if (rc != 0) {
+ rc = -1;
+ }
}
}
flash_area_close(fap_stat);
/* return back duplicate index */
- return max_idx;
+ return rc;
}
static int swap_status_write_record(uint32_t rec_offset, uint32_t copy_num, uint32_t copy_counter, const uint8_t *data)
@@ -214,35 +196,28 @@
uint32_t next_counter = copy_counter + 1U;
uint32_t next_crc;
- uint8_t buff[BOOT_SWAP_STATUS_ROW_SZ];
-
const struct flash_area *fap_stat = NULL;
rc = flash_area_open(FLASH_AREA_IMAGE_SWAP_STATUS, &fap_stat);
if (rc != 0) {
- return BOOT_EFLASH;
+ return -1;
}
/* copy data into buffer */
- (void)memcpy(buff, data, BOOT_SWAP_STATUS_PAYLD_SZ);
+ (void)memcpy(record_buff, data, BOOT_SWAP_STATUS_PAYLD_SZ);
/* append next counter to whole record row */
- (void)memcpy(&buff[BOOT_SWAP_STATUS_ROW_SZ-BOOT_SWAP_STATUS_CNT_SZ-BOOT_SWAP_STATUS_CRC_SZ], \
- &next_counter, \
+ (void)memcpy(&record_buff[BOOT_SWAP_STATUS_ROW_SZ-BOOT_SWAP_STATUS_CNT_SZ-BOOT_SWAP_STATUS_CRC_SZ],
+ (uint8_t *)&next_counter,
BOOT_SWAP_STATUS_CNT_SZ);
/* append record magic */
- (void)memcpy(&buff[BOOT_SWAP_STATUS_ROW_SZ-\
- BOOT_SWAP_STATUS_MGCREC_SZ-\
- BOOT_SWAP_STATUS_CNT_SZ-\
- BOOT_SWAP_STATUS_CRC_SZ], \
- stat_part_magic, \
- BOOT_SWAP_STATUS_MGCREC_SZ);
+ (void)memcpy(&record_buff[BOOT_SWAP_STATUS_PAYLD_SZ], (const uint8_t *)stat_part_magic, BOOT_SWAP_STATUS_MGCREC_SZ);
/* calculate CRC field*/
- next_crc = calc_record_crc(buff, BOOT_SWAP_STATUS_ROW_SZ-BOOT_SWAP_STATUS_CRC_SZ);
+ next_crc = calc_record_crc(record_buff, BOOT_SWAP_STATUS_ROW_SZ-BOOT_SWAP_STATUS_CRC_SZ);
/* append new CRC to whole record row */
- (void)memcpy(&buff[BOOT_SWAP_STATUS_ROW_SZ-BOOT_SWAP_STATUS_CRC_SZ], \
- &next_crc, \
+ (void)memcpy(&record_buff[BOOT_SWAP_STATUS_ROW_SZ-BOOT_SWAP_STATUS_CRC_SZ],
+ (uint8_t *)&next_crc,
BOOT_SWAP_STATUS_CRC_SZ);
/* we already know what copy number was last and correct */
@@ -256,80 +231,108 @@
}
fin_offset = rec_offset + copy_num*BOOT_SWAP_STATUS_D_SIZE;
+ /* erase obsolete status record before write */
+ rc = flash_area_erase(fap_stat, fin_offset, sizeof(record_buff));
+ if (rc != 0) {
+ return -1;
+ }
+
/* write prepared record into flash */
- rc = flash_area_write(fap_stat, fin_offset, buff, sizeof(buff));
+ rc = flash_area_write(fap_stat, fin_offset, record_buff, sizeof(record_buff));
flash_area_close(fap_stat);
return rc;
}
+static int boot_magic_decode(uint8_t *magic)
+{
+ if (memcmp(magic, (const uint8_t *)boot_img_magic, BOOT_MAGIC_SZ) == 0) {
+ return BOOT_MAGIC_GOOD;
+ }
+ return BOOT_MAGIC_BAD;
+}
+
/**
* Updates len bytes of status partition with values from *data-pointer.
*
- * @param targ_area_id Target area id for which status is being written.
- * Not a status-partition area id.
- * @param offset Status byte offset inside status table. Should not include CRC and CNT.
- * @param data Pointer to data status table to needs to be updated with.
- * @param len Number of bytes to be written
+ * @param target_area_id Target area id for which status is being written.
+ * Not a status-partition area id.
+ * @param offset Status byte offset inside status table. Should not include CRC and CNT.
+ * @param data Pointer to data status table to needs to be updated with.
+ * @param len Number of bytes to be written
*
- * @return 0 on success; nonzero on failure.
+ * @return 0 on success; -1 on failure.
*/
-int swap_status_update(uint32_t targ_area_id, uint32_t offs, const void *data, uint32_t len)
+int swap_status_update(uint8_t target_area_id, uint32_t offs, const void *data, uint32_t len)
{
int rc = -1;
int32_t init_offs;
- int32_t length = (int32_t)len;
- int32_t copy_num;
+ uint32_t copy_num = 0;
uint32_t rec_offs;
uint32_t copy_sz;
- uint32_t copy_counter;
+ uint32_t copy_counter = 0;
uint32_t data_idx = 0;
- uint32_t buff_idx = offs%BOOT_SWAP_STATUS_PAYLD_SZ;
+ uint32_t buff_idx = offs % BOOT_SWAP_STATUS_PAYLD_SZ;
- uint8_t buff[BOOT_SWAP_STATUS_PAYLD_SZ];
+ if ((UINT32_MAX - offs) < len) {
+ return -1;
+ }
/* check if end of data is still inside writable area */
- assert ((int)((offs + len) <= BOOT_SWAP_STATUS_D_SIZE_RAW));
+ if ((offs + len) > BOOT_SWAP_STATUS_D_SIZE_RAW) {
+ return -1;
+ }
/* pre-calculate sub-area offset */
- init_offs = swap_status_init_offset(targ_area_id);
- assert ((int)(init_offs >= 0));
+ init_offs = swap_status_init_offset(target_area_id);
+ if (init_offs < 0) {
+ return -1;
+ }
/* will start from it
* this will be write-aligned */
rec_offs = (uint32_t)init_offs + calc_record_offs(offs);
/* go over all records to be updated */
- while (length > 0) {
+ while (len != 0U) {
/* preserve record */
- copy_num = swap_status_read_record(rec_offs, buff, ©_counter);
+ rc = swap_status_read_record(rec_offs, status_buff, ©_counter, ©_num);
/* it returns copy number */
- if (copy_num < 0)
+ if (rc < 0)
{ /* something went wrong while read, exit */
rc = -1;
break;
}
/* update record data */
- if (length > (int)BOOT_SWAP_STATUS_PAYLD_SZ) {
+ if (len > BOOT_SWAP_STATUS_PAYLD_SZ) {
copy_sz = BOOT_SWAP_STATUS_PAYLD_SZ - buff_idx;
}
else {
- copy_sz = (uint32_t)length;
+ copy_sz = len;
}
- (void)memcpy((void *)&buff[buff_idx], &((uint8_t *)data)[data_idx], copy_sz);
+
+ (void)memcpy(status_buff + buff_idx, (const uint8_t *)data + data_idx, copy_sz);
buff_idx = 0;
/* write record back */
- rc = swap_status_write_record(rec_offs, (uint32_t)copy_num, copy_counter, buff);
- assert ((int)(rc == 0));
+ rc = swap_status_write_record(rec_offs, copy_num, copy_counter, status_buff);
+ if (rc != 0) {
+ break;
+ }
/* proceed to next record */
- length -= (int32_t)BOOT_SWAP_STATUS_PAYLD_SZ;
- rec_offs += BOOT_SWAP_STATUS_ROW_SZ;
- data_idx += BOOT_SWAP_STATUS_PAYLD_SZ;
+ if (len < BOOT_SWAP_STATUS_PAYLD_SZ) {
+ len = 0;
+ }
+ else {
+ len -= BOOT_SWAP_STATUS_PAYLD_SZ;
+ rec_offs += BOOT_SWAP_STATUS_ROW_SZ;
+ data_idx += BOOT_SWAP_STATUS_PAYLD_SZ;
+ }
+
}
return rc;
}
@@ -337,68 +340,206 @@
/**
* Reads len bytes of status partition with values from *data-pointer.
*
- * @param targ_area_id Target area id for which status is being read.
- * Not a status-partition area id.
- * @param offset Status byte offset inside status table. Should not include CRC and CNT.
- * @param data Pointer to data where status table values will be written.
- * @param len Number of bytes to be read from status table.
+ * @param target_area_id Target area id for which status is being read.
+ * Not a status-partition area id.
+ * @param offset Status byte offset inside status table. Should not include CRC and CNT.
+ * @param data Pointer to data where status table values will be written.
+ * @param len Number of bytes to be read from status table.
*
- * @return 0 on success; nonzero on failure.
+ * @return 0 on success; -1 on failure.
*/
-int swap_status_retrieve(uint32_t target_area_id, uint32_t offs, void *data, uint32_t len)
+int swap_status_retrieve(uint8_t target_area_id, uint32_t offs, void *data, uint32_t len)
{
int rc = 0;
int32_t init_offs;
- int32_t length = (int32_t)len;
- int32_t copy_num;
+ uint32_t copy_num = 0;
uint32_t rec_offs;
uint32_t copy_sz;
- uint32_t copy_counter;
+ uint32_t copy_counter = 0;
uint32_t data_idx = 0;
uint32_t buff_idx = offs % BOOT_SWAP_STATUS_PAYLD_SZ;
- uint8_t buff[BOOT_SWAP_STATUS_PAYLD_SZ];
+ if ((UINT32_MAX - offs) < len) {
+ return -1;
+ }
/* check if end of data is still inside writable area */
- // TODO: update for multi image
- assert ((int)((offs + len) <= BOOT_SWAP_STATUS_D_SIZE_RAW));
+ if ((offs + len) > BOOT_SWAP_STATUS_D_SIZE_RAW) {
+ return -1;
+ }
/* pre-calculate sub-area offset */
init_offs = swap_status_init_offset(target_area_id);
- assert ((int)(init_offs >= 0));
+ if (init_offs < 0) {
+ return -1;
+ }
/* will start from it
* this will be write-aligned */
rec_offs = (uint32_t)init_offs + calc_record_offs(offs);
/* go over all records to be updated */
- while (length > 0) {
+ while (len != 0U) {
/* preserve record */
- copy_num = swap_status_read_record(rec_offs, buff, ©_counter);
+ rc = swap_status_read_record(rec_offs, status_buff, ©_counter, ©_num);
/* it returns copy number */
- if (copy_num < 0) {
+ if (rc < 0) {
/* something went wrong while read, exit */
rc = -1;
break;
}
/* update record data */
- if (length > (int)BOOT_SWAP_STATUS_PAYLD_SZ) {
+ if (len > BOOT_SWAP_STATUS_PAYLD_SZ) {
copy_sz = BOOT_SWAP_STATUS_PAYLD_SZ - buff_idx;
}
else {
- copy_sz = (uint32_t)length;
+ copy_sz = len;
}
- (void)memcpy(&((uint8_t *)data)[data_idx], &buff[buff_idx], copy_sz);
+
+ (void)memcpy((uint8_t *)data + data_idx, status_buff + buff_idx, copy_sz);
buff_idx = 0;
/* proceed to next record */
- length -= (int32_t)BOOT_SWAP_STATUS_PAYLD_SZ;
- rec_offs += BOOT_SWAP_STATUS_ROW_SZ;
- data_idx += BOOT_SWAP_STATUS_PAYLD_SZ;
+ if (len < BOOT_SWAP_STATUS_PAYLD_SZ) {
+ len = 0;
+ }
+ else {
+ len -= BOOT_SWAP_STATUS_PAYLD_SZ;
+ rec_offs += BOOT_SWAP_STATUS_ROW_SZ;
+ data_idx += BOOT_SWAP_STATUS_PAYLD_SZ;
+ }
}
return rc;
}
+/**
+ * Copy trailer from status partition to primary image and set copy_done flag.
+ * This function calls only once, before set copy_done flag in status trailer
+ *
+ * @param fap Target area id for which status is being read.
+ *
+ * @return 0 on success; -1 on failure.
+ */
+int swap_status_to_image_trailer(const struct flash_area *fap)
+{
+ uint8_t erased_val;
+ uint8_t stat_erased_val;
+ const uint8_t *copy_src;
+ uint32_t cur_trailer_pos;
+ uint32_t primary_trailer_sz;
+ uint32_t primary_trailer_buf_sz;
+ uint32_t align = CY_FLASH_ALIGN;
+ int rc = 0;
+ const struct flash_area *fap_stat = NULL;
+ uint8_t primary_trailer_buf[MAX_TRAILER_BUF_SIZE];
+
+ /* get the erased flash byte for status partition */
+ rc = flash_area_open(FLASH_AREA_IMAGE_SWAP_STATUS, &fap_stat);
+ if (rc != 0) {
+ return rc;
+ }
+ stat_erased_val = flash_area_erased_val(fap_stat);
+ flash_area_close(fap_stat);
+
+ /* get status partition trailer size and copy it to buffer */
+ const uint32_t status_trailer_buf_sz = BOOT_SWAP_STATUS_SWAPSZ_SZ + BOOT_SWAP_STATUS_SWAPINF_SZ +
+ BOOT_SWAP_STATUS_COPY_DONE_SZ + BOOT_SWAP_STATUS_IMG_OK_SZ + BOOT_SWAP_STATUS_MAGIC_SZ;
+ uint8_t status_trailer_buf[status_trailer_buf_sz];
+ (void)memset(&status_trailer_buf, 0, status_trailer_buf_sz);
+ rc = swap_status_retrieve(fap->fa_id, boot_swap_size_off(fap), (uint8_t *)status_trailer_buf, status_trailer_buf_sz);
+ if (rc != 0) {
+ return rc;
+ }
+
+ /* check trailer magic in status partition */
+ if (boot_magic_decode(&status_trailer_buf[status_trailer_buf_sz - BOOT_SWAP_STATUS_MAGIC_SZ]) != BOOT_MAGIC_GOOD) {
+ return -1;
+ }
+
+ /* get primary slot trailer size without status data fields */
+ primary_trailer_sz = boot_trailer_sz(0);
+
+ /* align image trailer buffer size to minimal write size */
+#if !defined(__BOOTSIM__)
+ align = flash_area_align(fap);
+#else
+ align = CY_FLASH_ALIGN;
+#endif
+
+ if ((align > MAX_TRAILER_BUF_SIZE) || (align == 0U)) {
+ return -1;
+ }
+
+ primary_trailer_buf_sz = align;
+ while (primary_trailer_buf_sz < primary_trailer_sz) {
+ primary_trailer_buf_sz += align;
+ }
+ if (primary_trailer_buf_sz > MAX_TRAILER_BUF_SIZE) {
+ return -1;
+ }
+
+ /* erase primary slot trailer */
+ rc= flash_area_erase(fap, fap->fa_size - primary_trailer_buf_sz, primary_trailer_buf_sz);
+ if (rc != 0) {
+ return rc;
+ }
+
+ /* erase trailer area */
+ erased_val = flash_area_erased_val(fap); /* stat_erased_val and erased_val may differ! */
+ (void)memset(&primary_trailer_buf[primary_trailer_buf_sz-primary_trailer_sz], (int) erased_val, primary_trailer_sz);
+
+ /* copy and align flags and data from status_trailer_buf to primary_trailer_buf
+ Status part trailer --> Pimary image trailer */
+
+ /* copy trailer magic */
+ cur_trailer_pos = primary_trailer_buf_sz - BOOT_SWAP_STATUS_MAGIC_SZ;
+ copy_src = &status_trailer_buf[status_trailer_buf_sz - BOOT_SWAP_STATUS_MAGIC_SZ];
+ if (stat_erased_val != erased_val &&
+ bootutil_buffer_is_filled(copy_src, stat_erased_val, BOOT_SWAP_STATUS_MAGIC_SZ)) {
+
+ (void)memset(&primary_trailer_buf[cur_trailer_pos], (int)erased_val, BOOT_SWAP_STATUS_MAGIC_SZ);
+ }
+ else {
+ (void)memcpy(&primary_trailer_buf[cur_trailer_pos], copy_src, BOOT_SWAP_STATUS_MAGIC_SZ);
+ }
+
+ /* copy image_ok flag */
+ cur_trailer_pos -= BOOT_MAX_ALIGN;
+ copy_src = &status_trailer_buf[BOOT_SWAP_STATUS_SWAPSZ_SZ + BOOT_SWAP_STATUS_SWAPINF_SZ + BOOT_SWAP_STATUS_COPY_DONE_SZ];
+ if (stat_erased_val != erased_val && stat_erased_val == *copy_src) {
+ copy_src = &erased_val;
+ }
+ primary_trailer_buf[cur_trailer_pos] = *copy_src;
+
+ /* set copy_done flag */
+ cur_trailer_pos -= BOOT_MAX_ALIGN;
+ primary_trailer_buf[cur_trailer_pos] = BOOT_FLAG_SET;
+
+ /* copy swap_type flag */
+ cur_trailer_pos -= BOOT_MAX_ALIGN;
+ copy_src = &status_trailer_buf[BOOT_SWAP_STATUS_SWAPSZ_SZ];
+ if (stat_erased_val != erased_val && stat_erased_val == *copy_src) {
+ copy_src = &erased_val;
+ }
+ primary_trailer_buf[cur_trailer_pos] = *copy_src;
+
+ /* copy swap_size field */
+ cur_trailer_pos -= BOOT_MAX_ALIGN;
+ if (stat_erased_val != erased_val &&
+ bootutil_buffer_is_filled(status_trailer_buf, stat_erased_val, BOOT_SWAP_STATUS_SWAPSZ_SZ)) {
+
+ (void)memset(&primary_trailer_buf[cur_trailer_pos], (int)erased_val, BOOT_SWAP_STATUS_SWAPSZ_SZ);
+ }
+ else {
+ (void)memcpy(&primary_trailer_buf[cur_trailer_pos], status_trailer_buf, BOOT_SWAP_STATUS_SWAPSZ_SZ);
+ }
+
+ /* write primary image trailer with copy_done flag set */
+ rc = flash_area_write(fap, fap->fa_size - primary_trailer_buf_sz, primary_trailer_buf, primary_trailer_buf_sz);
+
+ return rc;
+}
+
#endif /* MCUBOOT_SWAP_USING_STATUS */
diff --git a/boot/bootutil/src/tlv.c b/boot/bootutil/src/tlv.c
index 37d12a3..00f5a04 100644
--- a/boot/bootutil/src/tlv.c
+++ b/boot/bootutil/src/tlv.c
@@ -98,7 +98,9 @@
struct image_tlv tlv;
int rc;
- if (it == NULL || it->hdr == NULL || it->fap == NULL) {
+ if (it == NULL || it->hdr == NULL || it->fap == NULL ||
+ off == NULL || len == NULL) {
+
return -1;
}
diff --git a/boot/bootutil/zephyr/CMakeLists.txt b/boot/bootutil/zephyr/CMakeLists.txt
index 82985ce..ea1fc2b 100644
--- a/boot/bootutil/zephyr/CMakeLists.txt
+++ b/boot/bootutil/zephyr/CMakeLists.txt
@@ -12,10 +12,34 @@
../../zephyr/include
)
-zephyr_library()
+zephyr_library_named(mcuboot_util)
zephyr_library_sources(
../src/bootutil_public.c
)
+
+if(CONFIG_BOOT_IMAGE_ACCESS_HOOKS)
+ if(NOT CONFIG_BOOT_IMAGE_ACCESS_HOOKS_FILE STREQUAL "")
+ if(IS_ABSOLUTE ${CONFIG_BOOT_IMAGE_ACCESS_HOOKS_FILE})
+ if(EXISTS ${CONFIG_BOOT_IMAGE_ACCESS_HOOKS_FILE})
+ set(HOOKS_FILE ${CONFIG_BOOT_IMAGE_ACCESS_HOOKS_FILE})
+ endif()
+ elseif((DEFINED CONF_DIR) AND
+ (EXISTS ${CONF_DIR}/${CONFIG_BOOT_IMAGE_ACCESS_HOOKS_FILE}))
+ set(HOOKS_FILE ${CONF_DIR}/${CONFIG_BOOT_IMAGE_ACCESS_HOOKS_FILE})
+ else(EXISTS ${APPLICATION_SOURCE_DIR}/${CONFIG_BOOT_IMAGE_ACCESS_HOOKS_FILE})
+ set(HOOKS_FILE ${APPLICATION_SOURCE_DIR}/${CONFIG_BOOT_IMAGE_ACCESS_HOOKS_FILE})
+ endif()
+ endif()
+
+ if(DEFINED HOOKS_FILE)
+ zephyr_library_sources(
+ ${HOOKS_FILE}
+ )
+ else()
+ message(STATUS "No hooks implementation file.")
+ endif()
+endif()
+
zephyr_library_link_libraries(MCUBOOT_BOOTUTIL)
target_link_libraries(MCUBOOT_BOOTUTIL INTERFACE zephyr_interface)
endif()
diff --git a/boot/cypress/.gitignore b/boot/cypress/.gitignore
index 9a2c99f..e8f03b4 100644
--- a/boot/cypress/.gitignore
+++ b/boot/cypress/.gitignore
@@ -26,6 +26,11 @@
/scripts/*.egg-info
/scripts/*.egg
+# Pre_build autogenerated files
+MCUBootApp/flashmap.mk
+BlinkyApp/flashmap.mk
+cy_flash_pal/cy_flash_map.h
+
# Build dirs
*out/*/*
*out/obj/*
@@ -38,4 +43,13 @@
*.bin
*.hex
*.log
-*.lst
\ No newline at end of file
+*.lst
+*.objdump
+
+packets/*
+policy/*
+keys/*
+
+BlinkyApp.ld
+*.modus
+*.cysecuretools
\ No newline at end of file
diff --git a/boot/cypress/BlinkyApp/BlinkyApp.md b/boot/cypress/BlinkyApp/BlinkyApp.md
index d380673..f3f20da 100644
--- a/boot/cypress/BlinkyApp/BlinkyApp.md
+++ b/boot/cypress/BlinkyApp/BlinkyApp.md
@@ -1,191 +1,184 @@
-### Blinking LED Test Application For Mcubootapp Bootloading Application
+## Blinking LED test application for MCUBootApp bootloading application
### Description
-Implements simple Blinky LED CM4 application to demonstrate MCUBootApp bootloading application operation in terms of boot and upgrade processes.
+Implements a simple Blinky LED application to demonstrate the MCUBootApp bootloading application operation for the boot and upgrade processes.
-It is validated and started by MCUBootApp which is running on CM0p core of PSoC 6 device.
+It is validated and started by MCUBootApp, which is running on the CM0p core of PSoC™ 6 devices, or CM33 core for the CYW20829 device.
Functionality:
-* Blinks RED led with 2 different rates, depending on type of image - BOOT or UPGRADE.
-* Prints debug info and version of itself to terminal at 115200 baud rate.
-* Manages watchdog timer started in MCUBootApp as one of confirmation mechanisms.
-* Sets special bit in flash to confirm image is operable (UPGRADE image).
-* Can be built for BOOT slot or UPGRADE slot of bootloader.
+* Blinks red LED with 2 different rates, depending on the image type - BOOT or UPGRADE.
+* Prints debug info and the appplication version to the terminal at baud rate 115200.
+* Manages the watchdog-timer start in MCUBootApp as one of the confirmation mechanisms.
+* Sets a special bit in flash to confirm that the image is operable (UPGRADE image).
+* Can be built for boot slot or UPGRADE slot of the bootloader.
* Can be used to evaluate `swap` and `overwrite only` upgrade modes.
-### Hardware Limitations
+### Hardware limitations
-Since this application is created to demonstrate MCUBoot library features and not as reference examples some considerations are taken.
+This application is created to demonstrate the MCUboot library features.
-1. Port/pin `P5_0` and `P5_1` used to configure serial port for debug prints. These pins are the most commonly used for serial port connection among available Cypress PSoC 6 kits. If you try to use custom hardware with this application - change definitions of `CY_DEBUG_UART_TX` and `CY_DEBUG_UART_RX` in `main.c` of BlinkyApp to port/pin pairs corresponding to your design.
-2. Port `GPIO_PRT13` pin `7U` used to define user connection LED. This pin is the most commonly used for USER_LED connection among available Cypress PSoC 6 kits. If you try to use custom hardware with this application - change definitions of `LED_PORT` and `LED_PIN` in `main.c` of BlinkyApp to port/pin pairs corresponding to your design.
+1. Port/pin `P5_0` and `P5_1` are used to configure a serial port for debug prints. These pins are the most commonly used for serial port connection among available Cypress PSoC™ 6 kits. To use custom hardware with this application, change the definitions of `CY_DEBUG_UART_TX` and `CY_DEBUG_UART_RX` in `main.c` of BlinkyApp to port/pin pairs corresponding to your design.
+2. Port `GPIO_PRT13` pin `7U` is used to define the user connection-LED. This pin is the most commonly used for USER_LED connection among available Cypress PSoC™ 6 kits. To use custom hardware with this application, change the definitions of `LED_PORT` and `LED_PIN` in `main.c` of BlinkyApp to port/pin pairs corresponding to your design.
-### Pre-build Action
+### Pre-build action
-Pre-build action is implemented to define start address and size of flash, as well as RAM start address and size for BlinkyApp.
+Pre-build action is implemented to define the start address and flash size, as well as the RAM start address and BlinkyApp size.
-These values are set by specifing following macros (default values shown):
-`SLOT_SIZE ?= 0x10000` - for slot located in internal flash
-`SLOT_SIZE ?= 0x40200` - for slot located in external flash
+`FLASH_MAP` `make` parameter is used to provide an input file for pre-build action. Refer to `MCUBootApp.md` for details.
-For PSoC 6 2M devices:
-`DEFINES_APP += -DRAM_START=0x08040000`
-`DEFINES_APP += -DRAM_SIZE=0x10000`
+The result of pre-build script is auto-generated `flashmap.mk` file with a set of makefile flags:
-For PSoC 6 1M and 512K devices:
-`DEFINES_APP += -DRAM_START=0x08020000`
-`DEFINES_APP += -DRAM_SIZE=0x10000`
+`PRIMARY_IMG_START` - start address of primary image in flash, this value is defined in the JSON flash map as the `"value"` field of the address section for `"application_#"`.
-For all devices:
-`DEFINES_APP += -DUSER_APP_START=0x10018000`
+`SECONDARY_IMG_START`- start address of secondary image in flash, this value is defined in the JSON flash map as the `"upgrade_address"` field of the `"address"` section for `"application_#"`.
-in `boot/cypress/BlinkyApp.mk`.
+`SLOT_SIZE` - slot size for the primary and the secondary images, this value is taken from `"value"` field of `"size"` section of `"application_#"` from JSON file.
-Pre-build action calls GCC preprocessor which replaces defines to particular values in `BlinkyApp_template.ld`.
+`BOOTLOADER_SIZE` - size of Bootloader application, this value is defined in the JSON flash map as the `"size"` field of the address section for `"bootloader"`.
-**Important**: make sure RAM areas of CM4-based BlinkyApp and CM0p-based MCUBootApp bootloader do not overlap.
+`USE_EXTERNAL_FLASH` - is set to 1 if flash map with `_smif` suffix is chosen.
-Memory (stack) corruption of CM0p application can cause failure if SystemCall-served operations invoked from CM4.
+`USE_XIP` - is set to 1 if the "external_flash" section with "mode": "XIP" is present in the flash map file.
-### Building An Application
+These values are set by specifying the following macros (default values shown):
+`SLOT_SIZE ?= 0x10000` - for slot located in internal flash of PSoC™ 6 chips
+`SLOT_SIZE ?= 0x40200` - for slot located in external flash of PsoC™ 6 kits
+`SLOT_SIZE ?= 0x20000` - for slot located in external flash of CYW20829 kits
-Supported platforms:
+The pre-build action also calls the GCC preprocessor, which replaces the defines to particular values in `BlinkyApp_template.ld`.
+
+**Important (PSoC™ 6)**: ensure that the RAM areas of CM4-based BlinkyApp and CM0p-based MCUBootApp bootloader do not overlap.
+
+Memory (stack) corruption of the CM0p application can cause a failure if SystemCall-served operations were invoked from CM4.
+
+### Building an application
+
+The supported platforms:
* PSOC_062_2M
* PSOC_062_1M
* PSOC_062_512K
+* CYW20829
-Root directory for build is **boot/cypress.**
+The root directory for build is **boot/cypress.**
-**Single image**
+**Single-image**
-The following command will build regular HEX file of a BlinkyApp for primary (BOOT) slot:
+The following command will build BlinkyApp as a regular HEX file for the primary (BOOT) slot to be used in single image case with `swap` upgrade type of Bootloader:
- make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=BOOT
+ make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=BOOT FLASH_MAP=cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_single.json IMG_ID=1
-_Note: HEADER_OFFSET=%SLOT_SIZE%_
+To build an image for the secondary (UPGRADE) slot to be used in single image case with `swap` upgrade type of Bootloader:
-To build image for secondary (UPGRADE) slot to use in `swap` upgrade:
+ make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE FLASH_MAP=cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_single.json IMG_ID=1
- make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE HEADER_OFFSET=0x10000 SWAP_UPGRADE=1
+To build an image for the secondary (UPGRADE) slot to be used in single image case with `overwrite` upgrade type of Bootloader:
-To build image for secondary (UPGRADE) slot to use in `overwrite only` upgrade:
+ make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE FLASH_MAP=cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_single.json IMG_ID=1
- make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE HEADER_OFFSET=0x10000 SWAP_UPGRADE=0
+**Multi-image**
-To build image for primary (BOOT) image for custom slot size `0x70000`:
+`BlinkyApp` can be built in multi-image bootloader configuration for PSoC™ 6 chips only.
- make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=BOOT SLOT_SIZE=0x70000
+To obtain the appropriate hex files to use with multi-image MCUBootApp, makefile flag `IMG_ID` is used.
-To build image for secondary (UPGRADE) image for custom slot size `0x70000` to use in `swap` upgrade:
+`IMG_ID` flag value should correspond to `application_#` number of JSON file used for build. For example to build `BlinkyApp` for UPGRADE slot of second image following command is used:
- make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE SLOT_SIZE=0x70000 HEADER_OFFSET=0x70000 SWAP_UPGRADE=1
+ make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE FLASH_MAP=cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_single.json IMG_ID=2
-**Multi image**
-
-`BlinkyApp` can be built to use in multi image bootloader configuration.
-
-To obtain appropriate hex files to use with multi image MCUBootApp, makefile flag `HEADER_OFFSET=` can be used.
-
-Example usage:
-
-Considering default config:
-
-* first image BOOT (PRIMARY) slot starts `0x10018000`
-* slot size `0x10000`
-* second image BOOT (PRIMARY) slot starts at `0x10038000`
-
-To obtain appropriate artifact for second image PRIMARY slot run this command:
-
- make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=BOOT HEADER_OFFSET=0x20000
-
-*Note:* only 2 images are supported at the moment.
+When this option is omitted, `IMG_ID=1` is assumed.
**Upgrade mode dependency**
-`MCUBootApp` can upgrade image either by overwriting an image from a secondary slot to a primary slot or by swapping the two images.
+`MCUBootApp` can upgrade an image either by overwriting the image from a secondary slot to a primary slot or by swapping the two images.
-To build `BlinkyApp` for different upgrade mode `SWAP_UPGRADE` flag is used.
+To build `BlinkyApp` for different upgrade mode choose flash map JSON file with the corresponding suffix - either _swap_ or _overwrite_.
-`SWAP_UPGRADE=0` - for overwrite mode.
-`SWAP_UPGRADE=1` - for swap upgrade mode (default).
+**Upgrade image for external memory (PSoC™ 6)**
-**Upgrade image for external memory**
+To prepare MCUBootApp for work with external memory, refer to [ExternalMemory.md](../MCUBootApp/ExternalMemory.md).
-To prepare MCUBootApp for work with external memory refer to `MCUBootApp/ExternalMemory.md`.
+To build a `BlinkyApp` upgrade image for external memory to be used in single image configuration with overwrite upgrade mode, use command:
-To build `BlinkyApp` upgrade image for external memory use command:
+ make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE FLASH_MAP=cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_single_smif.json IMG_ID=1
- make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE HEADER_OFFSET=0x7FE8000 ERASED_VALUE=0xff USE_EXTERNAL_FLASH=1
+`ERASED_VALUE` defines the memory cell contents in the erased state. It is `0x00` for PSoC™ 6 internal flash and `0xff` for S25FL512S. For `CYW20289` default value is `0xff` since it only uses an external flash.
-`HEADER_OFFSET` defines the offset from original boot image address. This one in line above suggests secondary slot will start from `0x18000000`, which is a start of external memory related addreses on PSoC 6 devices.
+In multi-image configuration, an upgrade image for the second application is built using command:
-`ERASED_VALUE` defines the memory cell contents in erased state. It is `0x00` for PSoC 6 internal Flash and `0xff` for S25FL512S.
-
-In case of using muti-image configuration, upgrade image for second application can be built using next command:
-
- make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE HEADER_OFFSET=0x8228000 ERASED_VALUE=0xff USE_EXTERNAL_FLASH=1
-
-Note: for S25FL512S block address should be mutiple of 0x40000.
+ make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE FLASH_MAP=cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_multi_smif.json IMG_ID=2
**Encrypted upgrade image**
-To prepare MCUBootApp for work with encrypted upgrade image please refer to `MCUBootApp/Readme.md`.
+To prepare MCUBootApp for work with an encrypted upgrade image, refer to [MCUBootApp.md](../MCUBootApp/MCUBootApp.md).
-To obtain encrypted upgrade image of BlinkyApp extra flag ENC_IMG=1 should be passed in command line, for example:
+To obtain an encrypted upgrade image of BlinkyApp, pass extra flag `ENC_IMG=1` in the command line, for example:
- make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE HEADER_OFFSET=0x20000 ENC_IMG=1
+ make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE FLASH_MAP=cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_single_smif.json IMG_ID=1 ENC_IMG=1
-This also suggests user already placed corresponing *.pem key in \keys folder. The key variables are defined in root Makefile as SIGN_KEY_FILE and ENC_KEY_FILE
+This also suggests that the user has already placed a corresponding *.pem key in the \keys folder. The key variables are defined in root Makefile as SIGN_KEY_FILE and ENC_KEY_FILE
-### Complete Build Flags Description
-- `BUILDCFG` - configuration type
+Refer to [CYW20829.md](../platforms/CYW20829/CYW20829.md) for details of encrypted image build for the CYW20289 platfrom.
+
+### Complete build flags description
+- `BUILDCFG` - The configuration type
- Release
- Debug
-- `MAKEINFO` - build verbosity level
+- `VERBOSE` - The build verbosity level
- 0 (default) - less build info
- 1 - verbose output of compilation
- `PLATFORM`
- - `PSOC_062_2M` - only supported now
-- `SLOT_SIZE` - size of primary/secondary slot of MCUBootApp this app will be used with
+ - `PSOC_062_2M`
+ - `PSOC_062_1M`
+ - `PSOC_062_512K`
+ - `CYW20289`
+- `SLOT_SIZE` - The size of the primary/secondary slot of MCUBootApp. This app will be used with
- 0x%VALUE%
-- `HEADER_OFFSET` - shift start address of image by value
- - 0 (default) - no offset of output hex file
- - 0x%VALUE% - offset for output hex file
-- `IMG_TYPE` - for which slot of MCUBootApp image is build
- - `BOOT` (default) - build image for primary (BOOT) slot
- - `UPGRADE` - build image for secondary (UPGRADE) slot
-- `SWAP_UPGRADE` - define upgrade mode type on `MCUBootApp` this app will be used with
- - `0` - for overwrite mode.
- - `1` - (default) for swap upgrade mode
-- `ERASED_VALUE` - define memory cell contents in erased state
- - `0x0` - internal memory
- - `0xff` - external memory
-- `TOOLCHAIN_PATH` - path to gcc compiler to use for build
- - Example: TOOLCHAIN_PATH=/home/fw-security/ModusToolbox/tools_2.0/gcc-7.2.1
- - Example: TOOLCHAIN_PATH=C:\gcc
+- `IMG_TYPE` - The slot of MCUBootApp, for which the image is being built.
+ - `BOOT` (default) - A build image for the primary (BOOT) slot.
+ - `UPGRADE` - A build image for the secondary (UPGRADE) slot.
+- `ERASED_VALUE` - Define memory cell contents in the erased state.
+ - `0x0` - Internal memory.
+ - `0xff` - External memory.
+- `TOOLCHAIN_PATH` - The path to the GCC compiler to use for build.
+ - Example: TOOLCHAIN_PATH=/home/user/ModusToolbox/tools_2.4/gcc
+ - Example: TOOLCHAIN_PATH=C:/ModusToolbox/tools_2.4/gcc
-### Post-Build
+Flags set by pre-build action.
-Post build action is executed at compile time for `BlinkyApp`. In case of build for `PSOC_062_2M`, `PSOC_062_1M`, `PSOC_062_512K` platforms it calls `imgtool` from `MCUBoot` scripts and adds signature to compiled image.
+- `USE_OVERWRITE` - Define the Upgrade mode type of `MCUBootApp` to use with this app.
+ - `1` - For Overwrite mode.
+ - `0` - (default) For Swap Upgrade mode.
+- `USE_EXTERNAL_FLASH` - Define support of external flash.
+ - `1` - external flash is present.
+ - `0` - external flash is absent.
+- `USE_XIP` - Define support of eXecute in Place mode.
+ - `0` - Not used
+ - `1` - Used
-Flags passed to `imgtool` for signature are defined in `SIGN_ARGS` variable in BlinkyApp.mk.
+### Post-build
-### How To Program An Application
+The post-build action is executed at the compile time for `BlinkyApp`. For the `PSOC_062_2M`, `PSOC_062_1M`, `PSOC_062_512K` platforms, it calls `imgtool` from `MCUboot` scripts and adds a signature to the compiled image.
-There are couple ways of programming BlinkyApp firmware. Following instructions assume usage of one of Cypress development kits, for example `CY8CPROTO_062_4343W`.
+Flags passed to `imgtool` for a signature are defined in the `SIGN_ARGS` variable in BlinkyApp.mk.
+
+For `CYW20829`, `cysecuretools` is used for the image signing.
+
+### How to program an application
+
+BlinkyApp firmware can be programmed in different ways. The following instructions assume the usage of one of Cypress development kits, for example `CY8CPROTO_062_4343W`.
1. Direct usage of OpenOCD.
-OpenOCD package is supplied with ModusToolbox IDE and can be found in installation folder under `./tools_2.1/openocd`.
+Connect a board to your computer. Switch Kitprog3 to DAP-BULK mode by clicking the `SW3 MODE` button until `LED2 STATUS` constantly shines.
-Open terminal application - and execute following command after substitution `PATH_TO_APPLICATION.hex` and `OPENOCD` paths.
+The OpenOCD package is supplied with ModusToolbox™ IDE and can be found in the ModusToolbox™ installation folder `ModusToolbox/tools_2.4/openocd`.
-Connect a board to your computer. Switch Kitprog3 to DAP-BULK mode by pressing `SW3 MODE` button until `LED2 STATUS` constantly shines.
+Open the terminal application and execute the following command after substitution of the `PATH_TO_APPLICATION.hex` and `OPENOCD` paths:
- export OPENOCD=/Applications/ModusToolbox/tools_2.1/openocd
+ export OPENOCD=/Applications/ModusToolbox/tools_2.4/openocd
${OPENOCD}/bin/openocd -s ${OPENOCD}/scripts \
-f ${OPENOCD}/scripts/interface/kitprog3.cfg \
@@ -197,48 +190,48 @@
Follow [link](https://www.cypress.com/products/psoc-programming-solutions) to download.
-Connect board to your computer. Switch Kitprog3 to DAP-BULK mode by pressing `SW3 MODE` button until `LED2 STATUS` constantly shines. Open `Cypress Programmer` and click `Connect`, then choose hex file: `MCUBootApp.hex` or `BlinkyApp.hex` and click `Program`. Check log to ensure programming success. Reset board.
+Connect the board to your computer. Switch Kitprog3 to DAP-BULK mode by clicking the `SW3 MODE` button until `LED2 STATUS` constantly shines. Open `Cypress Programmer` and click `Connect`, then choose the hex file `MCUBootApp.hex` or `BlinkyApp.hex`, and finally click `Program`. Check the log to ensure that the programming is successful. Reset the board.
3. Using `DAPLINK`.
-Connect board to your computer. Switch embeded Kitprog3 to `DAPLINK` mode by pressing `SW3 MODE` button until `LED2 STATUS` blinks fast and mass storage device appeared in OS. Drag and drop `hex` files you wish to program to `DAPLINK` drive in your OS.
+Connect the board to your computer. Switch embedded Kitprog3 to `DAPLINK` mode by clicking the `SW3 MODE` button until `LED2 STATUS` blinks fast and the USB mass storage device displays in the OS. Drag and drop the `hex` files to be programmed to the `DAPLINK` drive in your OS.
**Hex file names to use for programming**
-`BlinkyApp` always produce build artifacts in 2 separate folders: `BlinkyApp/out/PSOC_062_2M/Debug/boot` and `BlinkyApp/out/PSOC_062_2M/Debug/upgrade`.
+`BlinkyApp` always produces build artifacts in two separate folders: `BlinkyApp/out/PSOC_062_2M/Debug/boot` and `BlinkyApp/out/PSOC_062_2M/Debug/upgrade`.
These files are ready to be flashed to the board:
-* **BlinkyApp.hex** from `boot` folder
-* **BlinkyApp_upgrade.hex** from `upgrade` folder
+* **BlinkyApp.hex** from the `boot` folder
+* **BlinkyApp_upgrade.hex** from the `upgrade` folder
-`BlinkyApp_unsigned.hex` hex file is also preserved in both cases for possible troubleshooting.
+The `BlinkyApp_unsigned.hex` hex file is also preserved in both cases for possible troubleshooting.
-**Important: When swap status upgrade mode used**
+**Important: When Swap status Upgrade mode is used**
- In case of using this application in a system with `swap` type of upgrade refer first to `MCUBootApp.md` section **SWAP/Expected lifecycle**.
+ While using this application in a system with the `swap` type of upgrade, refer first to the [MCUBootApp.md](../MCUBootApp/MCUBootApp.md) section **SWAP/Expected lifecycle**.
-**BlinkyApp.hex** should be programmed to a device once. All firmware upgrades should be delivered using secondary (UPGRADE) slot thus **BlinkyApp_upgrade.hex** image.
+**BlinkyApp.hex** can be programmed to a device once. All firmware upgrades are delivered using the secondary (UPGRADE) slot, thus a **BlinkyApp_upgrade.hex** image.
-If user for some reason tries to program **BlinkyApp.hex** to primary slot directly second time - **system state should be reset**.
+If the user tries to program **BlinkyApp.hex** to the primary slot directly for the second time - **system state should be reset**.
-To reset system state at least `swap status partition` area in flash should be erased - see addresses in `MCUBootApp.md` paragraph **Memory maps**.
+To reset the system state, erase at least the `swap status partition` area in flash - see the addresses in the [MCUBootApp.md](../MCUBootApp/MCUBootApp.md) paragraph **Memory maps**.
-To erase swap status partition area in MCUBootApp with a single image configuration with default memory map using `OpenOCD` execute command:
+To erase the swap status partition area in MCUBootApp with single-image configuration with the default memory map, use the `OpenOCD` command:
$OPENOCD_PATH/bin/openocd -s "$OPENOCD_PATH/scripts" -f "$OPENOCD_PATH/ scripts/interface/kitprog3.cfg" -f "$OPENOCD_PATH/scripts/target/psoc6_2m.cfg" -c "init; reset init" -c "flash erase_address 0x10038000 0x1000" -c "reset; shutdown"
-To erase swap status partition area in MCUBootApp with a multi image configuration with default memory map using `OpenOCD` execute command:
+To erase the swap status partition area in MCUBootApp with multi-image configuration with the default memory map, use the `OpenOCD` command:
$OPENOCD_PATH/bin/openocd -s "$OPENOCD_PATH/scripts" -f "$OPENOCD_PATH/ scripts/interface/kitprog3.cfg" -f "$OPENOCD_PATH/scripts/target/psoc6_2m.cfg" -c "init; reset init" -c "flash erase_address 0x10078000 0x2000" -c "reset; shutdown"
-In both cases it is easier to erase all device flash or all flash after MCUBootApp. This command erases all flash after MCUBootApp including primary, secondary and swap status partiton.
+In both cases, it is easier to erase the whole device flash or all flash after MCUBootApp. This command erases all flash after MCUBootApp, including the primary, secondary, and swap status partiton:
- $OPENOCD_PATH/bin/openocd -s "$OPENOCD_PATH/scripts" -f "$OPENOCD_PATH/ scripts/interface/kitprog3.cfg" -f "$OPENOCD_PATH/scripts/target/psoc6_2m.cfg" -c "init; reset init" -c "flash erase_address 0x10018000" -c "reset; shutdown"
+ $OPENOCD_PATH/bin/openocd -s "$OPENOCD_PATH/scripts" -f "$OPENOCD_PATH/ scripts/interface/kitprog3.cfg" -f "$OPENOCD_PATH/scripts/target/psoc6_2m.cfg" -c "init; reset init" -c "flash erase_address 0x10018000 0x1E8000" -c "reset; shutdown"
-### Example Terminal Output
+### Example terminal output
-When user application programmed in BOOT slot:
+When the user application is programmed in the boot slot:
===========================
[BlinkyApp] BlinkyApp v1.0 [CM4]
@@ -250,7 +243,7 @@
[BlinkyApp] Update watchdog timer started in MCUBootApp to mark sucessful start of user app
[BlinkyApp] Turn off watchdog timer
-When user application programmed in UPRADE slot and upgrade procedure was successful:
+When the user application is programmed in the upgrade slot and the upgrade procedure was successful:
===========================
[BlinkyApp] BlinkyApp v2.0 [+]
diff --git a/boot/cypress/BlinkyApp/BlinkyApp.mk b/boot/cypress/BlinkyApp/BlinkyApp.mk
index edfaed6..d06cd99 100644
--- a/boot/cypress/BlinkyApp/BlinkyApp.mk
+++ b/boot/cypress/BlinkyApp/BlinkyApp.mk
@@ -32,89 +32,21 @@
# - image type to BOOT
COMPILER ?= GCC_ARM
IMG_TYPE ?= BOOT
-
-# For which core this application is built
-CORE ?= CM4
+IMG_ID ?= 1
# image type can be BOOT or UPGRADE
IMG_TYPES = BOOT UPGRADE
-# use SWAP_UPGRADE = 0 for overwrite only mode
-# use SWAP_UPGRADE = 1 for swap upgrade mode
-SWAP_UPGRADE ?= 1
-
-# possible values are 0 and 0xff
-# internal Flash by default
-ERASED_VALUE ?= 0
-
-ifneq ($(COMPILER), GCC_ARM)
-$(error Only GCC ARM is supported at this moment)
-endif
-
CUR_APP_PATH = $(PRJ_DIR)/$(APP_NAME)
-include $(PRJ_DIR)/platforms.mk
-include $(PRJ_DIR)/common_libs.mk
-include $(PRJ_DIR)/toolchains.mk
-
-# Application-specific DEFINES
-ifeq ($(IMG_TYPE), BOOT)
- DEFINES_APP := -DBOOT_IMG
-else
- DEFINES_APP := -DUPGRADE_IMG
- DEFINES_APP += -DSWAP_ENABLED=$(SWAP_UPGRADE)
+ifneq ($(FLASH_MAP), )
+$(CUR_APP_PATH)/flashmap.mk:
+ $(PYTHON_PATH) scripts/flashmap.py -p $(PLATFORM) -i $(FLASH_MAP) -o $(PRJ_DIR)/cy_flash_pal/cy_flash_map.h -d $(IMG_ID) > $(CUR_APP_PATH)/flashmap.mk
+include $(CUR_APP_PATH)/flashmap.mk
+DEFINES_APP := -DCY_FLASH_MAP_JSON
endif
-# Define start of application, RAM start and size, slot size
-ifeq ($(PLATFORM), PSOC_062_2M)
- DEFINES_APP += -DRAM_START=0x08040000
- DEFINES_APP += -DRAM_SIZE=0x10000
-else ifeq ($(PLATFORM), PSOC_062_1M)
- DEFINES_APP += -DRAM_START=0x08020000
- DEFINES_APP += -DRAM_SIZE=0x10000
-else ifeq ($(PLATFORM), PSOC_062_512K)
- DEFINES_APP += -DRAM_START=0x08020000
- DEFINES_APP += -DRAM_SIZE=0x10000
-endif
-ifeq ($(USE_EXTERNAL_FLASH), 1)
-$(warning You are trying to build BlinkyApp for MCUBootApp with external memory support. Ensure you build MCUBootApp with USE_EXTERNAL_FLASH=1 flag!)
- SLOT_SIZE ?= 0x40200
-else
- SLOT_SIZE ?= 0x10000
-endif
-
-DEFINES_APP += -DUSER_APP_SIZE=$(SLOT_SIZE)
-DEFINES_APP += -DUSER_APP_START=0x10018000
-
-# Collect Test Application sources
-SOURCES_APP_SRC := $(wildcard $(CUR_APP_PATH)/*.c)
-# Collect all the sources
-SOURCES_APP += $(SOURCES_APP_SRC)
-
-# Collect includes for BlinkyApp
-INCLUDE_DIRS_APP := $(addprefix -I, $(CURDIR))
-INCLUDE_DIRS_APP += $(addprefix -I, $(CUR_APP_PATH))
-
-# Overwite path to linker script if custom is required, otherwise default from BSP is used
-ifeq ($(COMPILER), GCC_ARM)
-LINKER_SCRIPT := $(subst /cygdrive/c,c:,$(CUR_APP_PATH)/linker/$(APP_NAME).ld)
-else
-$(error Only GCC ARM is supported at this moment)
-endif
-
-ASM_FILES_APP :=
-ASM_FILES_APP += $(ASM_FILES_STARTUP)
-
-# We still need this for MCUBoot apps signing
-IMGTOOL_PATH ?= ../../scripts/imgtool.py
-
-# add flag to imgtool if not using swap for upgrade
-ifeq ($(SWAP_UPGRADE), 0)
-UPGRADE_TYPE := --overwrite-only
-endif
-
-SIGN_ARGS := sign --header-size 1024 --pad-header --align 8 -v "2.0" -S $(SLOT_SIZE) -M 512 $(UPGRADE_TYPE) -R $(ERASED_VALUE) -k keys/$(SIGN_KEY_FILE).pem
-
+# TODO: optimize here and in MCUBootApp.mk
# Output folder
OUT := $(APP_NAME)/out
# Output folder to contain build artifacts
@@ -122,25 +54,201 @@
OUT_CFG := $(OUT_TARGET)/$(BUILDCFG)
+BOOTLOADER_SIZE ?= $(PLATFORM_BOOTLOADER_SIZE)
+
# Set build directory for BOOT and UPGRADE images
ifeq ($(IMG_TYPE), UPGRADE)
- ifeq ($(ENC_IMG), 1)
- SIGN_ARGS += --encrypt ../../$(ENC_KEY_FILE).pem
- SIGN_ARGS += --use-random-iv
- endif
- SIGN_ARGS += --pad
- UPGRADE_SUFFIX :=_upgrade
OUT_CFG := $(OUT_CFG)/upgrade
else
OUT_CFG := $(OUT_CFG)/boot
endif
+# Set parameters needed for signing
+ifeq ($(IMG_TYPE), UPGRADE)
+ UPGRADE_SUFFIX :=_upgrade
+endif
+
+include $(PRJ_DIR)/platforms.mk
+include $(PRJ_DIR)/common_libs.mk
+include $(PRJ_DIR)/toolchains.mk
+
+# use USE_OVERWRITE = 1 for overwrite only mode
+# use USE_OVERWRITE = 0 for swap upgrade mode
+ifeq ($(USE_OVERWRITE), )
+USE_OVERWRITE ?= $(PLATFORM_DEFAULT_USE_OVERWRITE)
+endif
+
+# possible values are 0 and 0xff
+# internal Flash by default
+ifeq ($(ERASED_VALUE), )
+ERASED_VALUE ?= $(PLATFORM_DEFAULT_ERASED_VALUE)
+endif
+
+# Application-specific DEFINES
+ifeq ($(IMG_TYPE), BOOT)
+ DEFINES_APP := -DBOOT_IMAGE
+ ENC_IMG := 0
+else
+ DEFINES_APP := -DUPGRADE_IMAGE
+ DEFINES_APP += -DSWAP_DISABLED=$(USE_OVERWRITE)
+endif
+
+# Inherit platform default values for application start
+# if not set directly as make command argument
+# App start may vary, depending on mode of operation
+# for example in XIP mode image start adress and app start
+# address may be different
+USER_APP_START ?= $(PLATFORM_USER_APP_START)
+
+ifeq ($(USER_APP_RAM_START), )
+USER_APP_RAM_START ?= $(PLATFORM_DEFAULT_RAM_START)
+endif
+ifeq ($(USER_APP_RAM_SIZE), )
+USER_APP_RAM_SIZE ?= $(PLATFORM_DEFAULT_RAM_SIZE)
+endif
+
+DEFINES_APP += -DUSER_APP_RAM_START=$(USER_APP_RAM_START)
+DEFINES_APP += -DUSER_APP_RAM_SIZE=$(USER_APP_RAM_SIZE)
+DEFINES_APP += -DUSER_APP_START=$(USER_APP_START)
+DEFINES_APP += -DPRIMARY_IMG_START=$(PRIMARY_IMG_START)
+DEFINES_APP += -DUSER_APP_SIZE=$(SLOT_SIZE)
+DEFINES_APP += $(PLATFORM_DEFINES_APP)
+
+ifeq ($(USE_XIP), 1)
+DEFINES_APP += -DUSE_XIP
+LD_SUFFIX = _xip
+endif
+
+# Add version metadata to image
+ifneq ($(IMG_VER), )
+IMG_VER_ARG = -v "$(IMG_VER)"
+else
+IMG_VER_ARG = $(PLATFORM_DEFAULT_IMG_VER_ARG)
+$(info WARNING - setting platform default version number, to set custom value - pass IMG_VER=x.x.x argument to make command)
+endif
+
+# Add dependencies metadata to image
+ifneq ($(IMG_DEPS_ID), )
+ifneq ($(IMG_DEPS_VER), )
+IMG_DEPS_ARG = -d "($(IMG_DEPS_ID), $(IMG_DEPS_VER))"
+endif
+endif
+
+# Collect Test Application sources
+SOURCES_APP_SRC := $(wildcard $(CUR_APP_PATH)/*.c)
+
+# Include confirmation flag setting (img_ok) implementation
+ifeq ($(IMG_TYPE), UPGRADE)
+ifeq ($(USE_OVERWRITE), 0)
+SOURCES_APP_SRC += $(PRJ_DIR)/platforms/$(FAMILY)/img_confirm/set_img_ok.c
+endif
+endif
+
+# Set offset for secondary image
+ifeq ($(IMG_TYPE), UPGRADE)
+HEADER_OFFSET := $(SECONDARY_IMG_START)
+else
+HEADER_OFFSET := $(PRIMARY_IMG_START)
+endif
+
+# Collect all the sources
+SOURCES_APP += $(SOURCES_APP_SRC)
+SOURCES_APP += $(PLATFORM_SOURCES_FLASH)
+
+# Collect includes for BlinkyApp
+INCLUDE_DIRS_APP := $(addprefix -I, $(CURDIR))
+INCLUDE_DIRS_APP += $(addprefix -I, $(CUR_APP_PATH))
+INCLUDE_DIRS_APP += $(addprefix -I, $(PLATFORM_INCLUDE_DIRS_FLASH))
+
+# ++++
+INCLUDE_DIRS_APP += $(addprefix -I, $(PRJ_DIR)/MCUBootApp/config)
+INCLUDE_DIRS_APP += $(addprefix -I, $(PRJ_DIR)/MCUBootApp)
+INCLUDE_DIRS_APP += $(addprefix -I, $(PRJ_DIR)/../bootutil/include)
+INCLUDE_DIRS_APP += $(addprefix -I, $(PRJ_DIR)/../bootutil/src)
+INCLUDE_DIRS_APP += $(addprefix -I, $(PRJ_DIR)/../bootutil/include/bootutil)
+# +++
+
+# Overwite path to linker script if custom is required, otherwise default from BSP is used
+ifeq ($(COMPILER), GCC_ARM)
+LINKER_SCRIPT := $(CUR_APP_PATH)/linker/$(APP_NAME).ld
+else
+$(error Only GCC ARM is supported at this moment)
+endif
+
+ASM_FILES_APP :=
+ASM_FILES_APP += $(ASM_FILES_STARTUP)
+
+# add flag to imgtool if not using swap for upgrade
+ifeq ($(USE_OVERWRITE), 1)
+UPGRADE_TYPE := --overwrite-only
+endif
+
+SIGN_ARGS := $(PLATFORM_SIGN_ARGS) $(IMG_VER_ARG) $(IMG_DEPS_ARG)
+
+# Set parameters needed for signing
+ifeq ($(IMG_TYPE), UPGRADE)
+ # Set img_ok flag to trigger swap type permanent
+ ifeq ($(CONFIRM), 1)
+ SIGN_ARGS += --confirm
+ endif
+ SIGN_ARGS += --pad
+endif
+
+$(info $(SIGN_ARGS))
+
pre_build:
$(info [PRE_BUILD] - Generating linker script for application $(CUR_APP_PATH)/linker/$(APP_NAME).ld)
- @$(CC) -E -x c $(CFLAGS) $(INCLUDE_DIRS) $(CUR_APP_PATH)/linker/$(APP_NAME)_template.ld | grep -v '^#' >$(CUR_APP_PATH)/linker/$(APP_NAME).ld
+ @$(CC) -E -x c $(CFLAGS) $(INCLUDE_DIRS) $(CUR_APP_PATH)/linker/$(APP_NAME)_$(CORE)_template$(LD_SUFFIX).ld | grep -v '^#' >$(CUR_APP_PATH)/linker/$(APP_NAME).ld
-# Post build action to execute after main build job
-post_build: $(OUT_CFG)/$(APP_NAME).hex
- $(info [POST_BUILD] - Executing post build script for $(APP_NAME))
- mv -f $(OUT_CFG)/$(APP_NAME).hex $(OUT_CFG)/$(APP_NAME)_unsigned.hex
- $(PYTHON_PATH) $(IMGTOOL_PATH) $(SIGN_ARGS) $(OUT_CFG)/$(APP_NAME)_unsigned.hex $(OUT_CFG)/$(APP_NAME)$(UPGRADE_SUFFIX).hex
+###############################################################################
+# Print debug information about all settings used and/or set in this file
+ifeq ($(VERBOSE), 1)
+$(info #### BlinkyApp.mk ####)
+$(info APP_NAME <-- $(APP_NAME))
+$(info ASM_FILES_APP <-> $(ASM_FILES_APP))
+$(info ASM_FILES_STARTUP <-- $(ASM_FILES_STARTUP))
+$(info BUILDCFG <-- $(BUILDCFG))
+$(info CC <-- $(CC))
+$(info CFLAGS <-- $(CFLAGS))
+$(info COMPILER <-> $(COMPILER))
+$(info CONFIRM <-- $(CONFIRM))
+$(info CORE <-- $(CORE))
+$(info CURDIR <-- $(CURDIR))
+$(info CUR_APP_PATH <-- $(CUR_APP_PATH))
+$(info DEFINES_APP <-> $(DEFINES_APP))
+$(info ENC_IMG --> $(ENC_IMG))
+$(info ERASED_VALUE <-> $(ERASED_VALUE))
+$(info IMG_TYPE <-> $(IMG_TYPE))
+$(info INCLUDE_DIRS <-- $(INCLUDE_DIRS))
+$(info INCLUDE_DIRS_APP <-> $(INCLUDE_DIRS_APP))
+$(info LINKER_SCRIPT <-> $(LINKER_SCRIPT))
+$(info OUT <-> $(OUT))
+$(info OUT_CFG <-> $(OUT_CFG))
+$(info OUT_TARGET <-> $(OUT_TARGET))
+$(info PLATFORM <-- $(PLATFORM))
+$(info PLATFORM_DEFAULT_ERASED_VALUE <-- $(PLATFORM_DEFAULT_ERASED_VALUE))
+$(info PLATFORM_DEFAULT_RAM_SIZE <-- $(PLATFORM_DEFAULT_RAM_SIZE))
+$(info PLATFORM_DEFAULT_RAM_START <-- $(PLATFORM_DEFAULT_RAM_START))
+$(info PLATFORM_DEFAULT_SLOT_SIZE <-- $(PLATFORM_DEFAULT_SLOT_SIZE))
+$(info PLATFORM_DEFAULT_USER_APP_START <-- $(PLATFORM_DEFAULT_USER_APP_START))
+$(info PLATFORM_DEFAULT_PRIMARY_IMG_START <-- $(PLATFORM_DEFAULT_PRIMARY_IMG_START))
+$(info PLATFORM_DEFAULT_USE_OVERWRITE <-- $(PLATFORM_DEFAULT_USE_OVERWRITE))
+$(info PLATFORM_DEFINES_APP <-- $(PLATFORM_DEFINES_APP))
+$(info PLATFORM_INCLUDE_DIRS_FLASH <-- $(PLATFORM_INCLUDE_DIRS_FLASH))
+$(info PLATFORM_SIGN_ARGS <-- $(PLATFORM_SIGN_ARGS))
+$(info PLATFORM_SOURCES_FLASH <-- $(PLATFORM_SOURCES_FLASH))
+$(info PRJ_DIR <-- $(PRJ_DIR))
+$(info IMG_VER_ARG <-- $(IMG_VER_ARG))
+$(info IMG_DEPS_ARG <-- $(IMG_DEPS_ARG))
+$(info SIGN_ARGS <-> $(SIGN_ARGS))
+$(info SLOT_SIZE <-> $(SLOT_SIZE))
+$(info SOURCES_APP <-> $(SOURCES_APP))
+$(info SOURCES_APP_SRC <-> $(SOURCES_APP_SRC))
+$(info UPGRADE_SUFFIX --> $(UPGRADE_SUFFIX))
+$(info UPGRADE_TYPE --> $(UPGRADE_TYPE))
+$(info USER_APP_RAM_SIZE <-> $(USER_APP_RAM_SIZE))
+$(info USER_APP_RAM_START <-> $(USER_APP_RAM_START))
+$(info USER_APP_START <-> $(USER_APP_START))
+$(info PRIMARY_IMG_START <-> $(PRIMARY_IMG_START))
+$(info USE_OVERWRITE <-> $(USE_OVERWRITE))
+endif
diff --git a/boot/cypress/BlinkyApp/BlinkyApp_CM4_Debug.launch b/boot/cypress/BlinkyApp/BlinkyApp_CM4_Debug.launch
deleted file mode 100644
index 34a173b..0000000
--- a/boot/cypress/BlinkyApp/BlinkyApp_CM4_Debug.launch
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.openocd.launchConfigurationType">
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doContinue" value="false"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doDebugInRam" value="false"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doFirstReset" value="true"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateConsole" value="true"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateTelnetConsole" value="false"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doSecondReset" value="false"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbCLient" value="true"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbServer" value="true"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.enableSemihosting" value="true"/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.firstResetType" value="init"/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherCommands" value="set mem inaccessible-by-default off"/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherOptions" value=""/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerConnectionAddress" value=""/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerExecutable" value="${cy_tools_path:openocd}/bin/openocd"/>
-<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerGdbPortNumber" value="3333"/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerLog" value=""/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerOther" value="-s "${cy_tools_path:openocd}/scripts" -s "${workspace_loc}/BlinkyLED_config/GeneratedSource" -c "source [find interface/kitprog3.cfg]" -c "source [find target/psoc6_2m.cfg]" -c "gdb_port 3332" -c "puts stderr {Started by GNU MCU Eclipse}" -c "init; reset init""/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTclPortNumber" value="6666"/>
-<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTelnetPortNumber" value="4444"/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherInitCommands" value=""/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherRunCommands" value=""/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.secondResetType" value=""/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value=""/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value="/Users/rnok/repos/cy_mcuboot_project/cy_mcuboot/boot/cypress/BlinkyApp/out/boot/CY8CKIT-064S2-4343W/Debug/BlinkyApp.elf"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU MCU OpenOCD"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
-<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="false"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value=""/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value="/Users/rnok/repos/cy_mcuboot_project/cy_mcuboot/boot/cypress/BlinkyApp/out/CY8CKIT-064S2-4343W/Debug/boot/BlinkyApp.elf"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
-<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${cy_sdk_install_dir}/tools/gcc-7.2.1-1.0/bin/arm-none-eabi-gdb${cy_exe_platform_ext}"/>
-<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
-<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/>
-<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
-<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
-<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="boot/cypress/BlinkyApp/out/PSOC_062_2M/Debug/boot/BlinkyApp.elf"/>
-<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="cy_mcuboot"/>
-<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
-<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.1139973781"/>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/cy_mcuboot"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="4"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"> <memoryBlockExpression address="268566528" label="0x10020000"/> <memoryBlockExpression address="268632064" label="0x10030000"/> </memoryBlockExpressionList> "/>
-<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
-</launchConfiguration>
diff --git a/boot/cypress/BlinkyApp/libs.mk b/boot/cypress/BlinkyApp/libs.mk
index 6e1ba7a..08fc130 100644
--- a/boot/cypress/BlinkyApp/libs.mk
+++ b/boot/cypress/BlinkyApp/libs.mk
@@ -31,31 +31,59 @@
CUR_LIBS_PATH = $(PRJ_DIR)/libs
# Collect source files for Retarget-io
+ifneq ($(PLATFORM), CYW20829)
SOURCES_RETARGET_IO := $(wildcard $(CUR_LIBS_PATH)/retarget-io/*.c)
+endif
SOURCES_WATCHDOG := $(wildcard $(CUR_LIBS_PATH)/watchdog/*.c)
# Collect source files for HAL
-SOURCES_HAL := $(wildcard $(CUR_LIBS_PATH)/psoc6hal/COMPONENT_PSOC6HAL/source/*.c)
-SOURCES_HAL += $(wildcard $(CUR_LIBS_PATH)/psoc6hal/COMPONENT_PSOC6HAL/source/triggers/*.c)
-SOURCES_HAL += $(wildcard $(CUR_LIBS_PATH)/psoc6hal/COMPONENT_PSOC6HAL/source/pin_packages/*.c)
+ifneq ($(PLATFORM), CYW20829)
+SOURCES_HAL_BLINKY := $(wildcard $(CUR_LIBS_PATH)/mtb-hal-cat1/source/*.c)
+SOURCES_HAL_BLINKY += $(wildcard $(CUR_LIBS_PATH)/mtb-hal-cat1/COMPONENT_CAT1A/source/triggers/*.c)
+SOURCES_HAL_BLINKY += $(wildcard $(CUR_LIBS_PATH)/mtb-hal-cat1/COMPONENT_CAT1A/source/pin_packages/*.c)
+endif
# Retarget-io related include directories
INCLUDE_DIRS_RETARGET_IO := $(CUR_LIBS_PATH)/retarget-io
INCLUDE_DIRS_WATCHDOG := $(CUR_LIBS_PATH)/watchdog
# Collect dirrectories containing headers for PSOC6 HAL
-INCLUDE_DIRS_HAL := $(CUR_LIBS_PATH)/psoc6hal/include
-INCLUDE_DIRS_HAL += $(CUR_LIBS_PATH)/psoc6hal/COMPONENT_PSOC6HAL/include
-INCLUDE_DIRS_HAL += $(CUR_LIBS_PATH)/psoc6hal/COMPONENT_PSOC6HAL/include/pin_packages
-INCLUDE_DIRS_HAL += $(CUR_LIBS_PATH)/psoc6hal/COMPONENT_PSOC6HAL/include/triggers
+ifneq ($(PLATFORM), CYW20829)
+INCLUDE_DIRS_HAL_BLINKY := $(CUR_LIBS_PATH)/mtb-hal-cat1/COMPONENT_CAT1A
+INCLUDE_DIRS_HAL_BLINKY := $(CUR_LIBS_PATH)/mtb-hal-cat1/COMPONENT_CAT1A/include
+INCLUDE_DIRS_HAL_BLINKY += $(CUR_LIBS_PATH)/mtb-hal-cat1/include
+INCLUDE_DIRS_HAL_BLINKY += $(CUR_LIBS_PATH)/mtb-hal-cat1/include_pvt
+INCLUDE_DIRS_HAL_BLINKY += $(CUR_LIBS_PATH)/mtb-hal-cat1/COMPONENT_CAT1A/include/pin_packages
+INCLUDE_DIRS_HAL_BLINKY += $(CUR_LIBS_PATH)/mtb-hal-cat1/COMPONENT_CAT1A/include/triggers
+endif
# Collected source files for libraries
-SOURCES_LIBS += $(SOURCES_RETARGET_IO)
SOURCES_LIBS += $(SOURCES_WATCHDOG)
-SOURCES_LIBS += $(SOURCES_HAL)
+ifneq ($(PLATFORM), CYW20829)
+SOURCES_LIBS += $(SOURCES_RETARGET_IO)
+SOURCES_LIBS += $(SOURCES_HAL_BLINKY)
+endif
# Collected include directories for libraries
+INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_WATCHDOG))
+ifneq ($(PLATFORM), CYW20829)
INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_RETARGET_IO))
-INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_WATCHDOG))
-INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_HAL))
-INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_WATCHDOG))
+INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_HAL_BLINKY))
+endif
+
+###############################################################################
+# Print debug information about all settings used and/or set in this file
+ifeq ($(VERBOSE), 1)
+$(info #### libs.mk ####)
+$(info CUR_LIBS_PATH <-- $(CUR_LIBS_PATH))
+$(info INCLUDE_DIRS_HAL_BLINKY <-> $(INCLUDE_DIRS_HAL_BLINKY))
+$(info INCLUDE_DIRS_LIBS --> $(INCLUDE_DIRS_LIBS))
+$(info INCLUDE_DIRS_RETARGET_IO <-> $(INCLUDE_DIRS_RETARGET_IO))
+$(info INCLUDE_DIRS_WATCHDOG <-> $(INCLUDE_DIRS_WATCHDOG))
+$(info PLATFORM <-- $(PLATFORM))
+$(info PRJ_DIR <-- $(PRJ_DIR))
+$(info SOURCES_HAL_BLINKY <-> $(SOURCES_HAL_BLINKY))
+$(info SOURCES_LIBS --> $(SOURCES_LIBS))
+$(info SOURCES_RETARGET_IO <-> $(SOURCES_RETARGET_IO))
+$(info SOURCES_WATCHDOG <-> $(SOURCES_WATCHDOG))
+endif
diff --git a/boot/cypress/BlinkyApp/linker/BlinkyApp_CM33_template_xip.ld b/boot/cypress/BlinkyApp/linker/BlinkyApp_CM33_template_xip.ld
new file mode 100644
index 0000000..bf7ea08
--- /dev/null
+++ b/boot/cypress/BlinkyApp/linker/BlinkyApp_CM33_template_xip.ld
@@ -0,0 +1,503 @@
+/***************************************************************************//**
+* \file cyw20829_ns.ld
+* \version 1.0.0
+*
+* Linker file for the GNU C compiler.
+*
+* The main purpose of the linker script is to describe how the sections in the
+* input files should be mapped into the output file, and to control the memory
+* layout of the output file.
+*
+* \note The entry point location is fixed and starts at 0x10000000. The valid
+* application image should be placed there.
+*
+* \note The linker files included with the PDL template projects must be generic
+* and handle all common use cases. Your project may not use every section
+* defined in the linker files. In that case you may see warnings during the
+* build process. In your project, you can simply comment out or remove the
+* relevant code in the linker file.
+*
+********************************************************************************
+* \copyright
+* Copyright 2016-2020 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+*******************************************************************************/
+
+OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+GROUP(-lgcc -lc -lnosys )
+SEARCH_DIR(.)
+GROUP(libgcc.a libc.a libm.a libnosys.a)
+ENTRY(Reset_Handler)
+
+/* The size of the stack section at the end of CM4 SRAM */
+STACK_SIZE = 0x1000;
+
+USER_APP_START_ADDR = 0x400 + USER_APP_START_OFF;
+
+FLASH_START_ADDR_SAHB = 0x60000000 + USER_APP_START_ADDR;
+FLASH_START_ADDR_CBUS = 0x08000000 + USER_APP_START_ADDR;
+RAM_START_ADDR_SAHB = 0x20000000;
+RAM_START_ADDR_CBUS = 0x04000000;
+RAM_END_ADDR_SAHB = 0x20020000; /* 128K */
+RAM_END_ADDR_CBUS = 0x04020000; /* 128K */
+FLASH_END_ADDR_SAHB = 0x60080000; /* 512K */
+
+BOOTSTRAP_OFFSET_FLASH = 0x00000050; /* toc2=0x10, l1_desc=0x1C, sign_header=0x20, padding=0x4 (encrypted data should be aligned to 0x10 boundary) */
+BOOTSTRAP_OFFSET_RAM = 0x0001E000; /* was 0x00004000 Modify this value to change the size of Bootstrap code + Data */
+APPCODE_OFFSET_FLASH = 0x00002200;
+
+RAMVECTORS_ALIGNMENT = 512;
+
+/* Memory reserved for Bootstrap code and data */
+BOOTSTRAP_SIZE = RAM_END_ADDR_SAHB - RAM_START_ADDR_SAHB - BOOTSTRAP_OFFSET_RAM; /* 0x00002000 */
+/* vma for bootstrap code region */
+CODE_VMA = RAM_START_ADDR_CBUS + BOOTSTRAP_OFFSET_RAM; /* 0x0401E000 */
+/* lma for bootstrap code region */
+CODE_LMA = FLASH_START_ADDR_SAHB + BOOTSTRAP_OFFSET_FLASH; /* 0x6000004C */
+/* Maximum bootstrap code + data size */
+CODE_BS_SIZE = BOOTSTRAP_SIZE; /* 8KB */
+/* vma for bootstrap data region */
+DATA_BS_VMA = RAM_START_ADDR_SAHB + BOOTSTRAP_OFFSET_RAM; /* 0x2001E000 */
+/* vma for bootstrap and app data region */
+DATA_VMA = RAM_START_ADDR_SAHB; /* 0x20000000 */
+/* vma for appCodeRam region */
+DATA_CBUS_VMA = RAM_START_ADDR_CBUS; /* 0x04000000 */
+/* lma for bootstrap and app data region */
+DATA_LMA = CODE_LMA + CODE_BS_SIZE; /* 0x6000204C */
+/* data size */
+DATA_SIZE = RAM_END_ADDR_SAHB - DATA_VMA - BOOTSTRAP_SIZE; /* 0x1E000 */
+/* vma for application XIP region */
+XIP_VMA = FLASH_START_ADDR_CBUS + APPCODE_OFFSET_FLASH; /* 0x08002200 */
+/* lma for application XIP region */
+XIP_LMA = FLASH_START_ADDR_SAHB + APPCODE_OFFSET_FLASH; /* 0x60002200 */
+/* size of XIP region */
+XIP_SIZE = FLASH_END_ADDR_SAHB - XIP_LMA;
+/* Total size of SRAM */
+RAM_SIZE = RAM_END_ADDR_SAHB - RAM_START_ADDR_SAHB; /* 0x00020000 */
+/* Size of Bootstrap data is kept same as BOOTSTRAP_SIZE */
+DATA_BS_SIZE = BOOTSTRAP_SIZE;
+
+/* Force symbol to be entered in the output file as an undefined symbol. Doing
+* this may, for example, trigger linking of additional modules from standard
+* libraries. You may list several symbols for each EXTERN, and you may use
+* EXTERN multiple times. This command has the same effect as the -u command-line
+* option.
+*/
+EXTERN(Reset_Handler)
+
+/* The MEMORY section below describes the location and size of blocks of memory in the target.
+* Use this section to specify the memory regions available for allocation.
+*/
+MEMORY
+{
+ /* The ram and flash regions control RAM and flash memory allocation for the CM33 core.
+ */
+ code (rx) : ORIGIN = CODE_VMA, LENGTH = CODE_BS_SIZE
+ bsData (rwx) : ORIGIN = DATA_BS_VMA, LENGTH = DATA_BS_SIZE
+ appCodeRam (rx) : ORIGIN = DATA_CBUS_VMA, LENGTH = DATA_SIZE
+ data (rwx) : ORIGIN = DATA_VMA, LENGTH = DATA_SIZE
+ xip (rx) : ORIGIN = XIP_VMA, LENGTH = XIP_SIZE
+}
+
+/* Library configurations */
+GROUP(libgcc.a libc.a libm.a libnosys.a)
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ * Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ * __exidx_start
+ * __exidx_end
+ * __copy_table_start__
+ * __copy_table_end__
+ * __zero_table_start__
+ * __zero_table_end__
+ * __etext
+ * __data_start__
+ * __preinit_array_start
+ * __preinit_array_end
+ * __init_array_start
+ * __init_array_end
+ * __fini_array_start
+ * __fini_array_end
+ * __data_end__
+ * __bss_start__
+ * __bss_end__
+ * __end__
+ * end
+ * __HeapLimit
+ * __StackLimit
+ * __StackTop
+ * __stack
+ * __Vectors_End
+ * __Vectors_Size
+ */
+
+SECTIONS
+{
+ /* .stack_dummy section doesn't contains any symbols. It is only
+ * used for linker to calculate size of stack sections, and assign
+ * values to stack symbols later */
+ .stack_dummy RAM_START_ADDR_SAHB (NOLOAD):
+ {
+ KEEP(*(.stack*))
+ } > data
+
+ /* Set stack top beginning of RAM minus the size of stack, and stack limit move down by
+ * size of stack_dummy section */
+ . = ALIGN(32);
+ __StackTop = RAM_START_ADDR_SAHB + STACK_SIZE;
+ __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+ PROVIDE(__stack = __StackTop);
+
+ . = ALIGN(RAMVECTORS_ALIGNMENT);
+ __ramVectors_vma__ = RAM_START_ADDR_SAHB + STACK_SIZE;
+
+ .ramVectors __ramVectors_vma__ (NOLOAD):
+ {
+ __ram_vectors_start__ = .;
+ KEEP(*(.ram_vectors))
+ . = ALIGN(4);
+ __ram_vectors_end__ = .;
+ } > data
+
+ __appTextRam_vma__ = (__ram_vectors_end__ - RAM_START_ADDR_SAHB) + RAM_START_ADDR_CBUS;
+ __appTextRam_lma__ = (__zero_table_end__ - FLASH_START_ADDR_CBUS) + FLASH_START_ADDR_SAHB;
+ __ezerotable = __zero_table_end__;
+
+ .appTextRam __appTextRam_vma__ : AT (__appTextRam_lma__)
+ {
+ . = ALIGN(4);
+ __app_text_ram_begin__ = .;
+ KEEP(*(.cy_ramfunc*))
+ . = ALIGN(4);
+
+ *cy_smif.o(.text*)
+ *cy_smif_memslot.o(.text*)
+ *cy_smif_sfdp.o(.text*)
+ *cy_gpio.o(.text*)
+ *cy_smif_hybrid_sect.o(.text*)
+
+ . = ALIGN(4);
+ __app_text_ram_end__ = .;
+
+ } > appCodeRam
+
+ __data_vma__ = (__app_text_ram_end__ - RAM_START_ADDR_CBUS) + RAM_START_ADDR_SAHB;
+ __data_lma__ = (__app_text_ram_end__ - __app_text_ram_begin__) + __appTextRam_lma__;
+ __etext = __data_lma__ - FLASH_START_ADDR_SAHB + FLASH_START_ADDR_CBUS;
+
+ .data __data_vma__ : AT (__data_lma__)
+ {
+ __data_start__ = .;
+
+ *(vtable)
+ *(.data*)
+
+ . = ALIGN(4);
+ /* preinit data */
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP(*(.preinit_array))
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+
+ . = ALIGN(4);
+ /* init data */
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__init_array_end = .);
+
+ . = ALIGN(4);
+ /* finit data */
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP(*(SORT(.fini_array.*)))
+ KEEP(*(.fini_array))
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ . = ALIGN(4);
+ KEEP(*(.jcr*))
+ . = ALIGN(4);
+
+ . = ALIGN(4);
+ KEEP(*(.cy_l2func*))
+ . = ALIGN(4);
+
+ __data_end__ = .;
+
+ } > data
+
+ /* Check if data is exceeding the flash size */
+ ASSERT((__data_lma__ + (__data_end__ - __data_start__)) <= FLASH_END_ADDR_SAHB, "data section exceeds Flash size !")
+
+ /* Place variables in the section that should not be initialized during the
+ * device startup.
+ */
+ .noinit (NOLOAD) : ALIGN(8)
+ {
+ KEEP(*(.noinit))
+ } > data
+
+ /* The uninitialized global or static variables are placed in this section.
+ *
+ * The NOLOAD attribute tells linker that .bss section does not consume
+ * any space in the image. The NOLOAD attribute changes the .bss type to
+ * NOBITS, and that makes linker to A) not allocate section in memory, and
+ * A) put information to clear the section with all zeros during application
+ * loading.
+ *
+ * Without the NOLOAD attribute, the .bss section might get PROGBITS type.
+ * This makes linker to A) allocate zeroed section in memory, and B) copy
+ * this section to RAM during application loading.
+ */
+ .bss (NOLOAD):
+ {
+ . = ALIGN(4);
+ __bss_start__ = .;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ } > data
+
+ /* Use ramining RAM for Heap */
+ __heap_size__ = (RAM_SIZE - ((__bss_end__ - RAM_START_ADDR_SAHB) + (RAM_END_ADDR_CBUS - __bootstrapText_vma__)) - 4);
+
+ .heap (NOLOAD):
+ {
+ . = ALIGN(8);
+ __HeapBase = .;
+ __end1__ = .;
+ end = __end1__;
+ KEEP(*(.heap*))
+ . += __heap_size__;
+ __HeapLimit = .;
+ } > data
+
+ __bootstrapText_vma__ = ORIGIN(code);
+ __bootstrapText_lma__ = CODE_LMA;
+
+ /* Cortex-M33 bootstrap code area */
+ .bootstrapText __bootstrapText_vma__ : AT (__bootstrapText_lma__)
+ {
+ /* Cortex-M33 code vector table */
+ . = ALIGN(4);
+ __bootstrapText_begin = .;
+
+ __Vectors = . ;
+ KEEP(*(.vectors))
+ . = ALIGN(4);
+ __Vectors_End = .;
+ __Vectors_Size = __Vectors_End - __Vectors;
+ __end__ = .;
+
+ . = ALIGN(4);
+
+ /* startup code */
+ *ns_start_cyw20829.o(.text*)
+ *ns_system_cyw20829.o(.text*)
+
+ /* drivers */
+ *cy_device.o(.text*)
+ *cy_btss.o(.text*)
+ *cy_gpio.o(.text*)
+ *cy_sysclk_v2.o(.text*)
+ *cy_syspm_v2.o(.text*)
+ *cy_sysint_v2.o(.text*)
+ *cy_syslib*.o(.text*)
+ *ppu_v1.o(.text*)
+ *cy_mpc.o(.text*)
+ *cy_pd_ppu.o(.text*)
+ *cy_smif.o(.text*)
+ *cy_smif_memslot.o(.text*)
+ *cy_smif_sfdp.o(.text*)
+ *cyhal_system.o(.text*)
+
+ KEEP(*(.cy_l1func*))
+
+ . = ALIGN(4);
+ __bootstrapText_end = .;
+ } > code
+
+ __bootstrap_zerotable_lma__ = (CODE_LMA + (__bootstrapText_end - __bootstrapText_begin));
+
+ .bootstrapzero.table : AT (__bootstrap_zerotable_lma__)
+ {
+ . = ALIGN(4);
+ __bootstrapzero_table_start__ = .;
+ LONG (__bootstrap_bss_start__)
+ LONG ((__bootstrap_bss_end__ - __bootstrap_bss_start__)/4)
+ . = ALIGN(4);
+ __bootstrapzero_table_end__ = .;
+ } > code
+
+ __bootstrapData_vma__ = ((__bootstrapzero_table_end__ - RAM_START_ADDR_CBUS) + RAM_START_ADDR_SAHB);
+ __bootstrapData_lma__ = (__bootstrap_zerotable_lma__ + (__bootstrapzero_table_end__ - __bootstrapzero_table_start__));
+
+ .bootstrapData __bootstrapData_vma__ : AT (__bootstrapData_lma__)
+ {
+ __bootstrapData_start__ = .;
+ . = ALIGN(4);
+
+ /* startup code */
+ *ns_start_cyw20829.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *ns_system_cyw20829.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+
+ /* drivers */
+ *cy_device.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_btss.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_gpio.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_sysclk_v2.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_syspm_v2.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_sysint_v2.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_syslib.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *ppu_v1.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_mpc.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_pd_ppu.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_smif.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_smif_memslot.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_smif_sfdp.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cycfg_qspi_memslot.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cyhal_system.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+
+ KEEP(*(.cy_l1data*))
+
+ . = ALIGN(4);
+
+ __bootstrapData_end__ = .;
+ __bootstrap_size_end__ = .;
+ } > bsData
+
+ .bootstrapBss (NOLOAD):
+ {
+ . = ALIGN(4);
+ __bootstrap_bss_start__ = .;
+
+ /* startup code */
+ *ns_start_cyw20829.o(.bss* COMMON)
+ *ns_system_cyw20829.o(.bss* COMMON)
+
+ /* drivers */
+ *cy_device.o(.bss* COMMON)
+ *cy_btss.o(.bss* COMMON)
+ *cy_gpio.o(.bss* COMMON)
+ *cy_sysclk_v2.o(.bss* COMMON)
+ *cy_syspm_v2.o(.bss* COMMON)
+ *cy_sysint_v2.o(.bss* COMMON)
+ *cy_syslib.o(.bss* COMMON)
+ *ppu_v1.o(.bss* COMMON)
+ *cy_mpc.o(.bss* COMMON)
+ *cy_pd_ppu.o(.bss* COMMON)
+ *cy_smif.o(.bss* COMMON)
+ *cy_smif_memslot.o(.bss* COMMON)
+ *cy_smif_sfdp.o(.bss* COMMON)
+
+ KEEP(*(.cy_l1bss*))
+
+ . = ALIGN(4);
+ __bootstrap_bss_end__ = .;
+ } > bsData
+
+ /* Check if bootstrap code + data exceeds RAM limit */
+ ASSERT(__bootstrap_bss_end__ < RAM_END_ADDR_SAHB, "bootstrap region exceeds RAM size !")
+
+ __app_text_vma__ = ORIGIN(xip);
+ __app_text_lma__ = XIP_LMA;
+
+ /* Cortex-M33 application flash area */
+ .appText (__app_text_vma__) : AT (__app_text_lma__)
+ {
+ /* Cortex-M33 flash vector table */
+ . = ALIGN(4);
+ __text_begin = .;
+
+ *(EXCLUDE_FILE(*cy_gpio.o
+ *cy_smif.o
+ *cy_smif_memslot.o
+ *cy_smif_sfdp.o
+ *cy_smif_hybrid_sect.o) .text*)
+
+ KEEP(*(.init))
+ KEEP(*(.fini))
+
+ /* Read-only code (constants). */
+ *(.rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+
+ KEEP(*(.eh_frame*))
+ . = ALIGN(4);
+ __text_end = .;
+
+ } > xip
+
+
+ .copy.table : AT (__app_text_lma__ + (__text_end - __text_begin))
+ {
+ . = ALIGN(4);
+ __copy_table_start__ = .;
+
+ /* Copy data section to RAM */
+ LONG (__etext) /* From */
+ LONG (__data_start__) /* To */
+ LONG ((__data_end__ - __data_start__)/4) /* Size */
+
+ /* Copy appTextRam section to RAM */
+ LONG (__ezerotable) /* From */
+ LONG (__ram_vectors_end__) /* To */
+ LONG ((__app_text_ram_end__ - __app_text_ram_begin__)/4) /* Size */
+
+ . = ALIGN(4);
+ __copy_table_end__ = .;
+ } > xip
+
+
+
+ .ARM.extab : AT (__app_text_lma__ + (__text_end - __text_begin) + (__copy_table_end__ - __copy_table_start__))
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > xip
+
+ __exidx_start = .;
+
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > xip
+ __exidx_end = .;
+
+
+ /* To clear multiple BSS sections,
+ * uncomment .zero.table section and,
+ * define __STARTUP_CLEAR_BSS_MULTIPLE in CAT1B devices */
+ .zero.table : AT (__exidx_end - __app_text_vma__ + __app_text_lma__)
+ {
+ . = ALIGN(4);
+ __zero_table_start__ = .;
+ LONG (__bss_start__)
+ LONG ((__bss_end__ - __bss_start__)/4)
+
+ . = ALIGN(4);
+ __zero_table_end__ = .;
+ } > xip
+}
+
+/* start of bootstrap code sahb address */
+__bootstrap_start_addr__ = RAM_START_ADDR_SAHB + BOOTSTRAP_OFFSET_RAM;
+/* bootstrap size */
+__bootstrap_size__ = __bootstrap_size_end__ - __bootstrap_start_addr__;
+
diff --git a/boot/cypress/BlinkyApp/linker/BlinkyApp_template.ld b/boot/cypress/BlinkyApp/linker/BlinkyApp_CM4_template.ld
similarity index 76%
rename from boot/cypress/BlinkyApp/linker/BlinkyApp_template.ld
rename to boot/cypress/BlinkyApp/linker/BlinkyApp_CM4_template.ld
index 81fbc22..4324012 100644
--- a/boot/cypress/BlinkyApp/linker/BlinkyApp_template.ld
+++ b/boot/cypress/BlinkyApp/linker/BlinkyApp_CM4_template.ld
@@ -1,6 +1,6 @@
/***************************************************************************//**
-* \file cy8c6xxa_cm4_dual.ld
-* \version 2.60
+* \file cyb06xxa_cm4.ld
+* \version 2.91
*
* Linker file for the GNU C compiler.
*
@@ -8,7 +8,7 @@
* input files should be mapped into the output file, and to control the memory
* layout of the output file.
*
-* \note The entry point location is fixed and starts at 0x10000000. The valid
+* \note The entry point location is fixed and starts at 0x100E0000. The valid
* application image should be placed there.
*
* \note The linker files included with the PDL template projects must be generic
@@ -19,7 +19,7 @@
*
********************************************************************************
* \copyright
-* Copyright 2016-2019 Cypress Semiconductor Corporation
+* Copyright 2016-2021 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -61,13 +61,8 @@
MEMORY
{
/* The ram and flash regions control RAM and flash memory allocation for the CM4 core.
- * You can change the memory allocation by editing the 'ram' and 'flash' regions.
- * Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use.
- * Using this memory region for other purposes will lead to unexpected behavior.
- * Your changes must be aligned with the corresponding memory regions for CM0+ core in 'xx_cm0plus.ld',
- * where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.ld'.
*/
- ram (rwx) : ORIGIN = RAM_START, LENGTH = RAM_SIZE
+ ram (rwx) : ORIGIN = USER_APP_RAM_START, LENGTH = USER_APP_RAM_SIZE
flash (rx) : ORIGIN = USER_APP_START, LENGTH = USER_APP_SIZE
/* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash.
@@ -78,13 +73,7 @@
em_eeprom (rx) : ORIGIN = 0x14000000, LENGTH = 0x8000 /* 32 KB */
/* The following regions define device specific memory regions and must not be changed. */
- sflash_user_data (rx) : ORIGIN = 0x16000800, LENGTH = 0x800 /* Supervisory flash: User data */
- sflash_nar (rx) : ORIGIN = 0x16001A00, LENGTH = 0x200 /* Supervisory flash: Normal Access Restrictions (NAR) */
- sflash_public_key (rx) : ORIGIN = 0x16005A00, LENGTH = 0xC00 /* Supervisory flash: Public Key */
- sflash_toc_2 (rx) : ORIGIN = 0x16007C00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 */
- sflash_rtoc_2 (rx) : ORIGIN = 0x16007E00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 Copy */
xip (rx) : ORIGIN = 0x18000000, LENGTH = 0x8000000 /* 128 MB */
- efuse (r) : ORIGIN = 0x90700000, LENGTH = 0x100000 /* 1 MB */
}
/* Library configurations */
@@ -129,6 +118,7 @@
/* Cortex-M4 application flash area */
.text ORIGIN(flash) + BOOT_HEADER_SIZE :
{
+ /* Cortex-M4 flash vector table */
. = ALIGN(4);
__Vectors = . ;
KEEP(*(.vectors))
@@ -223,8 +213,9 @@
} > ram
- .data __ram_vectors_end__ : AT (__etext)
+ .data __ram_vectors_end__ :
{
+ . = ALIGN(4);
__data_start__ = .;
*(vtable)
@@ -258,7 +249,7 @@
__data_end__ = .;
- } > ram
+ } > ram AT>flash
/* Place variables in the section that should not be initialized during the
@@ -338,88 +329,18 @@
} > em_eeprom
- /* Supervisory Flash: User data */
- .cy_sflash_user_data :
- {
- KEEP(*(.cy_sflash_user_data))
- } > sflash_user_data
-
-
- /* Supervisory Flash: Normal Access Restrictions (NAR) */
- .cy_sflash_nar :
- {
- KEEP(*(.cy_sflash_nar))
- } > sflash_nar
-
-
- /* Supervisory Flash: Public Key */
- .cy_sflash_public_key :
- {
- KEEP(*(.cy_sflash_public_key))
- } > sflash_public_key
-
-
- /* Supervisory Flash: Table of Content # 2 */
- .cy_toc_part2 :
- {
- KEEP(*(.cy_toc_part2))
- } > sflash_toc_2
-
-
- /* Supervisory Flash: Table of Content # 2 Copy */
- .cy_rtoc_part2 :
- {
- KEEP(*(.cy_rtoc_part2))
- } > sflash_rtoc_2
-
-
/* Places the code in the Execute in Place (XIP) section. See the smif driver
* documentation for details.
*/
- .cy_xip :
+ cy_xip :
{
+ __cy_xip_start = .;
KEEP(*(.cy_xip))
+ __cy_xip_end = .;
} > xip
- /* eFuse */
- .cy_efuse :
- {
- KEEP(*(.cy_efuse))
- } > efuse
-
-
- /* These sections are used for additional metadata (silicon revision,
- * Silicon/JTAG ID, etc.) storage.
- */
- .cymeta 0x90500000 : { KEEP(*(.cymeta)) } :NONE
}
-/* The following symbols used by the cymcuelftool. */
-/* Flash */
-__cy_memory_0_start = 0x10000000;
-__cy_memory_0_length = 0x00200000;
-__cy_memory_0_row_size = 0x200;
-
-/* Emulated EEPROM Flash area */
-__cy_memory_1_start = 0x14000000;
-__cy_memory_1_length = 0x8000;
-__cy_memory_1_row_size = 0x200;
-
-/* Supervisory Flash */
-__cy_memory_2_start = 0x16000000;
-__cy_memory_2_length = 0x8000;
-__cy_memory_2_row_size = 0x200;
-
-/* XIP */
-__cy_memory_3_start = 0x18000000;
-__cy_memory_3_length = 0x08000000;
-__cy_memory_3_row_size = 0x200;
-
-/* eFuse */
-__cy_memory_4_start = 0x90700000;
-__cy_memory_4_length = 0x100000;
-__cy_memory_4_row_size = 1;
-
/* EOF */
diff --git a/boot/cypress/BlinkyApp/linker/BlinkyApp_template.ld b/boot/cypress/BlinkyApp/linker/BlinkyApp_CM4_template_xip.ld
similarity index 75%
copy from boot/cypress/BlinkyApp/linker/BlinkyApp_template.ld
copy to boot/cypress/BlinkyApp/linker/BlinkyApp_CM4_template_xip.ld
index 81fbc22..55b307a 100644
--- a/boot/cypress/BlinkyApp/linker/BlinkyApp_template.ld
+++ b/boot/cypress/BlinkyApp/linker/BlinkyApp_CM4_template_xip.ld
@@ -1,6 +1,6 @@
/***************************************************************************//**
-* \file cy8c6xxa_cm4_dual.ld
-* \version 2.60
+* \file BlinkyApp.ld
+* \version 2.91
*
* Linker file for the GNU C compiler.
*
@@ -8,7 +8,7 @@
* input files should be mapped into the output file, and to control the memory
* layout of the output file.
*
-* \note The entry point location is fixed and starts at 0x10000000. The valid
+* \note The entry point location is fixed and starts at 0x100E0000. The valid
* application image should be placed there.
*
* \note The linker files included with the PDL template projects must be generic
@@ -19,7 +19,8 @@
*
********************************************************************************
* \copyright
-* Copyright 2016-2019 Cypress Semiconductor Corporation
+* Copyright 2016-2021 Cypress Semiconductor Corporation
+* Copyright 2022 Infineon Technologies AG
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -43,7 +44,6 @@
/* Size of the stack section at the end of CM4 SRAM */
STACK_SIZE = 0x1000;
-
/* The size of the MCU boot header area at the start of FLASH */
BOOT_HEADER_SIZE = 0x400;
@@ -61,15 +61,11 @@
MEMORY
{
/* The ram and flash regions control RAM and flash memory allocation for the CM4 core.
- * You can change the memory allocation by editing the 'ram' and 'flash' regions.
- * Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use.
- * Using this memory region for other purposes will lead to unexpected behavior.
- * Your changes must be aligned with the corresponding memory regions for CM0+ core in 'xx_cm0plus.ld',
- * where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.ld'.
*/
- ram (rwx) : ORIGIN = RAM_START, LENGTH = RAM_SIZE
+ ram (rwx) : ORIGIN = USER_APP_RAM_START, LENGTH = USER_APP_RAM_SIZE
flash (rx) : ORIGIN = USER_APP_START, LENGTH = USER_APP_SIZE
+ public_ram (rw) : ORIGIN = 0x08000000, LENGTH = 0x800
/* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash.
* You can assign sections to this memory region for only one of the cores.
* Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region.
@@ -78,13 +74,7 @@
em_eeprom (rx) : ORIGIN = 0x14000000, LENGTH = 0x8000 /* 32 KB */
/* The following regions define device specific memory regions and must not be changed. */
- sflash_user_data (rx) : ORIGIN = 0x16000800, LENGTH = 0x800 /* Supervisory flash: User data */
- sflash_nar (rx) : ORIGIN = 0x16001A00, LENGTH = 0x200 /* Supervisory flash: Normal Access Restrictions (NAR) */
- sflash_public_key (rx) : ORIGIN = 0x16005A00, LENGTH = 0xC00 /* Supervisory flash: Public Key */
- sflash_toc_2 (rx) : ORIGIN = 0x16007C00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 */
- sflash_rtoc_2 (rx) : ORIGIN = 0x16007E00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 Copy */
xip (rx) : ORIGIN = 0x18000000, LENGTH = 0x8000000 /* 128 MB */
- efuse (r) : ORIGIN = 0x90700000, LENGTH = 0x100000 /* 1 MB */
}
/* Library configurations */
@@ -126,9 +116,11 @@
SECTIONS
{
+
/* Cortex-M4 application flash area */
.text ORIGIN(flash) + BOOT_HEADER_SIZE :
{
+ /* Cortex-M4 flash vector table */
. = ALIGN(4);
__Vectors = . ;
KEEP(*(.vectors))
@@ -136,9 +128,11 @@
__Vectors_End = .;
__Vectors_Size = __Vectors_End - __Vectors;
__end__ = .;
-
. = ALIGN(4);
- *(.text*)
+
+ EXCLUDE_FILE(*cy_smif.o *cy_smif_memslot.o *cy_smif_sfdp.o
+ *cy_sysclk.o *cy_smif_hybrid_sect.o *flash_qspi.o
+ *cy_syslib.o *cy_syslib_gcc.o *system_psoc6_cm4.o) *(.text)
KEEP(*(.init))
KEEP(*(.fini))
@@ -223,8 +217,9 @@
} > ram
- .data __ram_vectors_end__ : AT (__etext)
+ .data __ram_vectors_end__ :
{
+ . = ALIGN(4);
__data_start__ = .;
*(vtable)
@@ -256,9 +251,18 @@
KEEP(*(.cy_ramfunc*))
. = ALIGN(4);
+ *cy_smif.o(.text*)
+ *cy_smif_memslot.o(.text*)
+ *cy_smif_sfdp.o(.text*)
+ *cy_sysclk.o(.text*)
+ *cy_smif_hybrid_sect.o(.text*)
+ *flash_qspi.o(.text*)
+ *cy_syslib.o(.text*)
+ *cy_syslib_gcc.o(.text*)
+
__data_end__ = .;
- } > ram
+ } > ram AT>flash
/* Place variables in the section that should not be initialized during the
@@ -303,6 +307,14 @@
__HeapLimit = .;
} > ram
+ .cy_sharedmem (NOLOAD):
+ {
+ . = ALIGN(4);
+ __public_ram_start__ = .;
+ KEEP(*(.cy_sharedmem))
+ . = ALIGN(4);
+ __public_ram_end__ = .;
+ } > public_ram
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
@@ -338,88 +350,18 @@
} > em_eeprom
- /* Supervisory Flash: User data */
- .cy_sflash_user_data :
- {
- KEEP(*(.cy_sflash_user_data))
- } > sflash_user_data
-
-
- /* Supervisory Flash: Normal Access Restrictions (NAR) */
- .cy_sflash_nar :
- {
- KEEP(*(.cy_sflash_nar))
- } > sflash_nar
-
-
- /* Supervisory Flash: Public Key */
- .cy_sflash_public_key :
- {
- KEEP(*(.cy_sflash_public_key))
- } > sflash_public_key
-
-
- /* Supervisory Flash: Table of Content # 2 */
- .cy_toc_part2 :
- {
- KEEP(*(.cy_toc_part2))
- } > sflash_toc_2
-
-
- /* Supervisory Flash: Table of Content # 2 Copy */
- .cy_rtoc_part2 :
- {
- KEEP(*(.cy_rtoc_part2))
- } > sflash_rtoc_2
-
-
/* Places the code in the Execute in Place (XIP) section. See the smif driver
* documentation for details.
*/
- .cy_xip :
+ cy_xip :
{
+ __cy_xip_start = .;
KEEP(*(.cy_xip))
+ __cy_xip_end = .;
} > xip
- /* eFuse */
- .cy_efuse :
- {
- KEEP(*(.cy_efuse))
- } > efuse
-
-
- /* These sections are used for additional metadata (silicon revision,
- * Silicon/JTAG ID, etc.) storage.
- */
- .cymeta 0x90500000 : { KEEP(*(.cymeta)) } :NONE
}
-/* The following symbols used by the cymcuelftool. */
-/* Flash */
-__cy_memory_0_start = 0x10000000;
-__cy_memory_0_length = 0x00200000;
-__cy_memory_0_row_size = 0x200;
-
-/* Emulated EEPROM Flash area */
-__cy_memory_1_start = 0x14000000;
-__cy_memory_1_length = 0x8000;
-__cy_memory_1_row_size = 0x200;
-
-/* Supervisory Flash */
-__cy_memory_2_start = 0x16000000;
-__cy_memory_2_length = 0x8000;
-__cy_memory_2_row_size = 0x200;
-
-/* XIP */
-__cy_memory_3_start = 0x18000000;
-__cy_memory_3_length = 0x08000000;
-__cy_memory_3_row_size = 0x200;
-
-/* eFuse */
-__cy_memory_4_start = 0x90700000;
-__cy_memory_4_length = 0x100000;
-__cy_memory_4_row_size = 1;
-
/* EOF */
diff --git a/boot/cypress/BlinkyApp/main.c b/boot/cypress/BlinkyApp/main.c
index 1679bf2..59cee6a 100644
--- a/boot/cypress/BlinkyApp/main.c
+++ b/boot/cypress/BlinkyApp/main.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2020 Cypress Semiconductor Corporation
+ * Copyright (c) 2021 Infineon Technologies AG
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -21,21 +22,37 @@
* specific language governing permissions and limitations
* under the License.
*/
- /*******************************************************************************/
+#ifdef CYW20829
+#include <inttypes.h>
+#include "cybsp.h"
+#include "cycfg_pins.h"
+#include "cyhal_wdt.h"
+#else
#include "system_psoc6.h"
+#endif /* CYW20829 */
+
#include "cy_pdl.h"
-#include "cyhal.h"
#include "cy_retarget_io.h"
+#include "cyhal.h"
#include "watchdog.h"
-/* Define pins for UART debug output */
+#include "flash_qspi.h"
+#if !(SWAP_DISABLED) && defined(UPGRADE_IMAGE)
+#include "set_img_ok.h"
+#endif
+
+/* Define pins for UART debug output */
+#ifdef CYW20829
+#define CY_DEBUG_UART_TX (CYBSP_DEBUG_UART_TX)
+#define CY_DEBUG_UART_RX (CYBSP_DEBUG_UART_RX)
+#else
#define CY_DEBUG_UART_TX (P5_1)
#define CY_DEBUG_UART_RX (P5_0)
+#endif /* CYW20829 */
#if defined(PSOC_062_2M)
-#warning "Check if User LED is correct for your target board."
#define LED_PORT GPIO_PRT13
#define LED_PIN 7U
#elif defined(PSOC_062_1M)
@@ -44,12 +61,11 @@
#elif defined(PSOC_062_512K)
#define LED_PORT GPIO_PRT11
#define LED_PIN 1U
+#elif defined(CYW20829)
+#define LED_PORT GPIO_PRT0
+#define LED_PIN 0U
#endif
-#define LED_NUM 5U
-#define LED_DRIVEMODE CY_GPIO_DM_STRONG_IN_OFF
-#define LED_INIT_DRIVESTATE 1
-
const cy_stc_gpio_pin_config_t LED_config =
{
.outVal = 1,
@@ -67,53 +83,31 @@
.vohSel = 0UL,
};
-#define WATCHDOG_UPD_MESSAGE "[BlinkyApp] Update watchdog timer started in MCUBootApp to mark successful start of user app\r\n"
-#define WATCHDOG_FREE_MESSAGE "[BlinkyApp] Turn off watchdog timer\r\n"
+uint32_t smif_id = 1; /* Assume SlaveSelect_0 is used for External Memory */
-#ifdef BOOT_IMG
+#ifdef BOOT_IMAGE
#define BLINK_PERIOD (1000u)
#define GREETING_MESSAGE_VER "[BlinkyApp] BlinkyApp v1.0 [CM4]\r\n"
#define GREETING_MESSAGE_INFO "[BlinkyApp] Red led blinks with 1 sec period\r\n"
-#elif defined(UPGRADE_IMG)
+#elif defined(UPGRADE_IMAGE)
#define BLINK_PERIOD (250u)
#define GREETING_MESSAGE_VER "[BlinkyApp] BlinkyApp v2.0 [+]\r\n"
#define GREETING_MESSAGE_INFO "[BlinkyApp] Red led blinks with 0.25 sec period\r\n"
#else
- #error "[BlinkyApp] Please specify type of image: -DBOOT_IMG or -DUPGRADE_IMG\r\n"
+ #error "[BlinkyApp] Please specify type of image: -DBOOT_IMAGE or -DUPGRADE_IMAGE\r\n"
#endif
-void check_result(int res)
+#define WATCHDOG_FREE_MESSAGE "[BlinkyApp] Turn off watchdog timer\r\n"
+
+static void check_result(int res)
{
if (res != CY_RSLT_SUCCESS) {
CY_ASSERT(0);
+ /* Loop forever... */
+ for (;;) {}
}
}
-/*
-* Writes 1 byte `src` into flash memory at `address`
-* It does a sequence of RD/Modify/WR of data in a Flash Row.
- */
-int flash_write_byte(uint32_t address, uint8_t src)
-{
- cy_en_flashdrv_status_t rc = CY_FLASH_DRV_SUCCESS;
- uint32_t row_addr = 0;
- uint8_t row_buff[512];
-
- /* accepting arbitrary address */
- row_addr = (address/CY_FLASH_SIZEOF_ROW)*CY_FLASH_SIZEOF_ROW;
-
- /* preserving Row */
- memcpy(row_buff, (void *)row_addr, sizeof(row_buff));
-
- /* Modifying the target byte */
- row_buff[address%CY_FLASH_SIZEOF_ROW] = src;
-
- /* Programming updated row back */
- rc = Cy_Flash_WriteRow(row_addr, (const uint32_t *)row_buff);
-
- return (int) rc;
-}
-
void test_app_init_hardware(void)
{
/* enable interrupts */
@@ -121,6 +115,7 @@
/* Disabling watchdog so it will not interrupt normal flow later */
Cy_GPIO_Pin_Init(LED_PORT, LED_PIN, &LED_config);
+
/* Initialize retarget-io to use the debug UART port */
check_result(cy_retarget_io_init(CY_DEBUG_UART_TX, CY_DEBUG_UART_RX,
CY_RETARGET_IO_BAUDRATE));
@@ -133,50 +128,63 @@
printf("[BlinkyApp] UART initialized \r\n");
printf("[BlinkyApp] Retarget I/O set to 115200 baudrate \r\n");
+#ifdef CYW20829
+ cy_en_smif_status_t rc = CY_SMIF_CMD_NOT_FOUND;
+
+ rc = qspi_init_sfdp(smif_id);
+ if (CY_SMIF_SUCCESS == rc) {
+ printf("[BlinkyApp] External Memory initialized w/ SFDP. \r\n");
+ }
+ else {
+ printf("[BlinkyApp] External Memory initialization w/ SFDP FAILED: 0x%" PRIx32 " \r\n", (uint32_t)rc);
+ }
+#endif /* CYW20829 */
}
int main(void)
{
uint32_t blinky_period = BLINK_PERIOD;
+#if defined CYW20829
+ cybsp_init();
+#endif /* CYW20829 */
+
test_app_init_hardware();
printf(GREETING_MESSAGE_INFO);
- /* Update watchdog timer to mark successful start up of application */
- printf(WATCHDOG_UPD_MESSAGE);
- cy_wdg_kick();
+ /* Disable watchdog timer to mark successful start up of application.
+ * For PSOC6 WDT is disabled in SystemInit() function.
+ */
printf(WATCHDOG_FREE_MESSAGE);
+#ifdef CYW20829
+ cyhal_wdt_t *cyw20829_wdt = NULL;
+ cyhal_wdt_free(cyw20829_wdt);
+#else
cy_wdg_free();
+#endif /* CYW20829 */
-#if defined(SWAP_ENABLED) && defined(UPGRADE_IMG)
-
- #define USER_SWAP_IMAGE_OK_OFFS (24)
- #define USER_SWAP_IMAGE_OK (1)
- uint32_t img_ok_addr;
- int rc;
+#if !(SWAP_DISABLED) && defined(UPGRADE_IMAGE)
+ int rc = -1;
printf("[BlinkyApp] Try to set img_ok to confirm upgrade image\r\n");
/* Write Image OK flag to the slot trailer, so MCUBoot-loader
- * will not revert new image */
- img_ok_addr = USER_APP_START + USER_APP_SIZE - USER_SWAP_IMAGE_OK_OFFS;
- if (*((uint8_t *)img_ok_addr) != USER_SWAP_IMAGE_OK)
- {
- rc = flash_write_byte(img_ok_addr, USER_SWAP_IMAGE_OK);
- if (0 == rc)
- {
- printf("[BlinkyApp] SWAP Status : Image OK was set at 0x%08lx.\r\n", img_ok_addr);
- }
- else
- {
- printf("[BlinkyApp] SWAP Status : Failed to set Image OK.\r\n");
- }
- } else
- {
+ * will not revert new image
+ */
+ rc = set_img_ok(IMG_OK_ADDR, USER_SWAP_IMAGE_OK);
+
+ if (IMG_OK_ALREADY_SET == rc) {
printf("[BlinkyApp] Img_ok is already set in trailer\r\n");
}
-#endif
+ else if (IMG_OK_SET_SUCCESS == rc) {
+ printf("[BlinkyApp] SWAP Status : Image OK was set at 0x%08x.\r\n", IMG_OK_ADDR);
+ }
+ else {
+ printf("[BlinkyApp] SWAP Status : Failed to set Image OK.\r\n");
+ }
+
+#endif /* !(SWAP_DISABLED) && defined(UPGRADE_IMAGE) */
for (;;)
{
@@ -186,5 +194,6 @@
/* Invert the USER LED state */
Cy_GPIO_Inv(LED_PORT, LED_PIN);
}
+
return 0;
}
diff --git a/boot/cypress/BlinkyApp/set_img_ok.h b/boot/cypress/BlinkyApp/set_img_ok.h
new file mode 100644
index 0000000..68d4ac2
--- /dev/null
+++ b/boot/cypress/BlinkyApp/set_img_ok.h
@@ -0,0 +1,39 @@
+/********************************************************************************
+* Copyright 2021 Infineon Technologies AG
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#if !defined(SET_IMG_OK_H)
+#define SET_IMG_OK_H
+
+#include "cy_flash.h"
+#include "flash_qspi.h"
+#include "sysflash/sysflash.h"
+#include <string.h>
+
+#define FLASH_ROW_BUF_SZ CY_FLASH_ALIGN
+#define IMG_TRAILER_SZ CY_FLASH_ALIGN
+
+#define USER_SWAP_IMAGE_OK_OFFS (24)
+#define USER_SWAP_IMAGE_OK (1)
+#define IMG_OK_ADDR (PRIMARY_IMG_START + USER_APP_SIZE - USER_SWAP_IMAGE_OK_OFFS)
+
+#define IMG_OK_SET_FAILED -1
+#define IMG_OK_ALREADY_SET 1
+#define IMG_OK_SET_SUCCESS 0
+
+int set_img_ok(uint32_t address, uint8_t value);
+
+#endif /* SET_IMG_OK_H */
\ No newline at end of file
diff --git a/boot/cypress/MCUBootApp/ExternalMemory.md b/boot/cypress/MCUBootApp/ExternalMemory.md
index ce1cb7e..70f862d 100644
--- a/boot/cypress/MCUBootApp/ExternalMemory.md
+++ b/boot/cypress/MCUBootApp/ExternalMemory.md
@@ -1,88 +1,106 @@
-### External Memory Support For Secondary Slot
+### Support of secondary slot in external memory for PSoC™ 6 devices
+
+* For the CYW20829 external memory support, see the [CYW20829.md](../platforms/CYW20829/CYW20829.md) file.
#### Description
-Given document describes the use of external memory module as a secondary (upgrade) slot with Cypress' PSoC 6 devices.
+This document describes the use of the external memory module as a secondary (upgrade) slot with Cypress PSoC™ 6 devices.
-The demonstration device is `CY8CPROTO-062-4343W` board which is PSoC 6 device with 2M of Flash available, but other kits with 1M (CY8CKIT-062-WIFI-BT) or 512K (CY8CPROTO-062S3-4343W) chips can be used as well.
-The memory module present on boards is S25FL512SAGMFI010 512-Mbit external Quad SPI NOR Flash.
+The demonstration device is the `CY8CPROTO-062-4343W` board, which is a PSoC™ 6 device with 2M-flash, but other kits with 1M (CY8CKIT-062-WIFI-BT) or 512K (CY8CPROTO-062S3-4343W) chips can be used as well.
+The memory module on boards is S25FL512SAGMFI010 512-Mbit external Quad SPI NOR flash.
-Using external memory for secondary slot allows to nearly double the size of Boot Image.
+Using external memory for secondary slots allows nearly doubling the Boot Image size.
-#### Operation Design and Flow
+#### Operation design and flow
-The design is based on using SFDP command's auto-discovery functionality of memory module IC and Cypress' SMIF PDL driver.
+The design is based on using the SFDP command's auto-discovery functionality of memory module IC and Cypress SMIF PDL driver.
-It is assumed that user's design meets following:
-* The memory-module used is SFDP-compliant;
-* There only one module is being used for secondary slot;
-* The address for secondary slot should start from 0x18000000.
-This corresponds to PSoC 6's SMIF (Serial Memory InterFace) IP block mapping.
-* The slot size and start address for upgrade slot meets requirements, when using swap upgrade.
+A user's design example:
+* The memory-module is SFDP-compliant.
+* Only one module is used for the secondary slot.
+* The address for the secondary slot starts from 0x18000000.
+This corresponds to PSoC™ 6 SMIF (Serial Memory InterFace) IP block mapping.
+* The slot size and start address for the upgrade slot meet the requirements, when using swap upgrade.
-The default flash map can be foung in MCUBootApp.md.
+The default flash map can be found in the [MCUBootApp.md](MCUBootApp.md) file.
-MCUBootApp's `main.c` contains the call to Init-SFDP API which performs required GPIO configurations, SMIF IP block configurations, SFDP protocol read and memory-config structure initialization.
+MCUBootApp's `main.c` contains the call to Init-SFDP API, which performs the required GPIO configurations, SMIF IP block configuration, SFDP protocol read and memory-config structure initialization.
-After that MCUBootApp is ready to accept upgrade image from external memory module.
+Now, MCUBootApp is ready to accept an upgrade image from the external memory module.
Upgrades from external memory are supported for both `overwrite only` and `swap with status partition` modes of MCUBootApp.
-##### Requirements to size and start address of upgrade slot when using swap mode.
+##### Requirements to size and start address of upgrade slot when using Swap mode
-Due to mcuboot image structure some restrictions applies when using upgrades from external flash. The main requirement is the following:
+Due to the MCUboot image structure, some restrictions apply when using upgrades from external flash. The main requirement:
-**Trailer portion of UPGRADE image should be possible to erase separately.**
+**The trailer portion of an upgrade image can be erased separately.**
-To achive this requirement image trailer should be placed separately on full flash page, which equls 0x40200 in case of S25FL512SAGMFI010. Considering default slot size for external memory case described in MCUBootApp.md, occupied external flash would look as follows:
+To meet this requirement, the image trailer is placed separately on a full flash page, which equals 0x40200 for S25FL512SAGMFI010.
+Considering the default slot size for the external memory case described in the [MCUBootApp.md](MCUBootApp.md) file, occupied external flash looks as follows:
0x18000000 [xxxxxxxxxxxxxxxx][ttfffffffffffff][fffffffffffffff]
Here:
-`0x18000000` - start address of external memory
-`[xxxxxxxxxxxxxxxx]` - first flash page of minimum erase size 0x40000 occupied by firmware.
-`[tt]` - trailer portion (last 0x200 of image) of upgrade slot placed on separate flash page.
-`[fffff]` - remained portion of flash page, used to store image trailer - this area should not be used for anything else.
+`0x18000000` - The start address of external memory.
+`[xxxxxxxxxxxxxxxx]` - The first flash page of minimum erase size 0x40000 occupied by the firmware.
+`[tt]` - The trailer portion (last 0x200 of image) of the upgrade slot placed on a separate flash page.
+`[fffff]` - The remained portion of the flash page, used to store the image trailer - this area cannot be used for anything else.
-When using slots sizes other, then default `0x40200` described above shoulb be considered.
+When using slots sizes other than default, consider the above-described `0x40200`.
-When slot size does not aligned to `0x40000`, start address of UPGRADE image in external flash should be calculated starting from image trailer location. Consider example below.
+When the slot size is not aligned to `0x40200`, the start address of the upgrade image in the external flash is calculated starting from the image trailer location. Consider the following example:
-Primary slot size required is 590336 bytes (576k + 512b).
+The primary slot size required is 590336 bytes (576k + 512b).
-4 flash pages are required to fit secondary slot (P1-P4):
+Four flash pages are required to fit the secondary slot (P1-P4):
0x1800 0000 - 0x1804 0000 - P1
0x1804 0000 - 0x1808 0000 - P2
0x1808 0000 - 0x180C 0000 - P3
0x1808 0000 - 0x180C 0000 - P4
-Primary slot consist of 512 bytes of image trailer, it goes to P4, 2 full sectors of 256k goes in P3 and P2, reminded 64k is resided in P1.
+The primary slot consists of 512 bytes of the image trailer, it goes to P4, 2 full sectors of 256k goes in P3 and P2, the remainder of 64k is resided in P1.
-Thus start address of secondary slot is: 0x1804 0000 - 0x10000 (64k) = 0x1803 0000. Size occupied is 4 * 256k = 786k
+Thus, the start address of the secondary slot is: 0x1804 0000 - 0x10000 (64k) = 0x1803 0000. The size occupied is 4 * 256k = 786k
-##### How to enable external memory support:
+#### Execute in place (XIP) mode
-1. Pass `USE_EXTERNAL_FLASH=1` flag to `make` command when building MCUBootApp.
-2. Navigate to `cy_flash_map.c` and check if secondary slot start address and size meet the application's needs.
-3. Define which slave select is used for external memory on a board by setting `smif_id` value in `main.c`.
-4. Build MCUBootApp as described in `Readme.md`.
+In the XIP mode firmware image can be placed in the external memory and executed from there directly. This mode is useful for devices with small internal flash or when one wishes to reserve internal flash for other purposes.
-**Note 3**: External memory code is developed basing on PDL and can be run on CM0p core only. It may require modifications if used on CM4.
+On CYW20829 platform XIP mode is always used due to absence of internal memory.
-**How to build upgrade image for external memory:**
+This is optional for PSoC™ 6 devices. The JSON flash map should contain `"mode": "XIP"` in the `"external_flash" section`. `USE_XIP` flag is added to auto-generated `flashmap.mk` on pre-build action.
- make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE HEADER_OFFSET=0x7FE8000 ERASED_VALUE=0xff
+When XIP mode is used primary slot of an image can be placed in external memory.
-`HEADER_OFFSET` defines the offset from original boot image address. This one in line above suggests secondary slot will start from `0x18000000`.
+This repository provides default flash map files with suffix _xip_ to be used for XIP mode in `cy_flash_pal/flash_%platform_name%/flashmap`.
-`ERASED_VALUE` defines the memory cell contents in erased state. It is `0x00` for PSoC 6's internal Flash and `0xff` for S25FL512S.
+#### How to enable external memory support
-**Programming to external memory**
+External memory is enabled when `make` flag `USE_EXTERNAL_FLASH` is set to `1`. Value of this flag is set in auto-generated `flashmap.mk` files when field `"external_flash"` is present in JSON file.
-The MCUBootApp programming can be done similarly to described in `Readme.md`:
+Default flash maps with suffix _smif_ are provided in `cy_flash_pal/flash_psoc6/flashmap` folder for PSoC™ 6 devices, where presense of external memory in system is optional.
- export OPENOCD=/Applications/ModusToolbox/tools_2.1/openocd
+Build MCUBootApp as described in the [MCUBootApp.md](MCUBootApp.md) file.
+
+**Building an upgrade image for external memory:**
+
+ make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE ERASED_VALUE=0xff FLASH_MAP=cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_single_smif.json IMG_ID=1
+
+`ERASED_VALUE` - Defines the memory cell contents in the erased state. It is `0x00` for PSoC™ 6 internal flash and `0xff` for S25FL512S.
+
+**Programming external memory**
+
+Programming tools require configuration of SMIF block to debug/program external memory. When `MCUBootApp` is built with `BUILDCFG=Debug` flag SMIF configuration structures are added to the `MCUBootApp.hex` image. Additional sections:
+
+At SFlash address `0x16000800` address of SMIF configuration structure is placed.
+
+At SFlash address `0x16007c00` updated content of TOC2 structure is placed.
+
+The MCUBootApp can be programmed similarly to described in the [MCUBootApp.md](MCUBootApp.md) file:
+
+ export OPENOCD=/Applications/ModusToolbox/tools_2.4/openocd
${OPENOCD}/bin/openocd -s ${OPENOCD}/scripts \
-f ${OPENOCD}/scripts/interface/kitprog3.cfg \
@@ -91,11 +109,11 @@
-c "init; reset init; program PATH_TO_APPLICATION.hex" \
-c "resume; reset; exit"
-There is a NULL-pointer placed for SMIF configuration pointer in TOC2 (Table Of Contents, `cy_serial_flash_prog.c`).
-This is done to force CY8PROTO-062-4343W DAP Link firmware to program external memory with hardcoded values.
+There is a NULL-pointer placed for the SMIF configuration pointer in TOC2 (Table Of Contents, `cy_serial_flash_prog.c`).
+This is done to force the CY8PROTO-062-4343W DAP Link firmware to program external memory with hardcoded values.
-1. Press SW3 Mode button on a board to switch the board into DAP Link mode.
-2. Once DAP Link removable disk appeared drop (copy) the upgrade image HEX file to it.
-This will invoke firmware to program external memory.
+1. Click the SW3 Mode button on the board to switch the board to DAP Link mode.
+2. Once DAP Link removable disk displays, drop (copy) the upgrade image HEX file to it.
+This will invoke the firmware to program external memory.
-**Note 3:** the programming of external memory is limited to S25FL512S p/n only at this moment.
+**Note :** the programming of external memory is limited to S25FL512S p/n only at this moment.
diff --git a/boot/cypress/MCUBootApp/MCUBootApp.md b/boot/cypress/MCUBootApp/MCUBootApp.md
index f4337c7..d15f667 100644
--- a/boot/cypress/MCUBootApp/MCUBootApp.md
+++ b/boot/cypress/MCUBootApp/MCUBootApp.md
@@ -1,234 +1,430 @@
-## MCUBootApp - demo bootloading application to be used with Cypress targets
+## MCUBootApp - demo bootloading application to use with Cypress targets
-### Solution Description
+### Solution description
-MCUBootApp is created to demonstrate operation of MCUBoot library on Cypress' PSoC 6 device. It supports various operation modes and features of MCUBoot library.
+This solution demonstrates operation of MCUboot on Cypress PSoC™ 6 and CYW20829 devices.
-* single/multi image operation modes
-* overwrite/swap upgrade modes
-* interrupted upgrade recovery for swap upgrades
-* upgrade image confirmation
-* reverting of bad upgrade images
-* secondary slots located in external flash
+* Single-/Multi-image operation modes
+* Overwrite/Swap upgrade modes
+* Interrupted upgrade recovery for swap upgrades
+* Upgrade image confirmation
+* Reverting of bad upgrade images
+* Secondary slots located in external flash
-This demo supports PSoC 6 chips with 1M, 2M and 512K Flash on board.
-Evaluation kits are:
+This demo supports PSoC™ 6 chips with the 1M-, 2M-, and 512K-flash on board, and the CYW20829 chip with no internal flash.
+The evaluation kits are:
* `CY8CPROTO-062-4343W`
* `CY8CKIT-062-WIFI-BT`
-* `CY8CPROTO-062S3-4343W`.
+* `CY8CPROTO-062S3-4343W`
+* `CYW920829M2EVB-01`
-### Memory Maps
+### Platfrom specifics
-MCUBoot terminology assumes a slot from which **boot** is happening to be named **primary**, and a slot where **upgrade** image is placed - **secondary**.
+MCUBootApp can be built for different platforms. So, the main application makefile `MCUBootApp.mk` operates with common build variables and flags. Most of them can be passed to build system as a `make` command parameter and each platform defines the default value prefixed with `PLATFORM_` in the corresponding makefile - `PSOC6.mk` or `CYW20829.mk`. The build flags and variables are described in detail in the following paragraphs.
-#### Internal Flash
+### Memory maps
-The flash map is defined at compile time. It can be configured through makefiles and `MCUBootApp/sysflash/sysflash.h` and `cypress/cy_flash_pal/cy_flash_map.c`.
+The MCUboot terminology names a slot from which **boot** occurs as **primary** and a slot where an **upgrade** image is placed as **secondary**. Some platforms support both internal and external flash, some only external flash.
-The default `MCUBootApp` flash map is defined for demonstration purpose. Sizes of slots are adjusted to be compatible with all supported device families: 1M, 2M and 512K.
+The flash map of bootloader is defined at compile time and cannot be changed dynamically. Flash map is prepared in the industry-accepted JSON (JavaScript Object Notation) format. It should follow the rules described in section **How to modify flash map**.
-Actual addresses provided below are calculated by preprocessor in `sysflash.h` and `cy_flash_map.c` per slot sizes set.
+`MCUBootApp` contains JSON templates for flash maps with commonly used configurations. They can be found in `cy_flash_pal/flash_%platform_name%/flashmap` The slots' sizes are defined per platform to be compatible with all supported device families.
-##### Single Image Mode
+The actual addresses are provided in corresponding platform doc files:
-| Start addr | End addr | Size | Description |
-|------------|------------|---------|-------------------------------------------|
-| 0x10000000 | 0x10018000 | 0x18000 | MCUBootApp (bootloader) area; |
-| 0x10018000 | 0x10028000 | 0x10000 | Primary_1 (BOOT) slot for BlinkyApp; |
-| 0x10028000 | 0x10038000 | 0x10000 | Secondary_1 (UPGRADE) slot for BlinkyApp; |
+- [PSOC6.md](../platforms/PSOC6/PSOC6.md)
+- [CYW20289.md](../platforms/CYW20829/CYW20829.md)
-If upgrade type is swap using scratch:
+#### How to modify flash map
-| Start addr | Size | Description |
-|------------|-----------|---------------------------------|
-| 0x10038000 | 0x1800 | Start of swap status partition; |
-| 0x10039800 | 0x1000 | Start of scratch area partition;|
+When modifying slots sizes, ensure aligning new values with the linker script files for appropriate applications.
-##### Multi Image Mode
+##### Flash map definition
+Flash map describes what flash memory areas are allocated and defines their addresses and sizes. Also, it specifies the type of external flash memory, if applicable.
-| Start addr | End addr | Size | Description |
-|------------|------------|---------|-------------------------------------------|
-| 0x10000000 | 0x10018000 | 0x18000 | MCUBootApp (bootloader) area; |
-| 0x10018000 | 0x10028000 | 0x10000 | Primary_1 (BOOT) slot for BlinkyApp; |
-| 0x10028000 | 0x10038000 | 0x10000 | Secondary_1 (UPGRADE) slot for BlinkyApp; |
-| 0x10038000 | 0x10058000 | 0x20000 | Primary_2 (BOOT) slot of Bootloader |
-| 0x10058000 | 0x10078000 | 0x20000 | Secondary_2 (UPGRADE) slot of Bootloader |
+To build `MCUBootApp` with the given flash map (e.g., `flash_map.json`), supply the following parameter to `make`:
+`FLASH_MAP=flash_map.json`
-If upgrade type swap:
+###### Flash map format
+Flash map must have the `"boot_and_upgrade"` section, define the location of `MCUBootApp` and at least one image. For instance:
+```
+{
+ "boot_and_upgrade": {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x10000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x18000"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10018000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x10000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x18030200"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x10000"
+ }
+ }
+ }
+}
+```
+Here an application identifier should follow the pattern, i.e., the 2nd image in the multi-image case is `"application_2"`, the 3rd is `"application_3"`, and so on. Up to four applications are supported at this moment.
-| Start addr | Size | Description |
-|------------|-----------|---------------------------------|
-| 0x10078000 | 0x2800 | Start of swap status partition; |
-| 0x1007a800 | 0x1000 | Start of scratch area partition;|
+For each image the location and size of its primary slot is given in the `"address"` and `"size"` parameters. The location and size of the secondary slot is specified in the `"upgrade_address"` and `"upgrade_size"`. All four values described above are mandatory.
-**SWAP upgrade from external memory**
+There also should be a mandatory `"bootloader"` section, describing the location and size of `MCUBootApp` in the `"address"` and `"size"` parameters, respectively.
-When MCUBootApp is configured to support upgrade images places in external memory following fixed addresses are predefined:
+Under some circumstances (e.g., PSoC™ 62 with application slots in both internal and external flash memories), the slot address must be properly aligned, as the image trailer should start exactly at the erase block boundary. When an improper address is specified, `make` will fail with a message like:
+```
+Misaligned application_1 (secondary slot) - suggested address 0x18030200
+```
+This gives the nearest larger address that satisfy the slot location requirements. Other errors, such as overlapping flash areas, are also checked and reported.
-| SMIF base address | Offset | Description |
-|-------------------|-------------|---------------------------------|
-| 0x18000000 | 0x0 | Start of Secondary_1 (UPGRADE) image; |
-| 0x18000000 | 0x240000 | Start of Secondary_2 (UPGRADE) image; |
-| 0x18000000 | 0x440000 | Start of scratch area partition;|
+###### Scratch area
+If there is a scratch area, what is generally true, its location and size is given in the `"scratch_address"` and `"scratch_size"` parameters of the `"bootloader"` subsection. For example:
+```
+{
+ "boot_and_upgrade": {
+ "bootloader": {
+ . . .
+ "scratch_address": {
+ "description": "Address of the scratch area",
+ "value": "0x18440000"
+ },
+ "scratch_size": {
+ "description": "Size of the scratch area",
+ "value": "0x10000"
+ },
+ },
+ . . .
+```
-##### Single Image Mode
+###### Swap status partition
+If the desired upgrade mode is `swap scratch with status partition`, one should define the `"status_address"` and `"status_size"` parameters in the `"bootloader"` subsection, e.g.:
+```
+{
+ "boot_and_upgrade": {
+ "bootloader": {
+ . . .
+ "status_address": {
+ "description": "Address of the swap status partition",
+ "value": "0x10038000"
+ },
+ "status_size": {
+ "description": "Size of the swap status partition",
+ "value": "0x3800"
+ }
+ },
+ . . .
+```
+The required size of the status partition relies on many factors. If an insufficient size is given in the flash map, `make` will fail with a message such as:
+```
+Insufficient swap status area - suggested size 0x3800
+```
+To calculate the minimal correct size of the status partition, one could specify `"value": "0"` for the `"status_size"`. After the intentional `make` failure, copy the correct size from the error message.
-| Start addr | End addr | Size | Description |
-|------------|------------|---------|-------------------------------------------|
-| 0x10000000 | 0x10018000 | 0x18000 | MCUBootApp (bootloader) area; |
-| 0x10018000 | 0x10058200 | 0x40200 | Primary_1 (BOOT) slot for BlinkyApp; |
-| 0x18000000 | 0x18040200 | 0x40200 | Secondary_1 (UPGRADE) slot for BlinkyApp; |
+###### External flash
+If an external flash memory is used, one should specify its parameters. The first way is specyfing the exact model:
+```
+{
+ "external_flash": [
+ {
+ "model": "S25HS256T"
+ }
+ ],
+ "boot_and_upgrade": {
+ . . .
+```
+However, the supported model list is incomplete. The known models are Infineon `S25HS256T`/`S25HS512T`/`S25HS01GT` SEMPER™ NOR Flash ICs, and a couple of SPI Flash ICs from other vendors. Another way is specyfing the important parameters, like:
+```
+{
+ "external_flash": [
+ {
+ "flash-size": "0x100000",
+ "erase-size": "0x1000"
+ }
+ ],
+ "boot_and_upgrade": {
+ . . .
+```
+for a typical 8-Mbit SPI flash with uniform 4-KByte erase blocks. While JSON list syntax is used for the `"external_flash"` section, only single instance is supported at this moment.
-If upgrade type swap:
+If the main application image is located in the external flash, `XIP` (eXecute In Place) mode should be turned on. To do so, supply the corresponding `"mode"` parameter:
+```
+{
+ "external_flash": [
+ {
+ "model": "S25HS256T",
+ "mode": "XIP"
+ }
+ ],
+ . . .
+```
+###### Service RAM Application
+The CYW20829 platform has a hardware-supported security counter. For more details on rollback protection support, refer to the [CYW20289.md](../platforms/CYW20829/CYW20829.md) file.
+The mentioned feature requires a dedicated area in the flash memory to store the Service RAM Application and other required data. The layout of these areas is defined in the `"service_app"` JSON section:
+```
+ . . .
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ . . .
+ },
+ "service_app": {
+ "address": {
+ "description": "Address of the service application",
+ "value": "0x60070000"
+ },
+ "size": {
+ "description": "Size of the service application",
+ "value": "0x8000"
+ },
+ "params_address": {
+ "description": "Address of the service application input parameters",
+ "value": "0x60078000"
+ },
+ "params_size": {
+ "description": "Size of the service application input parameters",
+ "value": "0x400"
+ },
+ "desc_address": {
+ "description": "Address of the service application descriptor",
+ "value": "0x60078400"
+ },
+ "desc_size": {
+ "description": "Size of the service application descriptor",
+ "value": "0x20"
+ }
+ },
+ "application_1": {
+ . . .
+```
+###### Shared secondary slot
+In the multi-image case, one can reduce the utilization of flash memory by placing secondary images into the same area. This area is reffered to as **Shared secondary slot**. This is especially desirable if there are more than two images.
-| Start addr | Size | Description |
-|------------|-----------|---------------------------------|
-| 0x10058200 | 0x3c00 | Start of swap status partition; |
+Important consideration is that this option assumes updates are performed in sequential manner (consider the Swap upgrade method): place the 1st image into the shared slot, reset to MCUBoot, check the updated image and set the Image OK flag for the 1st image, reset to MCUBoot for permanent swap. Then place the 2nd image into the shared slot, reset to MCUBoot, check the updated image and set the Image OK flag for the 2nd image, reset to MCUBoot for permanent swap, etc.
-##### Multi Image Mode
+Take into account that it is possible to revert only the last updated image, as its previous version resides in the Shared secondary slot. There is no way to revert changes for previous images, as their backups are gone! That is trade-off of the Shared secondary slot.
-| Start addr | End addr | Size | Description |
-|------------|------------|---------|-------------------------------------------|
-| 0x10000000 | 0x10018000 | 0x18000 | MCUBootApp (bootloader) area; |
-| 0x10018000 | 0x10058200 | 0x40200 | Primary_1 (BOOT) slot for BlinkyApp; |
-| 0x10058200 | 0x10098400 | 0x40200 | Primary_2 (BOOT) slot of Bootloader |
-| 0x18000000 | 0x18040200 | 0x40200 | Secondary_1 (UPGRADE) slot for BlinkyApp; |
-| 0x18240000 | 0x18280200 | 0x40200 | Secondary_2 (UPGRADE) slot of Bootloader; |
+Shared secondary slot is rather a virtual concept, we still create individual flash areas for all secondary images. However, this areas are now overlapped (this is prohibited in the standard multi-image scenario). Moreover, special placing of secondary slots is required, as described below. Consider the triple-image example:
+```
+| |---------| |\
+| | | | \
+|---------| | | \
+| | | | \
+| Image 1 | Image 2 |---------| \
+| | | | Shared
+|---------| | | Secondary
+| Trailer | | Image 3 | Slot
+|---------|---------| | /
+| | Trailer | | /
+| |---------|---------| /
+| | | Trailer | /
+| | |---------|/
+```
+The purpose of such layout is to allow MCUBoot to understand what image is placed in the shared secondary slot. While secondary images now can (and should) overlap, their trailers must under no circumstances share the same address!
-If upgrade type is swap using scratch:
+Normally image trailer occupies the whole erase block (e.g. 512 bytes for PSoC™ 62 internal Flash, or 256 kilobytes for SEMPER™ Secure NOR Flash). There is a specific case when images are placed in both memory types, refer to the [PSOC6.md](../platforms/PSOC6/PSOC6.md) file.
-| Start addr | Size | Description |
-|------------|-----------|---------------------------------|
-| 0x10098400 | 0x6400 | Start of swap status partition; |
+One can declare all secondary slots as shared using the following JSON syntax:
+```
+ "boot_and_upgrade": {
+ "bootloader": {
+ . . .
+ "shared_slot": {
+ "description": "Using shared secondary slot",
+ "value": true
+ }
+ },
+```
+Alternatively, this can be done for each application:
+```
+ "boot_and_upgrade": {
+ "bootloader": {
+ . . .
+ },
+ "application_1": {
+ . . .
+ "shared_slot": {
+ "description": "Using shared secondary slot",
+ "value": true
+ }
+ },
+ "application_2": {
+ . . .
+ "shared_slot": {
+ "description": "Using shared secondary slot",
+ "value": true
+ }
+ },
+ . . .
+```
+where `true` marks the shared slot, `false` marks the normal (non-shared) secondary slot. In theory, one can use a separate secondary slot for the 1st image, and shared secondary slot for all other images.
-##### How To Modify Flash Map
+When the `shared_slot` flag is set, different checks are performed at the pre-build stage. For instance, the following error is reported if image trailers appear at the same address:
+```
+Same trailer address for application_3 (secondary slot) and application_2 (secondary slot)
+```
+As mentioned above, shared secondary slot is a virtual concept, so overlapped flash areas are created for each image's secondary slot. No separate flash area is created for the shared slot itself.
-When modifying slots sizes - make sure to align new values with linker script files for appropriate applications.
+**Upgrade process deviations**
-**Option 1**
+Shared slot feature has some differences and limitations in the update algorithm when there is one or more invalid images in primary slots and upgrade of these images is initiated through the shared upgrade slot (so-called **bootstrap** mode of bootloader). In this case, the bootloader allows to update the image even if other images are not valid (unlike the classic multi-image case). Bootloader however does not transfer control to these images until all primary slots become valid. ImageOK flag is set by updated images only after their successful validation and start.
-Navigate to `sysflash.h` and modify slots sizes directly to meet your needs.
+Considering above there is a certain limitation for the shared slot mode. For **swap mode**, an update of valid slots is not possible as long as there is at least one image with an invalid prime slot.
-`CY_BOOT_BOOTLOADER_SIZE` defines size of MCUBootApp.
-`CY_BOOT_IMAGE_1_SIZE` defines slot size for single image case.
-`CY_BOOT_IMAGE_2_SIZE` defines slot size of second image in multi image case.
+Attempting to upgrade a valid primary slot of one image with an invalid primary slot of another image may run a revert procedure the next time the bootloader is started (provided that the data of shared slot has not been changed before). Therefore, for the shared slot, it is recommended to first make all invalid primary slots valid and only then update other images through the shared slot.
-__Option 2.__
+###### JSON syntax rules
+| Group | Item | Description |
+|--------------------|-------------------|----------------------------------------------------------|
+| `external_flash` | `model` | External flash model (if supported), e.g. `S25HS256T` |
+| `external_flash` | `flash-size` | External flash size in bytes (if model is not supported) |
+| `external_flash` | `erase-size` | Erase block size in bytes (if model is not supported) |
+| `external_flash` | `mode` | Set to `XIP` for eXecute In Place |
+| `boot_and_upgrade` | `bootloader` | Contains flash areas used by the `MCUBootApp` |
+| `bootloader` | `address` | Absolute address of the `MCUBootApp` |
+| `bootloader` | `size` | Size of the `MCUBootApp` in bytes |
+| `bootloader` | `scratch_address` | Absolute address of the Scratch Area |
+| `bootloader` | `scratch_size` | Size of the Scratch Area in bytes |
+| `bootloader` | `status_address` | Absolute address of the Swap Status Partition |
+| `bootloader` | `status_size` | Size of the Swap Status Partition in bytes |
+| `bootloader` | `shared_slot` | Marking the shared secondary slot for all images |
+| `boot_and_upgrade` | `service_app` | Reserves flash space for Service RAM Application |
+| `service_app` | `address` | Address of the Service RAM Application |
+| `service_app` | `size` | Size of the Service RAM Application |
+| `service_app` | `params_address` | Address of the input parameters (follows the app) |
+| `service_app` | `params_size` | Size of the service application input parameters |
+| `service_app` | `desc_address` | Address of the app descriptor (follows the parameters) |
+| `service_app` | `desc_size` | Size of the service application descriptor (always 0x20) |
+| `boot_and_upgrade` | `application_1` | Contains flash areas of the 1st application image |
+| `boot_and_upgrade` | `application_2` | 2nd image, see the description of `application_1` |
+| `boot_and_upgrade` | `application_3` | 3rd image, see the description of `application_1` |
+| `boot_and_upgrade` | `application_4` | 4th image, see the description of `application_1` |
+| `application_1` | `address` | Absolute address of the Primary Slot of the 1st image |
+| `application_1` | `size` | Size (in bytes) of the Primary Slot of the 1st image |
+| `application_1` | `upgrade_address` | Absolute address of the Secondary Slot of the 1st image |
+| `application_1` | `upgrade_size` | Size (in bytes) of the Secondary Slot of the 1st image |
+| `application_1` | `shared_slot` | Marking the shared secondary slot for the 1st image |
+| `address` | `value` | Value of the given address (hex or decimal) |
+| `scratch_address` | `value` | Value of the Scratch Area address (hex or decimal) |
+| `status_address` | `value` | Value of the Status Partition address (hex or decimal) |
+| `upgrade_address` | `value` | Value of the Secondary Slot address (hex or decimal) |
+| `size` | `value` | Value of the given size (hex or decimal) |
+| `scratch_size` | `value` | Value of the Scratch Area size (hex or decimal) |
+| `status_size` | `value` | Value of the Status Partition size (hex or decimal) |
+| `upgrade_size` | `value` | Value of the Secondary Slot size (hex or decimal) |
+| `shared_slot` | `value` | Set to `true` for the Shared secondary slot |
-Navigate to `sysflash/sysflash.h` and uncomment `CY_FLASH_MAP_EXT_DESC` definition.
-Now define and initialize `struct flash_area *boot_area_descs[]` in a code with flash memory addresses and sizes you need at the beginning of application, so flash APIs from `cy_flash_pal/cy_flash_map.c` will use it.
+###### Flash map internals
+When the `FLASH_MAP=` option is supplied to `make`, it involves the Python script `boot/cypress/scripts/flashmap.py`. It takes the JSON file and converts flash map into the C header file `boot/cypress/MCUBootApp/cy_flash_pal/cy_flash_map.h`.
-__Note:__ for both options make sure to use correct `MCUBOOT_MAX_IMG_SECTORS`. This should correspond to slot size used. Maximum value of sectors can be set by passing a flag `MAX_IMG_SECTORS=__number__` to `make`. By default it is set to 256 sectors, which corresponds to `0x20000` slot size in multi image use case. Sector size assumed to be 512 bytes, so 128 sectors needed to fill `0x10000`, 256 sectors for `0x20000` and so on.
+At the same time it creates the `boot/cypress/MCUBootApp/flashmap.mk`, which is conditionally included from the `boot/cypress/MCUBootApp/MCUBootApp.mk`. The generated file contains various definitions derived from the flash map, such as `MCUBOOT_IMAGE_NUMBER`, `MAX_IMG_SECTORS`, `USE_EXTERNAL_FLASH`, and `USE_XIP`. So, there is no need to specify these and similar parameters manually.
-###### How To Override The Flash Map Values During Build Process
+Do not edit neither `sysflash/cy_flash_map.h` nor `flashmap.mk`, as both files are overwritten on every build.
-It is possible to override MCUBootApp definitions from build system. Navigate to `MCUBootApp.mk`, find section `DEFINES_APP +=`
-Using this construction macros can be defined and passed to compiler.
+#### External flash
-The full list of macros used to configure the custom multi image case with upgrade from external memory:
+Some Cypress devices, for example `CYW20829`, only have external flash, so all memory areas are located in external flash.
-* MCUBOOT_MAX_IMG_SECTORS
-* CY_FLASH_MAP_EXT_DESC
-* CY_BOOT_SCRATCH_SIZE
-* CY_BOOT_BOOTLOADER_SIZE
-* CY_BOOT_IMAGE_1_SIZE
-* CY_BOOT_IMAGE_2_SIZE
-* CY_BOOT_EXTERNAL_FLASH_SECONDARY_1_OFFSET
-* CY_BOOT_EXTERNAL_FLASH_SECONDARY_2_OFFSET
-* CY_BOOT_EXTERNAL_FLASH_SCRATCH_OFFSET
+Hoewever, PSoC™ 6 chips has internal flash and, additionally, support the external memory connection. Thus, it is possible to place secondary (upgrade) slots in the external memory module and use most of internal flash for the primary image.
+For more details on External Memory usage, refer to the [ExternalMemory.md](ExternalMemory.md) file.
-As an example in a makefile slots sizes redefinition should look like following:
+#### PSoC™ 6 RAM
-`DEFINES_APP +=-DCY_BOOT_EXTERNAL_FLASH_SCRATCH_OFFSET=0x18780000`
-`DEFINES_APP +=-DMCUBOOT_MAX_IMG_SECTORS=168`
-`DEFINES_APP +=-DCY_BOOT_IMAGE_1_SIZE=0x15000`
-`DEFINES_APP +=-DCY_BOOT_IMAGE_2_SIZE=0x15000`
+RAM areas in the MCUBootApp bootloading application and BlinkyApp are defined as an example pair. If your user application requires a different RAM area, ensure that it is not overlapped with the MCUBootApp RAM area. The memory (stack) corruption of the bootloading application can cause a failure if SystemCall-served operations were invoked from the user app.
-#### External Flash
+The MCUBootApp linker script also contains the special section `public_ram`, which serves as a shared RAM area between the CM0p and CM4 cores. When CM4 and CM0p cores perform operations with internal flash, this area is used for the interprocessor data sharing.
-It is also possible to place secondary (upgrade) slots in external memory module and use most of internal for primary image.
-Details about External Memory usage are described in separate guiding document `MCUBootApp/ExternalMemory.md`.
+#### CYW20829 RAM
-#### RAM
+Only one CM33 core is used in the CYW20829 chips, so there are no restrictions for the RAM usage by the layer1 and layer2 applications (i.e. MCUBootApp and BlinkyApp).
-RAM areas in CM0p-based MCUBootApp bootloading application and CM4-based BlinkyApp are defined as an example pair. If your CM4 user application requires different RAM area make sure it is not overlap with MCUBootApp ram area. Memory (stack) corruption of CM0p application can cause failure if SystemCall-served operations invoked from CM4.
+### Hardware cryptography acceleration
-MCUBootApp linker script also contains special section `public_ram`. This section serves for shared ram area between CM0p and CM4 cores. When CM4 and CM0p cores perform operations with internal flash, this area is used for interprocessor connection data sharing.
+Cypress PSoC™ 6 MCU family supports hardware acceleration of the cryptography based on the mbedTLS Library via a shim layer. The implementation of this layer is supplied as the separate submodule `cy-mbedtls-acceleration`. The hardware acceleration of the cryptography shortens the boot time by more than four times compared to the software implementation (observation results).
-### Hardware Cryptography Acceleration
+The CYW20289 chip has hardware acceleration of the SHA256 algorithm only, and in other cases, uses pure software implementation of the cryptography based on MbedTLS.
-Cypress PSoC 6 MCU family supports hardware acceleration of cryptography based on mbedTLS Library via shim layer. Implementation of this layer is supplied as separate submodule `cy-mbedtls-acceleration`. HW acceleration of cryptography shortens boot time in more then 4 times, comparing to software implementation (observation results).
+To enable the hardware acceleration in `MCUBootApp`, pass flag `USE_CRYPTO_HW=1` to `make` during build.
-To enable hardware acceleration in `MCUBootApp` pass flag `USE_CRYPTO_HW=1` to `make` while build.
+The hardware cryptographic acceleration is disabled for all devices at the moment. `USE_CRYPTO_HW` flag is set to 0 by default. This package will be updated in next version.
-Hardware acceleration of cryptography is enabled for PSoC 6 devices by default.
+__NOTE__: Hardware acceleration is not available in current version of mcuboot since `cy-mbedtls-acceleration` does not support `mbedTLS 3.0` yet.
-### Multi Image Mode
+### Multi-image mode
-Multi image operation considers upgrading and verification of more then one image on the device.
+Multi-image operation considers upgrading and verification of more than one image on a device.
-By default MCUBootApp is configured for single image mode. To enable multi image operation pass `MCUBOOT_IMAGE_NUMBER=2` as parameter to `make`.
+Single or multi-image mode is dictated by `MCUBOOT_IMAGE_NUMBER` `make` flag. This flag's value is set in auto-generated `flashmap.mk` file per flash map used. There is no need to pass it manually.
- `MCUBOOT_IMAGE_NUMBER` can also be changed permanently in `MCUBootApp/config/mcuboot_config.h` file. This value can only be set to 2 (only dual-image is supported at the moment).
+In Multi-image operation up to four images are supported.
-In multi image operation (two images are considered for simplicity) MCUBootApp bootloading application operates as following:
+Consider MCUBootApp with 2 images supported. Operation is the following:
-1. Verifies Primary_1 and Primary_2 images;
-2. Verifies Secondary_1 and Secondary_2 images;
-3. Upgrades Secondary to Primary if valid images found;
-4. Boots image from Primary_1 slot only;
-5. Boots Primary_1 only if both - Primary_1 and Primary_2 are present and valid;
+1. Verification of the Secondary_1 and Secondary_2 images.
+2. Upgrades Secondary to Primary if valid images found.
+3. Verification of the Primary_1 and Primary_2 images.
+4. Boots the image from the Primary_1 slot only.
+5. Boots Primary_1 only if both - Primary_1 and Primary_2 are present and valid.
-This ensures two dependent applications can be accepted by device only in case both images are valid.
+This ensures that two dependent applications can be accepted by the device only if both images are valid.
-### Upgrade Modes
+### Upgrade modes
-There are two different types of upgrade process supported by MCUBootApp. In case of `overwrite only` type of upgrade - secondary image is simply copied to primary slot after successful validation. No way to revert upgrade in a case when secondary image is inoperable.
+There are two different types of the upgrade process supported by MCUBootApp. For the `overwrite only` type of upgrade - the secondary image is simply copied to the primary slot after successful validation. No way to revert upgrade if the secondary image is inoperable.
-In case of `swap` upgrade mode - images in primary and secondary slots are swaped. Upgrade can be reverted if secondary image did not confirm its operation.
+For `swap` upgrade mode - images in the primary and secondary slots are swapped. Upgrade can be reverted if the secondary image did not confirm its operation.
-Upgrade mode is the same for all images in multi image mode.
+Upgrade mode is the same for all images in Multi-image mode.
-#### Overwrite Only
+#### Overwrite only
-To build MCUBootApp for overwrite upgrades only `MCUBootApp/config/mcuboot_config/mcuboot_config.h` should contain following define:
+To build MCUBootApp for overwrite upgrades only, `MCUBootApp/config/mcuboot_config/mcuboot_config.h` must contain the following definition:
`#define MCUBOOT_OVERWRITE_ONLY 1`
-This define can also be set in `MCUBootApp/MCUBootApp.mk`:
+This flag's value is set in auto-generated `flashmap.mk` file per flash map used. There is no need to pass it manually.
-`DEFINES_APP +=-DMCUBOOT_OVERWRITE_ONLY=1`
+In Overwrite-only mode, MCUBootApp first checks if any upgrade image is present in the secondary slot(s), then validates the digital signature of the upgrade image in the secondary slot(s). If validation is successful, MCUBootApp starts copying the secondary slot content to the primary slot. After the copy is done, MCUBootApp starts the upgrade image execution from the primary slot.
-In ovewrite only mode MCUBootApp first checks if any upgrade image is present in secondary slot(s), then validates digital signature of upgrade image in secondary slot(s). If validation is successful MCUBootApp starts copying secondary slot content to primary slot. After copy is done MCUBootApp starts upgrade image execution from primary slot.
+If the upgraded application does not work - there is no way to revert back to the previous working version. Only the new upgrade firmware can fix the previous broken upgrade.
-If upgraded application does not work - there is no way no revert back to previous working version. In this case only new upgrade firmware can fix previous broken upgrade.
+#### Swap mode
-#### Swap Mode
-
-There are 2 basic types of swap modes supported in MCUBoot:
-* scratch
-* move
-
-For devices with large minimum erase size like PSoC 6 with 512 bytes and also for configurations which use external flash with even bigger minimum erase size there is an additional option in MCUBoot to use dedicated `status partition` for robust storage of swap related information.
+For devices with a large minimum-erase size like PSoC™ 6 with 512 bytes and also for configurations, which use external flash with an even bigger minimum-erase size, there is an additional option in MCUBoot to use the dedicated `status partition` for robust storage of swap-related information.
##### Why use swap with status partition
-Originally MCUBoot library has been designed with a consideration, that minimum write/erase size of flash would always be 8 bytes or less. This value is critical, because swap algorithms use it to align portions of data that contain swap operation status of each flash sector in slot before writing to flash. Data alignment is also performed before writes of special purpose data to image trailer.
+Originally, the MCUboot library has been designed with a consideration that the minimum write/erase size of flash is always 8 bytes or less. This value is critical, because the swap algorithms use it to align portions of data that contain the swap operation status of each flash sector in a slot before writing to flash. Data alignment is also performed before writes of special-purpose data to the image trailer.
-Writing of flash sector status or image trailer data should be `single cycle` operation to ensure power loss and unpredicted resets robustness of bootloading applications. This requirement eliminates usage of `read-modify-write` type of operations with flash.
+Writing of the flash sector status or image trailer data will be the `single cycle` operation to ensure that the power loss and unpredicted resets robustness of bootloading applications. This requirement eliminates the usage of the `read-modify-write` type of operations with flash.
-`Swap with status partition` is implemented specifically to address devices with large write/erase size. It is based on existing mcuboot swap algorithms, but does not have restriction of 8 bytes alignment. Instead minimum write/erase size can be specified by user and algorithm will calculate sizes of status partition, considering this value. All write/erase operations are aligned to this minimum write/erase size as well.
+`Swap with status partition` is implemented specifically to address devices with a large write/erase size. It is based on existing MCUboot swap algorithms, but does not have restriction of the 8-byte alignment. Instead, the minimum write/erase size can be specified by the user and the algorithm will calculate sizes of the status partition considering this value. All write/erase operations are aligned to this minimum write/erase size as well.
-##### Swap Status Partition Description
+##### Swap status partition description
-The main distinction of `swap with status partition` is that separate flash area (partition) is used to store swap status values and image trailer instead of using free flash area at the end of primary/secondary image slot.
+The main distinction of `swap with status partition` is that a separate flash area (partition) is used to store the swap status values and image trailer instead of using the free flash area at the end of the primary/secondary image slot.
This partition consists of separate areas:
-* area to store swap status values
+* the area to store swap status values
* swap_status_0
* ...
* swap_status_x
-* area to store image trailer data:
+* the area to store image trailer data:
* Encryption key 0
* Encryption key 1
* Swap size
@@ -237,7 +433,7 @@
* Image ok
* Boot image magic
-Principal diagram of status partition:
+The principal diagram of the status partition:
```
+-+-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ \
@@ -278,146 +474,167 @@
```
**Scheme legend:**
-`PRIMARY` and `SECONRADY` are areas in status partition to contain data regarding corresponding slot in mcuboot.
-`D0`, `D1` and `Dx` are duplicates of data described on the left. At least 2 duplicates should be present in system. This duplication is used to eliminate flash wear. Each of `Dx` contains valid data for `current swap step - 1`. Each swap operation for flash sector updates status for this sector in current `Dx` and value on `CNT` inreases. Next operation checks least value of `CNT` in available `Dx`'s, copies there data from `Dx` with `CNT+1` and updates status of current sector. This continues until all sectors in slot are moved and then swaped.
-`CRC` - 4 bytes value - checksum of data contaited in area.
-`CNT` - 4 bytes value.
-`swap_status_0`, `swap_status_1`- one byte values, that contain status for corresponding image sector.
-`swap_status_x` - last sector of `BOOT_MAX_IMAGE_SECTORS`.
-`swap_status_max` - maximum number of sectors that fits in min write/erase size for particular flash hardware. If `swap_status_max` is less then `swap_status_x` additional slice of min write/erase flash area is allocated to store swap status data.
-`Image trailer` - should be at least 64 bytes. Code calculates how many min write/erase sizes need to be allocated to store image trailer data.m.
+`PRIMARY` and `SECONDARY` are areas in the status partition to contain data regarding a corresponding slot in MCUboot.
+`D0`, `D1`, and `Dx` are duplicates of data described on the left. At least 2 duplicates are present in the system. This duplication is used to eliminate flash wear. Each of `Dx` contains valid data for `current swap step - 1`. Each swap operation for the flash sector updates the status for this sector in the current `Dx` and the value on `CNT` increases. The next operation checks the least value of `CNT` in the available `Dx`s, copies the data from `Dx` with `CNT+1` and updates the status of the current sector. This continues until all sectors in the slot are moved and then swapped.
+`CRC` - A 4-byte value - the checksum of data contained in the area.
+`CNT` - A 4-byte value.
+`swap_status_0`, `swap_status_1` - 1-byte values that contain the status for a corresponding image sector.
+`swap_status_x` - The last sector of `BOOT_MAX_IMAGE_SECTORS`.
+`swap_status_max` - The maximum number of sectors that fits in the min write/erase size for particular flash hardware. If `swap_status_max` is less than `swap_status_x`, an additional slice of the min write/erase flash area is allocated to store swap status data.
+`Image trailer` - No less than 64 bytes. The code calculates how many min write/erase sizes to allocate for storing image trailer data.
-**Calculation example for PSoC 6 with minimum write/erase size of 512 bytes is used.**
+**A calculation example for PSoC™ 6 with the minimum write/erase size of 512 bytes.**
-Following considered:
-* Single image case
+The following are considered:
+* Single-image case
* Minimum write/erase size 512 bytes
* PRIMARY/SECONDARY slots size `0x50000`
* BOOT_MAX_IMG_SECTORS 0x50000 / 512 = 640
* Number of duplicates `Dx = 2`
-One slice of `min write/erase` size can store data for maximum number of 500 sectors: 512 - 4 (CRC) - 4 (CNT) - 4 (area magic) = 500. Since BOOT_MAX_IMG_SECTORS is 640 - 2 slices of `min write/erase` is allocated. Total size is 1024 bytes.
-Image trailer data fits in 64 bytes, so one slice of `min write/erase` size is allocated. Total size is 1024 + 512 = 1536 bytes.
-Duplicates number equals 2. Total size is 1536 * 2 = 3072 bytes.
-2 slots are used in particular case PRIMARY and SECONDARY, each needs 3072 bytes to store swap status data. Tolal is 3072 * 2 = 6144 bytes.
+One slice of the `min write/erase` size can store data for the maximum number of 500 sectors: 512 - 4 (CRC) - 4 (CNT) - 4 (area magic) = 500. BOOT_MAX_IMG_SECTORS is 640, so 2 slices of `min write/erase` are allocated. The total size is 1024 bytes.
+Image trailer data fits in 64 bytes, so one slice of the `min write/erase` size is allocated. The total size is 1024 + 512 = 1536 bytes.
+The number of duplicates 2. The total size is 1536 * 2 = 3072 bytes.
+2 slots are used in the particular case PRIMARY and SECONDARY, each needs 3072 bytes to store swap status data. The total is 3072 * 2 = 6144 bytes.
-Swap status partition occupies 6144 bytes of flash area in this case.
+The swap status partition occupies 6144 bytes of the flash area.
**Expected lifecycle**
-Since bootloading application that uses swap using status partition upgrade mode stores system state in separate flash area following product lifecycle is expected:
-`Empty` - Fully erased device
-`Ready` - `Empty` device is programmed with MCUBoot based bootloading application - MCUBootApp in this case.
-`Flashed` - Initial version v1.0 of user applicatio, BlinkyApp is this case, flashed to primary (BOOT) slot.
-`Upgraded` - updated firmware image of user application is delivered to secondary slot (UPGRADE) and bootloading application performs upgrade.
+The bootloading application uses the swap using the status partition, so Upgrade mode stores the system state in a separate flash area and the following product lifecycle is expected:
-It is expected that product stays in `Upgraded` state ultil end of its lifecycle.
+`Empty` - A fully-erased device.
+`Ready` - `Empty` -The device is programmed with the MCUboot-based bootloading application - MCUBootApp in this case.
+`Flashed` - Initial version v1.0 of the user application, BlinkyApp in this case, is flashed to the primary (BOOT) slot.
+`Upgraded` - The updated firmware image of the user application is delivered to the secondary slot (UPGRADE) and the bootloading application performs upgrade.
-In case there is a need to wipe out product and flash new firmware directly to primary (BOOT) slot - device should be transfered to `Empty` or `Ready` state and then walk through all states again.
+It is expected that the product stays in the `Upgraded` state until the end of its lifecycle.
-### Hardware Limitations
+If there is a need to wipe out product and flash new firmware directly to the primary (BOOT) slot, the device is transferred to the `Empty` or `Ready` state and then walks through all the states again.
-Since this application is created to demonstrate MCUBoot library features and not as reference examples some considerations are taken.
+### Hardware limitations
-1. `SCB5` used to configure serial port for debug prints. This is the most commonly used Serial Communication Block number among available Cypress PSoC 6 kits. If you try to use custom hardware with this application - change definition of `CYBSP_UART_HW` in `main.c` of MCUBootApp to SCB* that correspond to your design.
+This application is created to demonstrate the MCUboot library features and not as a reference examples. So, some considerations are taken.
-2. `CY_SMIF_SLAVE_SELECT_0` is used as definition SMIF driver API. This configuration is used on evaluation kit for this example CY8CPROTO-062-4343W. If you try to use custom hardware with this application - change value of `smif_id` in `main.c` of MCUBootApp to value that corresponds to your design.
+1. `SCB5` is used to configure a serial port for debug prints. This is the most commonly used Serial Communication Block number among available Cypress PSoC™ 6 kits. To use custom hardware with this application, set custom `SCB*` and pins in the `cypress/MCUBootApp/custom_debug_uart_cfg.h` file and pass the `USE_CUSTOM_DEBUG_UART=1` parameter to the `make` command upon MCUBootApp build.
-### Downloading Solution's Assets
+The `custom_debug_uart_cfg.h` file description:
-There is a set assets required:
+`CUSTOM_UART_HW` - Sets a custom SCB name used as the debug serial port. (e.g. `SCB1`, `SCB2`, ...)
+`CUSTOM_UART_SCB_NUMBER` - Sets the number of SCB. It is `x` in the custom SCBx, which is set in `CUSTOM_UART_HW`.
+ (e.g. `1` if `CUSTOM_UART_HW` is set to SCB1, `2` if `CUSTOM_UART_HW`is set to SCB2, ...)
+`CUSTOM_UART_PORT` - Sets the GPIO port number whose pins are used as RX and TX of the debug serial port.
+`CUSTOM_UART_RX_PIN` - Sets the pin number in the GPIO port used as RX of the debug serial port.
+`CUSTOM_UART_TX_PIN` - Sets the pin number in the GPIO port used as TX of the debug serial port.
+
+The above-described applies only to the `PSoC™ 062` platform.
+
+2. `CY_SMIF_SLAVE_SELECT_0` is used to define the chip select for the SMIF driver. This configuration is used on the evaluation kit for this example CY8CPROTO-062-4343W. To use custom hardware with this application, change the value of `smif_id` in `main.c` of MCUBootApp to a value that corresponds to your design.
+
+### Downloading solution assets
+
+The required set of assets:
* MCUBooot Library (root repository)
-* PSoC 6 HAL Library (submodule)
-* PSoC 6 Peripheral Drivers Library (PDL) (submodule)
+* HAL Library (submodule)
+* Peripheral Drivers Library (PDL) (submodule)
* mbedTLS Cryptographic Library (submodule)
To get submodules - run the following command:
git submodule update --init --recursive
-### Configuring MCUBootApp Bootloading Application
+### Configuring MCUBootApp bootloading application
-1. Choose upgrade mode:
-
-`SWAP` - this mode is set by default in `MCUBootApp/config/mcuboot_config/mcuboot_config.h`. `MCUBOOT_SWAP_USING_STATUS` preprocessor symbol is defined to enable this mode.
+1. Choose Upgrade mode and number of images.
-`Ovewrite only` - pass `USE_OVERWRITE=1` parameter to `make` for overwrite mode compilation.
-
-2. Change memory map
+`cy_flash_pal/flash_%platform_name%/flashmap` folder contains a set of predefined flash map JSON files with suffixes _overwrite_ or _swap_ for upgrade methods and _single_ or _multi_ for images number in its names. Depending on the file chosen upgrade method and images number is configured:
-Check paragraph **How to modify Flash map** above.
+`USE_OVERWRITE` `make` flag is set to 1 or 0 for `overwrite` or `swap` mode;
+`MCUBOOT_IMAGE_NUMBER` flag is set to number of corresponding `application_#` sections in flash map file.
-3. Enable hardware acceleration of cryptography
+These flags values are set in auto-generated `flashmap.mk` file per flash map used. There is no need to pass them manually.
-Pass `USE_CRYPTO_HW=1` to `make` command. This option is enabled by default.
+2. Enable the hardware acceleration of the cryptography on devices that support this feature.
-4. Change number of images - single or multi image configuration
+Pass `USE_CRYPTO_HW=1` to the `make` command. This option is temporarily disabled by default - see paragraph **Hardware cryptography acceleration**.
+
+Additionally user can configure hardware rollback protection on the supported platforms. To do this flash map file from `cy_flash_pal/flash_%platform_name%/flashmap/hw_rollback_prot` folder should be used.
+
+`USE_HW_ROLLBACK_PROT` `make` flag is set to 1 in auto-generated `flashmap.mk`.
+
+Rollback protection feature is currently supported on CYW20829 devices in Secure mode only.
+
+### Building solution
+
+Folder `boot/cypress` contains make-files infrastructure for building MCUBootApp bootloader applications. Example build commands are provided later in this document for different build configurations.
+
+* Build MCUBootApp in the `Debug` configuration for Single-image mode with swap upgrade.
+
+ make app APP_NAME=MCUBootApp PLATFORM=PSOC_062_2M BUILDCFG=Debug FLASH_MAP=cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_single.json
+
+* Build MCUBootApp in `Release` configuration for Multi-image mode with overwrite update.
+
+ make app APP_NAME=MCUBootApp PLATFORM=PSOC_062_2M BUILDCFG=Release FLASH_MAP=cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_multi.json
+
+The root directory for build is `boot/cypress`.
+
+### Encrypted image support
+
+To protect firmware content from read, plain binary data can be encrypted. MCUBootApp supports the encrypted image in some implementations, depending on the platform.
+
+On PSoC™ 6, an upgrade image can be encrypted and then programmed to corresponding Secondary slot of MCUBootApp. It is then decrypted and transferred to the primary slot using the preferred upgrade method. For more details on the encrypted image implementation, refer to the [PSOC6.md](../platforms/PSOC6/PSOC6.md) file.
+
+On CYW20829, an encrypted image is supported in both slots. The firmware here is located in external memory, so, the chip's SMIF block encrypted eXecution In Place (XIP) feature is used. Encrypted firmware is placed directly in the primary slot and is decrypted on the fly. The encrypted upgrade image is first validated by MCUBootApp in the secondary slot and then transferred to the primary slot as it is. For more details on the encrypted image implementation, refer to the [CYW20289.md](../platforms/CYW20829/CYW20829.md) file.
+
+### Rollback protection
+
+MCUboot supports the security counter implementation to provide downgrade prevention. This mechanism allows the user to explicitly restrict the possibility to execute/upgrade images whose security counters are less than the current firmware counter. So, it can be guaranteed, that obsolete firmware with possible vulnerabilities can not be executed on the device.
+
+**Currently, only the CYW20829 platform supports the hardware rollback counter protection.**
+For more details on the implementation, refer to the [CYW20289.md](../platforms/CYW20829/CYW20829.md) file.
+
+### Complete build flags and parameters description
-Pass `MCUBOOT_IMAGE_NUMBER=1` for single image configuration
-Pass `MCUBOOT_IMAGE_NUMBER=2` for multi image configuration
+Can be passed to `make` or set in makefiles.
-### Building Solution
+`MCUBOOT_LOG_LEVEL` - Can be set at `MCUBOOT_LOG_LEVEL_DEBUG` to enable the verbose output of MCUBootApp.
+`ENC_IMG` - When set to `1`, enables the encrypted image support in MCUBootApp.
+`APP_DEFAULT_POLICY` - The path to a policy file to use for signing MCUBootApp and user application (BlinkyApp) on the CYW20829 platform.
+`USE_BOOTSTRAP` - When set to `1` and Swap mode is enabled, the application in the secondary slot will overwrite the primary slot, if the primary slot application is invalid.
+`USE_CRYPTO_HW` - When set to `1`, uses the hardware accelerated cryptography on the PSoC™ 6 platform, and SHA-256 HW acceleration for the CYW20289 platform.
+`LSC` - The lifecycle state of the chip. Possible options are `SECURE` and `NORMAL_NO_SECURE` (effective on CYW20829 chip only).
-This folder `boot/cypress` contains make files infrastructure for building MCUBootApp bootloader application. Example build command are provided below for couple different build configurations.
+Set by script in auto-generated makefile file.
-* Build MCUBootApp in `Debug` configuration for single image use case.
+`MCUBOOT_IMAGE_NUMBER` - The number of images to be supported by the current build of MCUBootApp.
+`USE_OVERWRITE` - `0` - Use swap with Scratch upgrade mode, `1` - use Overwrite only upgrade.
+`USE_EXTERNAL_FLASH` - When set to `1`, enables the external memory support on the PSoC™ 6 platform. This value is always set to `1` on CYW20829.
+`USE_HW_ROLLBACK_PROT` - When set to `1`, enables the hardware rollback protection on the CYW20829 platform with Secure mode enabled.
- make app APP_NAME=MCUBootApp PLATFORM=PSOC_062_2M BUILDCFG=Debug MCUBOOT_IMAGE_NUMBER=1
+### Programming solution
-* Build MCUBootApp in `Release` configuration for multi image use case.
+The MCUBootApp firmware can be programmed in different ways.
- make app APP_NAME=MCUBootApp PLATFORM=PSOC_062_2M BUILDCFG=Release MCUBOOT_IMAGE_NUMBER=2
+1. The direct usage of OpenOCD.
-Root directory for build is `boot/cypress`.
+The OpenOCD package is supplied with ModusToolbox™ IDE and can be found in installation folder `ModusToolbox/tools_2.4/openocd`.
-### Encrypted Image Support
+Set environment variable `OPENOCD` to the path to the openocd folder in ModusToolbox™. Exact commands for programming images are provided in the corresponding platform readme files.
-To protect user image from unwanted read - Upgrade Image Encryption can be applied. The ECDH/HKDF with EC256 scheme is used in a given solution as well as mbedTLS as a crypto provider.
-
-To enable image encryption support use `ENC_IMG=1` build flag (BlinkyApp should also be built with this flash set 1).
-
-User is also responsible for providing corresponding binary key data in `enc_priv_key[]` (file `\MCUBootApp\keys.c`). The public part will be used by imgtool when signing and encrypting upgrade image. Signing image with encryption is described in `\BlinkyApp\Readme.md`.
-
-After MCUBootApp is built with these settings unencrypted and encrypted images will be accepted in secondary (upgrade) slot.
-
-Example command:
-
- make app APP_NAME=MCUBootApp PLATFORM=PSOC_062_2M BUILDCFG=Debug MCUBOOT_IMAGE_NUMBER=1 ENC_IMG=1
-
-__NOTE__: Debug configuration of MCUBootApp with multi image encrypted upgrades in external flash (built with flags `BUILDCFG=Debug` `MCUBOOT_IMG_NUMBER=2 USE_EXTERNAL_FLASH=1 ENC_IMG=1`) is set to use optimization level `-O2 -g3` to fit into `0x18000` allocated for `MCUBootApp`.
-
-### Programming Solution
-
-There are couple ways of programming MCUBootApp firmware. Following instructions assume usage of one of Cypress development kits `CY8CPROTO_062_4343W`.
-
-1. Direct usage of OpenOCD.
-
-OpenOCD package is supplied with ModuToolbox IDE and can be found in installation folder under `./tools_2.1/openocd`.
-
-Open terminal application - and execute following command after substitution `PATH_TO_APPLICATION.hex` and `OPENOCD` paths.
-
-Connect a board to your computer. Switch Kitprog3 to DAP-BULK mode by pressing `SW3 MODE` button until `LED2 STATUS` constantly shines.
-
- export OPENOCD=/Applications/ModusToolbox/tools_2.1/openocd
-
- ${OPENOCD}/bin/openocd -s ${OPENOCD}/scripts \
- -f ${OPENOCD}/scripts/interface/kitprog3.cfg \
- -f ${OPENOCD}/scripts/target/psoc6_2m.cfg \
- -c "init; reset init; program PATH_TO_APPLICATION.hex" \
- -c "resume; reset; exit"
-
-2. Using GUI tool `Cypress Programmer`
+2. Using the GUI tool `Cypress Programmer`
Follow [link](https://www.cypress.com/products/psoc-programming-solutions) to download.
-Connect board to your computer. Switch Kitprog3 to DAP-BULK mode by pressing `SW3 MODE` button until `LED2 STATUS` constantly shines. Open `Cypress Programmer` and click `Connect`, then choose hex file: `MCUBootApp.hex` or `BlinkyApp.hex` and click `Program`. Check log to ensure programming success. Reset board.
+Connect the board to your computer. Switch Kitprog3 to DAP-BULK mode by clicking the `SW3 MODE` button until `LED2 STATUS` constantly shines. Open `Cypress Programmer` and click `Connect`, then choose hex file: `MCUBootApp.hex` or `BlinkyApp.hex` and click `Program`. Check the log to ensure the programming is successful. Reset the board.
3. Using `DAPLINK`.
-Connect board to your computer. Switch embeded Kitprog3 to `DAPLINK` mode by pressing `SW3 MODE` button until `LED2 STATUS` blinks fast and mass storage device appeared in OS. Drag and drop `hex` files you wish to program to `DAPLINK` drive in your OS.
+This mode is currently supported only on PSoC™ 6 development kits.
-### Build Environment Troubleshooting
+Connect the board to your computer. Switch the embedded Kitprog3 to `DAPLINK` mode by clicking the `SW3 MODE` button until `LED2 STATUS` blinks fast and the mass storage device displays on the OS. Drag and drop `hex` files you wish to program to the `DAPLINK` drive in your OS.
+
+### Build environment troubleshooting
Regular shell/terminal combination on Linux and MacOS.
@@ -426,18 +643,11 @@
* Cygwin
* Msys2
-Also IDE may be used:
-* Eclipse / ModusToolbox ("makefile project from existing source")
+Also, an IDE can be used:
+* Eclipse / ModusToolbox™ ("makefile project from existing source")
-*Make* - make sure it is added to system's `PATH` variable and correct path is first in the list;
+*Make* - ensure that it is added to the system's `PATH` variable and the correct path is the first on the list.
-*Python/Python3* - make sure you have correct path referenced in `PATH`;
+*Python/Python3* - ensure that you have the correct path referenced in `PATH`.
-*Msys2* - to use systems PATH navigate to msys2 folder, open `msys2_shell.cmd`, uncomment set `MSYS2_PATH_TYPE=inherit`, restart MSYS2 shell.
-
-*Cygwin* - add following to build command `CURDIR=pwd | cygpath --mixed -f -` so that build command looks like that:
-
- make app APP_NAME=MCUBootApp PLATFORM=PSOC_062_2M CURDIR=`pwd | cygpath --mixed -f -`
-
-This will iherit system's PATH so should find `python3.7` installed in regular way as well as imgtool and its dependencies.
-
+*Msys2* - To use the systems path, navigate to the msys2 folder, open `msys2_shell.cmd`, uncomment set `MSYS2_PATH_TYPE=inherit`, restart the MSYS2 shell. This will inherit the system's path and find `python` installed in the regular way as well as `imgtool` and its dependencies.
diff --git a/boot/cypress/MCUBootApp/MCUBootApp.mk b/boot/cypress/MCUBootApp/MCUBootApp.mk
index 7b9a48a..e6ed9ed 100644
--- a/boot/cypress/MCUBootApp/MCUBootApp.mk
+++ b/boot/cypress/MCUBootApp/MCUBootApp.mk
@@ -25,111 +25,31 @@
include host.mk
+APP_NAME := MCUBootApp
+
# Cypress' MCUBoot Application supports GCC ARM only at this moment
# Set default compiler to GCC if not specified from command line
COMPILER ?= GCC_ARM
-USE_CRYPTO_HW ?= 1
-USE_EXTERNAL_FLASH ?= 0
-USE_OVERWRITE ?= 0
+CUR_APP_PATH = $(PRJ_DIR)/$(APP_NAME)
+
+ifneq ($(FLASH_MAP), )
+$(CUR_APP_PATH)/flashmap.mk:
+ $(PYTHON_PATH) scripts/flashmap.py -p $(PLATFORM) -i $(FLASH_MAP) -o $(PRJ_DIR)/cy_flash_pal/cy_flash_map.h > $(CUR_APP_PATH)/flashmap.mk
+include $(CUR_APP_PATH)/flashmap.mk
+DEFINES_APP := -DCY_FLASH_MAP_JSON
+endif
+
MCUBOOT_IMAGE_NUMBER ?= 1
ENC_IMG ?= 0
-
-# For which core this application is built
-CORE ?= CM0P
+USE_BOOTSTRAP ?= 1
+MCUBOOT_LOG_LEVEL ?= MCUBOOT_LOG_LEVEL_DEBUG
+USE_SHARED_SLOT ?= 0
ifneq ($(COMPILER), GCC_ARM)
$(error Only GCC ARM is supported at this moment)
endif
-CUR_APP_PATH = $(PRJ_DIR)/$(APP_NAME)
-
-include $(PRJ_DIR)/platforms.mk
-include $(PRJ_DIR)/common_libs.mk
-include $(PRJ_DIR)/toolchains.mk
-
-# default slot size is 0x10000 for single image
-# larger slot size is 0x20000 for multi image, 512bytes per row/sector, so 256 sectors will work for both
-MAX_IMG_SECTORS ?= 256
-
-# define slot sizes for IMAGE1 and IMAGE2 in case of usage with
-# external memory upgrade. 0x40000 slot size is acceptable for
-# all platforms in single image case with external upgrade
-ifeq ($(USE_EXTERNAL_FLASH), 1)
-IMAGE_1_SLOT_SIZE ?= 0x40200
-ifeq ($(MCUBOOT_IMAGE_NUMBER), 2)
-IMAGE_2_SLOT_SIZE ?= 0x40200
-endif
-endif
-
-# Application-specific DEFINES
-DEFINES_APP := -DMBEDTLS_CONFIG_FILE="\"mcuboot_crypto_config.h\""
-DEFINES_APP += -DECC256_KEY_FILE="\"keys/$(SIGN_KEY_FILE).pub\""
-DEFINES_APP += -DCORE=$(CORE)
-DEFINES_APP += -DMCUBOOT_IMAGE_NUMBER=$(MCUBOOT_IMAGE_NUMBER)
-
-ifeq ($(USE_OVERWRITE), 1)
-DEFINES_APP += -DMCUBOOT_OVERWRITE_ONLY
-endif
-
-ifeq ($(USE_EXTERNAL_FLASH), 1)
-DEFINES_APP += -DCY_BOOT_USE_EXTERNAL_FLASH
-MAX_IMG_SECTORS = 1536
-DEFINES_APP += -DCY_BOOT_IMAGE_1_SIZE=$(IMAGE_1_SLOT_SIZE)
-ifeq ($(MCUBOOT_IMAGE_NUMBER), 2)
-DEFINES_APP += -DCY_BOOT_IMAGE_2_SIZE=$(IMAGE_2_SLOT_SIZE)
-endif
-endif
-
-DEFINES_APP += -DMCUBOOT_MAX_IMG_SECTORS=$(MAX_IMG_SECTORS)
-# Hardrware acceleration support
-ifeq ($(USE_CRYPTO_HW), 1)
-DEFINES_APP += -DMBEDTLS_USER_CONFIG_FILE="\"mcuboot_crypto_acc_config.h\""
-DEFINES_APP += -DCY_CRYPTO_HAL_DISABLE
-DEFINES_APP += -DCY_MBEDTLS_HW_ACCELERATION
-endif
-# Encrypted image support
-ifeq ($(ENC_IMG), 1)
-DEFINES_APP += -DENC_IMG=1
-# Use higher optimization level for enc image in multi image mode
-# with external flash so it would fit into 0x18000 size of MCUBootApp
-ifeq ($(BUILDCFG), Debug)
-ifeq ($(MCUBOOT_IMAGE_NUMBER), 2)
-ifeq ($(USE_EXTERNAL_FLASH), 1)
-CFLAGS_OPTIMIZATION := -O2 -g3
-endif
-endif
-endif
-endif
-
-# Collect MCUBoot sourses
-SOURCES_MCUBOOT := $(wildcard $(CURDIR)/../bootutil/src/*.c)
-# Collect MCUBoot Application sources
-SOURCES_APP_SRC := $(wildcard $(CUR_APP_PATH)/*.c)
-
-# Collect Flash Layer port sources
-SOURCES_FLASH_PORT := $(wildcard $(CURDIR)/cy_flash_pal/*.c)
-SOURCES_FLASH_PORT += $(wildcard $(CURDIR)/cy_flash_pal/flash_qspi/*.c)
-# Collect all the sources
-SOURCES_APP := $(SOURCES_MCUBOOT)
-SOURCES_APP += $(SOURCES_APP_SRC)
-SOURCES_APP += $(SOURCES_FLASH_PORT)
-
-INCLUDE_DIRS_MCUBOOT := $(addprefix -I, $(CURDIR)/../bootutil/include)
-INCLUDE_DIRS_MCUBOOT += $(addprefix -I, $(CURDIR)/../bootutil/src)
-INCLUDE_DIRS_MCUBOOT += $(addprefix -I, $(CURDIR)/..)
-
-INCLUDE_DIRS_APP := $(addprefix -I, $(CURDIR))
-INCLUDE_DIRS_APP += $(addprefix -I, $(CURDIR)/cy_flash_pal/flash_qspi)
-INCLUDE_DIRS_APP += $(addprefix -I, $(CURDIR)/cy_flash_pal/include)
-INCLUDE_DIRS_APP += $(addprefix -I, $(CURDIR)/cy_flash_pal/include/flash_map_backend)
-INCLUDE_DIRS_APP += $(addprefix -I, $(CUR_APP_PATH))
-INCLUDE_DIRS_APP += $(addprefix -I, $(CUR_APP_PATH)/config)
-INCLUDE_DIRS_APP += $(addprefix -I, $(CUR_APP_PATH)/os)
-
-ASM_FILES_APP :=
-ASM_FILES_APP += $(ASM_FILES_STARTUP)
-
# Output folder
OUT := $(APP_NAME)/out
# Output folder to contain build artifacts
@@ -137,9 +57,198 @@
OUT_CFG := $(OUT_TARGET)/$(BUILDCFG)
-# Overwite path to linker script if custom is required
+include $(PRJ_DIR)/platforms.mk
+include $(PRJ_DIR)/common_libs.mk
+include $(PRJ_DIR)/toolchains.mk
+
+ifeq ($(MAX_IMG_SECTORS), )
+MAX_IMG_SECTORS ?= $(PLATFORM_MAX_IMG_SECTORS)
+endif
+
+# Application-specific DEFINES
+DEFINES_APP += -DMBEDTLS_CONFIG_FILE="\"mcuboot_crypto_config.h\""
+DEFINES_APP += -DECC256_KEY_FILE="\"keys/$(SIGN_KEY_FILE).pub\""
+DEFINES_APP += -D$(CORE)
+DEFINES_APP += -DMCUBOOT_IMAGE_NUMBER=$(MCUBOOT_IMAGE_NUMBER)
+DEFINES_APP += -DUSE_SHARED_SLOT=$(USE_SHARED_SLOT)
+
+# Define MCUboot size and pass it to linker script
+BOOTLOADER_SIZE ?= $(PLATFORM_BOOTLOADER_SIZE)
+LDFLAGS_DEFSYM += -Wl,--defsym,BOOTLOADER_SIZE=$(BOOTLOADER_SIZE)
+
+
+APP_DEFAULT_POLICY ?= $(PLATFORM_APP_DEFAULT_POLICY)
+
+ifeq ($(USE_EXTERNAL_FLASH), 1)
+ifeq ($(USE_XIP), 1)
+DEFINES_APP += -DUSE_XIP
+endif
+DEFINES_APP += -DCY_BOOT_USE_EXTERNAL_FLASH
+DEFINES_APP += -DCY_MAX_EXT_FLASH_ERASE_SIZE=$(PLATFORM_CY_MAX_EXT_FLASH_ERASE_SIZE)
+endif
+
+ifeq ($(USE_OVERWRITE), 1)
+DEFINES_APP += -DMCUBOOT_OVERWRITE_ONLY
+ifeq ($(USE_SW_DOWNGRADE_PREV), 1)
+DEFINES_APP += -DMCUBOOT_DOWNGRADE_PREVENTION
+endif
+else
+ifeq ($(USE_BOOTSTRAP), 1)
+DEFINES_APP += -DMCUBOOT_BOOTSTRAP
+endif
+endif
+DEFINES_APP += -DMCUBOOT_MAX_IMG_SECTORS=$(MAX_IMG_SECTORS)
+DEFINES_APP += -DMCUBOOT_LOG_LEVEL=$(MCUBOOT_LOG_LEVEL)
+ifeq ($(USE_HW_ROLLBACK_PROT), 1)
+DEFINES_APP += -DMCUBOOT_HW_ROLLBACK_PROT
+# Service RAM app address (size 0x8000)
+DEFINES_APP += -DSERVICE_APP_OFFSET=$(PLATFORM_SERVICE_APP_OFFSET)
+# Service RAM app input parameters address (size 0x400)
+DEFINES_APP += -DSERVICE_APP_INPUT_PARAMS_OFFSET=$(PLATFORM_SERVICE_APP_INPUT_PARAMS_OFFSET)
+# Service RAM app descriptor addr (size 0x20)
+DEFINES_APP += -DSERVICE_APP_DESC_OFFSET=$(PLATFORM_SERVICE_APP_DESC_OFFSET)
+# Service RAM app size
+DEFINES_APP += -DSERVICE_APP_SIZE=$(PLATFORM_SERVICE_APP_SIZE)
+endif
+# Hardrware acceleration support
+ifeq ($(USE_CRYPTO_HW), 1)
+DEFINES_APP += -DMBEDTLS_USER_CONFIG_FILE="\"mcuboot_crypto_acc_config.h\""
+DEFINES_APP += -DCY_CRYPTO_HAL_DISABLE
+DEFINES_APP += -DCY_MBEDTLS_HW_ACCELERATION
+endif
+
+# Compile with user redefined values for UART HW, port, pins
+ifeq ($(USE_CUSTOM_DEBUG_UART), 1)
+DEFINES_APP += -DUSE_CUSTOM_DEBUG_UART=1
+endif
+
+# Encrypted image support
+ifeq ($(ENC_IMG), 1)
+DEFINES_APP += -DENC_IMG=1
+ifeq ($(PLATFORM), CYW20829)
+DEFINES_APP += -DMCUBOOT_ENC_IMAGES_XIP
+endif
+# Use maximum optimization level for PSOC6 encrypted image with
+# external flash so it would fit into 0x18000 size of MCUBootApp
+ifneq ($(PLATFORM), CYW20829)
+ifeq ($(BUILDCFG), Debug)
+ifeq ($(USE_EXTERNAL_FLASH), 1)
+CFLAGS_OPTIMIZATION := -Os -g3
+endif
+endif
+endif
+endif
+
+
+# Collect MCUBoot sourses
+SOURCES_MCUBOOT := $(wildcard $(PRJ_DIR)/../bootutil/src/*.c)
+# Collect MCUBoot Application sources
+SOURCES_APP_SRC := main.c cy_security_cnt.c keys.c
+
+# Collect Flash Layer sources and header files dirs
+INCLUDE_DIRS_FLASH := $(PLATFORM_INCLUDE_DIRS_FLASH)
+INCLUDE_DIRS_UTILS := $(PLATFORM_INCLUDE_DIRS_UTILS)
+SOURCES_FLASH := $(PLATFORM_SOURCES_FLASH)
+
+# Collect all the sources
+SOURCES_APP := $(SOURCES_MCUBOOT)
+SOURCES_APP += $(SOURCES_FLASH)
+SOURCES_APP += $(addprefix $(CUR_APP_PATH)/, $(SOURCES_APP_SRC))
+SOURCES_APP += $(PLATFORM_APP_SOURCES)
+
+INCLUDE_DIRS_MCUBOOT := $(addprefix -I, $(PRJ_DIR)/../bootutil/include)
+INCLUDE_DIRS_MCUBOOT += $(addprefix -I, $(PRJ_DIR)/../bootutil/src)
+INCLUDE_DIRS_MCUBOOT += $(addprefix -I, $(PRJ_DIR)/..)
+
+INCLUDE_DIRS_APP += $(addprefix -I, $(PRJ_DIR))
+INCLUDE_DIRS_APP += $(addprefix -I, $(CUR_APP_PATH))
+INCLUDE_DIRS_APP += $(addprefix -I, $(CUR_APP_PATH)/config)
+INCLUDE_DIRS_APP += $(addprefix -I, $(CUR_APP_PATH)/os)
+INCLUDE_DIRS_APP += $(addprefix -I, $(INCLUDE_DIRS_FLASH))
+INCLUDE_DIRS_APP += $(addprefix -I, $(INCLUDE_DIRS_UTILS))
+
+ASM_FILES_APP :=
+ASM_FILES_APP += $(ASM_FILES_STARTUP)
+
+# Pass variables to linker script and overwrite path to it, if custom is required
ifeq ($(COMPILER), GCC_ARM)
-LINKER_SCRIPT := $(subst /cygdrive/c,c:,$(CUR_APP_PATH)/$(APP_NAME).ld)
+LDFLAGS += $(LDFLAGS_DEFSYM)
+LINKER_SCRIPT := $(CUR_APP_PATH)/$(APP_NAME)_$(CORE).ld
else
$(error Only GCC ARM is supported at this moment)
-endif
\ No newline at end of file
+endif
+
+###############################################################################
+# Print debug information about all settings used and/or set in this file
+ifeq ($(VERBOSE), 1)
+$(info #### MCUBootApp.mk ####)
+$(info APP_DEFAULT_POLICY --> $(APP_DEFAULT_POLICY))
+$(info APP_NAME <-> $(APP_NAME))
+$(info ASM_FILES_APP --> $(ASM_FILES_APP))
+$(info ASM_FILES_STARTUP <-- $(ASM_FILES_STARTUP))
+$(info BOOTLOADER_SIZE <-> $(BOOTLOADER_SIZE))
+$(info BUILDCFG <-- $(BUILDCFG))
+$(info CFLAGS_OPTIMIZATION --> $(CFLAGS_OPTIMIZATION))
+$(info COMPILER <-> $(COMPILER))
+$(info CORE <-- $(CORE))
+$(info CUR_APP_PATH <-- $(CUR_APP_PATH))
+$(info DEFINES_APP --> $(DEFINES_APP))
+$(info ENC_IMG <-> $(ENC_IMG))
+$(info EXTERNAL_FLASH_PRIMARY_2_OFFSET <-> $(EXTERNAL_FLASH_PRIMARY_2_OFFSET))
+$(info EXTERNAL_FLASH_SCRATCH_OFFSET <-> $(EXTERNAL_FLASH_SCRATCH_OFFSET))
+$(info EXTERNAL_FLASH_SECONDARY_1_OFFSET <-> $(EXTERNAL_FLASH_SECONDARY_1_OFFSET))
+$(info EXTERNAL_FLASH_SECONDARY_2_OFFSET <-> $(EXTERNAL_FLASH_SECONDARY_2_OFFSET))
+$(info FLASH_MAP <-- $(FLASH_MAP))
+$(info IMAGE_1_SLOT_SIZE <-> $(IMAGE_1_SLOT_SIZE))
+$(info IMAGE_2_SLOT_SIZE <-> $(IMAGE_2_SLOT_SIZE))
+$(info INCLUDE_DIRS_APP --> $(INCLUDE_DIRS_APP))
+$(info INCLUDE_DIRS_FLASH <-> $(INCLUDE_DIRS_FLASH))
+$(info INCLUDE_DIRS_MCUBOOT --> $(INCLUDE_DIRS_MCUBOOT))
+$(info LDFLAGS --> $(LDFLAGS))
+$(info LDFLAGS_DEFSYM <-> $(LDFLAGS_DEFSYM))
+$(info LINKER_SCRIPT --> $(LINKER_SCRIPT))
+$(info MAX_IMG_SECTORS <-> $(MAX_IMG_SECTORS))
+$(info MCUBOOT_IMAGE_NUMBER <-> $(MCUBOOT_IMAGE_NUMBER))
+$(info MCUBOOT_LOG_LEVEL <-> $(MCUBOOT_LOG_LEVEL))
+$(info OUT <-> $(OUT))
+$(info OUT_CFG --> $(OUT_CFG))
+$(info OUT_TARGET <-> $(OUT_TARGET))
+$(info PLATFORM <-- $(PLATFORM))
+$(info PLATFORM_APP_DEFAULT_POLICY <-- $(PLATFORM_APP_DEFAULT_POLICY))
+$(info PLATFORM_APP_SOURCES <-- $(PLATFORM_APP_SOURCES))
+$(info PLATFORM_BOOTLOADER_SIZE <-- $(PLATFORM_BOOTLOADER_SIZE))
+$(info PLATFORM_CHUNK_SIZE <-- $(PLATFORM_CHUNK_SIZE))
+$(info PLATFORM_CY_MAX_EXT_FLASH_ERASE_SIZE <-- $(PLATFORM_CY_MAX_EXT_FLASH_ERASE_SIZE))
+$(info PLATFORM_EXTERNAL_FLASH_PRIMARY_2_OFFSET <-- $(PLATFORM_EXTERNAL_FLASH_PRIMARY_2_OFFSET))
+$(info PLATFORM_EXTERNAL_FLASH_SCRATCH_OFFSET <-- $(PLATFORM_EXTERNAL_FLASH_SCRATCH_OFFSET))
+$(info PLATFORM_EXTERNAL_FLASH_SECONDARY_1_OFFSET <-- $(PLATFORM_EXTERNAL_FLASH_SECONDARY_1_OFFSET))
+$(info PLATFORM_EXTERNAL_FLASH_SECONDARY_2_OFFSET <-- $(PLATFORM_EXTERNAL_FLASH_SECONDARY_2_OFFSET))
+$(info PLATFORM_IMAGE_1_SLOT_SIZE <-- $(PLATFORM_IMAGE_1_SLOT_SIZE))
+$(info PLATFORM_IMAGE_2_SLOT_SIZE <-- $(PLATFORM_IMAGE_2_SLOT_SIZE))
+$(info PLATFORM_INCLUDE_DIRS_FLASH <-- $(PLATFORM_INCLUDE_DIRS_FLASH))
+$(info PLATFORM_MAX_IMG_SECTORS <-- $(PLATFORM_MAX_IMG_SECTORS))
+$(info PLATFORM_SCRATCH_SIZE <-- $(PLATFORM_SCRATCH_SIZE))
+$(info PLATFORM_SERVICE_APP_DESC_OFFSET <-- $(PLATFORM_SERVICE_APP_DESC_OFFSET))
+$(info PLATFORM_SERVICE_APP_INPUT_PARAMS_OFFSET <-- $(PLATFORM_SERVICE_APP_INPUT_PARAMS_OFFSET))
+$(info PLATFORM_SERVICE_APP_OFFSET <-- $(PLATFORM_SERVICE_APP_OFFSET))
+$(info PLATFORM_SERVICE_APP_SIZE <-- $(PLATFORM_SERVICE_APP_SIZE))
+$(info PLATFORM_SOURCES_FLASH <-- $(PLATFORM_SOURCES_FLASH))
+$(info PLATFORM_STATUS_PARTITION_OFFSET <-- $(PLATFORM_STATUS_PARTITION_OFFSET))
+$(info PRJ_DIR <-- $(PRJ_DIR))
+$(info PYTHON_PATH <-- $(PYTHON_PATH))
+$(info SCRATCH_SIZE <-> $(SCRATCH_SIZE))
+$(info SIGN_KEY_FILE <-- $(SIGN_KEY_FILE))
+$(info SOURCES_APP --> $(SOURCES_APP))
+$(info SOURCES_APP_SRC <-> $(SOURCES_APP_SRC))
+$(info SOURCES_FLASH <-> $(SOURCES_FLASH))
+$(info SOURCES_MCUBOOT <-> $(SOURCES_MCUBOOT))
+$(info STATUS_PARTITION_OFFSET <-> $(STATUS_PARTITION_OFFSET))
+$(info USE_BOOTSTRAP <-> $(USE_BOOTSTRAP))
+$(info USE_CRYPTO_HW <-- $(USE_CRYPTO_HW))
+$(info USE_CUSTOM_DEBUG_UART <-- $(USE_CUSTOM_DEBUG_UART))
+$(info USE_CUSTOM_MEMORY_MAP <-- $(USE_CUSTOM_MEMORY_MAP))
+$(info USE_EXTERNAL_FLASH <-- $(USE_EXTERNAL_FLASH))
+$(info USE_HW_ROLLBACK_PROT <-- $(USE_HW_ROLLBACK_PROT))
+$(info USE_OVERWRITE <-- $(USE_OVERWRITE))
+$(info USE_XIP <-- $(USE_XIP))
+endif
diff --git a/boot/cypress/MCUBootApp/MCUBootApp.ld b/boot/cypress/MCUBootApp/MCUBootApp_CM0P.ld
similarity index 87%
rename from boot/cypress/MCUBootApp/MCUBootApp.ld
rename to boot/cypress/MCUBootApp/MCUBootApp_CM0P.ld
index c78c598..9d9a32d 100644
--- a/boot/cypress/MCUBootApp/MCUBootApp.ld
+++ b/boot/cypress/MCUBootApp/MCUBootApp_CM0P.ld
@@ -1,6 +1,6 @@
/***************************************************************************//**
* \file cy8c6xxa_cm0plus.ld
-* \version 2.60
+* \version 2.91
*
* Linker file for the GNU C compiler.
*
@@ -19,7 +19,7 @@
*
********************************************************************************
* \copyright
-* Copyright 2016-2019 Cypress Semiconductor Corporation
+* Copyright 2016-2021 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -40,7 +40,7 @@
GROUP(-lgcc -lc -lnosys)
ENTRY(Reset_Handler)
-/* Size of the stack section at the end of CM0+ SRAM */
+/* The size of the stack section at the end of CM0+ SRAM */
STACK_SIZE = 0x1000;
/* Force symbol to be entered in the output file as an undefined symbol. Doing
@@ -63,9 +63,16 @@
* Your changes must be aligned with the corresponding memory regions for the CM4 core in 'xx_cm4_dual.ld',
* where 'xx' is the device group; for example, 'cy8c6xx7_cm4_dual.ld'.
*/
- public_ram (rw) : ORIGIN = 0x08000000, LENGTH = 0x800
ram (rwx) : ORIGIN = 0x08000800, LENGTH = 0x1F800
- flash (rx) : ORIGIN = 0x10000000, LENGTH = 0x18000
+ flash (rx) : ORIGIN = 0x10000000, LENGTH = 0x17E90
+ smif_struct (rx) : ORIGIN = 0x10017E90, LENGTH = 0x170
+
+ /* This is an unprotected public RAM region, with the placed .cy_sharedmem.
+ * This region is used to place objects that require full access from both cores.
+ * Uncomment the following line, define the region origin and length, and uncomment the placement of
+ * the .cy_sharedmem section below.
+ */
+ public_ram (rw) : ORIGIN = 0x08000000, LENGTH = 0x800
/* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash.
* You can assign sections to this memory region for only one of the cores.
@@ -165,6 +172,11 @@
KEEP(*(.eh_frame*))
} > flash
+ /* place SMIF config structures here */
+ .smif_struct ORIGIN(smif_struct) :
+ {
+ KEEP(*(.smif_struct)) /* keep my variable even if not referenced */
+ } > smif_struct
.ARM.extab :
{
@@ -216,16 +228,6 @@
__etext = . ;
- /* Set stack top to end of RAM, and stack limit move down by
- * size of stack_dummy section */
- __StackTop = ORIGIN(ram) + LENGTH(ram);
- __StackLimit = __StackTop - STACK_SIZE ;
- PROVIDE(__stack = __StackTop);
-
- .stackSpace (NOLOAD) : ALIGN(8)
- {
- . = . + STACK_SIZE ;
- } > ram
.ramVectors (NOLOAD) : ALIGN(8)
{
@@ -234,18 +236,10 @@
__ram_vectors_end__ = .;
} > ram
- /* Unprotected public RAM */
- .cy_sharedmem (NOLOAD):
- {
- . = ALIGN(4);
- __public_ram_start__ = .;
- KEEP(*(.cy_sharedmem))
- . = ALIGN(4);
- __public_ram_end__ = .;
- } > public_ram
- .data __ram_vectors_end__ : AT (__etext)
+ .data __ram_vectors_end__ :
{
+ . = ALIGN(4);
__data_start__ = .;
*(vtable)
@@ -279,7 +273,12 @@
__data_end__ = .;
- } > ram
+ } > ram AT>flash
+
+
+ /* Check if code and .data region exceeds FLASH image limit */
+ __FlashImageSize = __etext - ORIGIN(flash) + SIZEOF(.data);
+ ASSERT( __FlashImageSize <= BOOTLOADER_SIZE, "Resulting image does not fit into MCUboot flash region")
/* Place variables in the section that should not be initialized during the
@@ -313,17 +312,49 @@
__bss_end__ = .;
} > ram
+
.heap (NOLOAD):
{
__HeapBase = .;
__end__ = .;
end = __end__;
KEEP(*(.heap*))
- . = ORIGIN(ram) + LENGTH(ram);
+ . = ORIGIN(ram) + LENGTH(ram) - STACK_SIZE;
__HeapLimit = .;
} > ram
+ /* To use unprotected public RAM, uncomment the following .cy_sharedmem section placement.*/
+ /*
+ .cy_sharedmem (NOLOAD):
+ {
+ . = ALIGN(4);
+ __public_ram_start__ = .;
+ KEEP(*(.cy_sharedmem))
+ . = ALIGN(4);
+ __public_ram_end__ = .;
+ } > public_ram
+ */
+
+ /* .stack_dummy section doesn't contains any symbols. It is only
+ * used for linker to calculate size of stack sections, and assign
+ * values to stack symbols later */
+ .stack_dummy (NOLOAD):
+ {
+ KEEP(*(.stack*))
+ } > ram
+
+
+ /* Set stack top to end of RAM, and stack limit move down by
+ * size of stack_dummy section */
+ __StackTop = ORIGIN(ram) + LENGTH(ram);
+ __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+ PROVIDE(__stack = __StackTop);
+
+ /* Check if data + heap + stack exceeds RAM limit */
+ ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
+
+
/* Emulated EEPROM Flash area */
.cy_em_eeprom :
{
@@ -369,9 +400,11 @@
/* Places the code in the Execute in Place (XIP) section. See the smif driver
* documentation for details.
*/
- .cy_xip :
+ cy_xip :
{
+ __cy_xip_start = .;
KEEP(*(.cy_xip))
+ __cy_xip_end = .;
} > xip
diff --git a/boot/cypress/MCUBootApp/MCUBootApp_CM0P_Debug.launch b/boot/cypress/MCUBootApp/MCUBootApp_CM0P_Debug.launch
deleted file mode 100644
index c23487b..0000000
--- a/boot/cypress/MCUBootApp/MCUBootApp_CM0P_Debug.launch
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.openocd.launchConfigurationType">
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doContinue" value="false"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doDebugInRam" value="false"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doFirstReset" value="true"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateConsole" value="true"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateTelnetConsole" value="false"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doSecondReset" value="false"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbCLient" value="true"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbServer" value="true"/>
-<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.enableSemihosting" value="true"/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.firstResetType" value="init"/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherCommands" value="set mem inaccessible-by-default off"/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherOptions" value=""/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerConnectionAddress" value=""/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerExecutable" value="${cy_tools_path:openocd}/bin/openocd"/>
-<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerGdbPortNumber" value="3333"/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerLog" value=""/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerOther" value="-s "${cy_tools_path:openocd}/scripts" -s "${workspace_loc}/boot/cypress" -c "source [find interface/kitprog3.cfg]" -c "source [find target/psoc6_2m.cfg]" -c "puts stderr {Started by GNU MCU Eclipse}""/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTclPortNumber" value="6666"/>
-<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTelnetPortNumber" value="4444"/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherInitCommands" value=""/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherRunCommands" value=""/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.secondResetType" value=""/>
-<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value=""/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value="./out/PSOC_062_2M/Debug/MCUBootApp.elf"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU MCU OpenOCD"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
-<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="false"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value=""/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value="./out/PSOC_062_2M/Debug/MCUBootApp.elf"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
-<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${cy_sdk_install_dir}/tools/gcc-7.2.1-1.0/bin/arm-none-eabi-gdb${cy_exe_platform_ext}"/>
-<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
-<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/>
-<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
-<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
-<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="boot/cypress/MCUBootApp/out/PSOC_062_2M/Debug/MCUBootApp.elf"/>
-<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="cy_mcuboot"/>
-<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
-<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/cy_mcuboot"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="4"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"> <memoryBlockExpression address="268566528" label="0x10020000"/> <memoryBlockExpression address="268632064" label="0x10030000"/> </memoryBlockExpressionList> "/>
-<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
-</launchConfiguration>
diff --git a/boot/cypress/MCUBootApp/MCUBootApp_CM33.ld b/boot/cypress/MCUBootApp/MCUBootApp_CM33.ld
new file mode 100644
index 0000000..e98f9e5
--- /dev/null
+++ b/boot/cypress/MCUBootApp/MCUBootApp_CM33.ld
@@ -0,0 +1,494 @@
+/***************************************************************************//**
+* \file cyw20829_ns.ld
+* \version 1.0.0
+*
+* Linker file for the GNU C compiler.
+*
+* The main purpose of the linker script is to describe how the sections in the
+* input files should be mapped into the output file, and to control the memory
+* layout of the output file.
+*
+* \note The entry point location is fixed and starts at 0x10000000. The valid
+* application image should be placed there.
+*
+* \note The linker files included with the PDL template projects must be generic
+* and handle all common use cases. Your project may not use every section
+* defined in the linker files. In that case you may see warnings during the
+* build process. In your project, you can simply comment out or remove the
+* relevant code in the linker file.
+*
+********************************************************************************
+* \copyright
+* Copyright 2016-2020 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+*******************************************************************************/
+
+OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+GROUP(-lgcc -lc -lnosys )
+SEARCH_DIR(.)
+GROUP(libgcc.a libc.a libm.a libnosys.a)
+ENTRY(Reset_Handler)
+
+/* The size of the stack section at the end of CM33 SRAM */
+STACK_SIZE = 0x2400;
+
+FLASH_START_ADDR_SAHB = 0x60000000;
+FLASH_START_ADDR_CBUS = 0x08000000;
+RAM_START_ADDR_SAHB = 0x20000000;
+RAM_START_ADDR_CBUS = 0x04000000;
+RAM_END_ADDR_SAHB = 0x20020000; /* 128K */
+RAM_END_ADDR_CBUS = 0x04020000; /* 128K */
+FLASH_END_ADDR_SAHB = 0x60080000; /* 512K */
+
+BOOTSTRAP_OFFSET_FLASH = 0x00000050; /* toc2=0x10, l1_desc=0x1C, sign_header=0x20, padding=0x4 (encrypted data should be aligned to 0x10 boundary) */
+BOOTSTRAP_OFFSET_RAM = 0x0001E000; /* was 0x00004000 Modify this value to change the size of Bootstrap code + Data */
+APPCODE_OFFSET_FLASH = 0x00002200;
+
+RAMVECTORS_ALIGNMENT = 512;
+
+/* Memory reserved for Bootstrap code and data */
+BOOTSTRAP_SIZE = RAM_END_ADDR_SAHB - RAM_START_ADDR_SAHB - BOOTSTRAP_OFFSET_RAM; /* 0x00002000 */
+/* vma for bootstrap code region */
+CODE_VMA = RAM_START_ADDR_CBUS + BOOTSTRAP_OFFSET_RAM; /* 0x0401E000 */
+/* lma for bootstrap code region */
+CODE_LMA = FLASH_START_ADDR_SAHB + BOOTSTRAP_OFFSET_FLASH; /* 0x6000004C */
+/* Maximum bootstrap code + data size */
+CODE_BS_SIZE = BOOTSTRAP_SIZE; /* 8KB */
+/* vma for bootstrap data region */
+DATA_BS_VMA = RAM_START_ADDR_SAHB + BOOTSTRAP_OFFSET_RAM; /* 0x2001E000 */
+/* vma for bootstrap and app data region */
+DATA_VMA = RAM_START_ADDR_SAHB; /* 0x20000000 */
+/* vma for appCodeRam region */
+DATA_CBUS_VMA = RAM_START_ADDR_CBUS; /* 0x04000000 */
+/* lma for bootstrap and app data region */
+DATA_LMA = CODE_LMA + CODE_BS_SIZE; /* 0x6000204C */
+/* data size */
+DATA_SIZE = RAM_END_ADDR_SAHB - DATA_VMA - BOOTSTRAP_SIZE; /* 0x1E000 */
+/* vma for application XIP region */
+XIP_VMA = FLASH_START_ADDR_CBUS + APPCODE_OFFSET_FLASH; /* 0x08002200 */
+/* lma for application XIP region */
+XIP_LMA = FLASH_START_ADDR_SAHB + APPCODE_OFFSET_FLASH; /* 0x60002200 */
+/* size of XIP region */
+XIP_SIZE = FLASH_END_ADDR_SAHB - XIP_LMA;
+/* Total size of SRAM */
+RAM_SIZE = RAM_END_ADDR_SAHB - RAM_START_ADDR_SAHB; /* 0x00020000 */
+/* Size of Bootstrap data is kept same as BOOTSTRAP_SIZE */
+DATA_BS_SIZE = BOOTSTRAP_SIZE;
+
+/* Force symbol to be entered in the output file as an undefined symbol. Doing
+* this may, for example, trigger linking of additional modules from standard
+* libraries. You may list several symbols for each EXTERN, and you may use
+* EXTERN multiple times. This command has the same effect as the -u command-line
+* option.
+*/
+EXTERN(Reset_Handler)
+
+/* The MEMORY section below describes the location and size of blocks of memory in the target.
+* Use this section to specify the memory regions available for allocation.
+*/
+MEMORY
+{
+ /* The ram and flash regions control RAM and flash memory allocation for the CM33 core.
+ */
+ code (rx) : ORIGIN = CODE_VMA, LENGTH = CODE_BS_SIZE
+ bsData (rwx) : ORIGIN = DATA_BS_VMA, LENGTH = DATA_BS_SIZE
+ appCodeRam (rx) : ORIGIN = DATA_CBUS_VMA, LENGTH = DATA_SIZE
+ data (rwx) : ORIGIN = DATA_VMA, LENGTH = DATA_SIZE
+ xip (rx) : ORIGIN = XIP_VMA, LENGTH = XIP_SIZE
+}
+
+/* Library configurations */
+GROUP(libgcc.a libc.a libm.a libnosys.a)
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ * Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ * __exidx_start
+ * __exidx_end
+ * __copy_table_start__
+ * __copy_table_end__
+ * __zero_table_start__
+ * __zero_table_end__
+ * __etext
+ * __data_start__
+ * __preinit_array_start
+ * __preinit_array_end
+ * __init_array_start
+ * __init_array_end
+ * __fini_array_start
+ * __fini_array_end
+ * __data_end__
+ * __bss_start__
+ * __bss_end__
+ * __end__
+ * end
+ * __HeapLimit
+ * __StackLimit
+ * __StackTop
+ * __stack
+ * __Vectors_End
+ * __Vectors_Size
+ */
+
+SECTIONS
+{
+ /* .stack_dummy section doesn't contains any symbols. It is only
+ * used for linker to calculate size of stack sections, and assign
+ * values to stack symbols later */
+ .stack_dummy RAM_START_ADDR_SAHB (NOLOAD):
+ {
+ __StackLimit = .;
+ KEEP(*(.stack*))
+ . = STACK_SIZE;
+ __StackTop = .;
+ } > data
+
+PROVIDE(__stack = __StackTop);
+
+ __ramVectors_vma__ = ALIGN(RAMVECTORS_ALIGNMENT);
+
+ .ramVectors __ramVectors_vma__ (NOLOAD):
+ {
+ __ram_vectors_start__ = .;
+ KEEP(*(.ram_vectors))
+ . = ALIGN(4);
+ __ram_vectors_end__ = .;
+ } > data
+
+ __appTextRam_vma__ = (__ram_vectors_end__ - RAM_START_ADDR_SAHB) + RAM_START_ADDR_CBUS;
+ __appTextRam_lma__ = (__zero_table_end__ - FLASH_START_ADDR_CBUS) + FLASH_START_ADDR_SAHB;
+ __ezerotable = __zero_table_end__;
+
+ .appTextRam __appTextRam_vma__ : AT (__appTextRam_lma__)
+ {
+ . = ALIGN(4);
+ __app_text_ram_begin__ = .;
+ KEEP(*(.cy_ramfunc*))
+ . = ALIGN(4);
+
+ *cy_smif.o(.text*)
+ *cy_smif_memslot.o(.text*)
+ *cy_smif_sfdp.o(.text*)
+ *cy_gpio.o(.text*)
+ *cy_smif_hybrid_sect.o(.text*)
+
+ . = ALIGN(4);
+ __app_text_ram_end__ = .;
+
+ } > appCodeRam
+
+ __data_vma__ = (__app_text_ram_end__ - RAM_START_ADDR_CBUS) + RAM_START_ADDR_SAHB;
+ __data_lma__ = (__app_text_ram_end__ - __app_text_ram_begin__) + __appTextRam_lma__;
+ __etext = __data_lma__ - FLASH_START_ADDR_SAHB + FLASH_START_ADDR_CBUS;
+
+ .data __data_vma__ : AT (__data_lma__)
+ {
+ __data_start__ = .;
+
+ *(vtable)
+ *(.data*)
+
+ . = ALIGN(4);
+ /* preinit data */
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP(*(.preinit_array))
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+
+ . = ALIGN(4);
+ /* init data */
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__init_array_end = .);
+
+ . = ALIGN(4);
+ /* finit data */
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP(*(SORT(.fini_array.*)))
+ KEEP(*(.fini_array))
+ . = ALIGN(4);
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ . = ALIGN(4);
+ KEEP(*(.jcr*))
+ . = ALIGN(4);
+
+ __data_end__ = .;
+
+ } > data
+
+ /* Check if data is exceeding the flash size */
+ ASSERT((__data_lma__ + (__data_end__ - __data_start__)) <= FLASH_END_ADDR_SAHB, "data section exceeds Flash size !")
+
+ /* Place variables in the section that should not be initialized during the
+ * device startup.
+ */
+ .noinit (NOLOAD) : ALIGN(8)
+ {
+ KEEP(*(.noinit))
+ } > data
+
+ /* The uninitialized global or static variables are placed in this section.
+ *
+ * The NOLOAD attribute tells linker that .bss section does not consume
+ * any space in the image. The NOLOAD attribute changes the .bss type to
+ * NOBITS, and that makes linker to A) not allocate section in memory, and
+ * A) put information to clear the section with all zeros during application
+ * loading.
+ *
+ * Without the NOLOAD attribute, the .bss section might get PROGBITS type.
+ * This makes linker to A) allocate zeroed section in memory, and B) copy
+ * this section to RAM during application loading.
+ */
+ .bss (NOLOAD):
+ {
+ . = ALIGN(4);
+ __bss_start__ = .;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ } > data
+
+ /* Use ramining RAM for Heap */
+ __heap_size__ = (RAM_SIZE - ((__bss_end__ - RAM_START_ADDR_SAHB) + (RAM_END_ADDR_CBUS - __bootstrapText_vma__)) - 4);
+
+ .heap (NOLOAD):
+ {
+ . = ALIGN(8);
+ __HeapBase = .;
+ __end1__ = .;
+ end = __end1__;
+ KEEP(*(.heap*))
+ . += __heap_size__;
+ __HeapLimit = .;
+ } > data
+
+ __bootstrapText_vma__ = ORIGIN(code);
+ __bootstrapText_lma__ = CODE_LMA;
+
+ /* Cortex-M33 bootstrap code area */
+ .bootstrapText __bootstrapText_vma__ : AT (__bootstrapText_lma__)
+ {
+ /* Cortex-M33 code vector table */
+ . = ALIGN(4);
+ __bootstrapText_begin = .;
+
+ __Vectors = . ;
+ KEEP(*(.vectors))
+ . = ALIGN(4);
+ __Vectors_End = .;
+ __Vectors_Size = __Vectors_End - __Vectors;
+ __end__ = .;
+
+ . = ALIGN(4);
+
+ /* startup code */
+ *ns_start_cyw20829.o(.text*)
+ *ns_system_cyw20829.o(.text*)
+
+ /* drivers */
+ *cy_device.o(.text*)
+ *cy_btss.o(.text*)
+ *cy_sysclk_v2.o(.text*)
+ *cy_syspm_v2.o(.text*)
+ *cy_sysint_v2.o(.text*)
+ *cy_syslib*.o(.text*)
+ *ppu_v1.o(.text*)
+ *cy_mpc.o(.text*)
+ *cy_pd_ppu.o(.text*)
+ *cy_smif.o(.text*)
+ *cy_smif_memslot.o(.text*)
+ *cy_smif_sfdp.o(.text*)
+ *cy_gpio.o(.text*)
+ *cyhal_system.o(.text*)
+ *lib_a-memset.o(.text*)
+ *lib_a-memcpy-stub.o(.text*)
+
+ KEEP(*(.cy_l1func*))
+
+ . = ALIGN(4);
+ __bootstrapText_end = .;
+ } > code
+
+ __bootstrap_zerotable_lma__ = (CODE_LMA + (__bootstrapText_end - __bootstrapText_begin));
+
+ .bootstrapzero.table : AT (__bootstrap_zerotable_lma__)
+ {
+ . = ALIGN(4);
+ __bootstrapzero_table_start__ = .;
+ LONG (__bootstrap_bss_start__)
+ LONG ((__bootstrap_bss_end__ - __bootstrap_bss_start__)/4)
+ . = ALIGN(4);
+ __bootstrapzero_table_end__ = .;
+ } > code
+
+ __bootstrapData_vma__ = ((__bootstrapzero_table_end__ - RAM_START_ADDR_CBUS) + RAM_START_ADDR_SAHB);
+ __bootstrapData_lma__ = (__bootstrap_zerotable_lma__ + (__bootstrapzero_table_end__ - __bootstrapzero_table_start__));
+
+ .bootstrapData __bootstrapData_vma__ : AT (__bootstrapData_lma__)
+ {
+ __bootstrapData_start__ = .;
+ . = ALIGN(4);
+
+ /* startup code */
+ *ns_start_cyw20829.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *ns_system_cyw20829.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+
+ /* drivers */
+ *cy_device.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_btss.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_sysclk_v2.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_syspm_v2.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_sysint_v2.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_syslib.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *ppu_v1.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_mpc.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_pd_ppu.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_smif.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_smif_memslot.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_smif_sfdp.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cy_gpio.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cycfg_qspi_memslot.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *cyhal_system.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *lib_a-memset.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+ *lib_a-memcpy-stub.o(.data* .rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+
+ KEEP(*(.cy_l1data*))
+
+ . = ALIGN(4);
+
+ __bootstrapData_end__ = .;
+ __bootstrap_size_end__ = .;
+ } > bsData
+
+ .bootstrapBss (NOLOAD):
+ {
+ . = ALIGN(4);
+ __bootstrap_bss_start__ = .;
+
+ /* startup code */
+ *ns_start_cyw20829.o(.bss* COMMON)
+ *ns_system_cyw20829.o(.bss* COMMON)
+
+ /* drivers */
+ *cy_device.o(.bss* COMMON)
+ *cy_btss.o(.bss* COMMON)
+ *cy_sysclk_v2.o(.bss* COMMON)
+ *cy_syspm_v2.o(.bss* COMMON)
+ *cy_sysint_v2.o(.bss* COMMON)
+ *cy_syslib.o(.bss* COMMON)
+ *ppu_v1.o(.bss* COMMON)
+ *cy_mpc.o(.bss* COMMON)
+ *cy_pd_ppu.o(.bss* COMMON)
+ *cy_smif.o(.bss* COMMON)
+ *cy_smif_memslot.o(.bss* COMMON)
+ *cy_smif_sfdp.o(.bss* COMMON)
+ *cy_gpio.o(.bss* COMMON)
+ *lib_a-memset.o(.bss* COMMON)
+ *lib_a-memcpy-stub.o(.bss* COMMON)
+ KEEP(*(.cy_l1bss*))
+
+ . = ALIGN(4);
+ __bootstrap_bss_end__ = .;
+ } > bsData
+
+ /* Check if bootstrap code + data exceeds RAM limit */
+ ASSERT(__bootstrap_bss_end__ < RAM_END_ADDR_SAHB, "bootstrap region exceeds RAM size !")
+
+ __app_text_vma__ = ORIGIN(xip);
+ __app_text_lma__ = XIP_LMA;
+
+ /* Cortex-M33 application flash area */
+ .appText (__app_text_vma__) : AT (__app_text_lma__)
+ {
+ /* Cortex-M33 flash vector table */
+ . = ALIGN(4);
+ __text_begin = .;
+
+ *(EXCLUDE_FILE(*cy_smif.o *cy_smif_memslot.o *cy_smif_sfdp.o *cy_gpio.o *cy_smif_hybrid_sect.o) .text*)
+
+ KEEP(*(.init))
+ KEEP(*(.fini))
+
+ /* Read-only code (constants). */
+ *(.rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
+
+ KEEP(*(.eh_frame*))
+ . = ALIGN(4);
+ __text_end = .;
+
+ } > xip
+
+
+ .copy.table : AT (__app_text_lma__ + (__text_end - __text_begin))
+ {
+ . = ALIGN(4);
+ __copy_table_start__ = .;
+
+ /* Copy data section to RAM */
+ LONG (__etext) /* From */
+ LONG (__data_start__) /* To */
+ LONG ((__data_end__ - __data_start__)/4) /* Size */
+
+ /* Copy appTextRam section to RAM */
+ LONG (__ezerotable) /* From */
+ LONG (__ram_vectors_end__) /* To */
+ LONG ((__app_text_ram_end__ - __app_text_ram_begin__)/4) /* Size */
+
+ . = ALIGN(4);
+ __copy_table_end__ = .;
+ } > xip
+
+
+
+ .ARM.extab : AT (__app_text_lma__ + (__text_end - __text_begin) + (__copy_table_end__ - __copy_table_start__))
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > xip
+
+ __exidx_start = .;
+
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > xip
+ __exidx_end = .;
+
+
+ /* To clear multiple BSS sections,
+ * uncomment .zero.table section and,
+ * define __STARTUP_CLEAR_BSS_MULTIPLE in CAT1B devices */
+ .zero.table : AT (__exidx_end - __app_text_vma__ + __app_text_lma__)
+ {
+ . = ALIGN(4);
+ __zero_table_start__ = .;
+ LONG (__bss_start__)
+ LONG ((__bss_end__ - __bss_start__)/4)
+
+ . = ALIGN(4);
+ __zero_table_end__ = .;
+ } > xip
+}
+
+/* start of bootstrap code sahb address */
+__bootstrap_start_addr__ = RAM_START_ADDR_SAHB + BOOTSTRAP_OFFSET_RAM;
+/* bootstrap size */
+__bootstrap_size__ = __bootstrap_size_end__ - __bootstrap_start_addr__;
diff --git a/boot/cypress/MCUBootApp/config/custom_debug_uart_cfg.h b/boot/cypress/MCUBootApp/config/custom_debug_uart_cfg.h
new file mode 100644
index 0000000..9d99c58
--- /dev/null
+++ b/boot/cypress/MCUBootApp/config/custom_debug_uart_cfg.h
@@ -0,0 +1,41 @@
+/********************************************************************************
+* Copyright 2021 Infineon Technologies AG
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#if !defined(CUSTOM_DEBUG_UART_CFG_H)
+#define CUSTOM_DEBUG_UART_CFG_H
+
+#if defined(USE_CUSTOM_DEBUG_UART)
+
+/* Define SCB which will be used as UART. */
+#define CUSTOM_UART_HW SCB1
+
+/* Define SCB number which will be used as UART.
+ * It is 'x' in SCBx
+ * */
+#define CUSTOM_UART_SCB_NUMBER 1
+
+#define CUSTOM_UART_PORT 10
+
+/* define RX pin */
+#define CUSTOM_UART_RX_PIN 0
+
+/* define TX pin */
+#define CUSTOM_UART_TX_PIN 1
+
+#endif /* defined(USE_CUSTOM_DEBUG_UART) */
+
+#endif /* CUSTOM_DEBUG_UART_CFG_H */
diff --git a/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_config.h b/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_config.h
index eeb15bc..c2b2348 100644
--- a/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_config.h
+++ b/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_config.h
@@ -22,7 +22,7 @@
/* Default maximum number of flash sectors per image slot; change
* as desirable. */
#ifndef MCUBOOT_MAX_IMG_SECTORS
-#define MCUBOOT_MAX_IMG_SECTORS 128u
+#define MCUBOOT_MAX_IMG_SECTORS 128U
#endif
/*
@@ -39,6 +39,8 @@
// #define MCUBOOT_SIGN_EC
+//#define MCUBOOT_OVERWRITE_ONLY 1
+
/*
* Upgrade mode
*
@@ -52,10 +54,18 @@
/* #define MCUBOOT_OVERWRITE_ONLY_FAST */
#else
/* Using SWAP w Scratch by default.
- * Comment/Uncomment which is needed. */
-#define MCUBOOT_SWAP_USING_SCRATCH 1
-/* #define MCUBOOT_SWAP_USING_MOVE 1 */
-#define MCUBOOT_SWAP_USING_STATUS 1
+ * Uncomment which is needed. */
+#define MCUBOOT_SWAP_USING_SCRATCH 1
+/* #define MCUBOOT_SWAP_USING_MOVE 1 */
+#define MCUBOOT_SWAP_USING_STATUS 1
+#endif
+
+/* This definition is used in boot_copy_region function to define
+ * minimum size of data chunk to be copied. This most likely is equal
+ * to erase size of target hardware.
+ */
+#ifndef MCUBOOT_PLATFORM_CHUNK_SIZE
+#define MCUBOOT_PLATFORM_CHUNK_SIZE 4096U
#endif
/*
@@ -94,6 +104,12 @@
#endif
/*
+ * Currently there is no configuration option, for this platform,
+ * that enables the system specific mcumgr commands in mcuboot
+ */
+#define MCUBOOT_PERUSER_MGMT_GROUP_ENABLED 0
+
+/*
* Logging
*/
@@ -151,7 +167,30 @@
#ifdef ENC_IMG
#define MCUBOOT_ENC_IMAGES
#define MCUBOOT_ENCRYPT_EC256
-#define NUM_ECC_BYTES (256 / 8)
#endif /* ENC_IMG */
+/*
+ * No direct idle call implemented
+ */
+#define MCUBOOT_CPU_IDLE() \
+ do { \
+ } while (0)
+
+/*
+ * Do not save ENCTLV by default
+ */
+//#define MCUBOOT_SWAP_SAVE_ENCTLV 1
+
+/* INFO: Misc functionality defines */
+/*
+#define MCUBOOT_HW_KEY
+#define MCUBOOT_HW_ROLLBACK_PROT
+#define MCUBOOT_MEASURED_BOOT
+#define MCUBOOT_DATA_SHARING
+*/
+/* Use basic fault injection hardening profile */
+//#define MCUBOOT_FIH_PROFILE_LOW
+
+//#define MCUBOOT_FIH_PROFILE_MEDIUM
+
#endif /* MCUBOOT_CONFIG_H */
diff --git a/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_logging.h b/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_logging.h
index 8a91f3f..9869e33 100644
--- a/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_logging.h
+++ b/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_logging.h
@@ -28,6 +28,7 @@
#ifndef MCUBOOT_LOGGING_H
#define MCUBOOT_LOGGING_H
+#include <stdbool.h>
#include <stdio.h>
#define MCUBOOT_LOG_LEVEL_OFF 0
@@ -46,17 +47,23 @@
#define MCUBOOT_LOG_LEVEL MCUBOOT_LOG_LEVEL_INFO
#endif
+#ifdef __BOOTSIM__
int sim_log_enabled(int level);
+#else
+static inline int sim_log_enabled(int level) {
+ (void)level;
+ return 1;
+}
+#endif
-#define sim_log_enabled(x) 1
#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_ERROR
#define MCUBOOT_LOG_ERR(_fmt, ...) \
do { \
- if (sim_log_enabled(MCUBOOT_LOG_LEVEL_ERROR)) { \
- fprintf(stderr, "[ERR] " _fmt "\n\r", ##__VA_ARGS__); \
+ if (sim_log_enabled(MCUBOOT_LOG_LEVEL_ERROR) != 0) { \
+ (void)fprintf(stderr, "[ERR] " _fmt "\n\r", ##__VA_ARGS__); \
} \
- } while (0)
+ } while ((bool)0)
#else
#define MCUBOOT_LOG_ERR(...) IGNORE(__VA_ARGS__)
#endif
@@ -64,10 +71,10 @@
#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_WARNING
#define MCUBOOT_LOG_WRN(_fmt, ...) \
do { \
- if (sim_log_enabled(MCUBOOT_LOG_LEVEL_WARNING)) { \
- fprintf(stderr, "[WRN] " _fmt "\n\r", ##__VA_ARGS__); \
+ if (sim_log_enabled(MCUBOOT_LOG_LEVEL_WARNING) != 0) { \
+ (void)fprintf(stderr, "[WRN] " _fmt "\n\r", ##__VA_ARGS__); \
} \
- } while (0)
+ } while ((bool)0)
#else
#define MCUBOOT_LOG_WRN(...) IGNORE(__VA_ARGS__)
#endif
@@ -75,10 +82,10 @@
#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_INFO
#define MCUBOOT_LOG_INF(_fmt, ...) \
do { \
- if (sim_log_enabled(MCUBOOT_LOG_LEVEL_INFO)) { \
- fprintf(stderr, "[INF] " _fmt "\n\r", ##__VA_ARGS__); \
+ if (sim_log_enabled(MCUBOOT_LOG_LEVEL_INFO) != 0) { \
+ (void)fprintf(stderr, "[INF] " _fmt "\n\r", ##__VA_ARGS__); \
} \
- } while (0)
+ } while ((bool)0)
#else
#define MCUBOOT_LOG_INF(...) IGNORE(__VA_ARGS__)
#endif
@@ -86,10 +93,10 @@
#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_DEBUG
#define MCUBOOT_LOG_DBG(_fmt, ...) \
do { \
- if (sim_log_enabled(MCUBOOT_LOG_LEVEL_DEBUG)) { \
- fprintf(stderr, "[DBG] " _fmt "\n\r", ##__VA_ARGS__); \
+ if (sim_log_enabled(MCUBOOT_LOG_LEVEL_DEBUG) != 0) { \
+ (void)fprintf(stderr, "[DBG] " _fmt "\n\r", ##__VA_ARGS__); \
} \
- } while (0)
+ } while ((bool)0)
#else
#define MCUBOOT_LOG_DBG(...) IGNORE(__VA_ARGS__)
#endif
diff --git a/boot/cypress/MCUBootApp/config/mcuboot_crypto_acc_config.h b/boot/cypress/MCUBootApp/config/mcuboot_crypto_acc_config.h
index b172740..c64be77 100644
--- a/boot/cypress/MCUBootApp/config/mcuboot_crypto_acc_config.h
+++ b/boot/cypress/MCUBootApp/config/mcuboot_crypto_acc_config.h
@@ -23,6 +23,13 @@
#ifndef MCUBOOT_MBEDTLS_DEVICE_H
#define MCUBOOT_MBEDTLS_DEVICE_H
+#ifdef CYW20829
+
+/* Only SHA256 is accelerated by Cryptolite */
+#define MBEDTLS_SHA256_ALT
+
+#else
+
/* Currently this target supports SHA1 */
// #define MBEDTLS_SHA1_C
@@ -51,4 +58,6 @@
#define MBEDTLS_ECDSA_SIGN_ALT
#define MBEDTLS_ECDSA_VERIFY_ALT
+#endif /* CYW20829 */
+
#endif /* MCUBOOT_MBEDTLS_DEVICE_H */
diff --git a/boot/cypress/MCUBootApp/config/mcuboot_crypto_config.h b/boot/cypress/MCUBootApp/config/mcuboot_crypto_config.h
index efb1bda..05b29ea 100644
--- a/boot/cypress/MCUBootApp/config/mcuboot_crypto_config.h
+++ b/boot/cypress/MCUBootApp/config/mcuboot_crypto_config.h
@@ -1607,30 +1607,6 @@
//#define MBEDTLS_SSL_PROTO_SSL3
/**
- * \def MBEDTLS_SSL_PROTO_TLS1
- *
- * Enable support for TLS 1.0.
- *
- * Requires: MBEDTLS_MD5_C
- * MBEDTLS_SHA1_C
- *
- * Comment this macro to disable support for TLS 1.0
- */
-#define MBEDTLS_SSL_PROTO_TLS1
-
-/**
- * \def MBEDTLS_SSL_PROTO_TLS1_1
- *
- * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled).
- *
- * Requires: MBEDTLS_MD5_C
- * MBEDTLS_SHA1_C
- *
- * Comment this macro to disable support for TLS 1.1 / DTLS 1.0
- */
-#define MBEDTLS_SSL_PROTO_TLS1_1
-
-/**
* \def MBEDTLS_SSL_PROTO_TLS1_2
*
* Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled).
@@ -1762,15 +1738,6 @@
#define MBEDTLS_SSL_SERVER_NAME_INDICATION
/**
- * \def MBEDTLS_SSL_TRUNCATED_HMAC
- *
- * Enable support for RFC 6066 truncated HMAC in SSL.
- *
- * Comment this macro to disable support for truncated HMAC in SSL
- */
-#define MBEDTLS_SSL_TRUNCATED_HMAC
-
-/**
* \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
*
* Fallback to old (pre-2.7), non-conforming implementation of the truncated
@@ -2980,6 +2947,7 @@
* This module is required for the SSL/TLS 1.2 PRF function.
*/
#define MBEDTLS_SHA256_C
+#define MBEDTLS_SHA224_C
/**
* \def MBEDTLS_SHA512_C
diff --git a/boot/cypress/MCUBootApp/cy_security_cnt.c b/boot/cypress/MCUBootApp/cy_security_cnt.c
index 81aa54e..d658345 100644
--- a/boot/cypress/MCUBootApp/cy_security_cnt.c
+++ b/boot/cypress/MCUBootApp/cy_security_cnt.c
@@ -14,8 +14,12 @@
* limitations under the License.
*/
-#include "bootutil/security_cnt.h"
+#if defined MCUBootApp && defined MCUBOOT_HW_ROLLBACK_PROT
+
#include <stdint.h>
+#include <string.h>
+#include "bootutil/security_cnt.h"
+#include "cy_security_cnt_platform.h"
fih_int
boot_nv_security_counter_init(void)
@@ -25,20 +29,27 @@
}
fih_int
-boot_nv_security_counter_get(uint32_t image_id, fih_int *security_cnt)
+boot_nv_security_counter_get(uint32_t image_id, fih_uint *security_cnt)
{
(void)image_id;
- *security_cnt = 30;
+ fih_int fih_ret = FIH_FAILURE;
- return 0;
+ if (NULL != security_cnt) {
+ FIH_CALL(platform_security_counter_get, fih_ret, security_cnt);
+ }
+
+ FIH_RET(fih_ret);
}
int32_t
-boot_nv_security_counter_update(uint32_t image_id, uint32_t img_security_cnt)
+boot_nv_security_counter_update(uint32_t image_id, uint32_t img_security_cnt, void * custom_data)
{
(void)image_id;
- (void)img_security_cnt;
+
+ int32_t rc = platform_security_counter_update(img_security_cnt, (uint8_t *)custom_data);
/* Do nothing. */
- return 0;
+ return rc;
}
+
+#endif /* defined MCUBootApp && defined MCUBOOT_HW_ROLLBACK_PROT */
diff --git a/boot/cypress/MCUBootApp/cy_serial_flash_prog.c b/boot/cypress/MCUBootApp/cy_serial_flash_prog.c
index 512df93..8bf7d8e 100644
--- a/boot/cypress/MCUBootApp/cy_serial_flash_prog.c
+++ b/boot/cypress/MCUBootApp/cy_serial_flash_prog.c
@@ -42,6 +42,10 @@
extern "C" {
#endif
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
+
+extern const cy_stc_smif_block_config_t smifBlockConfig;
+
typedef struct
{
const cy_stc_smif_block_config_t * smifCfg; /* Pointer to SMIF top-level configuration */
@@ -64,7 +68,11 @@
CY_SECTION(".cy_sflash_user_data") __attribute__( (used) )
/* const stc_smif_ipblocks_arr_t smifIpBlocksArr = {&smifBlockConfig_sfdp, 0x00000000}; */
/* if used zero-pointer to config, DAP link will use hardcoded config for CY8CPROTO-062-4343W */
-const stc_smif_ipblocks_arr_t smifIpBlocksArr = {0x00000000, 0x00000000};
+static const stc_smif_ipblocks_arr_t smifIpBlocksArr =
+{
+ .smifCfg = &smifBlockConfig,
+ .null_t = 0x00000000
+};
/**
* This data is used to populate the table of contents part 2. When present, it is used by the boot
@@ -75,7 +83,7 @@
* or by running 'cymcuelftool -S' to recompute the checksum.
*/
CY_SECTION(".cy_toc_part2") __attribute__( (used) )
-const uint32_t cyToc[128] =
+static const uint32_t cyToc[128] =
{
0x200-4, /* Offset=0x0000: Object Size, bytes */
0x01211220, /* Offset=0x0004: Magic Number (TOC Part 2, ID) */
@@ -93,6 +101,8 @@
/** \} group_serial_flash_variables */
+#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
+
#if defined(__cplusplus)
}
#endif
diff --git a/boot/cypress/MCUBootApp/keys.c b/boot/cypress/MCUBootApp/keys.c
index 4dbd5af..a3d00a2 100644
--- a/boot/cypress/MCUBootApp/keys.c
+++ b/boot/cypress/MCUBootApp/keys.c
@@ -55,6 +55,7 @@
*
********************************************************************************/
#include <bootutil/sign_key.h>
+#include <bootutil/enc_key.h>
#include <mcuboot_config/mcuboot_config.h>
#if !defined(MCUBOOT_HW_KEY)
@@ -175,7 +176,7 @@
const int bootutil_key_cnt = 1;
#endif /* !MCUBOOT_HW_KEY */
-unsigned char enc_priv_key[] = {
+static const unsigned char enc_priv_key[] = {
0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20,
diff --git a/boot/cypress/MCUBootApp/libs.mk b/boot/cypress/MCUBootApp/libs.mk
index 3fe8220..da58c88 100644
--- a/boot/cypress/MCUBootApp/libs.mk
+++ b/boot/cypress/MCUBootApp/libs.mk
@@ -26,71 +26,74 @@
################################################################################
# PDL library
################################################################################
+
PDL_VERSION = 121
THIS_APP_PATH = $(PRJ_DIR)/libs
MBEDTLS_PATH = $(PRJ_DIR)/../../ext
-# Add platform folder to build
-SOURCES_PLATFORM += $(wildcard $(PRJ_DIR)/platforms/*.c)
+# Add watchdog folder to build
SOURCES_WATCHDOG := $(wildcard $(THIS_APP_PATH)/watchdog/*.c)
# Add retartget IO implementation using pdl
-SOURCES_RETARGET_IO_PDL += $(wildcard $(THIS_APP_PATH)/retarget_io_pdl/*.c)
+SOURCES_RETARGET_IO_PDL := $(PLATFORM_SOURCES_RETARGET_IO_PDL)
# Collect dirrectories containing headers for PLATFORM
-INCLUDE_RETARGET_IO_PDL += $(THIS_APP_PATH)/retarget_io_pdl
+INCLUDE_RETARGET_IO_PDL := $(PLATFORM_INCLUDE_RETARGET_IO_PDL)
# PSOC6HAL source files
-SOURCES_HAL += $(THIS_APP_PATH)/psoc6hal/COMPONENT_PSOC6HAL/source/cyhal_crypto_common.c
-SOURCES_HAL += $(THIS_APP_PATH)/psoc6hal/COMPONENT_PSOC6HAL/source/cyhal_hwmgr.c
+SOURCES_HAL_MCUB := $(PLATFORM_SOURCES_HAL_MCUB)
+
+# PSOC6HAL include dirs
+INCLUDE_DIRS_HAL_MCUB := $(PLATFORM_INCLUDE_DIRS_HAL_MCUB)
# MbedTLS source files
SOURCES_MBEDTLS := $(wildcard $(MBEDTLS_PATH)/mbedtls/library/*.c)
-SOURCES_MBEDTLS += $(wildcard $(MBEDTLS_PATH)/mbedtls/crypto/library/*.c)
# Collected source files for libraries
-SOURCES_LIBS += $(SOURCES_HAL)
SOURCES_LIBS += $(SOURCES_MBEDTLS)
SOURCES_LIBS += $(SOURCES_WATCHDOG)
-SOURCES_LIBS += $(SOURCES_PLATFORM)
+
+# Collect source files for platform dependent libraries
+SOURCES_LIBS += $(SOURCES_HAL_MCUB)
SOURCES_LIBS += $(SOURCES_RETARGET_IO_PDL)
-# Include platforms folder
-INCLUDE_DIRS_PLATFORM := $(PRJ_DIR)/platforms
-
-# needed for Crypto HW Acceleration and headers inclusion, do not use for peripherals
-# peripherals should be accessed
-INCLUDE_DIRS_HAL := $(THIS_APP_PATH)/psoc6hal/COMPONENT_PSOC6HAL/include
-INCLUDE_DIRS_HAL += $(THIS_APP_PATH)/psoc6hal/include
-INCLUDE_DIRS_HAL += $(THIS_APP_PATH)/psoc6hal/COMPONENT_PSOC6HAL/include/pin_packages
-
-# MbedTLS related include directories
-INCLUDE_DIRS_MBEDTLS += $(MBEDTLS_PATH)/mbedtls/include
-INCLUDE_DIRS_MBEDTLS += $(MBEDTLS_PATH)/mbedtls/include/mbedtls
-INCLUDE_DIRS_MBEDTLS += $(MBEDTLS_PATH)/mbedtls/crypto/include
-INCLUDE_DIRS_MBEDTLS += $(MBEDTLS_PATH)/mbedtls/crypto/include/mbedtls
-
# Watchdog related includes
INCLUDE_DIRS_WATCHDOG := $(THIS_APP_PATH)/watchdog
+# MbedTLS related include directories
+INCLUDE_DIRS_MBEDTLS += $(MBEDTLS_PATH)/mbedtls/include
+INCLUDE_DIRS_MBEDTLS += $(MBEDTLS_PATH)/mbedtls/include/mbedtls
+INCLUDE_DIRS_MBEDTLS += $(MBEDTLS_PATH)/mbedtls/include/psa
+INCLUDE_DIRS_MBEDTLS += $(MBEDTLS_PATH)/mbedtls/library
+
# Collected include directories for libraries
-INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_HAL))
INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_WATCHDOG))
INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_MBEDTLS))
-INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_RETARGET_IO_PDL))
-INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_PLATFORM))
-################################################################################
-# mbedTLS hardware acceleration settings
-################################################################################
-ifeq ($(USE_CRYPTO_HW), 1)
-# cy-mbedtls-acceleration related include directories
-INCLUDE_DIRS_MBEDTLS_MXCRYPTO := $(THIS_APP_PATH)/cy-mbedtls-acceleration/mbedtls_MXCRYPTO
-# Collect source files for MbedTLS acceleration
-SOURCES_MBEDTLS_MXCRYPTO := $(wildcard $(THIS_APP_PATH)/cy-mbedtls-acceleration/mbedtls_MXCRYPTO/*.c)
-#
-INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_MBEDTLS_MXCRYPTO))
-# Collected source files for libraries
-SOURCES_LIBS += $(SOURCES_MBEDTLS_MXCRYPTO)
+# Collect platform dependent include dirs
+INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_HAL_MCUB))
+INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_RETARGET_IO_PDL))
+
+###############################################################################
+# Print debug information about all settings used and/or set in this file
+ifeq ($(VERBOSE), 1)
+$(info #### libs.mk ####)
+$(info INCLUDE_DIRS_HAL_MCUB <-> $(INCLUDE_DIRS_HAL_MCUB))
+$(info INCLUDE_DIRS_LIBS --> $(INCLUDE_DIRS_LIBS))
+$(info INCLUDE_DIRS_MBEDTLS <-> $(INCLUDE_DIRS_MBEDTLS))
+$(info INCLUDE_DIRS_WATCHDOG <-> $(INCLUDE_DIRS_WATCHDOG))
+$(info INCLUDE_RETARGET_IO_PDL <-> $(INCLUDE_RETARGET_IO_PDL))
+$(info MBEDTLS_PATH <-- $(MBEDTLS_PATH))
+$(info PLATFORM_INCLUDE_DIRS_HAL_MCUB <-- $(PLATFORM_INCLUDE_DIRS_HAL_MCUB))
+$(info PLATFORM_INCLUDE_RETARGET_IO_PDL <-- $(PLATFORM_INCLUDE_RETARGET_IO_PDL))
+$(info PLATFORM_SOURCES_HAL_MCUB <-- $(PLATFORM_SOURCES_HAL_MCUB))
+$(info PLATFORM_SOURCES_RETARGET_IO_PDL <-- $(PLATFORM_SOURCES_RETARGET_IO_PDL))
+$(info PRJ_DIR <-- $(PRJ_DIR))
+$(info SOURCES_HAL_MCUB <-> $(SOURCES_HAL_MCUB))
+$(info SOURCES_LIBS --> $(SOURCES_LIBS))
+$(info SOURCES_MBEDTLS <-> $(SOURCES_MBEDTLS))
+$(info SOURCES_RETARGET_IO_PDL <-> $(SOURCES_RETARGET_IO_PDL))
+$(info SOURCES_WATCHDOG <-> $(SOURCES_WATCHDOG))
+$(info THIS_APP_PATH <-- $(THIS_APP_PATH))
endif
diff --git a/boot/cypress/MCUBootApp/main.c b/boot/cypress/MCUBootApp/main.c
index dee1e1a..6097173 100644
--- a/boot/cypress/MCUBootApp/main.c
+++ b/boot/cypress/MCUBootApp/main.c
@@ -17,16 +17,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
+#include <inttypes.h>
+#include <stdbool.h>
+
/* Cypress pdl headers */
#include "cy_pdl.h"
-#include "cy_retarget_io_pdl.h"
-#include "cy_result.h"
+#ifdef CYW20829
+#include "cy_retarget_io.h"
+#include "cybsp.h"
+#include "cyhal_wdt.h"
+#include "cyw_20829_utils.h"
+#include "cy_service_app.h"
+#else
+#include "cy_retarget_io_pdl.h"
#include "cycfg_clocks.h"
#include "cycfg_peripherals.h"
-#include "cycfg_pins.h"
+#endif /* CYW20829 */
#include "flash_qspi.h"
+
+#include "cycfg_pins.h"
+#include "cy_result.h"
#include "sysflash/sysflash.h"
#include "flash_map_backend/flash_map_backend.h"
@@ -40,137 +52,261 @@
#include "watchdog.h"
+#define CY_RSLT_MODULE_MCUBOOTAPP 0x500U
+#define CY_RSLT_MODULE_MCUBOOTAPP_MAIN 0x51U
+
+/** General module error */
+#define MCUBOOTAPP_RSLT_ERR \
+ (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MCUBOOTAPP, CY_RSLT_MODULE_MCUBOOTAPP_MAIN, 0))
+
/* WDT time out for reset mode, in milliseconds. */
#define WDT_TIME_OUT_MS 4000
-/* Define pins for UART debug output */
-#define CYBSP_UART_ENABLED 1U
-#define CYBSP_UART_HW SCB5
-#define CYBSP_UART_IRQ scb_5_interrupt_IRQn
-
#ifdef CY_BOOT_USE_EXTERNAL_FLASH
/* Choose SMIF slot number (slave select).
* Acceptable values are:
* 0 - SMIF disabled (no external memory);
* 1, 2, 3 or 4 - slave select line memory module is connected to.
*/
-uint32_t smif_id = 1; /* Assume SlaveSelect_0 is used for External Memory */
-#endif
+#define SMIF_ID (1U) /* Assume SlaveSelect_0 is used for External Memory */
+#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
+#define BOOT_MSG_FINISH "MCUBoot Bootloader finished.\n" \
+ "Deinitializing hardware..."
-void hw_deinit(void);
+static void hw_deinit(void);
-static void do_boot(struct boot_rsp *rsp)
+static inline __attribute__((always_inline))
+fih_uint calc_app_addr(uintptr_t flash_base, const struct boot_rsp *rsp)
{
- uint32_t app_addr = 0;
+ return fih_uint_encode(flash_base +
+ rsp->br_image_off +
+ rsp->br_hdr->ih_hdr_size);
+}
- app_addr = (rsp->br_image_off + rsp->br_hdr->ih_hdr_size);
+#ifdef CYW20829
- BOOT_LOG_INF("Starting User Application on CM4 (wait)...");
- BOOT_LOG_INF("Start Address: 0x%08lx", app_addr);
- BOOT_LOG_INF("Deinitializing hardware...");
+#if defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP)
+CY_RAMFUNC_BEGIN /* SMIF will be deinitialized in this case! */
+#else
+inline __attribute__((always_inline))
+#endif /* defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) */
+__NO_RETURN
+static void cyw20829_launch_app(fih_uint app_addr, uint32_t *key, uint32_t *iv)
+{
+#if defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP)
+ qspi_deinit(SMIF_ID);
+#endif /* defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) */
+ cyw20829_RunApp(app_addr, key, iv);
+}
+#if defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP)
+CY_RAMFUNC_END /* SMIF will be deinitialized in this case! */
+#endif /* defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) */
- cy_retarget_io_wait_tx_complete(CYBSP_UART_HW, 10);
+#endif /* CYW20829 */
- hw_deinit();
+static bool do_boot(struct boot_rsp *rsp)
+{
+ uintptr_t flash_base = 0;
- Cy_SysEnableCM4(app_addr);
+#ifdef CYW20829
+ uint32_t *key = NULL;
+ uint32_t *iv = NULL;
+#endif /* CYW20829 */
+
+ if (rsp != NULL) {
+ int rc = flash_device_base(rsp->br_flash_dev_id, &flash_base);
+
+ if (0 == rc) {
+ fih_uint app_addr = calc_app_addr(flash_base, rsp);
+
+ BOOT_LOG_INF("Starting User Application (wait)...");
+ if (IS_ENCRYPTED(rsp->br_hdr)) {
+ BOOT_LOG_DBG(" * User application is encrypted");
+ }
+ BOOT_LOG_INF("Start slot Address: 0x%08" PRIx32, (uint32_t)fih_uint_decode(app_addr));
+
+ rc = flash_device_base(rsp->br_flash_dev_id, &flash_base);
+ if ((rc != 0) || fih_uint_not_eq(calc_app_addr(flash_base, rsp), app_addr)) {
+ return false;
+ }
+
+#ifdef CYW20829
+#ifdef MCUBOOT_ENC_IMAGES_XIP
+ if (IS_ENCRYPTED(rsp->br_hdr)) {
+ key = rsp->xip_key;
+ iv = rsp->xip_iv;
+ } else {
+ BOOT_LOG_ERR("User image is not encrypted, while MCUBootApp is compiled with encryption support.");
+ return false;
+ }
+#endif /* MCUBOOT_ENC_IMAGES_XIP */
+ /* This function does not return */
+ BOOT_LOG_INF(BOOT_MSG_FINISH);
+ hw_deinit();
+ cyw20829_launch_app(app_addr, key, iv);
+#else
+ /* This function turns on CM4 and returns */
+ BOOT_LOG_INF(BOOT_MSG_FINISH);
+
+ hw_deinit();
+#ifdef USE_XIP
+ BOOT_LOG_DBG("XIP: Switch to SMIF XIP mode");
+ qspi_set_mode(CY_SMIF_MEMORY);
+#endif
+ Cy_SysEnableCM4(fih_uint_decode(app_addr));
+ return true;
+#endif /* CYW20829 */
+ } else {
+ BOOT_LOG_ERR("Flash device ID not found");
+ return false;
+ }
+ }
+
+ return false;
}
int main(void)
{
struct boot_rsp rsp;
- cy_rslt_t rc = CY_RSLT_TYPE_ERROR;
+ cy_rslt_t rc = MCUBOOTAPP_RSLT_ERR;
bool boot_succeeded = false;
fih_int fih_rc = FIH_FAILURE;
+#ifdef CYW20829
+ rc = cybsp_init();
+ if (rc != CY_RSLT_SUCCESS) {
+ CY_ASSERT((bool)0);
+ /* Loop forever... */
+ while (true) {
+ __WFI();
+ }
+ }
+#else
SystemInit();
- //init_cycfg_clocks();
init_cycfg_peripherals();
init_cycfg_pins();
+#endif /* CYW20829 */
+ /* enable interrupts */
+ __enable_irq();
- /* Certain PSoC 6 devices enable CM4 by default at startup. It must be
+ /* Certain PSoC 6 devices enable CM4 by default at startup. It must be
* either disabled or enabled & running a valid application for flash write
* to work from CM0+. Since flash write may happen in boot_go() for updating
* the image before this bootloader app can enable CM4 in do_boot(), we need
* to keep CM4 disabled. Note that debugging of CM4 is not supported when it
* is disabled.
*/
- #if defined(CY_DEVICE_PSOC6ABLE2)
- if (CY_SYS_CM4_STATUS_ENABLED == Cy_SysGetCM4Status())
- {
+#ifndef CYW20829
+#if defined(CY_DEVICE_PSOC6ABLE2)
+ if (CY_SYS_CM4_STATUS_ENABLED == Cy_SysGetCM4Status()) {
Cy_SysDisableCM4();
}
- #endif /* #if defined(CY_DEVICE_PSOC6ABLE2) */
-
- /* enable interrupts */
- __enable_irq();
+#endif /* defined(CY_DEVICE_PSOC6ABLE2) */
/* Initialize retarget-io to use the debug UART port (CYBSP_UART_HW) */
- rc = cy_retarget_io_pdl_init(115200u);
-
- if (rc != CY_RSLT_SUCCESS)
- {
- CY_ASSERT(0);
+ rc = cy_retarget_io_pdl_init(CY_RETARGET_IO_BAUDRATE);
+#else
+ /* Initialize retarget-io to use the debug UART port */
+ rc = cy_retarget_io_init(CYBSP_DEBUG_UART_TX,
+ CYBSP_DEBUG_UART_RX,
+ CY_RETARGET_IO_BAUDRATE);
+#endif /* CYW20829 */
+ if (rc != CY_RSLT_SUCCESS) {
+ CY_ASSERT((bool)0);
+ /* Loop forever... */
+ while (true) {
+ __WFI();
+ }
}
BOOT_LOG_INF("MCUBoot Bootloader Started");
#ifdef CY_BOOT_USE_EXTERNAL_FLASH
- rc = CY_SMIF_CMD_NOT_FOUND;
+ {
+ cy_en_smif_status_t qspi_status = qspi_init_sfdp(SMIF_ID);
- rc = qspi_init_sfdp(smif_id);
- if (rc == CY_SMIF_SUCCESS)
- {
- BOOT_LOG_INF("External Memory initialized w/ SFDP.");
+ if (CY_SMIF_SUCCESS == qspi_status) {
+ rc = CY_RSLT_SUCCESS;
+ BOOT_LOG_INF("External Memory initialized w/ SFDP.");
+ } else {
+ rc = MCUBOOTAPP_RSLT_ERR;
+ BOOT_LOG_ERR("External Memory initialization w/ SFDP FAILED: 0x%08" PRIx32, (uint32_t)qspi_status);
+ }
}
- else
- {
- BOOT_LOG_ERR("External Memory initialization w/ SFDP FAILED: 0x%02x", (int)rc);
- }
- if (CY_SMIF_SUCCESS == rc)
-#endif
- {
+ if (CY_RSLT_SUCCESS == rc)
+#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
+ {
+#if defined(CYW20829) && defined(MCUBOOT_HW_ROLLBACK_PROT)
+ /* Check service application completion status */
+ if (check_service_app_status() != 0) {
+ BOOT_LOG_ERR("Service application failed");
+ CY_ASSERT((bool)0);
+ /* Loop forever... */
+ while (true) {
+ __WFI();
+ }
+ }
+#endif /* CYW20829 && MCUBOOT_HW_ROLLBACK_PROT */
+
+ (void)memset(&rsp, 0, sizeof(rsp));
FIH_CALL(boot_go, fih_rc, &rsp);
- if (fih_eq(fih_rc, FIH_SUCCESS))
- {
+ if (true == fih_eq(fih_rc, FIH_SUCCESS)) {
BOOT_LOG_INF("User Application validated successfully");
/* initialize watchdog timer. it should be updated from user app
* to mark successful start up of this app. if the watchdog is not updated,
* reset will be initiated by watchdog timer and swap revert operation started
* to roll back to operable image.
*/
- cy_wdg_init(WDT_TIME_OUT_MS);
- do_boot(&rsp);
- boot_succeeded = true;
- }
- else
- {
- BOOT_LOG_INF("MCUBoot Bootloader found none of bootable images");
+#ifdef CYW20829
+ cyhal_wdt_t *cyw20829_wdt = NULL;
+
+ rc = cyhal_wdt_init(cyw20829_wdt, WDT_TIME_OUT_MS);
+#else
+ rc = cy_wdg_init(WDT_TIME_OUT_MS);
+#endif /* CYW20829 */
+ if (CY_RSLT_SUCCESS == rc) {
+
+ boot_succeeded = do_boot(&rsp);
+
+ if (!boot_succeeded) {
+ BOOT_LOG_ERR("Boot of next app failed");
+ }
+ } else {
+ BOOT_LOG_ERR("Failed to init WDT");
+ }
+ } else {
+ BOOT_LOG_ERR("MCUBoot Bootloader found none of bootable images");
}
}
- while (1)
- {
+ while (true) {
if (boot_succeeded) {
- Cy_SysPm_CpuEnterDeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT);
- }
- else {
+ (void)Cy_SysPm_CpuEnterDeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT);
+ } else {
__WFI();
}
}
-
- return 0;
}
-void hw_deinit(void)
+static void hw_deinit(void)
{
+#ifdef CYW20829
+ /* Flush the TX buffer, need to be fixed in retarget_io */
+ Cy_SysLib_Delay(50);
+
+ cy_retarget_io_deinit();
+ cy_wdg_stop();
+ cy_wdg_free();
+ /* Note: qspi_deinit() is called (if needed) in cyw20829_launch_app() above */
+#else
+ cy_retarget_io_wait_tx_complete(CYBSP_UART_HW, 10);
cy_retarget_io_pdl_deinit();
Cy_GPIO_Port_Deinit(CYBSP_UART_RX_PORT);
Cy_GPIO_Port_Deinit(CYBSP_UART_TX_PORT);
-
-#ifdef CY_BOOT_USE_EXTERNAL_FLASH
- qspi_deinit(smif_id);
-#endif
+#if defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) && !defined(USE_XIP)
+ qspi_deinit(SMIF_ID);
+#endif /* defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) */
+#endif /* CYW20829 */
}
diff --git a/boot/cypress/MCUBootApp/sysflash/sysflash.h b/boot/cypress/MCUBootApp/sysflash/sysflash.h
deleted file mode 100644
index 961e74e..0000000
--- a/boot/cypress/MCUBootApp/sysflash/sysflash.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/* Manual version of auto-generated version. */
-
-#ifndef SYSFLASH_H
-#define SYSFLASH_H
-
-#include <stdint.h>
-#include "cy_syslib.h"
-
-#define FLASH_AREA_BOOTLOADER (0)
-#define FLASH_AREA_IMAGE_0 (1u)
-#define FLASH_AREA_IMAGE_1 (2u)
-#define FLASH_AREA_IMAGE_SCRATCH (3u)
-#define FLASH_AREA_IMAGE_2 (5u)
-#define FLASH_AREA_IMAGE_3 (6u)
-#define FLASH_AREA_IMAGE_SWAP_STATUS (7u)
-
-/* it is related to multi-image case */
-#define FLASH_AREA_IMAGE_IDX_1 (0u)
-#define FLASH_AREA_IMAGE_IDX_2 (1u)
-
-/* This defines if External Flash (SMIF) will be used for Upgrade Slots */
-/* #define CY_BOOT_USE_EXTERNAL_FLASH */
-
-/* use PDL-defined offset or one from SMFI config */
-#define CY_SMIF_BASE_MEM_OFFSET (0x18000000)
-
-#define CY_FLASH_ALIGN (CY_FLASH_SIZEOF_ROW)
-#define CY_FLASH_DEVICE_BASE (CY_FLASH_BASE)
-
-#ifndef CY_BOOT_SCRATCH_SIZE
-#ifndef CY_BOOT_USE_EXTERNAL_FLASH
-#define CY_BOOT_SCRATCH_SIZE (0x1000u)
-#else /* CY_BOOT_USE_EXTERNAL_FLASH */
-#define CY_BOOT_SCRATCH_SIZE (0x80000)
-#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
-#endif /* CY_BOOT_SCRATCH_SIZE */
-
-#ifndef CY_BOOT_SWAP_STATUS_SIZE
-#define CY_BOOT_SWAP_STATUS_SIZE (BOOT_SWAP_STATUS_SZ_PRIM + BOOT_SWAP_STATUS_SZ_SEC)
-#endif
-
-#ifndef CY_BOOT_BOOTLOADER_SIZE
-#define CY_BOOT_BOOTLOADER_SIZE (0x18000)
-#endif
-
-/* Sizes of CY_BOOT_IMAGE_1_SIZE and CY_BOOT_IMAGE_2_SIZE
- * can be defined from build system. Use default values otherwise
-*/
-#ifndef CY_BOOT_USE_EXTERNAL_FLASH
-#ifndef CY_BOOT_IMAGE_1_SIZE
-#define CY_BOOT_IMAGE_1_SIZE (0x10000)
-#endif /* CY_BOOT_IMAGE_1_SIZE */
-#if (MCUBOOT_IMAGE_NUMBER == 2)
-#ifndef CY_BOOT_IMAGE_2_SIZE
-#define CY_BOOT_IMAGE_2_SIZE (0x20000)
-#endif /* CY_BOOT_IMAGE_2_SIZE */
-#endif /* (MCUBOOT_IMAGE_NUMBER == 2) */
-#else /* CY_BOOT_USE_EXTERNAL_FLASH */
-#ifndef CY_BOOT_IMAGE_1_SIZE
-#define CY_BOOT_IMAGE_1_SIZE (0xC0000)
-#endif /* CY_BOOT_IMAGE_1_SIZE */
-#if (MCUBOOT_IMAGE_NUMBER == 2)
-#ifndef CY_BOOT_IMAGE_2_SIZE
-#define CY_BOOT_IMAGE_2_SIZE (0xC0000)
-#endif /* CY_BOOT_IMAGE_2_SIZE */
-#endif /* (MCUBOOT_IMAGE_NUMBER == 2) */
-#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
-
-#ifndef CY_BOOT_PRIMARY_1_SIZE
-#define CY_BOOT_PRIMARY_1_SIZE CY_BOOT_IMAGE_1_SIZE
-#endif
-
-#ifndef CY_BOOT_SECONDARY_1_SIZE
-#define CY_BOOT_SECONDARY_1_SIZE CY_BOOT_IMAGE_1_SIZE
-#endif
-
-#if (MCUBOOT_IMAGE_NUMBER == 2) /* if dual-image */
-#ifndef CY_BOOT_PRIMARY_2_SIZE
-#define CY_BOOT_PRIMARY_2_SIZE CY_BOOT_IMAGE_2_SIZE
-#endif
-
-#ifndef CY_BOOT_SECONDARY_2_SIZE
-#define CY_BOOT_SECONDARY_2_SIZE CY_BOOT_IMAGE_2_SIZE
-#endif
-#endif
-
-#ifndef CY_BOOT_EXTERNAL_FLASH_SECONDARY_1_OFFSET
-#define CY_BOOT_EXTERNAL_FLASH_SECONDARY_1_OFFSET (0x0u)
-#endif
-
-#ifndef CY_BOOT_EXTERNAL_FLASH_SECONDARY_2_OFFSET
-#define CY_BOOT_EXTERNAL_FLASH_SECONDARY_2_OFFSET (0x240000u)
-#endif
-
-#ifndef CY_BOOT_EXTERNAL_FLASH_SCRATCH_OFFSET
-#define CY_BOOT_EXTERNAL_FLASH_SCRATCH_OFFSET (0x440000u)
-#endif
-
-#ifndef CY_BOOT_SECONDARY_1_EXT_MEM_OFFSET
-#define CY_BOOT_SECONDARY_1_EXT_MEM_OFFSET (CY_SMIF_BASE_MEM_OFFSET + CY_BOOT_EXTERNAL_FLASH_SECONDARY_1_OFFSET)
-#endif
-
-#ifndef CY_BOOT_SECONDARY_2_EXT_MEM_OFFSET
-#define CY_BOOT_SECONDARY_2_EXT_MEM_OFFSET (CY_SMIF_BASE_MEM_OFFSET + CY_BOOT_EXTERNAL_FLASH_SECONDARY_2_OFFSET)
-#endif
-
-#define BOOT_MAX_SWAP_STATUS_SECTORS (64)
-
-#if (MCUBOOT_IMAGE_NUMBER == 1)
-#define FLASH_AREA_IMAGE_PRIMARY(x) (((x) == 0) ? \
- FLASH_AREA_IMAGE_0 : \
- FLASH_AREA_IMAGE_0)
-#define FLASH_AREA_IMAGE_SECONDARY(x) (((x) == 0) ? \
- FLASH_AREA_IMAGE_1 : \
- FLASH_AREA_IMAGE_1)
-
-#elif (MCUBOOT_IMAGE_NUMBER == 2)
-
-#ifndef CY_FLASH_MAP_EXT_DESC
-#define FLASH_AREA_IMAGE_PRIMARY(x) (((x) == 0) ? \
- FLASH_AREA_IMAGE_0 : \
- ((x) == 1) ? \
- FLASH_AREA_IMAGE_2 : \
- 255)
-#define FLASH_AREA_IMAGE_SECONDARY(x) (((x) == 0) ? \
- FLASH_AREA_IMAGE_1 : \
- ((x) == 1) ? \
- FLASH_AREA_IMAGE_3 : \
- 255)
-#else
-__STATIC_INLINE uint8_t FLASH_AREA_IMAGE_PRIMARY(uint32_t areaID)
-{
- uint8_t result;
-
- if (0U == areaID)
- {
- result = FLASH_AREA_IMAGE_0;
- }
- else
- if (1U == areaID)
- {
- result = FLASH_AREA_IMAGE_2;
- }
- else
- {
- result = 0xFF;
- }
-
- return result;
-}
-
-__STATIC_INLINE uint8_t FLASH_AREA_IMAGE_SECONDARY(uint32_t areaID)
-{
- uint8_t result;
-
- if (0U == areaID)
- {
- result = FLASH_AREA_IMAGE_1;
- }
- else
- if (1U == areaID)
- {
- result = FLASH_AREA_IMAGE_3;
- }
- else
- {
- result = 0xFF;
- }
-
- return result;
-}
-#endif
-#endif
-
-// #else
-// #warning "Image slot and flash area mapping is not defined"
-// #endif
-
-#define CY_IMG_HDR_SIZE 0x400
-
-#ifndef CY_FLASH_MAP_EXT_DESC
-/* Uncomment in case you want to use separately defined table of flash area descriptors */
-/* #define CY_FLASH_MAP_EXT_DESC */
-#endif
-
-#endif /* SYSFLASH_H */
diff --git a/boot/cypress/Makefile b/boot/cypress/Makefile
index b9952c5..d1c9b00 100644
--- a/boot/cypress/Makefile
+++ b/boot/cypress/Makefile
@@ -36,11 +36,14 @@
################################################################################
# Defines whether or not show verbose build output
-MAKEINFO ?= 1
+VERBOSE ?= 0
# Application name by default
APP_NAME ?= MCUBootApp
# Weather or now execute post build script after build - set to 0 for CI
-POST_BUILD ?= 1
+POST_BUILD_ENABLE ?= 1
+
+# Default number of GCC compilation threads
+THREADS_NUM ?= 8
SIGN_KEY_FILE ?= cypress-test-ec-p256
ENC_KEY_FILE ?= enc-ec256-pub
@@ -53,11 +56,20 @@
BUILDCFG ?= Debug
+ifeq ($(PLATFORM), CYW20829)
+# until mbedtls.3.0 support
+USE_CRYPTO_HW ?= 0
+endif
+
# Set of supported applications
APPS := MCUBootApp BlinkyApp
HEADER_OFFSET ?= 0
+# Defines whether or not make all compile warnings into errors for application
+# source code (but not for library source code)
+WARN_AS_ERR ?= 1
+
ifneq ($(filter $(APP_NAME), $(APPS)),)
include ./$(APP_NAME)/$(APP_NAME).mk
include ./$(APP_NAME)/libs.mk
@@ -69,7 +81,8 @@
ASM_FILES += $(ASM_FILES_LIBS)
C_FILES := $(SOURCES_APP)
-C_FILES += $(SOURCES_LIBS)
+C_FILES += $(SOURCES_PLATFORM)
+C_LIBS := $(SOURCES_LIBS)
INCLUDE_DIRS := $(INCLUDE_DIRS_APP)
INCLUDE_DIRS += $(INCLUDE_DIRS_MCUBOOT)
@@ -80,12 +93,13 @@
#INCLUDES := $(addprefix -include , $(INCLUDE_FILES))
O_FILES := $(notdir $(C_FILES:.c=.o)) $(addsuffix .o, $(notdir $(basename $(ASM_FILES))))
+O_LIBS := $(notdir $(C_LIBS:.c=.o))
-DEFINES := $(DEFINES_APP)
+DEFINES := $(DEFINES_APP) -D$(APP_NAME)
DEFINES += $(DEFINES_LIBS)
AS_FLAGS += $(DEFINES)
-ifeq ($(MAKEINFO), 1)
+ifeq ($(VERBOSE), 1)
$(info ==============================================================================)
$(info = Directories to look for header files: =)
$(info ==============================================================================)
@@ -100,26 +114,12 @@
# updating CFLAGS at this point as DEFINES are completed
CFLAGS += $(DEFINES) $(CFLAGS_OPTIMIZATION)
-VPATH = $(dir $(C_FILES) $(ASM_FILES))
+ifeq ($(WARN_AS_ERR), 1)
+CC_WARN_IN_ERR_FLAGS := -Werror
+endif
-#
-# STDE: For cygwin, adjust paths for compiler
-#
-MY_FILES := $(subst /cygdrive/c,c:,$(C_FILES))
-#$(info MY_FILES $(MY_FILES))
-C_FILES=$(MY_FILES)
+VPATH = $(dir $(C_FILES) $(ASM_FILES) $(C_LIBS))
-MY_DIRS := $(subst /cygdrive/c,c:,$(INCLUDE_DIRS))
-#$(info MY_DIRS $(MY_DIRS))
-INCLUDE_DIRS=$(MY_DIRS)
-
-MY_ASM_FILES := $(subst /cygdrive/c,c:,$(ASM_FILES))
-#$(info MY_ASM_FILES $(MY_ASM_FILES))
-ASM_FILES=$(MY_ASM_FILES)
-
-MY_LDFLAGS := $(subst /cygdrive/c,c:,$(LDFLAGS))
-#$(info MY_LDFLAGS $(MY_LDFLAGS))
-LDFLAGS=$(MY_LDFLAGS)
LDFLAGS += $(LDFLAGS_OPTIMIZATION)
# Default name pattern for output files
@@ -127,6 +127,7 @@
OUT_FILE_NAME ?= $(OUT_APP)/$(APP_NAME)
OUT_OBJ := $(OUT_CFG)/obj
+OUT_OBJ_LIBS_DIR := $(OUT_CFG)/obj/libs
OUT_APP := $(OUT_CFG)
.PHONY: all app build clean pre_build post_build
@@ -138,40 +139,62 @@
@`mkdir -p ./$(OUT_TARGET)`
@`mkdir -p ./$(OUT_CFG)`
@`mkdir -p ./$(OUT_OBJ)`
+ @`mkdir -p ./$(OUT_OBJ_LIBS_DIR)`
+ifeq ($(VERBOSE) , 1)
+ @echo
+ @echo ======================== PRE_BUILD STAGE ========================
+ @echo =================================================================
+ @echo
+endif
$(MAKE) pre_build
- $(MAKE) build -j8
+ifeq ($(VERBOSE) , 1)
+ @echo
+ @echo ======================== BUILD STAGE ========================
+ @echo =============================================================
+ @echo
+endif
+ $(MAKE) build -j $(THREADS_NUM)
+ifeq ($(VERBOSE) , 1)
+ @echo
+ @echo ======================== POST_BUILD STAGE ========================
+ @echo ==================================================================
+ @echo
+endif
$(MAKE) post_build
-build: $(OUT_APP)/$(APP_NAME).hex
+build: $(OUT_APP)/$(APP_NAME)_unsigned.hex
$(GCC_PATH)/bin/arm-none-eabi-objdump $(OUT_APP)/$(APP_NAME).elf -S --disassemble > $(OUT_APP)/$(APP_NAME).lst
$(GCC_PATH)/bin/arm-none-eabi-objdump -h $(OUT_APP)/$(APP_NAME).elf
$(GCC_PATH)/bin/arm-none-eabi-size --format=SysV $(OUT_APP)/$(APP_NAME).elf
-$(OUT_APP)/$(APP_NAME).hex: $(OUT_APP)/$(APP_NAME).elf
- $(GCC_PATH)/bin/arm-none-eabi-objcopy --change-addresses=$(HEADER_OFFSET) -O ihex $(OUT_APP)/$(APP_NAME).elf $(OUT_APP)/$(APP_NAME).hex
+$(OUT_APP)/$(APP_NAME)_unsigned.hex: $(OUT_APP)/$(APP_NAME).bin
+ $(GCC_PATH)/bin/arm-none-eabi-objcopy --change-addresses=$(HEADER_OFFSET) -O ihex $(OUT_APP)/$(APP_NAME).elf $(OUT_APP)/$(APP_NAME)_unsigned.hex
-$(OUT_APP)/$(APP_NAME).elf: $(addprefix $(OUT_OBJ)/, $(O_FILES))
+$(OUT_APP)/$(APP_NAME).bin: $(OUT_APP)/$(APP_NAME).elf
+ $(GCC_PATH)/bin/arm-none-eabi-objcopy $(OUT_APP)/$(APP_NAME).elf -S -O binary $(OUT_APP)/$(APP_NAME).bin --remove-section .cy_sflash_user_data --remove-section .cy_toc_part2
+
+$(OUT_APP)/$(APP_NAME).elf: $(addprefix $(OUT_OBJ)/, $(O_FILES)) $(addprefix $(OUT_OBJ_LIBS_DIR)/, $(O_LIBS))
@echo "LD $@"
-ifeq ($(MAKEINFO), 1)
+ifeq ($(VERBOSE), 1)
+ @echo
@echo $(LD) $(O_FILES) $(CC_DEPEND) $(@:.o=.d) -o $@ $(LDFLAGS) -T $(LINKER_SCRIPT) -Wl,-Map,$(OUT_FILE_NAME).map
endif
- @$(LD) $(addprefix $(OUT_OBJ)/, $(O_FILES)) $(CC_DEPEND) $(@:.o=.d) -o $@ $(LDFLAGS) -T $(LINKER_SCRIPT) -Wl,-Map,$(OUT_FILE_NAME).map
+ @$(LD) $(addprefix $(OUT_OBJ)/, $(O_FILES)) $(addprefix $(OUT_OBJ_LIBS_DIR)/, $(O_LIBS)) $(CC_DEPEND) $(@:.o=.d) -o $@ $(LDFLAGS) -T $(LINKER_SCRIPT) -Wl,-Map,$(OUT_FILE_NAME).map
$(OUT_OBJ)/%.o: %.c
@echo "CC $<"
-ifeq ($(MAKEINFO), 1)
- @echo $(CC) $(CFLAGS) $(INCLUDE_DIRS) $(CC_DEPEND) $(@:.o=.d) -c $< -o $@
-endif
- @$(CC) $(CFLAGS) $(INCLUDE_DIRS) $(CC_DEPEND) $(@:.o=.d) -c $< -o $@
-ifeq ($(MAKEINFO), 1)
+ifeq ($(VERBOSE), 1)
@echo
+ @echo $(CC) $(CFLAGS) $(CC_WARN_IN_ERR_FLAGS) $(INCLUDE_DIRS) $(CC_DEPEND) $(@:.o=.d) -c $< -o $@
endif
+ @$(CC) $(CFLAGS) $(CC_WARN_IN_ERR_FLAGS) $(INCLUDE_DIRS) $(CC_DEPEND) $(@:.o=.d) -c $< -o $@
$(OUT_OBJ)/%.o: %.S
@echo "AS $<"
ifeq ($(COMPILER), GCC_ARM)
-ifeq ($(MAKEINFO), 1)
+ifeq ($(VERBOSE), 1)
+ @echo
@echo @$(CC) $(CFLAGS) $(INCLUDE_DIRS) $(CC_DEPEND) $(@:.o=.d) -c $< -o $@
endif
@$(CC) $(CFLAGS) $(INCLUDE_DIRS) $(CC_DEPEND) $(@:.o=.d) -c $< -o $@
@@ -179,20 +202,28 @@
@echo $(AS) $< -o $@ $(AS_FLAGS)
@$(AS) $< -o $@ $(AS_FLAGS)
endif
-ifeq ($(MAKEINFO), 1)
+
+$(OUT_OBJ_LIBS_DIR)/%.o: %.c
+ @echo "CC $<"
+ifeq ($(VERBOSE), 1)
@echo
+ @echo $(CC) $(CFLAGS) $(INCLUDE_DIRS) $(CC_DEPEND) $(@:.o=.d) -c $< -o $@
endif
+ @$(CC) $(CFLAGS) $(INCLUDE_DIRS) $(CC_DEPEND) $(@:.o=.d) -c $< -o $@
clean:
@echo "Cleanup out directory..."
+ rm -f ./$(APP_NAME)/flashmap.mk ./cy_flash_pal/cy_flash_map.h
rm -rf $(OUT_TARGET)/$(BUILDCFG)
clean_boot:
@echo "Cleanup out BOOT directory of $(APP_NAME)..."
+ rm -f ./$(APP_NAME)/flashmap.mk
rm -rf $(OUT_TARGET)/$(BUILDCFG)/boot
clean_upgrade:
@echo "Cleanup out UPGRADE directory of $(APP_NAME)..."
+ rm -f ./$(APP_NAME)/flashmap.mk
rm -rf $(OUT_TARGET)/$(BUILDCFG)/upgrade
run_cppcheck:
@@ -204,10 +235,63 @@
../../scripts/imgtool.py keygen -k keys/$(SIGN_KEY_FILE).pem -t ecdsa-p256
../../scripts/imgtool.py getpub -k keys/$(SIGN_KEY_FILE).pem > keys/$(SIGN_KEY_FILE).pub
-ifeq ($(MAKEINFO) , 1)
-$(info ASM_FILES: $(ASM_FILES))
-$(info C_FILES: $(C_FILES))
-$(info INCLUDE_DIRS: $(INCLUDE_DIRS))
-$(info DEFINES: $(DEFINES))
-$(info CC: $(CC))
+###############################################################################
+# Print debug information about all settings used and/or set in this file
+ifeq ($(VERBOSE), 1)
+$(info #### Makefile ####)
+$(info APPS <-> $(APPS))
+$(info APP_NAME <-> $(APP_NAME))
+$(info AS <-- $(AS))
+$(info ASM_FILES <-> $(ASM_FILES))
+$(info ASM_FILES_APP <-- $(ASM_FILES_APP))
+$(info ASM_FILES_LIBS <-- $(ASM_FILES_LIBS))
+$(info AS_FLAGS <-> $(AS_FLAGS))
+$(info BUILDCFG <-> $(BUILDCFG))
+$(info CC <-- $(CC))
+$(info CC_DEPEND <-- $(CC_DEPEND))
+$(info CC_WARN_IN_ERR_FLAGS <-> $(CC_WARN_IN_ERR_FLAGS))
+$(info CFLAGS <-> $(CFLAGS))
+$(info CFLAGS_OPTIMIZATION <-- $(CFLAGS_OPTIMIZATION))
+$(info COMPILER <-- $(COMPILER))
+$(info CPP_CHECK_SCOPE <-- $(CPP_CHECK_SCOPE))
+$(info CURDIR <-- $(CURDIR))
+$(info CY_SEC_TOOLS_PATH --> $(CY_SEC_TOOLS_PATH))
+$(info C_FILES <-> $(C_FILES))
+$(info C_LIBS <-> $(C_LIBS))
+$(info DEFINES <-> $(DEFINES))
+$(info DEFINES_APP <-- $(DEFINES_APP))
+$(info DEFINES_LIBS <-- $(DEFINES_LIBS))
+$(info ENC_IMG --> $(ENC_IMG))
+$(info ENC_KEY_FILE --> $(ENC_KEY_FILE))
+$(info GCC_PATH <-- $(GCC_PATH))
+$(info HEADER_OFFSET <-> $(HEADER_OFFSET))
+$(info INCLUDE_DIRS <-> $(INCLUDE_DIRS))
+$(info INCLUDE_DIRS_APP <-- $(INCLUDE_DIRS_APP))
+$(info INCLUDE_DIRS_LIBS <-- $(INCLUDE_DIRS_LIBS))
+$(info INCLUDE_DIRS_MCUBOOT <-- $(INCLUDE_DIRS_MCUBOOT))
+$(info LD <-- $(LD))
+$(info LDFLAGS <-> $(LDFLAGS))
+$(info LDFLAGS_OPTIMIZATION <-- $(LDFLAGS_OPTIMIZATION))
+$(info LINKER_SCRIPT <-- $(LINKER_SCRIPT))
+$(info MAKE <-- $(MAKE))
+$(info OS <-- $(OS))
+$(info OUT <-- $(OUT))
+$(info OUT_APP <-> $(OUT_APP))
+$(info OUT_CFG <-- $(OUT_CFG))
+$(info OUT_FILE_NAME <-> $(OUT_FILE_NAME))
+$(info OUT_OBJ <-> $(OUT_OBJ))
+$(info OUT_OBJ_LIBS_DIR <-> $(OUT_OBJ_LIBS_DIR))
+$(info OUT_TARGET <-- $(OUT_TARGET))
+$(info O_FILES <-> $(O_FILES))
+$(info O_LIBS <-> $(O_LIBS))
+$(info PLATFORM <-- $(PLATFORM))
+$(info POST_BUILD_ENABLE --> $(POST_BUILD_ENABLE))
+$(info PYTHON_PATH <-> $(PYTHON_PATH))
+$(info SIGN_KEY_FILE <-> $(SIGN_KEY_FILE))
+$(info SOURCES_APP <-- $(SOURCES_APP))
+$(info SOURCES_LIBS <-- $(SOURCES_LIBS))
+$(info SOURCES_PLATFORM <-- $(SOURCES_PLATFORM))
+$(info THREADS_NUM <-> $(THREADS_NUM))
+$(info USE_CRYPTO_HW --> $(USE_CRYPTO_HW))
+$(info WARN_AS_ERR <-> $(WARN_AS_ERR))
endif
diff --git a/boot/cypress/README.md b/boot/cypress/README.md
index f2db991..8227da6 100644
--- a/boot/cypress/README.md
+++ b/boot/cypress/README.md
@@ -1,60 +1,56 @@
-### Port Of Mcuboot Library For Evaluation With Cypress PSoC 6 Chips
+## Port of MCUboot library for evaluation with Cypress PSoC™ 6 and CYW20829 chips
### Disclaimer
-Given solution is included in `mcuboot` repository with purpose to demonstrate basic consepts and features of MCUBoot library on Cypress PSoC 6 device. Applications are created per mcuboot library maintainers requirements. Implemetation differs from conventional and recomended by Cypress Semiconductors development flow for PSoC 6 devices. These applications are not recomended as a starting point for development and should not be considered as supported examples for PSoC 6 devices.
+This solution is included in the `MCUboot` repository in order to demonstrate the basic concepts and features of the MCUboot library on PSoC™ 6 and CYW20829 devices. Applications are created per MCUboot library maintainers requirements. The implementation differs from conventional and recommended by Cypress Semiconductors development flow for PSoC™ 6 and CYW20829 devices. These applications are not recommended as a starting point for development because they are not supported examples.
-Examples provided to use with **ModusToolbox® Software Environment** are a recommended reference point to start development of MCUBoot based bootloaders for PSoC 6 devices.
+Examples provided to use with **ModusToolbox™ Software Environment** are a recommended reference point to start development of MCUboot based bootloaders for PSoC™ 6 and CYW20829 devices.
-Refer to **Cypress Semiconductors** [github](https://github.com/cypresssemiconductorco) page to find examples.
+For examples, refer to the **Infineon Technologies AG** [github](https://github.com/Infineon/Code-Examples-for-ModusToolbox-Software) page.
-1. MCUboot-Based Basic Bootloader [mtb-example-psoc6-mcuboot-basic](https://github.com/cypresssemiconductorco/mtb-example-psoc6-mcuboot-basic)
-2. MCUboot-Based Bootloader with Rollback to Factory App in External Flash [mtb-example-anycloud-mcuboot-rollback](https://github.com/cypresssemiconductorco/mtb-example-anycloud-mcuboot-rollback)
+1. MCUboot-based basic bootloader [mtb-example-psoc6-mcuboot-basic](https://github.com/Infineon/mtb-example-psoc6-mcuboot-basic)
+2. MCUboot-based bootloader with rollback to factory app in external flash [mtb-example-anycloud-mcuboot-rollback](https://github.com/Infineon/mtb-example-anycloud-mcuboot-rollback)
-### Solution Description
+### Solution description
-There are two applications implemented:
-* MCUBootApp - PSoC 6 MCUBoot-based bootloading application;
-* BlinkyApp - simple PSoC 6 blinking LED application which is a target of BOOT/UPGRADE;
+The two applications implemented:
+* MCUBootApp - PSoC™ 6 and CYW20829 MCUboot-based bootloading application
+* BlinkyApp - a simple PSoC™ 6 and CYW20829 blinking LED application, which is a target of BOOT/UPGRADE
#### MCUBootApp
-* There are two types of upgrade operation supported:
- * **Overwrite only** - secondady image is only copied to primary slot after validation
- * **Swap** - seconrady and primary slots images are swapped in process of upgrade. Upgrade operation can be reverted in case of bad secondary image.
+* The two types of upgrade operation supported:
+ * **Overwrite only** - The secondary image is only copied to the primary slot after validation.
+ * **Swap** - The secondary and primary slots images are swapped during the upgrade process. Upgrade operation can be reverted if the secondary image is bad. "Bad image" does not set the imageOK flag in the image trailer. If imageOK is not set, MCUBootApp does not turn off WatchDog Timer and WDT resets the device to start the REVERT procedure.
-* There are two types of operation modes supported:
- * single image
- * multi image
+* The two types of operation modes supported:
+ * Single image
+ * Multi image
-* Secondary (upgrade) slot(s) can be placed in external memory. For more details about External Memory usage refer to separate guiding document `MCUBootApp/ExternalMemory.md`.
+* Some or all partitions (slots) can be placed in external memory. For more details about external memory usage, refer to [ExternalMemory.md](MCUBootApp/ExternalMemory.md).
-* MCUBootApp checks image integrity with SHA256, image authenticity with EC256 digital signature verification
-* Cryptographic functions can be based on completely software implementation or be hardware accelerated. mbedTLS library is used in both cases.
+* MCUBootApp checks the image integrity with SHA256, image authenticity with EC256 digital signature verification.
+* Cryptographic functions can be based on completely software implementation or be hardware accelerated on some platforms. The mbedTLS library is used in both cases.
-Detailed description of **MCUBootApp** is provided in `MCUBootApp/MCUBootApp.md`
-
-MCUBootApp checks image integrity with SHA256, image authenticity with EC256 digital signature verification and uses either completely software implementation of cryptographic functions or accelerated by hardware - both based on mbedTLS Library.
+For more details on **MCUBootApp**, refer to [MCUBootApp.md](MCUBootApp/MCUBootApp.md).
#### BlinkyApp
-* Can be built to use as primary or secondary image for both internal and external flash memory
-* Primary and secondary images differ in text printed to serial terminal and led blinking frequency.
-* Watchdog timer functionality is supported to confirm successful start/upgrade of application
-* User application side of mcuboot swap operation is demonstrated for secondary image build.
+* Can be built to use either primary or secondary image for both internal and external flash memory.
+* Primary and secondary images differ in text printed to the serial terminal and LED-blinking frequency.
+* The watchdog timer functionality is supported to confirm successful start/upgrade of the application.
+* The user-application side of MCUboot swap operation is demonstrated by two kinds of user images, compiled for the primary and secondary slot.
-Detailed description of **BlinkyApp** is provided in `BlinkyApp/BlinkyApp.md`
+For more details on **BlinkyApp**, refer to [BlinkyApp.md](BlinkyApp/BlinkyApp.md).
-### Downloading Solution's Assets
+### Downloading solution's assets
-There is a set assets required:
+The set of required libraries represented as submodules:
-* MCUBooot Library (root repository)
-* PSoC 6 Peripheral Drivers Library (PDL)
-* mbedTLS Cryptographic Library
+* MCUBooot library (root repository)
+* Peripheral Drivers library (PDL)
+* mbedTLS Cryptographic library
-Those are represented as submodules.
-
-To retrieve source code with subsequent submodules pull:
+To retrieve source code with subsequent submodules, pull:
git clone --recursive https://github.com/mcu-tools/mcuboot.git
@@ -63,47 +59,34 @@
cd mcuboot
git submodule update --init --recursive
-### Building Solution
+### Building solution
-Root directory for build is `boot/cypress`.
+The root directory for build is `boot/cypress`.
-Root folder contains make files infrastructure for building both MCUBootApp bootloading application and BlinkyApp user application.
+The root folder contains a make-files infrastructure for building both MCUBootApp bootloading-application and BlinkyApp user-application.
-Instructions on how to build and upload MCUBootApp bootloading application and sample user application are located in `MCUBootApp.md` and `BlinkyApp.md` files in corresponding folders.
+For instructions on how to build and upload MCUBootApp bootloading-application and sample user-application, refer to the [MCUBootApp.md](MCUBootApp/MCUBootApp.md) and [BlinkyApp.md](BlinkyApp/BlinkyApp.md) files in corresponding folders.
**Toolchain**
-**GCC_ARM** is the only supported (built and verified on GCC 7.2.1).
+**GCC_ARM** is only supported (built and verified on GCC 9.3.1).
-It is inluded with [ModusToolbox® Software Environment](https://www.cypress.com/products/modustoolbox-software-environment) and can be found in folder `./ModusToolbox/tools_2.1/gcc-7.2.1`.
+It is included with [ModusToolbox™ Software Environment](https://www.cypress.com/products/modustoolbox) and can be found in folder `./ModusToolbox/tools_2.4/gcc`.
-Default installation folder is expected by makefile build system.
+The default installation folder is expected by the makefile build system.
-In case of using another installation folder, version of **ModusToolbox IDE** or another GCC Compiler - path to a toolchain should be specified to a build system using **TOOLCHAIN_PATH** flag.
+To use another installation folder, version of **ModusToolbox™ IDE** or another GCC Compiler, specify the path to a toolchain using the **TOOLCHAIN_PATH** parameter.
-**Example:**
+### Build environment troubleshooting
- make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=BOOT TOOLCHAIN_PATH=/home/fw-security/ModusToolbox/tools_2.0/gcc-7.2.1
-
-Supported platforms for `MCUBoot`, `BlinkyApp`:
-
-* PSOC_062_2M
-* PSOC_062_1M
-* PSOC_062_512K
-
-### Build Environment Troubleshooting
-
-Following CLI / IDE are supported for project build:
+The following CLI/IDE are supported for project build:
* Cygwin on Windows systems
* unix style shells on *nix systems
-* Eclipse / ModusToolbox ("makefile project from existing source")
+* Eclipse / ModusToolbox™ ("makefile project from existing source")
-*Make* - make sure it is added to system's `PATH` variable and correct path is first in the list;
+*Make* - Ensure that it is added to the system's `PATH` variable and the correct path is the first on the list.
-*Python/Python3* - make sure you have correct path referenced in `PATH`;
+*Python/Python3* - Ensure that you have the correct path referenced in `PATH`.
-*Msys2* - to use systems PATH navigate to msys2 folder, open `msys2_shell.cmd`, uncomment set `MSYS2_PATH_TYPE=inherit`, restart MSYS2 shell.
-
-This will inherit system's PATH so should find `python3.7` installed in regular way as well as imgtool and its dependencies.
-
+*Msys2* - To use the system's path, navigate to the msys2 folder, open `msys2_shell.cmd`, uncomment set `MSYS2_PATH_TYPE=inherit`, restart the MSYS2 shell. This will inherit the system's path and find `python` installed in a regular way as well as `imgtool` and its dependencies.
diff --git a/boot/cypress/common_libs.mk b/boot/cypress/common_libs.mk
index f5d11f8..d380107 100644
--- a/boot/cypress/common_libs.mk
+++ b/boot/cypress/common_libs.mk
@@ -28,62 +28,124 @@
################################################################################
# PDL library
################################################################################
-PSOC6_LIBS_PATH = $(PRJ_DIR)/libs
+CY_LIBS_PATH = $(PRJ_DIR)/libs
-ifeq ($(CORE),CM0P)
-CORE_SIFFX=m0plus
-else
-CORE_SIFFX=m4
-endif
+# Collect common source files for PDL
+SOURCES_PDL := $(wildcard $(CY_LIBS_PATH)/mtb-pdl-cat1/drivers/source/*.c)
+SOURCES_PDL += $(wildcard $(CY_LIBS_PATH)/mtb-pdl-cat1/devices/COMPONENT_CAT$(PDL_CAT_SUFFIX)/source/*.c)
-# Collect source files for PDL
-SOURCES_PDL := $(wildcard $(PSOC6_LIBS_PATH)/mtb-pdl-cat1/drivers/source/*.c)
-SOURCES_PDL += $(wildcard $(PSOC6_LIBS_PATH)/mtb-pdl-cat1/devices/COMPONENT_CAT1A/source/*.c)
+COMPONENT_CORE_PATH := $(CY_LIBS_PATH)/mtb-pdl-cat1/devices/COMPONENT_CAT$(PDL_CAT_SUFFIX)/templates/COMPONENT_MTB/COMPONENT_$(CORE)
# PDL startup related files
-SOURCES_PDL_STARTUP := $(PSOC6_LIBS_PATH)/mtb-pdl-cat1/devices/COMPONENT_CAT1A/templates/COMPONENT_MTB/COMPONENT_$(CORE)/system_psoc6_c$(CORE_SIFFX).c
+SYSTEM_FILE_NAME := $(PLATFORM_SYSTEM_FILE_NAME)
+SOURCES_PDL_SYSTEM := $(COMPONENT_CORE_PATH)/$(SYSTEM_FILE_NAME)
+SOURCES_PDL_STARTUP := $(COMPONENT_CORE_PATH)/$(PLATFORM_SOURCES_PDL_STARTUP)
+
+# Collect source files for Retarget-io
+SOURCES_RETARGET_IO := $(PLATFORM_SOURCES_RETARGET_IO)
+
+# HAL source files
+SOURCES_HAL := $(PLATFORM_SOURCES_HAL)
+
+# Add platform folder to build
+SOURCES_PLATFORM := $(wildcard $(PRJ_DIR)/platforms/$(FAMILY)/*.c)
+SOURCES_PLATFORM += $(wildcard $(PRJ_DIR)/platforms/$(FAMILY)/secure/*.c)
# PDL related include directories
-INCLUDE_DIRS_PDL := $(PSOC6_LIBS_PATH)/mtb-pdl-cat1/drivers/include
-INCLUDE_DIRS_PDL += $(PSOC6_LIBS_PATH)/mtb-pdl-cat1/devices/COMPONENT_CAT1A/include/ip
-INCLUDE_DIRS_PDL += $(PSOC6_LIBS_PATH)/mtb-pdl-cat1/devices/COMPONENT_CAT1A/include
-INCLUDE_DIRS_PDL += $(PSOC6_LIBS_PATH)/mtb-pdl-cat1/cmsis/include
-
-# PDL startup related files
-INCLUDE_DIRS_PDL_STARTUP := $(PSOC6_LIBS_PATH)/mtb-pdl-cat1/devices/COMPONENT_CAT1A/templates/COMPONENT_MTB
+INCLUDE_DIRS_PDL := $(CY_LIBS_PATH)/mtb-pdl-cat1/drivers/include
+INCLUDE_DIRS_PDL += $(CY_LIBS_PATH)/mtb-pdl-cat1/devices/COMPONENT_CAT$(PDL_CAT_SUFFIX)/include/ip
+INCLUDE_DIRS_PDL += $(CY_LIBS_PATH)/mtb-pdl-cat1/devices/COMPONENT_CAT$(PDL_CAT_SUFFIX)/include
+INCLUDE_DIRS_PDL += $(CY_LIBS_PATH)/mtb-pdl-cat1/cmsis/include
+INCLUDE_DIRS_PDL += $(CY_LIBS_PATH)/mtb-pdl-cat1/devices/COMPONENT_CAT$(PDL_CAT_SUFFIX)/templates/COMPONENT_MTB
# core-libs related include directories
-INCLUDE_DIRS_CORE_LIB := $(PSOC6_LIBS_PATH)/core-lib/include
+INCLUDE_DIRS_CORE_LIB := $(CY_LIBS_PATH)/core-lib/include
-STARTUP_FILE := $(PSOC6_LIBS_PATH)/mtb-pdl-cat1/devices/COMPONENT_CAT1A/templates/COMPONENT_MTB/COMPONENT_$(CORE)/TOOLCHAIN_$(COMPILER)/startup_psoc6_$(PLATFORM_SUFFIX)_c$(CORE_SIFFX)
+# PDL startup related files
+INCLUDE_DIRS_PDL_STARTUP += $(COMPONENT_CORE_PATH)/HEADER_FILES
-ifeq ($(COMPILER), GCC_ARM)
- ASM_FILES_STARTUP := $(STARTUP_FILE).S
-else
-$(error Only GCC ARM is supported at this moment)
-endif
+# Retarget-io related include directories
+INCLUDE_DIRS_RETARGET_IO := $(PLATFORM_INCLUDE_DIRS_RETARGET_IO)
+# HAL include directories files
+INCLUDE_DIRS_HAL := $(PLATFORM_INCLUDE_DIRS_HAL)
+
+# Include platforms folder
+INCLUDE_DIRS_PLATFORM := $(PRJ_DIR)/platforms/$(FAMILY)
+INCLUDE_DIRS_PLATFORM += $(PRJ_DIR)/platforms/$(FAMILY)/secure
+
+# Assembler startup file for platform
+ASM_FILES_STARTUP := $(PLATFORM_STARTUP_FILE)
# Collected source files for libraries
SOURCES_LIBS := $(SOURCES_PDL)
+SOURCES_LIBS += $(SOURCES_PDL_SYSTEM)
SOURCES_LIBS += $(SOURCES_PDL_STARTUP)
+SOURCES_LIBS += $(SOURCES_PDL_RUNTIME)
+SOURCES_LIBS += $(SOURCES_HAL)
+SOURCES_LIBS += $(SOURCES_RETARGET_IO)
# Collected include directories for libraries
INCLUDE_DIRS_LIBS := $(addprefix -I,$(INCLUDE_DIRS_PDL))
INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_PDL_STARTUP))
INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_CORE_LIB))
+INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_HAL))
+INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_PLATFORM))
+INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_RETARGET_IO))
-ASM_FILES_PDL :=
-ifeq ($(COMPILER), GCC_ARM)
-ASM_FILES_PDL += $(PSOC6_LIBS_PATH)/mtb-pdl-cat1/drivers/source/TOOLCHAIN_GCC_ARM/cy_syslib_gcc.S
-else
-$(error Only GCC ARM is supported at this moment)
-endif
+# Syslib files
+ASM_FILES_PDL += $(CY_LIBS_PATH)/mtb-pdl-cat1/drivers/source/TOOLCHAIN_GCC_ARM/cy_syslib_gcc.S
ASM_FILES_LIBS := $(ASM_FILES_PDL)
# Add define for PDL version
DEFINES_PDL += -DPDL_VERSION=$(PDL_VERSION)
-DEFINES_LIBS := $(DEFINES_PLATFORM)
+DEFINES_LIBS := $(PLATFORM_DEFINES)
+DEFINES_LIBS += $(PLATFORM_DEFINES_LIBS)
DEFINES_LIBS += $(DEFINES_PDL)
+DEFINES_LIBS += -DCOMPONENT_CAT1
+DEFINES_LIBS += -DCOMPONENT_CAT$(PDL_CAT_SUFFIX)
+
+###############################################################################
+# Print debug information about all settings used and/or set in this file
+ifeq ($(VERBOSE), 1)
+$(info #### common_libs.mk ####)
+$(info ASM_FILES_LIBS --> $(ASM_FILES_LIBS))
+$(info ASM_FILES_PDL <-> $(ASM_FILES_PDL))
+$(info ASM_FILES_STARTUP --> $(ASM_FILES_STARTUP))
+$(info COMPONENT_CORE_PATH <-> $(COMPONENT_CORE_PATH))
+$(info CORE <-- $(CORE))
+$(info CY_LIBS_PATH <-- $(CY_LIBS_PATH))
+$(info DEFINES_LIBS --> $(DEFINES_LIBS))
+$(info DEFINES_PDL <-> $(DEFINES_PDL))
+$(info FAMILY <-- $(FAMILY))
+$(info INCLUDE_DIRS_CORE_LIB <-> $(INCLUDE_DIRS_CORE_LIB))
+$(info INCLUDE_DIRS_HAL <-> $(INCLUDE_DIRS_HAL))
+$(info INCLUDE_DIRS_LIBS --> $(INCLUDE_DIRS_LIBS))
+$(info INCLUDE_DIRS_PDL <-> $(INCLUDE_DIRS_PDL))
+$(info INCLUDE_DIRS_PDL_STARTUP <-> $(INCLUDE_DIRS_PDL_STARTUP))
+$(info INCLUDE_DIRS_PLATFORM <-> $(INCLUDE_DIRS_PLATFORM))
+$(info INCLUDE_DIRS_RETARGET_IO <-> $(INCLUDE_DIRS_RETARGET_IO))
+$(info PDL_CAT_SUFFIX <-- $(PDL_CAT_SUFFIX))
+$(info PDL_VERSION <-- $(PDL_VERSION))
+$(info PLATFORM_DEFINES <-- $(PLATFORM_DEFINES))
+$(info PLATFORM_DEFINES_LIBS <-- $(PLATFORM_DEFINES_LIBS))
+$(info PLATFORM_INCLUDE_DIRS_HAL <-- $(PLATFORM_INCLUDE_DIRS_HAL))
+$(info PLATFORM_INCLUDE_DIRS_RETARGET_IO <-- $(PLATFORM_INCLUDE_DIRS_RETARGET_IO))
+$(info PLATFORM_SOURCES_HAL <-- $(PLATFORM_SOURCES_HAL))
+$(info PLATFORM_SOURCES_PDL_STARTUP <-- $(PLATFORM_SOURCES_PDL_STARTUP))
+$(info PLATFORM_SOURCES_RETARGET_IO <-- $(PLATFORM_SOURCES_RETARGET_IO))
+$(info PLATFORM_STARTUP_FILE <-- $(PLATFORM_STARTUP_FILE))
+$(info PLATFORM_SYSTEM_FILE_NAME <-- $(PLATFORM_SYSTEM_FILE_NAME))
+$(info PRJ_DIR <-- $(PRJ_DIR))
+$(info SOURCES_HAL <-> $(SOURCES_HAL))
+$(info SOURCES_LIBS --> $(SOURCES_LIBS))
+$(info SOURCES_PDL <-> $(SOURCES_PDL))
+$(info SOURCES_PDL_RUNTIME <-- $(SOURCES_PDL_RUNTIME))
+$(info SOURCES_PDL_STARTUP <-> $(SOURCES_PDL_STARTUP))
+$(info SOURCES_PDL_SYSTEM <-> $(SOURCES_PDL_SYSTEM))
+$(info SOURCES_PLATFORM --> $(SOURCES_PLATFORM))
+$(info SOURCES_RETARGET_IO <-> $(SOURCES_RETARGET_IO))
+$(info SYSTEM_FILE_NAME <-> $(SYSTEM_FILE_NAME))
+endif
diff --git a/boot/cypress/cy_flash_pal/cy_flash_map.c b/boot/cypress/cy_flash_pal/cy_flash_map.c
deleted file mode 100644
index 11113fb..0000000
--- a/boot/cypress/cy_flash_pal/cy_flash_map.c
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * Copyright (c) 2018 Nordic Semiconductor ASA
- * Copyright (c) 2020 Cypress Semiconductor Corporation
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
- /*******************************************************************************/
-
-#ifdef MCUBOOT_HAVE_ASSERT_H
-#include "mcuboot_config/mcuboot_assert.h"
-#else
-#include <assert.h>
-#endif
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "mcuboot_config/mcuboot_config.h"
-#include "flash_map_backend/flash_map_backend.h"
-#include <sysflash/sysflash.h>
-
-#include "bootutil/bootutil_log.h"
-
-#include "cy_flash.h"
-
-#ifdef CY_BOOT_USE_EXTERNAL_FLASH
-#include "cy_smif_psoc6.h"
-#endif
-
-#ifdef MCUBOOT_SWAP_USING_STATUS
-#include "swap_status.h"
-#endif
-/*
- * For now, we only support one flash device.
- *
- * Pick a random device ID for it that's unlikely to collide with
- * anything "real".
- */
-#define FLASH_DEVICE_ID 111
-#define FLASH_MAP_ENTRY_MAGIC (0xd00dbeefU)
-
-#define FLASH_AREA_IMAGE_SECTOR_SIZE FLASH_AREA_IMAGE_SCRATCH_SIZE
-
-#ifndef CY_BOOTLOADER_START_ADDRESS
-#define CY_BOOTLOADER_START_ADDRESS (0x10000000u)
-#endif
-
-#ifndef CY_BOOT_INTERNAL_FLASH_ERASE_VALUE
-/* This is the value of internal flash bytes after an erase */
-#define CY_BOOT_INTERNAL_FLASH_ERASE_VALUE (0x00u)
-#endif
-
-#ifndef CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE
-/* This is the value of external flash bytes after an erase */
-#define CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE (0xffu)
-#endif
-
-#ifdef CY_FLASH_MAP_EXT_DESC
-/* Nothing to be there when external FlashMap Descriptors are used */
-#else
-static struct flash_area bootloader =
-{
- .fa_id = FLASH_AREA_BOOTLOADER,
- .fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
- .fa_off = CY_BOOTLOADER_START_ADDRESS,
- .fa_size = CY_BOOT_BOOTLOADER_SIZE
-};
-
-static struct flash_area primary_1 =
-{
- .fa_id = FLASH_AREA_IMAGE_PRIMARY(0),
- .fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
- .fa_off = CY_FLASH_BASE + CY_BOOT_BOOTLOADER_SIZE,
- .fa_size = CY_BOOT_PRIMARY_1_SIZE
-};
-
-static struct flash_area secondary_1 =
-{
- .fa_id = FLASH_AREA_IMAGE_SECONDARY(0),
-#ifndef CY_BOOT_USE_EXTERNAL_FLASH
- .fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
- .fa_off = CY_FLASH_BASE +\
- CY_BOOT_BOOTLOADER_SIZE +\
- CY_BOOT_PRIMARY_1_SIZE,
-#else
- .fa_device_id = FLASH_DEVICE_EXTERNAL_FLASH(CY_BOOT_EXTERNAL_DEVICE_INDEX),
- .fa_off = CY_BOOT_SECONDARY_1_EXT_MEM_OFFSET,
-#endif
- .fa_size = CY_BOOT_SECONDARY_1_SIZE
-};
-
-#if (MCUBOOT_IMAGE_NUMBER == 2) /* if dual-image */
-static struct flash_area primary_2 =
-{
- .fa_id = FLASH_AREA_IMAGE_PRIMARY(1),
- .fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
-#ifndef CY_BOOT_USE_EXTERNAL_FLASH
- .fa_off = CY_FLASH_BASE +\
- CY_BOOT_BOOTLOADER_SIZE +\
- CY_BOOT_PRIMARY_1_SIZE +\
- CY_BOOT_SECONDARY_1_SIZE,
-#else
- .fa_off = CY_FLASH_BASE +\
- CY_BOOT_BOOTLOADER_SIZE +\
- CY_BOOT_PRIMARY_1_SIZE,
-#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
- .fa_size = CY_BOOT_PRIMARY_2_SIZE
-};
-
-static struct flash_area secondary_2 =
-{
- .fa_id = FLASH_AREA_IMAGE_SECONDARY(1),
-#ifndef CY_BOOT_USE_EXTERNAL_FLASH
- .fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
- .fa_off = CY_FLASH_BASE +\
- CY_BOOT_BOOTLOADER_SIZE +\
- CY_BOOT_PRIMARY_1_SIZE +\
- CY_BOOT_SECONDARY_1_SIZE +\
- CY_BOOT_PRIMARY_2_SIZE,
-#else
- .fa_device_id = FLASH_DEVICE_EXTERNAL_FLASH(CY_BOOT_EXTERNAL_DEVICE_INDEX),
- .fa_off = CY_BOOT_SECONDARY_2_EXT_MEM_OFFSET,
-#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
- .fa_size = CY_BOOT_SECONDARY_2_SIZE
-};
-#endif /* MCUBOOT_IMAGE_NUMBER == 2 */
-#endif /* CY_FLASH_MAP_EXT_DESC */
-
-#ifdef MCUBOOT_SWAP_USING_STATUS
-#define SWAP_STATUS_PARTITION_SIZE (CY_BOOT_SWAP_STATUS_SIZE * BOOT_IMAGE_NUMBER)
-
-#ifndef CY_BOOT_USE_EXTERNAL_FLASH
-#if (MCUBOOT_IMAGE_NUMBER == 1) /* if single image, internal flash */
-#define SWAP_STATUS_PARTITION_OFF (CY_FLASH_BASE + \
- CY_BOOT_BOOTLOADER_SIZE + \
- CY_BOOT_PRIMARY_1_SIZE + \
- CY_BOOT_SECONDARY_1_SIZE)
-#elif (MCUBOOT_IMAGE_NUMBER == 2) /* if dual-image, internal flash */
-#define SWAP_STATUS_PARTITION_OFF (CY_FLASH_BASE + \
- CY_BOOT_BOOTLOADER_SIZE + \
- CY_BOOT_PRIMARY_1_SIZE + \
- CY_BOOT_SECONDARY_1_SIZE + \
- CY_BOOT_PRIMARY_2_SIZE + \
- CY_BOOT_SECONDARY_2_SIZE)
-#endif /* MCUBOOT_IMAGE_NUMBER */
-#else /* CY_BOOT_USE_EXTERNAL_FLASH */
-#if (MCUBOOT_IMAGE_NUMBER == 1) /* if single image, external flash */
-#define SWAP_STATUS_PARTITION_OFF (CY_FLASH_BASE + \
- CY_BOOT_BOOTLOADER_SIZE + \
- CY_BOOT_PRIMARY_1_SIZE)
-#elif (MCUBOOT_IMAGE_NUMBER == 2) /* if dual-image, external flash */
-#define SWAP_STATUS_PARTITION_OFF (CY_FLASH_BASE + \
- CY_BOOT_BOOTLOADER_SIZE + \
- CY_BOOT_PRIMARY_1_SIZE + \
- CY_BOOT_PRIMARY_2_SIZE)
-#endif /* MCUBOOT_IMAGE_NUMBER */
-#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
-static struct flash_area status =
-{
- .fa_id = FLASH_AREA_IMAGE_SWAP_STATUS,
- .fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
- .fa_off = SWAP_STATUS_PARTITION_OFF,
-#ifdef MCUBOOT_SWAP_USING_SCRATCH
- .fa_size = (SWAP_STATUS_PARTITION_SIZE + BOOT_SWAP_STATUS_SZ_SCRATCH)
-#else
- .fa_size = (SWAP_STATUS_PARTITION_SIZE)
-#endif /* MCUBOOT_SWAP_USING_SCRATCH */
-
-};
-#endif /* MCUBOOT_SWAP_USING_STATUS */
-
-#ifdef MCUBOOT_SWAP_USING_SCRATCH
-#ifndef CY_BOOT_SCRATCH_SIZE
-#ifndef CY_BOOT_USE_EXTERNAL_FLASH
-#define CY_BOOT_SCRATCH_SIZE (CY_FLASH_SIZEOF_ROW)
-#else
-#define CY_BOOT_SCRATCH_SIZE (CY_BOOT_SCRATCH_SIZE)
-#endif
-#endif
-static struct flash_area scratch =
-{
- .fa_id = FLASH_AREA_IMAGE_SCRATCH,
-#ifndef CY_BOOT_USE_EXTERNAL_FLASH
- .fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
-#if (MCUBOOT_IMAGE_NUMBER == 1) /* if single image */
- .fa_off = CY_FLASH_BASE +\
- CY_BOOT_BOOTLOADER_SIZE +\
- CY_BOOT_PRIMARY_1_SIZE +\
- CY_BOOT_SECONDARY_1_SIZE + \
- (SWAP_STATUS_PARTITION_SIZE + BOOT_SWAP_STATUS_SZ_SCRATCH),
-#elif (MCUBOOT_IMAGE_NUMBER == 2) /* if dual-image */
- .fa_off = CY_FLASH_BASE +\
- CY_BOOT_BOOTLOADER_SIZE +\
- CY_BOOT_PRIMARY_1_SIZE +\
- CY_BOOT_SECONDARY_1_SIZE +\
- CY_BOOT_PRIMARY_2_SIZE +\
- CY_BOOT_SECONDARY_2_SIZE + \
- (SWAP_STATUS_PARTITION_SIZE + BOOT_SWAP_STATUS_SZ_SCRATCH),
-#endif /* MCUBOOT_IMAGE_NUMBER */
-#else /* CY_BOOT_USE_EXTERNAL_FLASH */
- .fa_device_id = FLASH_DEVICE_EXTERNAL_FLASH(CY_BOOT_EXTERNAL_DEVICE_INDEX),
- .fa_off = CY_SMIF_BASE_MEM_OFFSET + CY_BOOT_EXTERNAL_FLASH_SCRATCH_OFFSET,
-#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
- .fa_size = CY_BOOT_SCRATCH_SIZE
-};
-#endif
-
-#ifdef CY_FLASH_MAP_EXT_DESC
-/* Use external Flash Map Descriptors */
-extern struct flash_area *boot_area_descs[];
-#else
-struct flash_area *boot_area_descs[] =
-{
- &bootloader,
- &primary_1,
- &secondary_1,
-#if (MCUBOOT_IMAGE_NUMBER == 2) /* if dual-image */
- &primary_2,
- &secondary_2,
-#endif
-#ifdef MCUBOOT_SWAP_USING_SCRATCH
- &scratch,
-#endif
-#ifdef MCUBOOT_SWAP_USING_STATUS
- &status,
-#endif
- NULL
-};
-#endif /* CY_FLASH_MAP_EXT_DESC */
-
-/*
-* Returns device flash start based on supported fa_id
-*/
-int flash_device_base(uint8_t fd_id, uintptr_t *ret)
-{
- if (fd_id != (uint8_t)FLASH_DEVICE_INTERNAL_FLASH) {
- BOOT_LOG_ERR("invalid flash ID %d; expected %d",
- fd_id, FLASH_DEVICE_INTERNAL_FLASH);
- return -1;
- }
- *ret = CY_FLASH_BASE;
- return 0;
-}
-
-/*
-* Opens the area for use. id is one of the `fa_id`s
-*/
-int flash_area_open(uint8_t id, const struct flash_area **fa)
-{
- int ret = -1;
- uint32_t i = 0;
-
- while(NULL != boot_area_descs[i])
- {
- if(id == boot_area_descs[i]->fa_id)
- {
- *fa = boot_area_descs[i];
- ret = 0;
- break;
- }
- i++;
- }
-
- return ret;
-}
-
-/*
-* Clear pointer to flash area fa
-*/
-void flash_area_close(const struct flash_area *fa)
-{
- (void)fa; /* Nothing to do there */
-}
-
-/*
-* Reads `len` bytes of flash memory at `off` to the buffer at `dst`
-*/
-int flash_area_read(const struct flash_area *fa, uint32_t off, void *dst,
- uint32_t len)
-{
- int rc = 0;
- size_t addr;
-
- /* check if requested offset not less then flash area (fa) start */
- assert((int)(off < fa->fa_off));
- assert((int)(off + len < fa->fa_off));
- /* convert to absolute address inside a device*/
- addr = fa->fa_off + off;
-
- if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
- {
- /* flash read by simple memory copying */
- (void)memcpy((void *)dst, (const void*)addr, (size_t)len);
- }
-#ifdef CY_BOOT_USE_EXTERNAL_FLASH
- else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG)
- {
- rc = psoc6_smif_read(fa, (int32_t)addr, dst, len);
- }
-#endif
- else
- {
- /* incorrect/non-existing flash device id */
- rc = -1;
- }
-
- if ((rc != 0) && (fa->fa_device_id != FLASH_DEVICE_UNDEFINED))
- {
- BOOT_LOG_ERR("Flash area read error, rc = %d", (int)rc);
- }
- return rc;
-}
-
-/*
-* Writes `len` bytes of flash memory at `off` from the buffer at `src`
- */
-int flash_area_write(const struct flash_area *fa, uint32_t off,
- const void *src, uint32_t len)
-{
- cy_en_flashdrv_status_t rc = CY_FLASH_DRV_SUCCESS;
- size_t write_start_addr;
- size_t write_end_addr;
- const uint32_t * row_ptr = NULL;
-
- assert((int)(off < fa->fa_off));
- assert((int)(off + len < fa->fa_off));
-
- /* convert to absolute address inside a device */
- write_start_addr = fa->fa_off + off;
- write_end_addr = fa->fa_off + off + len;
-
- if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
- {
- uint32_t row_number = 0;
- uint32_t row_addr = 0;
-
- assert((int)((len % CY_FLASH_SIZEOF_ROW) == 0U));
- assert((int)((write_start_addr % CY_FLASH_SIZEOF_ROW) == 0U));
-
- row_number = (write_end_addr - write_start_addr) / CY_FLASH_SIZEOF_ROW;
- row_addr = write_start_addr;
-
- row_ptr = (const uint32_t *) src;
-
- for (uint32_t i = 0; i < row_number; i++)
- {
- rc = (int)Cy_Flash_WriteRow(row_addr, row_ptr);
-
- row_addr += (uint32_t) CY_FLASH_SIZEOF_ROW;
- row_ptr = row_ptr + CY_FLASH_SIZEOF_ROW / 4U;
- }
- }
-#ifdef CY_BOOT_USE_EXTERNAL_FLASH
- else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG)
- {
- rc = psoc6_smif_write(fa, (int32_t)write_start_addr, src, len);
- }
-#endif
- else
- {
- /* incorrect/non-existing flash device id */
- rc = -1;
- }
-
- return (int) rc;
-}
-
-/*< Erases `len` bytes of flash memory at `off` */
-int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len)
-{
- cy_en_flashdrv_status_t rc = CY_FLASH_DRV_SUCCESS;
- size_t erase_start_addr;
- size_t erase_end_addr;
-
- assert((int)(len <= fa->fa_size));
- assert((int)(off < fa->fa_size));
- assert((int)(off + len < fa->fa_off + fa->fa_size));
-
- /* convert to absolute address inside a device*/
- erase_start_addr = fa->fa_off + off;
- erase_end_addr = fa->fa_off + off + len;
-
- if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
- {
- int row_number = 0;
- uint32_t row_addr = 0;
- uint32_t row_start_addr = (erase_start_addr / CY_FLASH_SIZEOF_ROW) * CY_FLASH_SIZEOF_ROW;
- uint32_t row_end_addr = (erase_end_addr / CY_FLASH_SIZEOF_ROW) * CY_FLASH_SIZEOF_ROW;
-
- /* assume single row needs to be erased */
- if (row_start_addr == row_end_addr) {
- rc = (int)Cy_Flash_EraseRow(row_start_addr);
- } else {
- row_number = (int)((row_end_addr - row_start_addr) / CY_FLASH_SIZEOF_ROW);
-
- while (row_number != 0)
- {
- row_number--;
- row_addr = row_start_addr + (uint32_t) row_number * (uint32_t) CY_FLASH_SIZEOF_ROW;
- rc = (int)Cy_Flash_EraseRow(row_addr);
- }
- }
- }
-#ifdef CY_BOOT_USE_EXTERNAL_FLASH
- else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG)
- {
- rc = psoc6_smif_erase((int)erase_start_addr, len);
- }
-#endif
- else
- {
- /* incorrect/non-existing flash device id */
- rc = -1;
- }
- return (int) rc;
-}
-
-/*< Returns this `flash_area`s alignment */
-size_t flash_area_align(const struct flash_area *fa)
-{
- size_t ret = (size_t)-1;
- if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
- {
- ret = CY_FLASH_ALIGN;
- }
-#ifdef CY_BOOT_USE_EXTERNAL_FLASH
- else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG)
- {
- ret = qspi_get_prog_size();
- }
-#endif
- else
- {
- /* incorrect/non-existing flash device id */
- ret = (size_t)-1;
- }
- return ret;
-}
-
-#ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
-/*< Initializes an array of flash_area elements for the slot's sectors */
-int flash_area_to_sectors(int idx, int *cnt, struct flash_area *fa)
-{
- int rc = 0;
-
- if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
- {
- (void)idx;
- (void)cnt;
- rc = 0;
- }
-#ifdef CY_BOOT_USE_EXTERNAL_FLASH
- else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG)
- {
- (void)idx;
- (void)cnt;
- rc = 0;
- }
-#endif
- else
- {
- /* incorrect/non-existing flash device id */
- rc = -1;
- }
- return rc;
-}
-#endif
-
-/*
- * This depends on the mappings defined in sysflash.h.
- * MCUBoot uses continuous numbering for the primary slot, the secondary slot,
- * and the scratch while zephyr might number it differently.
- */
-int flash_area_id_from_multi_image_slot(int image_index, int slot)
-{
- int rc;
- switch (slot) {
- case 0:
- rc = (int)FLASH_AREA_IMAGE_PRIMARY((uint32_t)image_index);
- break;
- case 1:
- rc = (int)FLASH_AREA_IMAGE_SECONDARY((uint32_t)image_index);
- break;
- case 2:
- rc = (int)FLASH_AREA_IMAGE_SCRATCH;
- break;
- default:
- rc = -1; /* flash_area_open will fail on that */
- break;
- }
- return rc;
-}
-
-int flash_area_id_from_image_slot(int slot)
-{
- return flash_area_id_from_multi_image_slot(0, slot);
-}
-
-int flash_area_id_to_multi_image_slot(int image_index, int area_id)
-{
- if (area_id == (int) FLASH_AREA_IMAGE_PRIMARY((uint32_t)image_index)) {
- return 0;
- }
- if (area_id == (int) FLASH_AREA_IMAGE_SECONDARY((uint32_t)image_index)) {
- return 1;
- }
-
- return -1;
-}
-
-int flash_area_id_to_image_slot(int area_id)
-{
- return flash_area_id_to_multi_image_slot(0, area_id);
-}
-
-/*
- * Erases aligned row of flash, where passed address resided
- */
-int flash_erase_row(uint32_t address)
-{
- cy_en_flashdrv_status_t rc = CY_FLASH_DRV_SUCCESS;
- uint32_t row_addr = 0;
-
- /* Calculate start of row arbitrary address */
- row_addr = (address/CY_FLASH_SIZEOF_ROW)*CY_FLASH_SIZEOF_ROW;
-
- /* Erase whole row of flash */
- rc = Cy_Flash_EraseRow(row_addr);
-
- return (int) rc;
-}
-
-uint8_t flash_area_erased_val(const struct flash_area *fa)
-{
- uint8_t ret = 0;
-
- if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
- {
- ret = (uint8_t) CY_BOOT_INTERNAL_FLASH_ERASE_VALUE;
- }
-#ifdef CY_BOOT_USE_EXTERNAL_FLASH
- else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG)
- {
- ret = (uint8_t) CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE;
- }
-#endif
- else
- {
- assert(false);
- }
-
- return ret ;
-}
-
-int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off,
- void *dst, uint32_t len)
-{
- /* The disabled flash area always tracts as empty */
- if (fa->fa_device_id != FLASH_DEVICE_UNDEFINED)
- {
- int rc;
- uint8_t *mem_dest = (uint8_t *)dst;
- uint8_t val = flash_area_erased_val(fa);
-
- rc = flash_area_read(fa, off, dst, len);
- if (rc != 0) {
- return -1;
- }
-
- for (uint8_t i = 0; i < len; i++) {
- if (mem_dest[i] != val) {
- return 0;
- }
- }
- }
- return 1;
-}
-
-#ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
-int flash_area_get_sectors(int idx, uint32_t *cnt, struct flash_sector *ret)
-{
- int rc = 0;
- uint32_t i = 0u;
- struct flash_area *fa = NULL;
-
- while(NULL != boot_area_descs[i])
- {
- if(idx == (int) boot_area_descs[i]->fa_id)
- {
- fa = boot_area_descs[i];
- break;
- }
- i++;
- }
-
- if(NULL != fa)
- {
- size_t sector_size = 0;
- size_t area_size = fa->fa_size;
-
- if(fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
- {
-#if defined(CY_BOOT_USE_EXTERNAL_FLASH) && defined(MCUBOOT_SWAP_USING_STATUS) \
- && !defined(MCUBOOT_SWAP_USING_SCRATCH)
- if(idx == (int) FLASH_AREA_IMAGE_SWAP_STATUS)
- {
- sector_size = CY_FLASH_SIZEOF_ROW;
- }
- else
- {
- sector_size = qspi_get_erase_size();
-#else
- sector_size = CY_FLASH_SIZEOF_ROW;
-#endif /* MCUBOOT_SWAP_USING_STATUS && CY_BOOT_USE_EXTERNAL_FLASH */
- }
-#ifdef CY_BOOT_USE_EXTERNAL_FLASH
- else if((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG)
- {
- /* implement for SMIF */
- /* lets assume they are equal */
-#ifdef MCUBOOT_SWAP_USING_STATUS
- sector_size = qspi_get_erase_size();
-#else
- sector_size = CY_FLASH_SIZEOF_ROW;
-#endif /* MCUBOOT_SWAP_USING_STATUS */
- }
-#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
- else
- {
- /* fa->fa_device_id = FLASH_DEVICE_UNDEFINED,
- in this case the area should be empty with a very simple sector size of 1 byte */
- area_size = 0u;
- sector_size = 1u;
- }
-
- if(0 == rc)
- {
- size_t sectors_n;
- uint32_t my_sector_addr = 0U;
- uint32_t my_sector_size;
-
- sectors_n = (area_size + (sector_size - 1U)) / sector_size;
-
- if (sectors_n > MCUBOOT_MAX_IMG_SECTORS)
- {
- sector_size *= 2;
- }
-
- sectors_n = 0;
- my_sector_addr = fa->fa_off;
- while (area_size > 0)
- {
- my_sector_size = sector_size;
-#ifdef MCUBOOT_SWAP_USING_SCRATCH
- uint32_t my_sector_offs = my_sector_addr % my_sector_size;
-
- if (my_sector_offs != 0)
- {
- my_sector_size = sector_size - my_sector_offs;
- }
-
- if (my_sector_size > area_size)
- {
- my_sector_size = area_size;
- }
-#endif
- ret[sectors_n].fs_size = my_sector_size;
- ret[sectors_n].fs_off = my_sector_addr;
-
- my_sector_addr += my_sector_size;
- area_size -= my_sector_size;
- sectors_n++;
- }
-
- if (sectors_n <= *cnt)
- {
- *cnt = sectors_n;
- }
- else
- {
- rc = -1;
- }
- }
- }
- else
- {
- rc = -1;
- }
-
- return rc;
-}
-#endif
diff --git a/boot/cypress/cy_flash_pal/flash_cyw208xx/cy_flash_map.c b/boot/cypress/cy_flash_pal/flash_cyw208xx/cy_flash_map.c
new file mode 100644
index 0000000..21b9e60
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/cy_flash_map.c
@@ -0,0 +1,412 @@
+/*
+ * Copyright (c) 2018 Nordic Semiconductor ASA
+ * Copyright (c) 2020 Cypress Semiconductor Corporation
+ * Copyright (c) 2022 Infineon Technologies AG
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "mcuboot_config/mcuboot_config.h"
+#include "flash_map_backend/flash_map_backend.h"
+#include "sysflash/sysflash.h"
+
+#include "bootutil/bootutil_log.h"
+#include "bootutil/bootutil_public.h"
+
+#include "cy_flash.h"
+#include "cy_flash_map.h"
+
+#include "cy_smif_cyw20829.h"
+
+#ifdef MCUBOOT_SWAP_USING_STATUS
+#include "swap_status.h"
+#endif
+
+#ifndef CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE
+/* This is the value of external flash bytes after an erase */
+#define CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE (0xFFu)
+#endif
+
+/*
+ * Returns device flash start based on supported fd_id
+ */
+int flash_device_base(uint8_t fd_id, uintptr_t *ret)
+{
+ int rc = -1;
+
+ if (NULL != ret) {
+
+ if (FLASH_DEVICE_INTERNAL_FLASH == fd_id) {
+ *ret = CY_FLASH_BASE;
+ rc = 0;
+ }
+ else if ((fd_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) {
+ *ret = CY_FLASH_BASE;
+ rc = 0;
+ }
+ else {
+ BOOT_LOG_ERR("invalid flash ID %u; expected %u or %u",
+ (unsigned)fd_id, FLASH_DEVICE_INTERNAL_FLASH,
+ FLASH_DEVICE_EXTERNAL_FLASH(CY_BOOT_EXTERNAL_DEVICE_INDEX));
+ }
+ }
+
+ return rc;
+}
+
+/*
+ * Opens the area for use. id is one of the `fa_id`s
+ */
+int flash_area_open(uint8_t id, const struct flash_area **fa)
+{
+ int ret = -1;
+ uint32_t i = 0u;
+
+ if (NULL != fa) {
+ while (NULL != boot_area_descs[i]) {
+ if (id == boot_area_descs[i]->fa_id) {
+ *fa = boot_area_descs[i];
+ ret = 0;
+ break;
+ }
+ i++;
+ }
+
+ if (ret == 0 &&
+ ((*fa)->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) != 0u) {
+
+ qspi_enable();
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Clear pointer to flash area fa
+ */
+void flash_area_close(const struct flash_area *fa)
+{
+ (void)fa; /* Nothing to do there */
+
+ if (NULL != fa) {
+ if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) {
+ qspi_disable();
+ }
+ }
+}
+
+/*
+ * Reads `len` bytes of flash memory at `off` to the buffer at `dst`
+ */
+int flash_area_read(const struct flash_area *fa, uint32_t off, void *dst,
+ uint32_t len)
+{
+ int rc = -1;
+ size_t addr;
+ uintptr_t flash_base = 0u;
+
+ if ( (NULL != fa) && (NULL != dst) ) {
+
+ if (off > fa->fa_size ||
+ len > fa->fa_size ||
+ off + len > fa->fa_size) {
+
+ return BOOT_EBADARGS;
+ }
+
+ rc = flash_device_base(fa->fa_device_id, &flash_base);
+
+ if (0 == rc) {
+ /* Convert to absolute address inside a device */
+ addr = flash_base + fa->fa_off + off;
+ rc = cyw20829_smif_read(fa, addr, dst, len);
+ }
+ }
+
+ return rc;
+}
+
+/*
+ * Writes `len` bytes of flash memory at `off` from the buffer at `src`
+ */
+int flash_area_write(const struct flash_area *fa, uint32_t off,
+ const void *src, uint32_t len)
+{
+ int rc = -1;
+ size_t write_start_addr = 0u;
+ uintptr_t flash_base = 0u;
+
+ if ( (NULL != fa) && (NULL != src) ) {
+
+ if (off > fa->fa_size ||
+ len > fa->fa_size ||
+ off + len > fa->fa_size) {
+
+ return BOOT_EBADARGS;
+ }
+
+ rc = flash_device_base(fa->fa_device_id, &flash_base);
+
+ if (0 == rc) {
+ /* Convert to absolute address inside a device */
+ write_start_addr = flash_base + fa->fa_off + off;
+ rc = cyw20829_smif_write(fa, write_start_addr, src, len);
+ }
+ }
+
+ return (int) rc;
+}
+
+/*< Erases `len` bytes of flash memory at `off` */
+int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len)
+{
+ int rc = -1;
+ size_t erase_start_addr = 0u;
+ uintptr_t flash_base = 0u;
+
+ if (NULL != fa) {
+
+ if (off > fa->fa_size ||
+ len > fa->fa_size ||
+ off + len > fa->fa_size) {
+
+ return BOOT_EBADARGS;
+ }
+
+ rc = flash_device_base(fa->fa_device_id, &flash_base);
+
+ if (0 == rc) {
+ /* Convert to absolute address inside a device */
+ erase_start_addr = flash_base + fa->fa_off + off;
+ rc = cyw20829_smif_erase(erase_start_addr, len);
+ }
+ }
+
+ return rc;
+}
+
+/*< Returns this `flash_area`s alignment */
+size_t flash_area_align(const struct flash_area *fa)
+{
+ size_t rc = 0u; /* error code (alignment cannot be zero) */
+
+ if (NULL != fa) {
+
+ if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) {
+ rc = qspi_get_erase_size();
+ }
+ }
+
+ return rc;
+}
+
+#ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
+/*< Initializes an array of flash_area elements for the slot's sectors */
+int flash_area_to_sectors(int idx, int *cnt, struct flash_area *fa)
+{
+ int rc = -1;
+
+ if (fa != NULL && cnt != NULL) {
+ if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) {
+ (void)idx;
+ (void)cnt;
+ rc = 0;
+ }
+ }
+
+ return rc;
+}
+#endif /* MCUBOOT_USE_FLASH_AREA_GET_SECTORS */
+
+/*
+ * This depends on the mappings defined in sysflash.h.
+ * MCUBoot uses continuous numbering for the primary slot, the secondary slot,
+ * and the scratch while zephyr might number it differently.
+ */
+int flash_area_id_from_multi_image_slot(int image_index, int slot)
+{
+ int rc;
+ if ((image_index < 0) || (image_index >= MCUBOOT_IMAGE_NUMBER)) {
+ return -1;
+ }
+
+ switch (slot) {
+ case 0:
+ rc = (int)FLASH_AREA_IMAGE_PRIMARY((uint32_t)image_index);
+ break;
+ case 1:
+ rc = (int)FLASH_AREA_IMAGE_SECONDARY((uint32_t)image_index);
+ break;
+ case 2:
+ rc = (int)FLASH_AREA_IMAGE_SCRATCH;
+ break;
+ default:
+ rc = -1; /* flash_area_open will fail on that */
+ break;
+ }
+ return rc;
+}
+
+int flash_area_id_from_image_slot(int slot)
+{
+ return flash_area_id_from_multi_image_slot(0, slot);
+}
+
+int flash_area_id_to_multi_image_slot(int image_index, int area_id)
+{
+ if ((image_index < 0) || (image_index >= MCUBOOT_IMAGE_NUMBER)) {
+ return -1;
+ }
+
+ if (area_id == (int) FLASH_AREA_IMAGE_PRIMARY((uint32_t)image_index)) {
+ return 0;
+ }
+ if (area_id == (int) FLASH_AREA_IMAGE_SECONDARY((uint32_t)image_index)) {
+ return 1;
+ }
+
+ return -1;
+}
+
+int flash_area_id_to_image_slot(int area_id)
+{
+ return flash_area_id_to_multi_image_slot(0, area_id);
+}
+
+uint8_t flash_area_erased_val(const struct flash_area *fa)
+{
+ uint8_t rc = 0;
+
+ if (NULL != fa) {
+ if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) {
+ rc = (uint8_t) CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE;
+ }
+ }
+
+ return rc;
+}
+
+#ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
+int flash_area_get_sectors(int idx, uint32_t *cnt, struct flash_sector *ret)
+{
+ int rc = 0;
+ uint32_t i = 0u;
+ struct flash_area *fa = NULL;
+ size_t sectors_n = 0u;
+ uint32_t my_sector_addr = 0u;
+ uint32_t my_sector_size = 0u;
+
+ while (NULL != boot_area_descs[i]) {
+ if (idx == (int) boot_area_descs[i]->fa_id) {
+ fa = boot_area_descs[i];
+ break;
+ }
+ i++;
+ }
+
+ if ( (NULL != fa) && (NULL != cnt) && (NULL != ret) ) {
+
+ size_t sector_size = 0;
+ size_t area_size = fa->fa_size;
+
+ if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) != 0u) {
+ /* implement for SMIF */
+ /* lets assume they are equal */
+#ifdef MCUBOOT_SWAP_USING_STATUS
+ int32_t qspi_status = qspi_get_status();
+
+ if (EXT_FLASH_DEV_DISABLED != qspi_status) {
+ sector_size = qspi_get_erase_size();
+ }
+ else {
+ sector_size = CY_FLASH_SIZEOF_ROW;
+ }
+#else /* MCUBOOT_SWAP_USING_STATUS */
+ sector_size = CY_FLASH_SIZEOF_ROW;
+#endif /* MCUBOOT_SWAP_USING_STATUS */
+ }
+ else {
+ /* fa->fa_device_id = FLASH_DEVICE_UNDEFINED,
+ in this case the area should be empty with a very simple sector size of 1 byte */
+ area_size = 0u;
+ sector_size = 1u;
+ }
+
+ sectors_n = (area_size + (sector_size - 1U)) / sector_size;
+
+ BOOT_LOG_DBG(" * FA: %u, off = 0x%" PRIx32
+ ", area_size = %lu, sector_size = %lu, sectors_n = %lu",
+ (unsigned)fa->fa_id, fa->fa_off, (unsigned long)area_size,
+ (unsigned long)sector_size, (unsigned long)sectors_n);
+
+ if (sectors_n > (size_t)MCUBOOT_MAX_IMG_SECTORS) {
+
+ BOOT_LOG_DBG(" + FA: %u, sectors_n(%lu) > MCUBOOT_MAX_IMG_SECTORS(%u) -> sector_size * 2",
+ (unsigned)fa->fa_id, (unsigned long)sectors_n,
+ (unsigned int) MCUBOOT_MAX_IMG_SECTORS);
+ sector_size *= 2u;
+ }
+
+ sectors_n = 0u;
+ my_sector_addr = fa->fa_off;
+
+ while (area_size > 0u) {
+
+ my_sector_size = sector_size;
+#ifdef MCUBOOT_SWAP_USING_SCRATCH
+ uint32_t my_sector_offs = my_sector_addr % my_sector_size;
+
+ if (my_sector_offs != 0u) {
+ my_sector_size = sector_size - my_sector_offs;
+ }
+
+ if (my_sector_size > area_size) {
+ my_sector_size = area_size;
+ }
+#endif /* MCUBOOT_SWAP_USING_SCRATCH */
+ ret[sectors_n].fs_size = my_sector_size;
+ ret[sectors_n].fs_off = my_sector_addr;
+
+ my_sector_addr += my_sector_size;
+ area_size -= my_sector_size;
+ sectors_n++;
+ }
+
+ if (sectors_n <= *cnt) {
+ *cnt = sectors_n;
+ }
+ else {
+ rc = -1;
+ }
+ }
+ else {
+ rc = -1;
+ }
+
+ return rc;
+}
+#endif /* MCUBOOT_USE_FLASH_AREA_GET_SECTORS */
diff --git a/boot/cypress/cy_flash_pal/cy_smif_psoc6.c b/boot/cypress/cy_flash_pal/flash_cyw208xx/cy_smif_cyw20829.c
similarity index 74%
copy from boot/cypress/cy_flash_pal/cy_smif_psoc6.c
copy to boot/cypress/cy_flash_pal/flash_cyw208xx/cy_smif_cyw20829.c
index c2dd5c3..f8daf7d 100644
--- a/boot/cypress/cy_flash_pal/cy_smif_psoc6.c
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/cy_smif_cyw20829.c
@@ -49,30 +49,24 @@
#include "stdlib.h"
#include "stdbool.h"
-#ifdef MCUBOOT_HAVE_ASSERT_H
-#include "mcuboot_config/mcuboot_assert.h"
-#else
-#include <assert.h>
-#endif
-
#include "flash_map_backend/flash_map_backend.h"
#include <sysflash/sysflash.h>
#include "cy_device_headers.h"
-#include "cy_smif_psoc6.h"
+#include "cy_smif_cyw20829.h"
#include "cy_flash.h"
#include "cy_syspm.h"
#include "flash_qspi.h"
-#define PSOC6_WR_SUCCESS (0)
-#define PSOC6_WR_ERROR_INVALID_PARAMETER (1)
-#define PSOC6_WR_ERROR_FLASH_WRITE (2)
+#define CYW20829_WR_SUCCESS (0)
+#define CYW20829_WR_ERROR_INVALID_PARAMETER (1)
+#define CYW20829_WR_ERROR_FLASH_WRITE (2)
-#define PSOC6_FLASH_ERASE_BLOCK_SIZE CY_FLASH_SIZEOF_ROW /* PSoC6 Flash erases by Row */
+#define CYW20829_FLASH_ERASE_BLOCK_SIZE CY_FLASH_SIZEOF_ROW /* CYW20829 Flash erases by Row */
-int psoc6_smif_read(const struct flash_area *fap,
- off_t addr,
+int cyw20829_smif_read(const struct flash_area *fap,
+ offset_t addr,
void *data,
size_t len)
{
@@ -83,7 +77,7 @@
cfg = qspi_get_memory_config(FLASH_DEVICE_GET_EXT_INDEX(fap->fa_device_id));
- address = (uint32_t) addr - CY_SMIF_BASE_MEM_OFFSET;
+ address = (uint32_t) addr - CY_XIP_BASE;
st = Cy_SMIF_MemRead(qspi_get_device(), cfg, address, data, len, qspi_get_context());
if (st == CY_SMIF_SUCCESS) {
@@ -92,8 +86,8 @@
return rc;
}
-int psoc6_smif_write(const struct flash_area *fap,
- off_t addr,
+int cyw20829_smif_write(const struct flash_area *fap,
+ offset_t addr,
const void *data,
size_t len)
{
@@ -104,22 +98,29 @@
cfg = qspi_get_memory_config(FLASH_DEVICE_GET_EXT_INDEX(fap->fa_device_id));
- address = (uint32_t) addr - CY_SMIF_BASE_MEM_OFFSET;
+ address = (uint32_t) addr - CY_XIP_BASE;
- st = Cy_SMIF_MemWrite(qspi_get_device(), cfg, address, data, len, qspi_get_context());
+ /* NOTE:
+ * External flash chip used on PSVP for 20829 requires memory
+ * to be erased before write for correct operation.
+ */
+ st = Cy_SMIF_MemEraseSector(qspi_get_device(), cfg, address, qspi_get_erase_size(), qspi_get_context());
+
+ if (st == CY_SMIF_SUCCESS) {
+ st = Cy_SMIF_MemWrite(qspi_get_device(), cfg, address, data, len, qspi_get_context());
+ }
if (st == CY_SMIF_SUCCESS) {
rc = 0;
}
return rc;
}
-int psoc6_smif_erase(off_t addr, size_t size)
+int cyw20829_smif_erase(offset_t addr, size_t size)
{
int rc = -1;
cy_en_smif_status_t st = CY_SMIF_SUCCESS;
- uint32_t address;
- if (size > 0)
+ if (size > 0u)
{
/* It is erase sector-only
*
@@ -128,19 +129,20 @@
* eraseSectorSize far from each other;
*/
cy_stc_smif_mem_config_t *memCfg = qspi_get_memory_config(0);
+ uint32_t eraseSize = qspi_get_erase_size();
- address = ((uint32_t)addr - CY_SMIF_BASE_MEM_OFFSET ) & ~((uint32_t)(memCfg->deviceCfg->eraseSize - 1u));
+ uint32_t address = ((uint32_t)addr - CY_XIP_BASE) & ~((uint32_t)(eraseSize - 1u));
- while ((size > 0) && (CY_SMIF_SUCCESS == st))
+ while ((size > 0u) && (CY_SMIF_SUCCESS == st))
{
st = Cy_SMIF_MemEraseSector(qspi_get_device(),
memCfg,
address,
- memCfg->deviceCfg->eraseSize,
+ eraseSize,
qspi_get_context());
- size -= (size >= memCfg->deviceCfg->eraseSize) ? memCfg->deviceCfg->eraseSize : size;
- address += memCfg->deviceCfg->eraseSize;
+ size -= (size >= eraseSize) ? eraseSize : size;
+ address += eraseSize;
}
if (st == CY_SMIF_SUCCESS) {
diff --git a/boot/cypress/cy_flash_pal/flash_cyw208xx/flash_qspi/cy_smif_hybrid_sect.c b/boot/cypress/cy_flash_pal/flash_cyw208xx/flash_qspi/cy_smif_hybrid_sect.c
new file mode 100644
index 0000000..0643ea1
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/flash_qspi/cy_smif_hybrid_sect.c
@@ -0,0 +1,350 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * 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.
+ */
+/*******************************************************************************
+* \file cy_smif_hybrid_sect.c
+* \version 1.0
+*
+* \brief
+* This is the source file of external flash driver for Semper Flash with
+* hybrid sectors.
+*
+********************************************************************************
+* \copyright
+*
+* (c) 2020, Cypress Semiconductor Corporation
+* or a subsidiary of Cypress Semiconductor Corporation. All rights
+* reserved.
+*
+* This software, including source code, documentation and related
+* materials ("Software"), is owned by Cypress Semiconductor
+* Corporation or one of its subsidiaries ("Cypress") and is protected by
+* and subject to worldwide patent protection (United States and foreign),
+* United States copyright laws and international treaty provisions.
+* Therefore, you may use this Software only as provided in the license
+* agreement accompanying the software package from which you
+* obtained this Software ("EULA").
+*
+* If no EULA applies, Cypress hereby grants you a personal, non-
+* exclusive, non-transferable license to copy, modify, and compile the
+* Software source code solely for use in connection with Cypress?s
+* integrated circuit products. Any reproduction, modification, translation,
+* compilation, or representation of this Software except as specified
+* above is prohibited without the express written permission of Cypress.
+*
+* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO
+* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING,
+* BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE. Cypress reserves the right to make
+* changes to the Software without notice. Cypress does not assume any
+* liability arising out of the application or use of the Software or any
+* product or circuit described in the Software. Cypress does not
+* authorize its products for use in any products where a malfunction or
+* failure of the Cypress product may reasonably be expected to result in
+* significant property damage, injury or death ("High Risk Product"). By
+* including Cypress's product in a High Risk Product, the manufacturer
+* of such system or application assumes all risk of such use and in doing
+* so agrees to indemnify Cypress against all liability.
+*
+******************************************************************************/
+
+#include "flash_qspi.h"
+#include "cy_smif_hybrid_sect.h"
+
+#define SMIF_TRANSFER_TIMEOUT (1000UL) /* The timeout (microseconds) to use in polling of
+ * the transfer status of the SMIF block
+ */
+
+#define SEMPER_ID_MANUF (0x34U)
+#define SEMPER_ID_DEV_MSB1 (0x2AU)
+#define SEMPER_ID_DEV_MSB2 (0x2BU)
+#define SEMPER_ID_DEV_LSB1 (0x19U)
+#define SEMPER_ID_DEV_LSB2 (0x1AU)
+#define SEMPER_ID_DEV_LSB3 (0x1BU)
+#define SEMPER_ID_LEN (0x0FU)
+#define SEMPER_ID_SECTARCH (0x03U)
+#define SEMPER_ID_FAMILY (0x90U)
+
+#define SEMPER_WRARG_CMD (0x71U) /* Write Any Register command */
+#define SEMPER_RDARG_CMD (0x65U) /* Read Any Register command */
+#define SEMPER_EN4BA_CMD (0xB7U) /* Enter 4 Byte Address Mode */
+#define SEMPER_ER256_CMD (0xD8U) /* Erase 256-KB Sector */
+#define SEMPER_RDIDN_CMD (0x9FU) /* Read manufacturer and device identification */
+
+#define SEMPER_CFR2N_ADDR (0x00000003UL) /* Non-volatile Configuration Register 2 address */
+#define SEMPER_CFR3N_ADDR (0x00000004UL) /* Non-volatile Configuration Register 3 address */
+
+#define SEMPER_CFR2N_ADRBYT (1U << 7U) /* Address Byte Length selection bit offset in CFR2N register */
+#define SEMPER_CFR3N_UNHYSA (1U << 3U) /* Uniform or Hybrid Sector Architecture selection bit offset in CFR3N register */
+
+#define SEMPER_WRARG_DATA_INDEX (4U) /* Input data index for WRARG command */
+
+#define SEMPER_WR_NV_TIMEOUT (500000U) /* Nonvolatile Register Write operation timeout */
+#define SEMPER_ERASE_256KB_TIME (6000U) /* 256 KB Sector Erase Time in ms */
+
+#define SEMPER_ADDR_LEN (4U)
+
+#define SEMPER_ERASE_SIZE (262144u) /* Erase size for Semper Flash is 256KB */
+
+#define PARAM_ID_MSB_OFFSET (0x08U) /* The offset of Parameter ID MSB */
+#define PARAM_ID_LSB_MASK (0xFFUL) /* The mask of Parameter ID LSB */
+
+static cy_en_smif_status_t qspi_read_register(uint32_t address, uint8_t *value);
+static cy_en_smif_status_t qspi_write_register(uint32_t address, uint8_t value);
+static cy_en_smif_status_t qspi_enter_4byte_addr_mode(void);
+static void value_to_byte_array(uint32_t value, uint8_t *byteArray,
+ uint32_t startPos, uint32_t size);
+
+/* Checks device and manufacturer ID. Expects ID buffer to be 6 byte length */
+bool qspi_is_semper_flash(uint8_t const id[], uint16_t length)
+{
+ bool isSemper = false;
+
+ if(id != NULL)
+ {
+ isSemper = true;
+
+ /* Check Manufacturer and Device ID if it is Semper flash */
+ if(id[length - 6u] != SEMPER_ID_MANUF)
+ {
+ isSemper = false;
+ }
+
+ if(isSemper && ((id[length - 5u] != SEMPER_ID_DEV_MSB1) &&
+ (id[length - 5u] != SEMPER_ID_DEV_MSB2)))
+ {
+ isSemper = false;
+ }
+
+ if(isSemper && ((id[length - 4u] != SEMPER_ID_DEV_LSB1) &&
+ (id[length - 4u] != SEMPER_ID_DEV_LSB2) &&
+ (id[length - 4u] != SEMPER_ID_DEV_LSB3)))
+ {
+ isSemper = false;
+ }
+
+ if(isSemper && (id[length - 3u] != SEMPER_ID_LEN))
+ {
+ isSemper = false;
+ }
+
+ if(isSemper && (id[length - 2u] != SEMPER_ID_SECTARCH))
+ {
+ isSemper = false;
+ }
+
+ if(isSemper && (id[length - 1u] != SEMPER_ID_FAMILY))
+ {
+ isSemper = false;
+ }
+ }
+
+ return isSemper;
+}
+
+cy_en_smif_status_t qspi_configure_semper_flash(void)
+{
+ cy_en_smif_status_t status;
+ uint8_t regVal;
+ cy_stc_smif_mem_config_t *memCfg;
+
+ status = qspi_enter_4byte_addr_mode();
+
+ if(CY_SMIF_SUCCESS == status)
+ {
+ /* Set Address Byte Length selection to 4 bytes for instructions */
+ status = qspi_read_register(SEMPER_CFR2N_ADDR, ®Val);
+ if((CY_SMIF_SUCCESS == status) &&
+ ((regVal & SEMPER_CFR2N_ADRBYT) == 0U))
+ {
+ regVal |= SEMPER_CFR2N_ADRBYT;
+ status = qspi_write_register(SEMPER_CFR2N_ADDR, regVal);
+ }
+
+ /* Enable Uniform Sector Architecture selection */
+ if(CY_SMIF_SUCCESS == status)
+ {
+ status = qspi_read_register(SEMPER_CFR3N_ADDR, ®Val);
+ if((CY_SMIF_SUCCESS == status) &&
+ ((regVal & SEMPER_CFR3N_UNHYSA) == 0U))
+ {
+ regVal |= SEMPER_CFR3N_UNHYSA;
+ status = qspi_write_register(SEMPER_CFR3N_ADDR, regVal);
+ }
+ }
+
+ if(CY_SMIF_SUCCESS == status)
+ {
+ memCfg = qspi_get_memory_config(0);
+ memCfg->deviceCfg->eraseSize = SEMPER_ERASE_SIZE;
+ memCfg->deviceCfg->eraseCmd->command = SEMPER_ER256_CMD;
+ memCfg->deviceCfg->eraseTime = SEMPER_ERASE_256KB_TIME;
+ }
+ }
+
+ return status;
+}
+
+/* Read 6 bytes of Manufacturer and Device ID */
+cy_en_smif_status_t qspi_read_memory_id(uint8_t *id, uint16_t length)
+{
+ cy_en_smif_status_t status;
+ cy_stc_smif_mem_config_t *memCfg;
+ SMIF_Type *QSPIPort;
+ cy_stc_smif_context_t *QSPI_context;
+ uint16_t dummyCycles = 64u;
+
+ memCfg = qspi_get_memory_config(0);
+ QSPIPort = qspi_get_device();
+ QSPI_context = qspi_get_context();
+
+ status = Cy_SMIF_TransmitCommand(QSPIPort,
+ SEMPER_RDIDN_CMD,
+ CY_SMIF_WIDTH_SINGLE,
+ NULL,
+ 0u,
+ CY_SMIF_WIDTH_SINGLE,
+ memCfg->slaveSelect,
+ CY_SMIF_TX_NOT_LAST_BYTE,
+ QSPI_context);
+
+ if(CY_SMIF_SUCCESS == status)
+ {
+ status = Cy_SMIF_SendDummyCycles(QSPIPort, dummyCycles);
+ }
+
+ if(CY_SMIF_SUCCESS == status)
+ {
+ status = Cy_SMIF_ReceiveDataBlocking(QSPIPort, id, length,
+ CY_SMIF_WIDTH_SINGLE,
+ QSPI_context);
+ }
+
+ return status;
+}
+
+static cy_en_smif_status_t qspi_read_register(uint32_t address, uint8_t *value)
+{
+ cy_en_smif_status_t status;
+ cy_stc_smif_mem_config_t *memCfg;
+ SMIF_Type *QSPIPort;
+ cy_stc_smif_context_t *QSPI_context;
+ uint8_t addressArray[SEMPER_ADDR_LEN];
+ uint16_t dummyCycles = 8u;
+
+ value_to_byte_array(address, addressArray, 0u, sizeof(addressArray));
+
+ memCfg = qspi_get_memory_config(0);
+ QSPIPort = qspi_get_device();
+ QSPI_context = qspi_get_context();
+
+ status = Cy_SMIF_TransmitCommand(QSPIPort,
+ SEMPER_RDARG_CMD,
+ CY_SMIF_WIDTH_SINGLE,
+ addressArray,
+ sizeof(addressArray),
+ CY_SMIF_WIDTH_SINGLE,
+ memCfg->slaveSelect,
+ CY_SMIF_TX_NOT_LAST_BYTE,
+ QSPI_context);
+
+ if(CY_SMIF_SUCCESS == status)
+ {
+ status = Cy_SMIF_SendDummyCycles(QSPIPort, dummyCycles);
+ }
+
+ if(CY_SMIF_SUCCESS == status)
+ {
+ status = Cy_SMIF_ReceiveDataBlocking(QSPIPort, value,
+ CY_SMIF_READ_ONE_BYTE, CY_SMIF_WIDTH_SINGLE, QSPI_context);
+ }
+
+ return status;
+}
+
+static cy_en_smif_status_t qspi_write_register(uint32_t address, uint8_t value)
+{
+ cy_en_smif_status_t status;
+ cy_stc_smif_mem_config_t *memCfg;
+ SMIF_Type *QSPIPort;
+ cy_stc_smif_context_t *QSPI_context;
+ uint8_t data[SEMPER_ADDR_LEN + 1u];
+
+ value_to_byte_array(address, data, 0u, SEMPER_ADDR_LEN);
+
+ data[SEMPER_WRARG_DATA_INDEX] = value;
+
+ memCfg = qspi_get_memory_config(0);
+ QSPIPort = qspi_get_device();
+ QSPI_context = qspi_get_context();
+
+ status = Cy_SMIF_MemCmdWriteEnable(QSPIPort, memCfg, QSPI_context);
+
+ if(CY_SMIF_SUCCESS == status)
+ {
+ status = Cy_SMIF_TransmitCommand(QSPIPort, SEMPER_WRARG_CMD,
+ CY_SMIF_WIDTH_SINGLE,
+ data, sizeof(data),
+ CY_SMIF_WIDTH_SINGLE,
+ memCfg->slaveSelect,
+ CY_SMIF_TX_LAST_BYTE,
+ QSPI_context);
+ }
+
+ if(CY_SMIF_SUCCESS == status)
+ {
+ status = Cy_SMIF_MemIsReady(QSPIPort, memCfg, SEMPER_WR_NV_TIMEOUT,
+ QSPI_context);
+ }
+
+ return status;
+}
+
+static cy_en_smif_status_t qspi_enter_4byte_addr_mode(void)
+{
+ cy_en_smif_status_t status;
+ cy_stc_smif_mem_config_t *memCfg;
+ SMIF_Type *QSPIPort;
+ cy_stc_smif_context_t *QSPI_context;
+
+ memCfg = qspi_get_memory_config(0);
+ QSPIPort = qspi_get_device();
+ QSPI_context = qspi_get_context();
+
+ status = Cy_SMIF_TransmitCommand(QSPIPort, SEMPER_EN4BA_CMD,
+ CY_SMIF_WIDTH_SINGLE,
+ NULL,
+ CY_SMIF_CMD_WITHOUT_PARAM,
+ CY_SMIF_WIDTH_SINGLE,
+ memCfg->slaveSelect,
+ CY_SMIF_TX_LAST_BYTE,
+ QSPI_context);
+
+ return status;
+}
+
+static void value_to_byte_array(uint32_t value, uint8_t *byteArray, uint32_t startPos, uint32_t size)
+{
+ do
+ {
+ size--;
+ byteArray[size + startPos] = (uint8_t)(value & PARAM_ID_LSB_MASK);
+ value >>= PARAM_ID_MSB_OFFSET; /* Shift to get the next byte */
+ } while (size > 0U);
+}
diff --git a/boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h b/boot/cypress/cy_flash_pal/flash_cyw208xx/flash_qspi/cy_smif_hybrid_sect.h
similarity index 78%
copy from boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h
copy to boot/cypress/cy_flash_pal/flash_cyw208xx/flash_qspi/cy_smif_hybrid_sect.h
index fe1150d..7e44118 100644
--- a/boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/flash_qspi/cy_smif_hybrid_sect.h
@@ -1,14 +1,14 @@
-/***************************************************************************//**
-* \file cy_smif_psoc6.h
+/*******************************************************************************
+* \file cy_smif_hybrid_sect.h
* \version 1.0
*
* \brief
-* This is the header file for PSoC6 SMIF driver adoption layer.
+* This is the header file for Semper external flash driver.
*
********************************************************************************
* \copyright
*
-* © 2019, Cypress Semiconductor Corporation
+* © 2020, Cypress Semiconductor Corporation
* or a subsidiary of Cypress Semiconductor Corporation. All rights
* reserved.
*
@@ -45,20 +45,13 @@
*
******************************************************************************/
-#ifndef CY_SMIF_PSOC6_H_
-#define CY_SMIF_PSOC6_H_
+#ifndef CY_SMIF_HYBRID_SECT_H
+#define CY_SMIF_HYBRID_SECT_H
-#include "stddef.h"
-#include "stdbool.h"
+#define EXT_MEMORY_ID_LENGTH (6U)
-#include "flash_qspi.h"
+bool qspi_is_semper_flash(uint8_t const id[], uint16_t length);
+cy_en_smif_status_t qspi_configure_semper_flash(void);
+cy_en_smif_status_t qspi_read_memory_id(uint8_t *id, uint16_t length);
-#ifndef off_t
-typedef long int off_t;
#endif
-
-int psoc6_smif_read(const struct flash_area *fap, off_t addr, void *data, size_t len);
-int psoc6_smif_write(const struct flash_area *fap, off_t addr, const void *data, size_t len);
-int psoc6_smif_erase(off_t addr, size_t size);
-
-#endif /* CY_SMIF_PSOC6_H_ */
diff --git a/boot/cypress/cy_flash_pal/flash_cyw208xx/flash_qspi/flash_qspi.c b/boot/cypress/cy_flash_pal/flash_cyw208xx/flash_qspi/flash_qspi.c
new file mode 100644
index 0000000..4bb8391
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/flash_qspi/flash_qspi.c
@@ -0,0 +1,634 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * 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.
+ */
+/*******************************************************************************
+* \file flash_qspi.c
+* \version 1.0
+*
+* \brief
+* This is the source file of external flash driver adaptation layer between pdl
+* and standard MCUBoot code.
+*
+********************************************************************************
+* \copyright
+*
+* (c) 2020, Cypress Semiconductor Corporation
+* or a subsidiary of Cypress Semiconductor Corporation. All rights
+* reserved.
+*
+* This software, including source code, documentation and related
+* materials ("Software"), is owned by Cypress Semiconductor
+* Corporation or one of its subsidiaries ("Cypress") and is protected by
+* and subject to worldwide patent protection (United States and foreign),
+* United States copyright laws and international treaty provisions.
+* Therefore, you may use this Software only as provided in the license
+* agreement accompanying the software package from which you
+* obtained this Software ("EULA").
+*
+* If no EULA applies, Cypress hereby grants you a personal, non-
+* exclusive, non-transferable license to copy, modify, and compile the
+* Software source code solely for use in connection with Cypress?s
+* integrated circuit products. Any reproduction, modification, translation,
+* compilation, or representation of this Software except as specified
+* above is prohibited without the express written permission of Cypress.
+*
+* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO
+* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING,
+* BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE. Cypress reserves the right to make
+* changes to the Software without notice. Cypress does not assume any
+* liability arising out of the application or use of the Software or any
+* product or circuit described in the Software. Cypress does not
+* authorize its products for use in any products where a malfunction or
+* failure of the Cypress product may reasonably be expected to result in
+* significant property damage, injury or death ("High Risk Product"). By
+* including Cypress's product in a High Risk Product, the manufacturer
+* of such system or application assumes all risk of such use and in doing
+* so agrees to indemnify Cypress against all liability.
+*
+******************************************************************************/
+#include <stdio.h>
+
+#include "cy_sysclk.h"
+#include "cy_gpio.h"
+#include "cy_gpio.h"
+#include "cy_smif.h"
+
+#include "flash_qspi.h"
+#include "cy_smif_hybrid_sect.h"
+
+#define CY_SMIF_SYSCLK_HFCLK_DIVIDER CY_SYSCLK_CLKHF_DIVIDE_BY_4
+
+#define CY_SMIF_INIT_TRY_COUNT (10U)
+#define CY_SMIF_INIT_TRY_DELAY (500U)
+
+/* This is the board specific stuff that should align with your board.
+ *
+ * QSPI resources:
+ *
+ * SS0 - P11_2
+ * SS1 - P11_1
+ * SS2 - P11_0
+ * SS3 - P12_4
+ *
+ * D3 - P11_3
+ * D2 - P11_4
+ * D1 - P11_5
+ * D0 - P11_6
+ *
+ * SCK - P11_7
+ *
+ * SMIF Block - SMIF0
+ *
+ */
+
+/* HSIOM values for SMIF pins */
+#define CYBOOT_SMIF_SPI_CLOCK_HSIOM (P2_5_SMIF_SPIHB_CLK)
+#define CYBOOT_SMIF_SS0_HSIOM (P2_0_SMIF_SPIHB_SELECT0)
+#define CYBOOT_SMIF_SS1_HSIOM (P0_5_SMIF_SPIHB_SELECT1)
+#define CYBOOT_SMIF_DATA0_HSIOM (P2_4_SMIF_SPIHB_DATA0)
+#define CYBOOT_SMIF_DATA1_HSIOM (P2_3_SMIF_SPIHB_DATA1)
+#define CYBOOT_SMIF_DATA2_HSIOM (P2_2_SMIF_SPIHB_DATA2)
+#define CYBOOT_SMIF_DATA3_HSIOM (P2_1_SMIF_SPIHB_DATA3)
+
+/* SMIF ports and pins */
+#define CYBOOT_SMIF_SPI_CLOCK_PORT (GPIO_PRT2)
+#define CYBOOT_SMIF_SPI_CLOCK_PIN (5U)
+#define CYBOOT_SMIF_SS0_PORT (GPIO_PRT2)
+#define CYBOOT_SMIF_SS0_PIN (0U)
+#define CYBOOT_SMIF_SS1_PORT (GPIO_PRT0)
+#define CYBOOT_SMIF_SS1_PIN (5U)
+#define CYBOOT_SMIF_DATA0_PORT (GPIO_PRT2)
+#define CYBOOT_SMIF_DATA0_PIN (4U)
+#define CYBOOT_SMIF_DATA1_PORT (GPIO_PRT2)
+#define CYBOOT_SMIF_DATA1_PIN (3U)
+#define CYBOOT_SMIF_DATA2_PORT (GPIO_PRT2)
+#define CYBOOT_SMIF_DATA2_PIN (2U)
+#define CYBOOT_SMIF_DATA3_PORT (GPIO_PRT2)
+#define CYBOOT_SMIF_DATA3_PIN (1U)
+
+/* SMIF SlaveSelect Configurations */
+struct qspi_ss_config
+{
+ GPIO_PRT_Type* SS_Port;
+ uint32_t SS_Pin;
+ en_hsiom_sel_t SS_Mux;
+};
+
+#if (defined(PSOC_064_2M) || \
+ defined(PSOC_064_1M) || \
+ defined(PSOC_062_2M))
+ #define CY_BOOTLOADER_SMIF_SS_CFG_NUM 4
+#elif defined(PSOC_064_512K)
+ #define CY_BOOTLOADER_SMIF_SS_CFG_NUM 3
+#elif defined(CYW20829)
+ #define CY_BOOTLOADER_SMIF_SS_CFG_NUM 2
+#else
+#error "Platform device name is unsupported."
+#endif
+
+static cy_stc_smif_context_t QSPI_context;
+
+static cy_stc_smif_block_config_t *smif_blk_config;
+
+#ifndef CYW20829
+static struct qspi_ss_config qspi_SS_Configuration[CY_BOOTLOADER_SMIF_SS_CFG_NUM] =
+{
+ {
+ .SS_Port = GPIO_PRT11,
+ .SS_Pin = 2U,
+ .SS_Mux = P11_2_SMIF_SPI_SELECT0
+ },
+ {
+ .SS_Port = GPIO_PRT11,
+ .SS_Pin = 1U,
+ .SS_Mux = P11_1_SMIF_SPI_SELECT1
+ },
+#if(CY_BOOTLOADER_SMIF_SS_CFG_NUM > 2)
+ {
+ .SS_Port = GPIO_PRT11,
+ .SS_Pin = 0U,
+ .SS_Mux = P11_0_SMIF_SPI_SELECT2
+ },
+#endif
+#if(CY_BOOTLOADER_SMIF_SS_CFG_NUM > 3)
+ {
+ .SS_Port = GPIO_PRT12,
+ .SS_Pin = 4U,
+ .SS_Mux = P12_4_SMIF_SPI_SELECT3
+ }
+#endif
+};
+
+static GPIO_PRT_Type *D3Port = GPIO_PRT11;
+static uint32_t D3Pin = 3U;
+static en_hsiom_sel_t D3MuxPort = P11_3_SMIF_SPI_DATA3;
+
+static GPIO_PRT_Type *D2Port = GPIO_PRT11;
+static uint32_t D2Pin = 4U;
+static en_hsiom_sel_t D2MuxPort = P11_4_SMIF_SPI_DATA2;
+
+static GPIO_PRT_Type *D1Port = GPIO_PRT11;
+static uint32_t D1Pin = 5U;
+static en_hsiom_sel_t D1MuxPort = P11_5_SMIF_SPI_DATA1;
+
+static GPIO_PRT_Type *D0Port = GPIO_PRT11;
+static uint32_t D0Pin = 6U;
+static en_hsiom_sel_t D0MuxPort = P11_6_SMIF_SPI_DATA0;
+
+static GPIO_PRT_Type *SCKPort = GPIO_PRT11;
+static uint32_t SCKPin = 7U;
+static en_hsiom_sel_t SCKMuxPort = P11_7_SMIF_SPI_CLK;
+
+#else
+
+static struct qspi_ss_config qspi_SS_Configuration[CY_BOOTLOADER_SMIF_SS_CFG_NUM] =
+{
+ {
+ .SS_Port = GPIO_PRT2,
+ .SS_Pin = 0U,
+ .SS_Mux = P2_0_SMIF_SPIHB_SELECT0
+ },
+ {
+ .SS_Port = GPIO_PRT0,
+ .SS_Pin = 5U,
+ .SS_Mux = P0_5_SMIF_SPIHB_SELECT1
+ }
+};
+
+static GPIO_PRT_Type *D3Port = GPIO_PRT2;
+static uint32_t D3Pin = 1U;
+static en_hsiom_sel_t D3MuxPort = P2_1_SMIF_SPIHB_DATA3;
+
+static GPIO_PRT_Type *D2Port = GPIO_PRT2;
+static uint32_t D2Pin = 2U;
+static en_hsiom_sel_t D2MuxPort = P2_2_SMIF_SPIHB_DATA2;
+
+static GPIO_PRT_Type *D1Port = GPIO_PRT2;
+static uint32_t D1Pin = 3U;
+static en_hsiom_sel_t D1MuxPort = P2_3_SMIF_SPIHB_DATA1;
+
+static GPIO_PRT_Type *D0Port = GPIO_PRT2;
+static uint32_t D0Pin = 4U;
+static en_hsiom_sel_t D0MuxPort = P2_4_SMIF_SPIHB_DATA0;
+
+static GPIO_PRT_Type *SCKPort = GPIO_PRT2;
+static uint32_t SCKPin = 5U;
+static en_hsiom_sel_t SCKMuxPort = P2_5_SMIF_SPIHB_CLK;
+#endif
+
+static GPIO_PRT_Type *SS_Port;
+static uint32_t SS_Pin;
+static en_hsiom_sel_t SS_MuxPort;
+
+static SMIF_Type *QSPIPort = SMIF0;
+
+static cy_stc_smif_mem_cmd_t sfdpcmd =
+{
+ .command = 0x5A,
+ .cmdWidth = CY_SMIF_WIDTH_SINGLE,
+ .addrWidth = CY_SMIF_WIDTH_SINGLE,
+ .mode = 0xFFFFFFFFU,
+ .dummyCycles = 8,
+ .dataWidth = CY_SMIF_WIDTH_SINGLE,
+};
+
+static cy_stc_smif_mem_cmd_t rdcmd0;
+static cy_stc_smif_mem_cmd_t wrencmd0;
+static cy_stc_smif_mem_cmd_t wrdiscmd0;
+static cy_stc_smif_mem_cmd_t erasecmd0;
+static cy_stc_smif_mem_cmd_t chiperasecmd0;
+static cy_stc_smif_mem_cmd_t pgmcmd0;
+static cy_stc_smif_mem_cmd_t readsts0;
+static cy_stc_smif_mem_cmd_t readstsqecmd0;
+static cy_stc_smif_mem_cmd_t writestseqcmd0;
+
+static cy_stc_smif_mem_device_cfg_t dev_sfdp_0 =
+{
+ .numOfAddrBytes = 4,
+ .readSfdpCmd = &sfdpcmd,
+ .readCmd = &rdcmd0,
+ .writeEnCmd = &wrencmd0,
+ .writeDisCmd = &wrdiscmd0,
+ .programCmd = &pgmcmd0,
+ .eraseCmd = &erasecmd0,
+ .chipEraseCmd = &chiperasecmd0,
+ .readStsRegWipCmd = &readsts0,
+ .readStsRegQeCmd = &readstsqecmd0,
+ .writeStsRegQeCmd = &writestseqcmd0,
+};
+
+static cy_stc_smif_mem_config_t mem_sfdp_0 =
+{
+ /* The base address the memory slave is mapped to in the PSoC memory map.
+ Valid when the memory-mapped mode is enabled. */
+ .baseAddress = CY_XIP_BASE,
+ /* The size allocated in the PSoC memory map, for the memory slave device.
+ The size is allocated from the base address. Valid when the memory mapped mode is enabled. */
+/* .memMappedSize = 0x4000000U, */
+ .flags = CY_SMIF_FLAG_DETECT_SFDP,
+ .slaveSelect = CY_SMIF_SLAVE_SELECT_0,
+ .dataSelect = CY_SMIF_DATA_SEL0,
+ .deviceCfg = &dev_sfdp_0
+};
+
+static cy_stc_smif_mem_config_t *mems_sfdp[1] =
+{
+ &mem_sfdp_0
+};
+
+static cy_stc_smif_block_config_t smifBlockConfig_sfdp =
+{
+ .memCount = 1,
+ .memConfig = mems_sfdp,
+};
+
+static cy_stc_smif_config_t const QSPI_config =
+{
+ .mode = (uint32_t)CY_SMIF_NORMAL,
+ .deselectDelay = 1,
+#ifdef CYW20829
+ .rxClockSel = (uint32_t)CY_SMIF_SEL_INVERTED_FEEDBACK_CLK,
+#else
+ .rxClockSel = (uint32_t)CY_SMIF_SEL_INV_INTERNAL_CLK,
+#endif
+ .blockEvent = (uint32_t)CY_SMIF_BUS_ERROR
+};
+
+/* SMIF pinouts configurations */
+static cy_stc_gpio_pin_config_t QSPI_SS_config =
+{
+ .outVal = 1,
+ .driveMode = CY_GPIO_DM_STRONG_IN_OFF,
+ .hsiom = P2_0_SMIF_SPIHB_SELECT0, /* lets use SS0 by default */
+ .intEdge = CY_GPIO_INTR_DISABLE,
+ .intMask = 0UL,
+ .vtrip = CY_GPIO_VTRIP_CMOS,
+ .slewRate = CY_GPIO_SLEW_FAST,
+ .driveSel = CY_GPIO_DRIVE_1_2,
+ .vregEn = 0UL,
+ .ibufMode = 0UL,
+ .vtripSel = 0UL,
+ .vrefSel = 0UL,
+ .vohSel = 0UL,
+};
+static const cy_stc_gpio_pin_config_t QSPI_DATA3_config =
+{
+ .outVal = 1,
+ .driveMode = CY_GPIO_DM_STRONG,
+ .hsiom = P2_1_SMIF_SPIHB_DATA3,
+ .intEdge = CY_GPIO_INTR_DISABLE,
+ .intMask = 0UL,
+ .vtrip = CY_GPIO_VTRIP_CMOS,
+ .slewRate = CY_GPIO_SLEW_FAST,
+ .driveSel = CY_GPIO_DRIVE_1_2,
+ .vregEn = 0UL,
+ .ibufMode = 0UL,
+ .vtripSel = 0UL,
+ .vrefSel = 0UL,
+ .vohSel = 0UL,
+};
+static const cy_stc_gpio_pin_config_t QSPI_DATA2_config =
+{
+ .outVal = 1,
+ .driveMode = CY_GPIO_DM_STRONG,
+ .hsiom = P2_2_SMIF_SPIHB_DATA2,
+ .intEdge = CY_GPIO_INTR_DISABLE,
+ .intMask = 0UL,
+ .vtrip = CY_GPIO_VTRIP_CMOS,
+ .slewRate = CY_GPIO_SLEW_FAST,
+ .driveSel = CY_GPIO_DRIVE_1_2,
+ .vregEn = 0UL,
+ .ibufMode = 0UL,
+ .vtripSel = 0UL,
+ .vrefSel = 0UL,
+ .vohSel = 0UL,
+};
+static const cy_stc_gpio_pin_config_t QSPI_DATA1_config =
+{
+ .outVal = 1,
+ .driveMode = CY_GPIO_DM_STRONG,
+ .hsiom = P2_3_SMIF_SPIHB_DATA1,
+ .intEdge = CY_GPIO_INTR_DISABLE,
+ .intMask = 0UL,
+ .vtrip = CY_GPIO_VTRIP_CMOS,
+ .slewRate = CY_GPIO_SLEW_FAST,
+ .driveSel = CY_GPIO_DRIVE_1_2,
+ .vregEn = 0UL,
+ .ibufMode = 0UL,
+ .vtripSel = 0UL,
+ .vrefSel = 0UL,
+ .vohSel = 0UL,
+};
+static const cy_stc_gpio_pin_config_t QSPI_DATA0_config =
+{
+ .outVal = 1,
+ .driveMode = CY_GPIO_DM_STRONG,
+ .hsiom = P2_4_SMIF_SPIHB_DATA0,
+ .intEdge = CY_GPIO_INTR_DISABLE,
+ .intMask = 0UL,
+ .vtrip = CY_GPIO_VTRIP_CMOS,
+ .slewRate = CY_GPIO_SLEW_FAST,
+ .driveSel = CY_GPIO_DRIVE_1_2,
+ .vregEn = 0UL,
+ .ibufMode = 0UL,
+ .vtripSel = 0UL,
+ .vrefSel = 0UL,
+ .vohSel = 0UL,
+};
+static const cy_stc_gpio_pin_config_t QSPI_SCK_config =
+{
+ .outVal = 1,
+ .driveMode = CY_GPIO_DM_STRONG,
+ .hsiom = P2_5_SMIF_SPIHB_CLK,
+ .intEdge = CY_GPIO_INTR_DISABLE,
+ .intMask = 0UL,
+ .vtrip = CY_GPIO_VTRIP_CMOS,
+ .slewRate = CY_GPIO_SLEW_FAST,
+ .driveSel = CY_GPIO_DRIVE_1_2,
+ .vregEn = 0UL,
+ .ibufMode = 0UL,
+ .vtripSel = 0UL,
+ .vrefSel = 0UL,
+ .vohSel = 0UL,
+};
+
+static bool qspiInitiallyEnabled = false;
+static int32_t qspiReservations = EXT_FLASH_DEV_FAILED;
+
+static void qspi_get_initial_status(void)
+{
+ qspiInitiallyEnabled = (SMIF_CTL(QSPIPort) & SMIF_CTL_ENABLED_Msk) != 0u;
+}
+
+static bool qspi_is_configured(void)
+{
+ return qspiInitiallyEnabled;
+}
+
+cy_en_smif_status_t qspi_init_hardware(void)
+{
+ cy_en_smif_status_t st;
+
+ qspi_get_initial_status();
+
+ if (!qspi_is_configured()) {
+ (void)Cy_GPIO_Pin_Init(D3Port, D3Pin, &QSPI_DATA3_config);
+ Cy_GPIO_SetHSIOM(D3Port, D3Pin, D3MuxPort);
+
+ (void)Cy_GPIO_Pin_Init(D2Port, D2Pin, &QSPI_DATA2_config);
+ Cy_GPIO_SetHSIOM(D2Port, D2Pin, D2MuxPort);
+
+ (void)Cy_GPIO_Pin_Init(D1Port, D1Pin, &QSPI_DATA1_config);
+ Cy_GPIO_SetHSIOM(D1Port, D1Pin, D1MuxPort);
+
+ (void)Cy_GPIO_Pin_Init(D0Port, D0Pin, &QSPI_DATA0_config);
+ Cy_GPIO_SetHSIOM(D0Port, D0Pin, D0MuxPort);
+
+ (void)Cy_GPIO_Pin_Init(SCKPort, SCKPin, &QSPI_SCK_config);
+ Cy_GPIO_SetHSIOM(SCKPort, SCKPin, SCKMuxPort);
+
+ (void)Cy_GPIO_Pin_Init(SS_Port, SS_Pin, &QSPI_SS_config);
+ Cy_GPIO_SetHSIOM(SS_Port, SS_Pin, SS_MuxPort);
+
+ (void)Cy_SysClk_ClkHfSetSource((uint32_t)CY_SYSCLK_CLKHF_IN_CLKPATH2, CY_SYSCLK_CLKHF_IN_CLKPATH0);
+ (void)Cy_SysClk_ClkHfSetDivider((uint32_t)CY_SYSCLK_CLKHF_IN_CLKPATH2, CY_SMIF_SYSCLK_HFCLK_DIVIDER);
+ (void)Cy_SysClk_ClkHfEnable((uint32_t)CY_SYSCLK_CLKHF_IN_CLKPATH2);
+
+ st = Cy_SMIF_Init(QSPIPort, &QSPI_config, 1000, &QSPI_context);
+ if (st != CY_SMIF_SUCCESS) {
+ return st;
+ }
+ }
+ qspiReservations = EXT_FLASH_DEV_DISABLED;
+
+ return CY_SMIF_SUCCESS;
+}
+
+void qspi_enable(void)
+{
+ if (EXT_FLASH_DEV_FAILED != qspiReservations) {
+ if (EXT_FLASH_DEV_DISABLED == qspiReservations) {
+ /*
+ * Setup the interrupt for the SMIF block. For the CM33 there
+ * is a two stage process to setup the interrupts.
+ */
+ if (!qspi_is_configured()) {
+ Cy_SMIF_Enable(QSPIPort, &QSPI_context);
+ }
+ }
+ qspiReservations++;
+ }
+}
+
+#if defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP)
+CY_RAMFUNC_BEGIN /* SMIF is deinitialized inside! */
+#endif /* defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) */
+void qspi_disable(void)
+{
+ if (EXT_FLASH_DEV_FAILED != qspiReservations) {
+ if (qspiReservations > EXT_FLASH_DEV_DISABLED) {
+ qspiReservations--;
+ if (EXT_FLASH_DEV_DISABLED == qspiReservations) {
+ if (!qspi_is_configured()) {
+ Cy_SMIF_Disable(QSPIPort);
+ }
+ }
+ }
+ }
+}
+#if defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP)
+CY_RAMFUNC_END /* SMIF will be deinitialized in this case! */
+#endif /* defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) */
+
+cy_stc_smif_mem_config_t *qspi_get_memory_config(uint8_t index)
+{
+ return smif_blk_config->memConfig[index];
+}
+
+SMIF_Type *qspi_get_device(void)
+{
+ return QSPIPort;
+}
+
+cy_stc_smif_context_t *qspi_get_context(void)
+{
+ return &QSPI_context;
+}
+
+cy_en_smif_status_t qspi_init(cy_stc_smif_block_config_t *blk_config)
+{
+ cy_en_smif_status_t st;
+ uint8_t devIdBuff[EXT_MEMORY_ID_LENGTH];
+
+ st = qspi_init_hardware();
+ if (st == CY_SMIF_SUCCESS) {
+ qspi_enable();
+
+ smif_blk_config = blk_config;
+ st = Cy_SMIF_MemInit(QSPIPort, smif_blk_config, &QSPI_context);
+
+ if(st == CY_SMIF_SUCCESS) {
+ st = qspi_read_memory_id(devIdBuff, EXT_MEMORY_ID_LENGTH);
+ }
+
+ if(st == CY_SMIF_SUCCESS) {
+ if(qspi_is_semper_flash(devIdBuff, EXT_MEMORY_ID_LENGTH) == true) {
+ st = qspi_configure_semper_flash();
+ }
+ }
+
+ qspi_disable();
+ }
+
+ if(st != CY_SMIF_SUCCESS) {
+ qspiReservations = EXT_FLASH_DEV_FAILED;
+ }
+ return st;
+}
+
+#if defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP)
+CY_RAMFUNC_BEGIN /* SMIF is deinitialized inside! */
+#endif /* defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) */
+void qspi_deinit(uint32_t smif_id)
+{
+ qspiReservations = EXT_FLASH_DEV_DISABLED + 1;
+
+ qspi_disable();
+
+ if (!qspi_is_configured()) {
+ Cy_SMIF_MemDeInit(QSPIPort);
+
+ (void)Cy_SysClk_ClkHfDisable((uint32_t)CY_SYSCLK_CLKHF_IN_CLKPATH1);
+
+ Cy_GPIO_Port_Deinit(qspi_SS_Configuration[smif_id-1U].SS_Port);
+ Cy_GPIO_Port_Deinit(SCKPort);
+ Cy_GPIO_Port_Deinit(D0Port);
+ Cy_GPIO_Port_Deinit(D1Port);
+ Cy_GPIO_Port_Deinit(D2Port);
+ Cy_GPIO_Port_Deinit(D3Port);
+ }
+}
+#if defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP)
+CY_RAMFUNC_END /* SMIF will be deinitialized in this case! */
+#endif /* defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) */
+
+cy_en_smif_status_t qspi_init_sfdp(uint32_t smif_id)
+{
+ cy_en_smif_status_t stat = CY_SMIF_SUCCESS;
+
+ cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig;
+
+
+ switch(smif_id) {
+ case 1:
+ (*memCfg)->slaveSelect = CY_SMIF_SLAVE_SELECT_0;
+ break;
+ case 2:
+ (*memCfg)->slaveSelect = CY_SMIF_SLAVE_SELECT_1;
+ break;
+ default:
+ stat = CY_SMIF_BAD_PARAM;
+ break;
+ }
+
+ if(CY_SMIF_SUCCESS == stat) {
+ SS_Port = qspi_SS_Configuration[smif_id-1U].SS_Port;
+ SS_Pin = qspi_SS_Configuration[smif_id-1U].SS_Pin;
+ SS_MuxPort = qspi_SS_Configuration[smif_id-1U].SS_Mux;
+
+ QSPI_SS_config.hsiom = SS_MuxPort;
+
+
+ uint32_t try_count = CY_SMIF_INIT_TRY_COUNT;
+ do {
+ stat = qspi_init(&smifBlockConfig_sfdp);
+
+ try_count--;
+ if (stat != CY_SMIF_SUCCESS) {
+ Cy_SysLib_Delay(CY_SMIF_INIT_TRY_DELAY);
+ }
+ } while ((stat != CY_SMIF_SUCCESS) && (try_count > 0U));
+ }
+ return stat;
+}
+
+uint32_t qspi_get_prog_size(void)
+{
+ cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig;
+ return (*memCfg)->deviceCfg->programSize;
+}
+
+uint32_t qspi_get_erase_size(void)
+{
+ cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig;
+ return (*memCfg)->deviceCfg->eraseSize;
+}
+
+uint32_t qspi_get_mem_size(void)
+{
+ cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig;
+ return (*memCfg)->deviceCfg->memSize;
+}
+
+int32_t qspi_get_status(void)
+{
+ return qspiReservations;
+}
+
diff --git a/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.h b/boot/cypress/cy_flash_pal/flash_cyw208xx/flash_qspi/flash_qspi.h
similarity index 87%
copy from boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.h
copy to boot/cypress/cy_flash_pal/flash_cyw208xx/flash_qspi/flash_qspi.h
index 80e0d51..e8c4953 100644
--- a/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.h
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/flash_qspi/flash_qspi.h
@@ -1,4 +1,4 @@
-/***************************************************************************//**
+/*******************************************************************************
* \file flash_qspi.h
* \version 1.0
*
@@ -44,27 +44,32 @@
* so agrees to indemnify Cypress against all liability.
*
******************************************************************************/
-#ifndef __FLASH_QSPI_H__
-#define __FLASH_QSPI_H__
+#ifndef FLASH_QSPI_H
+#define FLASH_QSPI_H
#include <stdint.h>
-#include "cy_pdl.h"
+#include "cy_sysint.h"
+#include "cy_smif.h"
+#include "cy_smif_memslot.h"
-/* make it exported if used in TOC (cy_serial_flash_prog.c) */
-/* cy_stc_smif_block_config_t smifBlockConfig_sfdp; */
+#define EXT_FLASH_DEV_DISABLED 0
+#define EXT_FLASH_DEV_FAILED -1
cy_en_smif_status_t qspi_init_sfdp(uint32_t smif_id);
cy_en_smif_status_t qspi_init(cy_stc_smif_block_config_t *blk_config);
cy_en_smif_status_t qspi_init_hardware(void);
+void qspi_deinit(uint32_t smif_id);
+
uint32_t qspi_get_prog_size(void);
uint32_t qspi_get_erase_size(void);
uint32_t qspi_get_mem_size(void);
+int32_t qspi_get_status(void);
+
+void qspi_enable(void);
+void qspi_disable(void);
SMIF_Type *qspi_get_device(void);
cy_stc_smif_context_t *qspi_get_context(void);
-cy_stc_smif_mem_config_t *qspi_get_memory_config(int index);
-void qspi_dump_device(cy_stc_smif_mem_device_cfg_t *dev);
+cy_stc_smif_mem_config_t *qspi_get_memory_config(uint8_t index);
-void qspi_deinit(uint32_t smif_id);
-
-#endif /* __FLASH_QSPI_H__ */
+#endif /* FLASH_QSPI_H */
diff --git a/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/cyw20829_xip_overwrite_multi2.json b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/cyw20829_xip_overwrite_multi2.json
new file mode 100644
index 0000000..8366917
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/cyw20829_xip_overwrite_multi2.json
@@ -0,0 +1,57 @@
+{
+ "external_flash": [
+ {
+ "model": "FM25W04",
+ "mode": "XIP"
+ }
+ ],
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x60000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x20000"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x60020000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x10000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x60040000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x10000"
+ }
+ },
+ "application_2": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x60030000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x10000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x60050000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x10000"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/cyw20829_xip_overwrite_single.json b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/cyw20829_xip_overwrite_single.json
new file mode 100644
index 0000000..8c98f08
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/cyw20829_xip_overwrite_single.json
@@ -0,0 +1,39 @@
+{
+ "external_flash": [
+ {
+ "model": "FM25W04",
+ "mode": "XIP"
+ }
+ ],
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x60000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x20000"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x60020000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x20000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x60040000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x20000"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/cyw20829_xip_swap_multi2.json b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/cyw20829_xip_swap_multi2.json
new file mode 100644
index 0000000..8031750
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/cyw20829_xip_swap_multi2.json
@@ -0,0 +1,73 @@
+{
+ "external_flash": [
+ {
+ "model": "FM25W04",
+ "mode": "XIP"
+ }
+ ],
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x60000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x20000"
+ },
+ "scratch_address": {
+ "description": "Address of the scratch area",
+ "value": "0x6007E000"
+ },
+ "scratch_size": {
+ "description": "Size of the scratch area",
+ "value": "0x2000"
+ },
+ "status_address": {
+ "description": "Address of the swap status partition",
+ "value": "0x60060000"
+ },
+ "status_size": {
+ "description": "Size of the swap status partition",
+ "value": "0x14000"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x60020000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x10000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x60040000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x10000"
+ }
+ },
+ "application_2": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x60030000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x10000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x60050000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x10000"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/cyw20829_xip_swap_single.json b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/cyw20829_xip_swap_single.json
new file mode 100644
index 0000000..3fb2ac2
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/cyw20829_xip_swap_single.json
@@ -0,0 +1,55 @@
+{
+ "external_flash": [
+ {
+ "model": "FM25W04",
+ "mode": "XIP"
+ }
+ ],
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x60000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x20000"
+ },
+ "scratch_address": {
+ "description": "Address of the scratch area",
+ "value": "0x6007E000"
+ },
+ "scratch_size": {
+ "description": "Size of the scratch area",
+ "value": "0x2000"
+ },
+ "status_address": {
+ "description": "Address of the swap status partition",
+ "value": "0x60060000"
+ },
+ "status_size": {
+ "description": "Size of the swap status partition",
+ "value": "0xC000"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x60020000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x20000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x60040000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x20000"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot/cyw20829_xip_overwrite_multi2.json b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot/cyw20829_xip_overwrite_multi2.json
new file mode 100644
index 0000000..b8f0835
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot/cyw20829_xip_overwrite_multi2.json
@@ -0,0 +1,83 @@
+{
+ "external_flash": [
+ {
+ "model": "FM25W04",
+ "mode": "XIP"
+ }
+ ],
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x60000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x20000"
+ }
+ },
+ "service_app": {
+ "address": {
+ "description": "Address of the service application",
+ "value": "0x60070000"
+ },
+ "size": {
+ "description": "Size of the service application",
+ "value": "0x8000"
+ },
+ "params_address": {
+ "description": "Address of the service application input parameters",
+ "value": "0x60078000"
+ },
+ "params_size": {
+ "description": "Size of the service application input parameters",
+ "value": "0x400"
+ },
+ "desc_address": {
+ "description": "Address of the service application descriptor",
+ "value": "0x60078400"
+ },
+ "desc_size": {
+ "description": "Size of the service application descriptor",
+ "value": "0x20"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x60020000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x10000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x60040000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x10000"
+ }
+ },
+ "application_2": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x60030000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x10000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x60050000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x10000"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot/cyw20829_xip_overwrite_single.json b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot/cyw20829_xip_overwrite_single.json
new file mode 100644
index 0000000..d46066d
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot/cyw20829_xip_overwrite_single.json
@@ -0,0 +1,65 @@
+{
+ "external_flash": [
+ {
+ "model": "FM25W04",
+ "mode": "XIP"
+ }
+ ],
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x60000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x20000"
+ }
+ },
+ "service_app": {
+ "address": {
+ "description": "Address of the service application",
+ "value": "0x60070000"
+ },
+ "size": {
+ "description": "Size of the service application",
+ "value": "0x8000"
+ },
+ "params_address": {
+ "description": "Address of the service application input parameters",
+ "value": "0x60078000"
+ },
+ "params_size": {
+ "description": "Size of the service application input parameters",
+ "value": "0x400"
+ },
+ "desc_address": {
+ "description": "Address of the service application descriptor",
+ "value": "0x60078400"
+ },
+ "desc_size": {
+ "description": "Size of the service application descriptor",
+ "value": "0x20"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x60020000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x20000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x60040000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x20000"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot/cyw20829_xip_swap_multi2.json b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot/cyw20829_xip_swap_multi2.json
new file mode 100644
index 0000000..242f7cc
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot/cyw20829_xip_swap_multi2.json
@@ -0,0 +1,99 @@
+{
+ "external_flash": [
+ {
+ "model": "FM25W04",
+ "mode": "XIP"
+ }
+ ],
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x60000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x20000"
+ },
+ "scratch_address": {
+ "description": "Address of the scratch area",
+ "value": "0x6007E000"
+ },
+ "scratch_size": {
+ "description": "Size of the scratch area",
+ "value": "0x2000"
+ },
+ "status_address": {
+ "description": "Address of the swap status partition",
+ "value": "0x6005C000"
+ },
+ "status_size": {
+ "description": "Size of the swap status partition",
+ "value": "0x14000"
+ }
+ },
+ "service_app": {
+ "address": {
+ "description": "Address of the service application",
+ "value": "0x60070000"
+ },
+ "size": {
+ "description": "Size of the service application",
+ "value": "0x8000"
+ },
+ "params_address": {
+ "description": "Address of the service application input parameters",
+ "value": "0x60078000"
+ },
+ "params_size": {
+ "description": "Size of the service application input parameters",
+ "value": "0x400"
+ },
+ "desc_address": {
+ "description": "Address of the service application descriptor",
+ "value": "0x60078400"
+ },
+ "desc_size": {
+ "description": "Size of the service application descriptor",
+ "value": "0x20"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x60020000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0xF000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x6003E000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0xF000"
+ }
+ },
+ "application_2": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x6002F000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0xF000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x6004D000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0xF000"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot/cyw20829_xip_swap_single.json b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot/cyw20829_xip_swap_single.json
new file mode 100644
index 0000000..addeee1
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot/cyw20829_xip_swap_single.json
@@ -0,0 +1,81 @@
+{
+ "external_flash": [
+ {
+ "model": "FM25W04",
+ "mode": "XIP"
+ }
+ ],
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x60000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x20000"
+ },
+ "scratch_address": {
+ "description": "Address of the scratch area",
+ "value": "0x6007E000"
+ },
+ "scratch_size": {
+ "description": "Size of the scratch area",
+ "value": "0x2000"
+ },
+ "status_address": {
+ "description": "Address of the swap status partition",
+ "value": "0x60060000"
+ },
+ "status_size": {
+ "description": "Size of the swap status partition",
+ "value": "0xC000"
+ }
+ },
+ "service_app": {
+ "address": {
+ "description": "Address of the service application",
+ "value": "0x60070000"
+ },
+ "size": {
+ "description": "Size of the service application",
+ "value": "0x8000"
+ },
+ "params_address": {
+ "description": "Address of the service application input parameters",
+ "value": "0x60078000"
+ },
+ "params_size": {
+ "description": "Size of the service application input parameters",
+ "value": "0x400"
+ },
+ "desc_address": {
+ "description": "Address of the service application descriptor",
+ "value": "0x60078400"
+ },
+ "desc_size": {
+ "description": "Size of the service application descriptor",
+ "value": "0x20"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x60020000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x20000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x60040000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x20000"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h b/boot/cypress/cy_flash_pal/flash_cyw208xx/include/cy_smif_cyw20829.h
similarity index 85%
copy from boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h
copy to boot/cypress/cy_flash_pal/flash_cyw208xx/include/cy_smif_cyw20829.h
index fe1150d..42b0c1e 100644
--- a/boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/include/cy_smif_cyw20829.h
@@ -1,4 +1,4 @@
-/***************************************************************************//**
+/*******************************************************************************
* \file cy_smif_psoc6.h
* \version 1.0
*
@@ -45,20 +45,18 @@
*
******************************************************************************/
-#ifndef CY_SMIF_PSOC6_H_
-#define CY_SMIF_PSOC6_H_
+#ifndef CY_SMIF_CYW20829_H_
+#define CY_SMIF_CYW20829_H_
#include "stddef.h"
#include "stdbool.h"
#include "flash_qspi.h"
-#ifndef off_t
-typedef long int off_t;
-#endif
+typedef unsigned long offset_t;
-int psoc6_smif_read(const struct flash_area *fap, off_t addr, void *data, size_t len);
-int psoc6_smif_write(const struct flash_area *fap, off_t addr, const void *data, size_t len);
-int psoc6_smif_erase(off_t addr, size_t size);
+int cyw20829_smif_read(const struct flash_area *fap, offset_t addr, void *data, size_t len);
+int cyw20829_smif_write(const struct flash_area *fap, offset_t addr, const void *data, size_t len);
+int cyw20829_smif_erase(offset_t addr, size_t size);
-#endif /* CY_SMIF_PSOC6_H_ */
+#endif /* CY_SMIF_CYW20829_H_ */
diff --git a/boot/cypress/cy_flash_pal/include/flash_map_backend/flash_map_backend.h b/boot/cypress/cy_flash_pal/flash_cyw208xx/include/flash_map_backend/flash_map_backend.h
similarity index 81%
copy from boot/cypress/cy_flash_pal/include/flash_map_backend/flash_map_backend.h
copy to boot/cypress/cy_flash_pal/flash_cyw208xx/include/flash_map_backend/flash_map_backend.h
index 4b9409b..82c5578 100644
--- a/boot/cypress/cy_flash_pal/include/flash_map_backend/flash_map_backend.h
+++ b/boot/cypress/cy_flash_pal/flash_cyw208xx/include/flash_map_backend/flash_map_backend.h
@@ -14,7 +14,7 @@
* "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
+ * 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
@@ -28,7 +28,6 @@
#ifndef FLASH_MAP_BACKEND_H
#define FLASH_MAP_BACKEND_H
-#include <mcuboot_config/mcuboot_config.h>
#include "cy_flash.h"
#define FLASH_DEVICE_INDEX_MASK (0x7Fu)
#define FLASH_DEVICE_GET_EXT_INDEX(n) ((n) & FLASH_DEVICE_INDEX_MASK)
@@ -39,7 +38,7 @@
#ifndef CY_BOOT_EXTERNAL_DEVICE_INDEX
/* assume first(one) SMIF device is used */
-#define CY_BOOT_EXTERNAL_DEVICE_INDEX (0)
+#define CY_BOOT_EXTERNAL_DEVICE_INDEX (0u)
#endif
/**
@@ -93,6 +92,26 @@
uint32_t fa_size;
};
+static inline uint8_t flash_area_get_id(const struct flash_area *fa)
+{
+ return fa->fa_id;
+}
+
+static inline uint8_t flash_area_get_device_id(const struct flash_area *fa)
+{
+ return fa->fa_device_id;
+}
+
+static inline uint32_t flash_area_get_off(const struct flash_area *fa)
+{
+ return fa->fa_off;
+}
+
+static inline uint32_t flash_area_get_size(const struct flash_area *fa)
+{
+ return fa->fa_size;
+}
+
/**
* @brief Structure describing a sector within a flash area.
*
@@ -112,6 +131,16 @@
uint32_t fs_size;
};
+static inline uint32_t flash_sector_get_off(const struct flash_sector *fs)
+{
+ return fs->fs_off;
+}
+
+static inline uint32_t flash_sector_get_size(const struct flash_sector *fs)
+{
+ return fs->fs_size;
+}
+
struct flash_map_entry {
uint32_t magic;
struct flash_area area;
@@ -128,7 +157,7 @@
/*< Opens the area for use. id is one of the `fa_id`s */
int flash_area_open(uint8_t id, const struct flash_area **fa);
-void flash_area_close(const struct flash_area *);
+void flash_area_close(const struct flash_area *fa);
/*< Reads `len` bytes of flash memory at `off` to the buffer at `dst` */
int flash_area_read(const struct flash_area *fa, uint32_t off, void *dst,
uint32_t len);
@@ -137,8 +166,6 @@
const void *src, uint32_t len);
/*< Erases `len` bytes of flash memory at `off` */
int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len);
-/*< Erases aligned row of flash, where passed address resided */
-int flash_erase_row(uint32_t address);
/*< Returns this `flash_area`s alignment */
size_t flash_area_align(const struct flash_area *fa);
/*< Initializes an array of flash_area elements for the slot's sectors */
@@ -159,12 +186,16 @@
*/
uint8_t flash_area_erased_val(const struct flash_area *fa);
-/*
- * Reads len bytes from off, and checks if the read data is erased.
- *
- * Returns 1 if erased, 0 if non-erased, and -1 on failure.
- */
-int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off,
- void *dst, uint32_t len);
+// *****************************************************************************
+#ifdef MCUBOOT_ENC_IMAGES_XIP
+
+#include "bootutil/image.h"
+#include "bootutil/enc_key.h"
+
+int bootutil_img_encrypt(struct enc_key_data *enc_state, int image_index,
+ struct image_header *hdr, const struct flash_area *fap, uint32_t off, uint32_t sz,
+ uint32_t blk_off, uint8_t *buf);
+#endif /* MCUBOOT_ENC_IMAGES_XIP */
+
#endif /* FLASH_MAP_BACKEND_H */
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/cy_flash_map.c b/boot/cypress/cy_flash_pal/flash_psoc6/cy_flash_map.c
new file mode 100644
index 0000000..af17b0b
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/cy_flash_map.c
@@ -0,0 +1,504 @@
+/*
+ * Copyright (c) 2018 Nordic Semiconductor ASA
+ * Copyright (c) 2020 Cypress Semiconductor Corporation
+ * Copyright (c) 2022 Infineon Technologies AG
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "mcuboot_config/mcuboot_config.h"
+#include "flash_map_backend/flash_map_backend.h"
+#include <sysflash/sysflash.h>
+
+#include "bootutil/bootutil_log.h"
+#include "bootutil/bootutil_public.h"
+#include "bootutil/fault_injection_hardening.h" /* for FIH_PANIC */
+
+#include "cy_flash.h"
+#include "cy_flash_map.h"
+
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
+#include "cy_smif_psoc6.h"
+#endif
+
+#ifdef MCUBOOT_SWAP_USING_STATUS
+#include "swap_status.h"
+#endif
+
+#ifndef CY_BOOT_INTERNAL_FLASH_ERASE_VALUE
+/* This is the value of internal flash bytes after an erase */
+#define CY_BOOT_INTERNAL_FLASH_ERASE_VALUE (0x00u)
+#endif /* CY_BOOT_INTERNAL_FLASH_ERASE_VALUE */
+
+#ifndef CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE
+/* This is the value of external flash bytes after an erase */
+#define CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE (0xFFu)
+#endif /* CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE */
+
+/*
+ * Returns device flash start based on supported fd_id
+ */
+int flash_device_base(uint8_t fd_id, uintptr_t *ret)
+{
+ int rc = -1;
+
+ if (FLASH_DEVICE_INTERNAL_FLASH == fd_id) {
+ *ret = CY_FLASH_BASE;
+ rc = 0;
+ }
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
+ else if ((fd_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) {
+ *ret = CY_SMIF_BASE_MEM_OFFSET;
+ rc = 0;
+ }
+#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
+ else {
+ BOOT_LOG_ERR("invalid flash ID %u; expected %u or %u",
+ (unsigned)fd_id, FLASH_DEVICE_INTERNAL_FLASH,
+ FLASH_DEVICE_EXTERNAL_FLASH(CY_BOOT_EXTERNAL_DEVICE_INDEX));
+ }
+
+ return rc;
+}
+
+/*
+ * Opens the area for use. id is one of the `fa_id`s
+ */
+int flash_area_open(uint8_t id, const struct flash_area **fa)
+{
+ int rc = -1;
+ uint32_t i = 0u;
+
+ while (NULL != boot_area_descs[i]) {
+
+ if (id == boot_area_descs[i]->fa_id) {
+ *fa = boot_area_descs[i];
+ rc = 0;
+ break;
+ }
+ i++;
+ }
+
+ return rc;
+}
+
+/*
+ * Clear pointer to flash area fa
+ */
+void flash_area_close(const struct flash_area *fa)
+{
+ (void)fa; /* Nothing to do there */
+}
+
+/*
+ * Reads `len` bytes of flash memory at `off` to the buffer at `dst`
+ */
+int flash_area_read(const struct flash_area *fa, uint32_t off, void *dst,
+ uint32_t len)
+{
+ int rc = -1;
+ size_t addr = 0u;
+ uintptr_t flash_base = 0u;
+
+ if ((NULL != dst) && (NULL != fa)) {
+
+ if (off > fa->fa_size ||
+ len > fa->fa_size ||
+ off + len > fa->fa_size) {
+
+ return BOOT_EBADARGS;
+ }
+
+ rc = flash_device_base(fa->fa_device_id, &flash_base);
+
+ if (0 == rc) {
+
+ addr = flash_base + fa->fa_off + off;
+
+ if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) {
+ /* flash read by simple memory copying */
+ (void)memcpy((void *)dst, (const void *)((uint8_t *)addr), (size_t)len);
+ }
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
+ else {
+ rc = psoc6_smif_read(fa, addr, dst, len);
+ }
+#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
+ }
+ }
+
+ return rc;
+}
+
+/*
+ * Writes `len` bytes of flash memory at `off` from the buffer at `src`
+ */
+int flash_area_write(const struct flash_area *fa, uint32_t off,
+ const void *src, uint32_t len)
+{
+ int rc = BOOT_EFLASH;
+ size_t write_start_addr = 0u;
+ size_t write_end_addr = 0u;
+ const uint32_t * row_ptr = NULL;
+ uintptr_t flash_base = 0u;
+
+ if ( (NULL != src) && (NULL != fa) ) {
+
+ if (off > fa->fa_size ||
+ len > fa->fa_size ||
+ off + len > fa->fa_size) {
+
+ return BOOT_EBADARGS;
+ }
+
+ rc = flash_device_base(fa->fa_device_id, &flash_base);
+
+ if (0 == rc) {
+
+ write_start_addr = flash_base + fa->fa_off + off;
+ write_end_addr = flash_base + fa->fa_off + off + len;
+
+ if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) {
+
+ uint32_t row_number = 0u;
+ uint32_t row_addr = 0u;
+
+ if (len % CY_FLASH_SIZEOF_ROW != 0u) {
+ return BOOT_EBADARGS;
+ }
+
+ if (write_start_addr % CY_FLASH_SIZEOF_ROW != 0u) {
+ return BOOT_EBADARGS;
+ }
+
+ row_number = (write_end_addr - write_start_addr) / CY_FLASH_SIZEOF_ROW;
+ row_addr = write_start_addr;
+
+ row_ptr = (const uint32_t *) src;
+
+ for (uint32_t i = 0; i < row_number; i++) {
+ if (Cy_Flash_WriteRow(row_addr, row_ptr) != CY_FLASH_DRV_SUCCESS) {
+ rc = BOOT_EFLASH;
+ break;
+ }
+
+ row_addr += (uint32_t) CY_FLASH_SIZEOF_ROW;
+ row_ptr = row_ptr + CY_FLASH_SIZEOF_ROW / 4U;
+ }
+ }
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
+ else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) != 0u) {
+ rc = psoc6_smif_write(fa, write_start_addr, src, len);
+ }
+#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
+ else {
+ return BOOT_EFLASH;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/*< Erases `len` bytes of flash memory at `off` */
+int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len)
+{
+ int rc = -1;
+ size_t erase_start_addr = 0u;
+ size_t erase_end_addr = 0u;
+ uintptr_t flash_base = 0u;
+
+ if (NULL != fa) {
+
+ if (off > fa->fa_size ||
+ len > fa->fa_size ||
+ off + len > fa->fa_size) {
+
+ return BOOT_EBADARGS;
+ }
+
+ rc = flash_device_base(fa->fa_device_id, &flash_base);
+
+ if (0 == rc) {
+
+ erase_start_addr = flash_base + fa->fa_off + off;
+ erase_end_addr = flash_base + fa->fa_off + off + len;
+
+ if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) {
+ uint32_t row_number = 0u;
+ uint32_t row_addr = 0u;
+ uint32_t row_start_addr = (erase_start_addr / CY_FLASH_SIZEOF_ROW) * CY_FLASH_SIZEOF_ROW;
+ uint32_t row_end_addr = (erase_end_addr / CY_FLASH_SIZEOF_ROW) * CY_FLASH_SIZEOF_ROW;
+
+ /* assume single row needs to be erased */
+ if (row_start_addr == row_end_addr) {
+ if (Cy_Flash_EraseRow(row_start_addr) != CY_FLASH_DRV_SUCCESS) {
+ rc = BOOT_EFLASH;
+ }
+ }
+ else {
+
+ row_number = (row_end_addr - row_start_addr) / CY_FLASH_SIZEOF_ROW;
+
+ while (0u != row_number) {
+ row_number--;
+ row_addr = row_start_addr + row_number * (uint32_t) CY_FLASH_SIZEOF_ROW;
+ if (Cy_Flash_EraseRow(row_addr) != CY_FLASH_DRV_SUCCESS) {
+ rc = BOOT_EFLASH;
+ break;
+ }
+ }
+ }
+ }
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
+ else {
+ rc = psoc6_smif_erase(erase_start_addr, len);
+ }
+#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
+ }
+ }
+
+ return rc;
+}
+
+/*< Returns this `flash_area`s alignment */
+size_t flash_area_align(const struct flash_area *fa)
+{
+ size_t rc = 0u; /* error code (alignment cannot be zero) */
+
+ if (NULL != fa) {
+ if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) {
+ rc = CY_FLASH_ALIGN;
+ }
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
+ else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) {
+ rc = qspi_get_prog_size();
+ }
+ else {
+ /* No action required */
+ }
+#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
+ }
+
+ return rc;
+}
+
+#ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
+/*< Initializes an array of flash_area elements for the slot's sectors */
+int flash_area_to_sectors(int idx, int *cnt, struct flash_area *fa)
+{
+ int rc = 0;
+
+ if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) {
+ (void)idx;
+ (void)cnt;
+ rc = 0;
+ }
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
+ else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) {
+ (void)idx;
+ (void)cnt;
+ rc = 0;
+ }
+#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
+ else
+ {
+ /* incorrect/non-existing flash device id */
+ rc = -1;
+ }
+ return rc;
+}
+#endif /* MCUBOOT_USE_FLASH_AREA_GET_SECTORS */
+
+/*
+ * This depends on the mappings defined in sysflash.h.
+ * MCUBoot uses continuous numbering for the primary slot, the secondary slot,
+ * and the scratch while zephyr might number it differently.
+ */
+int flash_area_id_from_multi_image_slot(int image_index, int slot)
+{
+ int rc;
+ if ((image_index < 0) || (image_index >= MCUBOOT_IMAGE_NUMBER)) {
+ return -1;
+ }
+
+ switch (slot) {
+ case 0:
+ rc = (int)FLASH_AREA_IMAGE_PRIMARY((uint32_t)image_index);
+ break;
+ case 1:
+ rc = (int)FLASH_AREA_IMAGE_SECONDARY((uint32_t)image_index);
+ break;
+ case 2:
+ rc = (int)FLASH_AREA_IMAGE_SCRATCH;
+ break;
+ default:
+ rc = -1; /* flash_area_open will fail on that */
+ break;
+ }
+ return rc;
+}
+
+int flash_area_id_from_image_slot(int slot)
+{
+ return flash_area_id_from_multi_image_slot(0, slot);
+}
+
+int flash_area_id_to_multi_image_slot(int image_index, int area_id)
+{
+ if ((image_index < 0) || (image_index >= MCUBOOT_IMAGE_NUMBER)) {
+ return -1;
+ }
+
+ if (area_id == (int) FLASH_AREA_IMAGE_PRIMARY((uint32_t)image_index)) {
+ return 0;
+ }
+ if (area_id == (int) FLASH_AREA_IMAGE_SECONDARY((uint32_t)image_index)) {
+ return 1;
+ }
+
+ return -1;
+}
+
+int flash_area_id_to_image_slot(int area_id)
+{
+ return flash_area_id_to_multi_image_slot(0, area_id);
+}
+
+uint8_t flash_area_erased_val(const struct flash_area *fa)
+{
+ uint8_t ret = 0u;
+
+ if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) {
+ ret = (uint8_t) CY_BOOT_INTERNAL_FLASH_ERASE_VALUE;
+ }
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
+ else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) != 0u) {
+ ret = (uint8_t) CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE;
+ }
+#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
+ else {
+ ret = 0u; /* The variable is reassigned to make the statement comply with the MISRA rule 15.7 */
+ FIH_PANIC; /* There is no appropriate error code */
+ }
+
+ return ret;
+}
+
+#ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
+int flash_area_get_sectors(int idx, uint32_t *cnt, struct flash_sector *ret)
+{
+ int rc = 0;
+ uint32_t i = 0u;
+ struct flash_area *fa = NULL;
+ size_t sectors_n = 0u;
+ uint32_t my_sector_addr = 0u;
+ uint32_t my_sector_size = 0u;
+
+ while (NULL != boot_area_descs[i]) {
+ if (idx == (int) boot_area_descs[i]->fa_id) {
+ fa = boot_area_descs[i];
+ break;
+ }
+ i++;
+ }
+
+ if ( (NULL != fa) && (NULL != cnt) && (NULL != ret) ) {
+ size_t sector_size = 0;
+ size_t area_size = fa->fa_size;
+
+ if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) {
+#if defined(CY_BOOT_USE_EXTERNAL_FLASH) && defined(MCUBOOT_SWAP_USING_STATUS) && !defined(MCUBOOT_SWAP_USING_SCRATCH)
+ if (idx == (int) FLASH_AREA_IMAGE_SWAP_STATUS) {
+ sector_size = CY_FLASH_SIZEOF_ROW;
+ }
+ else {
+ sector_size = qspi_get_erase_size();
+#else
+ sector_size = CY_FLASH_SIZEOF_ROW;
+#endif /* defined(CY_BOOT_USE_EXTERNAL_FLASH) && defined(MCUBOOT_SWAP_USING_STATUS) && !defined(MCUBOOT_SWAP_USING_SCRATCH) */
+ }
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
+ else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) {
+ /* implement for SMIF */
+ /* lets assume they are equal */
+#if defined(MCUBOOT_SWAP_USING_STATUS) || defined(USE_XIP)
+ sector_size = qspi_get_erase_size();
+#else
+ sector_size = CY_FLASH_SIZEOF_ROW;
+#endif /* MCUBOOT_SWAP_USING_STATUS */
+ }
+#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
+ else {
+ /* fa->fa_device_id = FLASH_DEVICE_UNDEFINED,
+ in this case the area should be empty with a very simple sector size of 1 byte */
+ area_size = 0u;
+ sector_size = 1u;
+ }
+
+ sectors_n = (area_size + (sector_size - 1U)) / sector_size;
+
+ if (sectors_n > (size_t)MCUBOOT_MAX_IMG_SECTORS) {
+ sector_size *= 2u;
+ }
+
+ sectors_n = 0;
+ my_sector_addr = fa->fa_off;
+ while (area_size > 0u) {
+ my_sector_size = sector_size;
+#ifdef MCUBOOT_SWAP_USING_SCRATCH
+ uint32_t my_sector_offs = my_sector_addr % my_sector_size;
+
+ if (my_sector_offs != 0u) {
+ my_sector_size = sector_size - my_sector_offs;
+ }
+
+ if (my_sector_size > area_size) {
+ my_sector_size = area_size;
+ }
+#endif /* MCUBOOT_SWAP_USING_SCRATCH */
+ ret[sectors_n].fs_size = my_sector_size;
+ ret[sectors_n].fs_off = my_sector_addr;
+
+ my_sector_addr += my_sector_size;
+ area_size -= my_sector_size;
+ sectors_n++;
+ }
+
+ if (sectors_n <= *cnt) {
+ *cnt = sectors_n;
+ }
+ else {
+ rc = -1;
+ }
+ }
+ else {
+ rc = -1;
+ }
+
+ return rc;
+}
+#endif /* MCUBOOT_USE_FLASH_AREA_GET_SECTORS */
diff --git a/boot/cypress/cy_flash_pal/cy_smif_psoc6.c b/boot/cypress/cy_flash_pal/flash_psoc6/cy_smif_psoc6.c
similarity index 93%
rename from boot/cypress/cy_flash_pal/cy_smif_psoc6.c
rename to boot/cypress/cy_flash_pal/flash_psoc6/cy_smif_psoc6.c
index c2dd5c3..d8f7a7e 100644
--- a/boot/cypress/cy_flash_pal/cy_smif_psoc6.c
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/cy_smif_psoc6.c
@@ -45,16 +45,12 @@
* so agrees to indemnify Cypress against all liability.
*
******************************************************************************/
+#ifndef CYW20829
+
#include "string.h"
#include "stdlib.h"
#include "stdbool.h"
-#ifdef MCUBOOT_HAVE_ASSERT_H
-#include "mcuboot_config/mcuboot_assert.h"
-#else
-#include <assert.h>
-#endif
-
#include "flash_map_backend/flash_map_backend.h"
#include <sysflash/sysflash.h>
@@ -72,7 +68,7 @@
#define PSOC6_FLASH_ERASE_BLOCK_SIZE CY_FLASH_SIZEOF_ROW /* PSoC6 Flash erases by Row */
int psoc6_smif_read(const struct flash_area *fap,
- off_t addr,
+ offset_t addr,
void *data,
size_t len)
{
@@ -93,7 +89,7 @@
}
int psoc6_smif_write(const struct flash_area *fap,
- off_t addr,
+ offset_t addr,
const void *data,
size_t len)
{
@@ -113,13 +109,13 @@
return rc;
}
-int psoc6_smif_erase(off_t addr, size_t size)
+int psoc6_smif_erase(offset_t addr, size_t size)
{
int rc = -1;
cy_en_smif_status_t st = CY_SMIF_SUCCESS;
uint32_t address;
- if (size > 0)
+ if (size > 0u)
{
/* It is erase sector-only
*
@@ -131,7 +127,7 @@
address = ((uint32_t)addr - CY_SMIF_BASE_MEM_OFFSET ) & ~((uint32_t)(memCfg->deviceCfg->eraseSize - 1u));
- while ((size > 0) && (CY_SMIF_SUCCESS == st))
+ while ((size > 0u) && (CY_SMIF_SUCCESS == st))
{
st = Cy_SMIF_MemEraseSector(qspi_get_device(),
memCfg,
@@ -150,3 +146,5 @@
return rc;
}
+
+#endif /* CY20829 */
diff --git a/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.c b/boot/cypress/cy_flash_pal/flash_psoc6/flash_qspi/flash_qspi.c
similarity index 83%
rename from boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.c
rename to boot/cypress/cy_flash_pal/flash_psoc6/flash_qspi/flash_qspi.c
index 6ac5894..f62c3eb 100644
--- a/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.c
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/flash_qspi/flash_qspi.c
@@ -95,7 +95,7 @@
struct qspi_ss_config
{
GPIO_PRT_Type* SS_Port;
- int SS_Pin;
+ uint32_t SS_Pin;
en_hsiom_sel_t SS_Mux;
};
@@ -104,55 +104,55 @@
defined(PSOC_062_2M) || \
defined(PSOC_062_1M))
#define CY_BOOTLOADER_SMIF_SS_CFG_NUM 4
-#elif defined(PSOC_064_512K) || defined(PSOC_062_512K)
+#elif defined(PSOC_064_512K) || defined(PSOC_062_512K) || defined(CYW20829)
#define CY_BOOTLOADER_SMIF_SS_CFG_NUM 3
#else
#error "Platform device name is unsupported."
#endif
-struct qspi_ss_config qspi_SS_Configuration[CY_BOOTLOADER_SMIF_SS_CFG_NUM] =
+static struct qspi_ss_config qspi_SS_Configuration[CY_BOOTLOADER_SMIF_SS_CFG_NUM] =
{
{
.SS_Port = GPIO_PRT11,
- .SS_Pin = 2,
+ .SS_Pin = 2u,
.SS_Mux = P11_2_SMIF_SPI_SELECT0
},
{
.SS_Port = GPIO_PRT11,
- .SS_Pin = 1,
+ .SS_Pin = 1u,
.SS_Mux = P11_1_SMIF_SPI_SELECT1
},
{
.SS_Port = GPIO_PRT11,
- .SS_Pin = 0,
+ .SS_Pin = 0u,
.SS_Mux = P11_0_SMIF_SPI_SELECT2
},
#if(CY_BOOTLOADER_SMIF_SS_CFG_NUM > 3)
{
.SS_Port = GPIO_PRT12,
- .SS_Pin = 4,
+ .SS_Pin = 4u,
.SS_Mux = P12_4_SMIF_SPI_SELECT3
}
#endif
};
static GPIO_PRT_Type *D3Port = GPIO_PRT11;
-static int D3Pin = 3;
+static uint32_t D3Pin = 3u;
static en_hsiom_sel_t D3MuxPort = P11_3_SMIF_SPI_DATA3;
static GPIO_PRT_Type *D2Port = GPIO_PRT11;
-static int D2Pin = 4;
+static uint32_t D2Pin = 4u;
static en_hsiom_sel_t D2MuxPort = P11_4_SMIF_SPI_DATA2;
static GPIO_PRT_Type *D1Port = GPIO_PRT11;
-static int D1Pin = 5;
+static uint32_t D1Pin = 5u;
static en_hsiom_sel_t D1MuxPort = P11_5_SMIF_SPI_DATA1;
static GPIO_PRT_Type *D0Port = GPIO_PRT11;
-static int D0Pin = 6;
+static uint32_t D0Pin = 6u;
static en_hsiom_sel_t D0MuxPort = P11_6_SMIF_SPI_DATA0;
static GPIO_PRT_Type *SCKPort = GPIO_PRT11;
-static int SCKPin = 7;
+static uint32_t SCKPin = 7u;
static en_hsiom_sel_t SCKMuxPort = P11_7_SMIF_SPI_CLK;
static SMIF_Type *QSPIPort = SMIF0;
@@ -196,23 +196,22 @@
{
/* The base address the memory slave is mapped to in the PSoC memory map.
Valid when the memory-mapped mode is enabled. */
- .baseAddress = 0x18000000U,
+ .baseAddress = CY_XIP_BASE,
/* The size allocated in the PSoC memory map, for the memory slave device.
The size is allocated from the base address. Valid when the memory mapped mode is enabled. */
-/* .memMappedSize = 0x4000000U, */
- .flags = CY_SMIF_FLAG_DETECT_SFDP,
+ .memMappedSize = CY_XIP_SIZE,
+ .flags = CY_SMIF_FLAG_DETECT_SFDP | CY_SMIF_FLAG_MEMORY_MAPPED,
.slaveSelect = CY_SMIF_SLAVE_SELECT_0,
.dataSelect = CY_SMIF_DATA_SEL0,
.deviceCfg = &dev_sfdp_0
};
+
static cy_stc_smif_mem_config_t *mems_sfdp[1] =
{
&mem_sfdp_0
};
-/* make it exported if used in TOC (cy_serial_flash_prog.c) */
-/* cy_stc_smif_block_config_t smifBlockConfig_sfdp = */
static cy_stc_smif_block_config_t smifBlockConfig_sfdp =
{
.memCount = 1,
@@ -223,7 +222,7 @@
static cy_stc_smif_context_t QSPI_context;
-cy_stc_smif_config_t const QSPI_config =
+static cy_stc_smif_config_t const QSPI_config =
{
.mode = (uint32_t)CY_SMIF_NORMAL,
.deselectDelay = 1,
@@ -231,12 +230,14 @@
.blockEvent = (uint32_t)CY_SMIF_BUS_ERROR
};
-cy_stc_sysint_t smifIntConfig =
+#ifdef CM0P
+static cy_stc_sysint_t smifIntConfig =
{/* ATTENTION: make sure proper Interrupts configured for CM0p or M4 cores */
.intrSrc = NvicMux7_IRQn,
.cm0pSrc = smif_interrupt_IRQn,
.intrPriority = 1
};
+#endif
/* SMIF pinouts configurations */
static cy_stc_gpio_pin_config_t QSPI_SS_config =
@@ -255,7 +256,7 @@
.vrefSel = 0UL,
.vohSel = 0UL,
};
-const cy_stc_gpio_pin_config_t QSPI_DATA3_config =
+static const cy_stc_gpio_pin_config_t QSPI_DATA3_config =
{
.outVal = 1,
.driveMode = CY_GPIO_DM_STRONG,
@@ -271,7 +272,7 @@
.vrefSel = 0UL,
.vohSel = 0UL,
};
-const cy_stc_gpio_pin_config_t QSPI_DATA2_config =
+static const cy_stc_gpio_pin_config_t QSPI_DATA2_config =
{
.outVal = 1,
.driveMode = CY_GPIO_DM_STRONG,
@@ -287,7 +288,7 @@
.vrefSel = 0UL,
.vohSel = 0UL,
};
-const cy_stc_gpio_pin_config_t QSPI_DATA1_config =
+static const cy_stc_gpio_pin_config_t QSPI_DATA1_config =
{
.outVal = 1,
.driveMode = CY_GPIO_DM_STRONG,
@@ -303,7 +304,7 @@
.vrefSel = 0UL,
.vohSel = 0UL,
};
-const cy_stc_gpio_pin_config_t QSPI_DATA0_config =
+static const cy_stc_gpio_pin_config_t QSPI_DATA0_config =
{
.outVal = 1,
.driveMode = CY_GPIO_DM_STRONG,
@@ -319,7 +320,7 @@
.vrefSel = 0UL,
.vohSel = 0UL,
};
-const cy_stc_gpio_pin_config_t QSPI_SCK_config =
+static const cy_stc_gpio_pin_config_t QSPI_SCK_config =
{
.outVal = 1,
.driveMode = CY_GPIO_DM_STRONG_IN_OFF,
@@ -336,64 +337,71 @@
.vohSel = 0UL,
};
-void Isr_SMIF(void)
+#ifdef CM0P
+static void Isr_SMIF(void)
{
Cy_SMIF_Interrupt(QSPIPort, &QSPI_context);
}
+#endif
cy_en_smif_status_t qspi_init_hardware(void)
{
cy_en_smif_status_t st;
- Cy_GPIO_Pin_Init(D3Port, D3Pin, &QSPI_DATA3_config);
+ (void)Cy_GPIO_Pin_Init(D3Port, D3Pin, &QSPI_DATA3_config);
Cy_GPIO_SetHSIOM(D3Port, D3Pin, D3MuxPort);
- Cy_GPIO_Pin_Init(D2Port, D2Pin, &QSPI_DATA2_config);
+ (void)Cy_GPIO_Pin_Init(D2Port, D2Pin, &QSPI_DATA2_config);
Cy_GPIO_SetHSIOM(D2Port, D2Pin, D2MuxPort);
- Cy_GPIO_Pin_Init(D1Port, D1Pin, &QSPI_DATA1_config);
+ (void)Cy_GPIO_Pin_Init(D1Port, D1Pin, &QSPI_DATA1_config);
Cy_GPIO_SetHSIOM(D1Port, D1Pin, D1MuxPort);
- Cy_GPIO_Pin_Init(D0Port, D0Pin, &QSPI_DATA0_config);
+ (void)Cy_GPIO_Pin_Init(D0Port, D0Pin, &QSPI_DATA0_config);
Cy_GPIO_SetHSIOM(D0Port, D0Pin, D0MuxPort);
- Cy_GPIO_Pin_Init(SCKPort, SCKPin, &QSPI_SCK_config);
+ (void)Cy_GPIO_Pin_Init(SCKPort, SCKPin, &QSPI_SCK_config);
Cy_GPIO_SetHSIOM(SCKPort, SCKPin, SCKMuxPort);
- Cy_SysClk_ClkHfSetSource(CY_SYSCLK_CLKHF_IN_CLKPATH2, CY_SYSCLK_CLKHF_IN_CLKPATH0);
- Cy_SysClk_ClkHfSetDivider(CY_SYSCLK_CLKHF_IN_CLKPATH2, CY_SMIF_SYSCLK_HFCLK_DIVIDER);
- Cy_SysClk_ClkHfEnable(CY_SYSCLK_CLKHF_IN_CLKPATH2);
+ (void)Cy_SysClk_ClkHfSetSource(CY_SYSCLK_CLKHF_IN_CLKPATH2, CY_SYSCLK_CLKHF_IN_CLKPATH0);
+ (void)Cy_SysClk_ClkHfSetDivider(CY_SYSCLK_CLKHF_IN_CLKPATH2, CY_SMIF_SYSCLK_HFCLK_DIVIDER);
+ (void)Cy_SysClk_ClkHfEnable(CY_SYSCLK_CLKHF_IN_CLKPATH2);
/*
* Setup the interrupt for the SMIF block. For the CM0 there
* is a two stage process to setup the interrupts.
*/
- Cy_SysInt_Init(&smifIntConfig, Isr_SMIF);
+#ifdef CM0P
+ (void)Cy_SysInt_Init(&smifIntConfig, Isr_SMIF);
+#endif
st = Cy_SMIF_Init(QSPIPort, &QSPI_config, 1000, &QSPI_context);
if (st != CY_SMIF_SUCCESS)
{
return st;
}
+
+#ifdef CM0P
NVIC_EnableIRQ(smifIntConfig.intrSrc); /* Finally, Enable the SMIF interrupt */
+#endif
Cy_SMIF_Enable(QSPIPort, &QSPI_context);
return CY_SMIF_SUCCESS;
}
-cy_stc_smif_mem_config_t *qspi_get_memory_config(int index)
+cy_stc_smif_mem_config_t *qspi_get_memory_config(uint8_t index)
{
return smif_blk_config->memConfig[index];
}
-SMIF_Type *qspi_get_device()
+SMIF_Type *qspi_get_device(void)
{
return QSPIPort;
}
-cy_stc_smif_context_t *qspi_get_context()
+cy_stc_smif_context_t *qspi_get_context(void)
{
return &QSPI_context;
}
@@ -418,7 +426,7 @@
cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig;
GPIO_PRT_Type *SS_Port;
- int SS_Pin;
+ uint32_t SS_Pin;
en_hsiom_sel_t SS_MuxPort;
switch(smif_id)
@@ -444,13 +452,13 @@
if(CY_SMIF_SUCCESS == stat)
{
- SS_Port = qspi_SS_Configuration[smif_id-1].SS_Port;
- SS_Pin = qspi_SS_Configuration[smif_id-1].SS_Pin;
- SS_MuxPort = qspi_SS_Configuration[smif_id-1].SS_Mux;
+ SS_Port = qspi_SS_Configuration[smif_id-1U].SS_Port;
+ SS_Pin = qspi_SS_Configuration[smif_id-1U].SS_Pin;
+ SS_MuxPort = qspi_SS_Configuration[smif_id-1U].SS_Mux;
QSPI_SS_config.hsiom = SS_MuxPort;
- Cy_GPIO_Pin_Init(SS_Port, SS_Pin, &QSPI_SS_config);
+ (void)Cy_GPIO_Pin_Init(SS_Port, SS_Pin, &QSPI_SS_config);
Cy_GPIO_SetHSIOM(SS_Port, SS_Pin, SS_MuxPort);
uint32_t try_count = CY_SMIF_INIT_TRY_COUNT;
@@ -491,15 +499,31 @@
Cy_SMIF_Disable(QSPIPort);
- Cy_SysClk_ClkHfDisable(CY_SYSCLK_CLKHF_IN_CLKPATH2);
+ (void)Cy_SysClk_ClkHfDisable(CY_SYSCLK_CLKHF_IN_CLKPATH2);
+#ifdef CM0P
NVIC_DisableIRQ(smifIntConfig.intrSrc);
Cy_SysInt_DisconnectInterruptSource(smifIntConfig.intrSrc, smifIntConfig.cm0pSrc);
+#endif
- Cy_GPIO_Port_Deinit(qspi_SS_Configuration[smif_id-1].SS_Port);
+ Cy_GPIO_Port_Deinit(qspi_SS_Configuration[smif_id-1U].SS_Port);
Cy_GPIO_Port_Deinit(SCKPort);
Cy_GPIO_Port_Deinit(D0Port);
Cy_GPIO_Port_Deinit(D1Port);
Cy_GPIO_Port_Deinit(D2Port);
Cy_GPIO_Port_Deinit(D3Port);
}
+
+void qspi_set_mode(cy_en_smif_mode_t mode)
+{
+ SMIF_Type* smif_mem = qspi_get_device();
+
+ Cy_SMIF_SetMode(smif_mem, mode);
+}
+
+cy_en_smif_mode_t qspi_get_mode(void)
+{
+ SMIF_Type* smif_mem = qspi_get_device();
+
+ return Cy_SMIF_GetMode(smif_mem);
+}
diff --git a/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.h b/boot/cypress/cy_flash_pal/flash_psoc6/flash_qspi/flash_qspi.h
similarity index 89%
rename from boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.h
rename to boot/cypress/cy_flash_pal/flash_psoc6/flash_qspi/flash_qspi.h
index 80e0d51..1458091 100644
--- a/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.h
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/flash_qspi/flash_qspi.h
@@ -44,15 +44,12 @@
* so agrees to indemnify Cypress against all liability.
*
******************************************************************************/
-#ifndef __FLASH_QSPI_H__
-#define __FLASH_QSPI_H__
+#ifndef FLASH_QSPI_H
+#define FLASH_QSPI_H
#include <stdint.h>
#include "cy_pdl.h"
-/* make it exported if used in TOC (cy_serial_flash_prog.c) */
-/* cy_stc_smif_block_config_t smifBlockConfig_sfdp; */
-
cy_en_smif_status_t qspi_init_sfdp(uint32_t smif_id);
cy_en_smif_status_t qspi_init(cy_stc_smif_block_config_t *blk_config);
cy_en_smif_status_t qspi_init_hardware(void);
@@ -62,9 +59,12 @@
SMIF_Type *qspi_get_device(void);
cy_stc_smif_context_t *qspi_get_context(void);
-cy_stc_smif_mem_config_t *qspi_get_memory_config(int index);
-void qspi_dump_device(cy_stc_smif_mem_device_cfg_t *dev);
+cy_stc_smif_mem_config_t *qspi_get_memory_config(uint8_t index);
void qspi_deinit(uint32_t smif_id);
-#endif /* __FLASH_QSPI_H__ */
+void qspi_set_mode(cy_en_smif_mode_t mode);
+cy_en_smif_mode_t qspi_get_mode(void);
+
+
+#endif /* FLASH_QSPI_H */
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_multi.json b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_multi.json
new file mode 100644
index 0000000..dea92e9
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_multi.json
@@ -0,0 +1,51 @@
+{
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x10000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x18000"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10018000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x10000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x10028000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x10000"
+ }
+ },
+ "application_2": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10038000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x20000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x10058000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x20000"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_multi_smif.json b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_multi_smif.json
new file mode 100644
index 0000000..12fce09
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_multi_smif.json
@@ -0,0 +1,56 @@
+{
+ "external_flash": [
+ {
+ "model": "S25HS256T"
+ }
+ ],
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x10000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x18000"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10018000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x40200"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x18000000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x40200"
+ }
+ },
+ "application_2": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10058200"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x40200"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x18240000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x40200"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_single.json b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_single.json
new file mode 100644
index 0000000..b377c7a
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_single.json
@@ -0,0 +1,33 @@
+{
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x10000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x18000"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10018000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x10000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x10028000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x10000"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_single_smif.json b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_single_smif.json
new file mode 100644
index 0000000..d3866d0
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_overwrite_single_smif.json
@@ -0,0 +1,38 @@
+{
+ "external_flash": [
+ {
+ "model": "S25HS256T"
+ }
+ ],
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x10000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x18000"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10018000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x40200"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x18000000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x40200"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_multi.json b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_multi.json
new file mode 100644
index 0000000..67c0557
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_multi.json
@@ -0,0 +1,67 @@
+{
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x10000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x18000"
+ },
+ "scratch_address": {
+ "description": "Address of the scratch area",
+ "value": "0x1007A800"
+ },
+ "scratch_size": {
+ "description": "Size of the scratch area",
+ "value": "0x2000"
+ },
+ "status_address": {
+ "description": "Address of the swap status partition",
+ "value": "0x10078000"
+ },
+ "status_size": {
+ "description": "Size of the swap status partition",
+ "value": "0x2800"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10018000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x10000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x10028000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x10000"
+ }
+ },
+ "application_2": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10038000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x20000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x10058000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x20000"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_multi_smif.json b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_multi_smif.json
new file mode 100644
index 0000000..cd80107
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_multi_smif.json
@@ -0,0 +1,72 @@
+{
+ "external_flash": [
+ {
+ "model": "S25HS256T"
+ }
+ ],
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x10000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x18000"
+ },
+ "scratch_address": {
+ "description": "Address of the scratch area",
+ "value": "0x18440000"
+ },
+ "scratch_size": {
+ "description": "Size of the scratch area",
+ "value": "0x80000"
+ },
+ "status_address": {
+ "description": "Address of the swap status partition",
+ "value": "0x10098400"
+ },
+ "status_size": {
+ "description": "Size of the swap status partition",
+ "value": "0x3c00"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10018000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x40200"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x18000000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x40200"
+ }
+ },
+ "application_2": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10058200"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x40200"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x18240000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x40200"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_shared.json b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_shared.json
new file mode 100644
index 0000000..90853dc
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_shared.json
@@ -0,0 +1,74 @@
+{
+ "boot_and_upgrade": {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x10000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x18000"
+ },
+ "scratch_address": {
+ "description": "Address of the scratch area",
+ "value": "0x1007A800"
+ },
+ "scratch_size": {
+ "description": "Size of the scratch area",
+ "value": "0x2000"
+ },
+ "status_address": {
+ "description": "Address of the swap status partition",
+ "value": "0x10078000"
+ },
+ "status_size": {
+ "description": "Size of the swap status partition",
+ "value": "0x2800"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10018000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x10000"
+ },
+ "shared_slot": {
+ "description": "Using shared secondary slot",
+ "value": true
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x10038200"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x10000"
+ }
+ },
+ "application_2": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10028000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x10000"
+ },
+ "shared_slot": {
+ "description": "Using shared secondary slot",
+ "value": true
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x10038400"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x10000"
+ }
+ }
+ }
+}
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_single.json b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_single.json
new file mode 100644
index 0000000..ca0f119
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_single.json
@@ -0,0 +1,49 @@
+{
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x10000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x18000"
+ },
+ "scratch_address": {
+ "description": "Address of the scratch area",
+ "value": "0x10040000"
+ },
+ "scratch_size": {
+ "description": "Size of the scratch area",
+ "value": "0x2000"
+ },
+ "status_address": {
+ "description": "Address of the swap status partition",
+ "value": "0x10038000"
+ },
+ "status_size": {
+ "description": "Size of the swap status partition",
+ "value": "0x1800"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10018000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x10000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x10028000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x10000"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_single_smif.json b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_single_smif.json
new file mode 100644
index 0000000..f921bba
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_single_smif.json
@@ -0,0 +1,54 @@
+{
+ "external_flash": [
+ {
+ "model": "S25HS256T"
+ }
+ ],
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x10000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x18000"
+ },
+ "scratch_address": {
+ "description": "Address of the scratch area",
+ "value": "0x18440000"
+ },
+ "scratch_size": {
+ "description": "Size of the scratch area",
+ "value": "0x80000"
+ },
+ "status_address": {
+ "description": "Address of the swap status partition",
+ "value": "0x10058200"
+ },
+ "status_size": {
+ "description": "Size of the swap status partition",
+ "value": "0x2400"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10018000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x40200"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x18000000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x40200"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_xip_overwrite.json b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_xip_overwrite.json
new file mode 100644
index 0000000..92e26e2
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_xip_overwrite.json
@@ -0,0 +1,39 @@
+{
+ "external_flash": [
+ {
+ "model": "S25HS256T",
+ "mode": "XIP"
+ }
+ ],
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x10000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x18000"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x18000000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x80000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x18080000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x80000"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_xip_swap.json b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_xip_swap.json
new file mode 100644
index 0000000..e0a7267
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/flashmap/psoc62_xip_swap.json
@@ -0,0 +1,55 @@
+{
+ "external_flash": [
+ {
+ "model": "S25HS256T",
+ "mode": "XIP"
+ }
+ ],
+ "boot_and_upgrade":
+ {
+ "bootloader": {
+ "address": {
+ "description": "Address of the bootloader",
+ "value": "0x10000000"
+ },
+ "size": {
+ "description": "Size of the bootloader",
+ "value": "0x18000"
+ },
+ "scratch_address": {
+ "description": "Address of the scratch area",
+ "value": "0x18440000"
+ },
+ "scratch_size": {
+ "description": "Size of the scratch area",
+ "value": "0x80000"
+ },
+ "status_address": {
+ "description": "Address of the swap status partition",
+ "value": "0x10018000"
+ },
+ "status_size": {
+ "description": "Size of the swap status partition",
+ "value": "0x3c00"
+ }
+ },
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x18000000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x40200"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x18080000"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x40200"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h b/boot/cypress/cy_flash_pal/flash_psoc6/include/cy_smif_psoc6.h
similarity index 88%
rename from boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h
rename to boot/cypress/cy_flash_pal/flash_psoc6/include/cy_smif_psoc6.h
index fe1150d..219f3c9 100644
--- a/boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/include/cy_smif_psoc6.h
@@ -48,17 +48,19 @@
#ifndef CY_SMIF_PSOC6_H_
#define CY_SMIF_PSOC6_H_
+#ifndef CYW20829
+
#include "stddef.h"
#include "stdbool.h"
#include "flash_qspi.h"
-#ifndef off_t
-typedef long int off_t;
-#endif
+typedef unsigned long offset_t;
-int psoc6_smif_read(const struct flash_area *fap, off_t addr, void *data, size_t len);
-int psoc6_smif_write(const struct flash_area *fap, off_t addr, const void *data, size_t len);
-int psoc6_smif_erase(off_t addr, size_t size);
+int psoc6_smif_read(const struct flash_area *fap, offset_t addr, void *data, size_t len);
+int psoc6_smif_write(const struct flash_area *fap, offset_t addr, const void *data, size_t len);
+int psoc6_smif_erase(offset_t addr, size_t size);
#endif /* CY_SMIF_PSOC6_H_ */
+
+#endif /* CYW20829 */
diff --git a/boot/cypress/cy_flash_pal/include/flash_map_backend/flash_map_backend.h b/boot/cypress/cy_flash_pal/flash_psoc6/include/flash_map_backend/flash_map_backend.h
similarity index 88%
rename from boot/cypress/cy_flash_pal/include/flash_map_backend/flash_map_backend.h
rename to boot/cypress/cy_flash_pal/flash_psoc6/include/flash_map_backend/flash_map_backend.h
index 4b9409b..194f798 100644
--- a/boot/cypress/cy_flash_pal/include/flash_map_backend/flash_map_backend.h
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/include/flash_map_backend/flash_map_backend.h
@@ -39,7 +39,7 @@
#ifndef CY_BOOT_EXTERNAL_DEVICE_INDEX
/* assume first(one) SMIF device is used */
-#define CY_BOOT_EXTERNAL_DEVICE_INDEX (0)
+#define CY_BOOT_EXTERNAL_DEVICE_INDEX (0u)
#endif
/**
@@ -93,6 +93,26 @@
uint32_t fa_size;
};
+static inline uint8_t flash_area_get_id(const struct flash_area *fa)
+{
+ return fa->fa_id;
+}
+
+static inline uint8_t flash_area_get_device_id(const struct flash_area *fa)
+{
+ return fa->fa_device_id;
+}
+
+static inline uint32_t flash_area_get_off(const struct flash_area *fa)
+{
+ return fa->fa_off;
+}
+
+static inline uint32_t flash_area_get_size(const struct flash_area *fa)
+{
+ return fa->fa_size;
+}
+
/**
* @brief Structure describing a sector within a flash area.
*
@@ -112,6 +132,16 @@
uint32_t fs_size;
};
+static inline uint32_t flash_sector_get_off(const struct flash_sector *fs)
+{
+ return fs->fs_off;
+}
+
+static inline uint32_t flash_sector_get_size(const struct flash_sector *fs)
+{
+ return fs->fs_size;
+}
+
struct flash_map_entry {
uint32_t magic;
struct flash_area area;
@@ -128,7 +158,7 @@
/*< Opens the area for use. id is one of the `fa_id`s */
int flash_area_open(uint8_t id, const struct flash_area **fa);
-void flash_area_close(const struct flash_area *);
+void flash_area_close(const struct flash_area *fa);
/*< Reads `len` bytes of flash memory at `off` to the buffer at `dst` */
int flash_area_read(const struct flash_area *fa, uint32_t off, void *dst,
uint32_t len);
@@ -137,8 +167,6 @@
const void *src, uint32_t len);
/*< Erases `len` bytes of flash memory at `off` */
int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len);
-/*< Erases aligned row of flash, where passed address resided */
-int flash_erase_row(uint32_t address);
/*< Returns this `flash_area`s alignment */
size_t flash_area_align(const struct flash_area *fa);
/*< Initializes an array of flash_area elements for the slot's sectors */
@@ -159,12 +187,4 @@
*/
uint8_t flash_area_erased_val(const struct flash_area *fa);
-/*
- * Reads len bytes from off, and checks if the read data is erased.
- *
- * Returns 1 if erased, 0 if non-erased, and -1 on failure.
- */
-int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off,
- void *dst, uint32_t len);
-
#endif /* FLASH_MAP_BACKEND_H */
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/smif_cfg_dbg/cycfg_qspi_memslot.c b/boot/cypress/cy_flash_pal/flash_psoc6/smif_cfg_dbg/cycfg_qspi_memslot.c
new file mode 100644
index 0000000..bcf6841
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/smif_cfg_dbg/cycfg_qspi_memslot.c
@@ -0,0 +1,474 @@
+/*******************************************************************************
+* File Name: cycfg_qspi_memslot.c
+*
+* Description:
+* Provides definitions of the SMIF-driver memory configuration.
+* This file was automatically generated and should not be modified.
+* QSPI Configurator 3.0.0.5613
+*
+********************************************************************************
+* Copyright 2022 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#include "cycfg_qspi_memslot.h"
+
+const cy_stc_smif_mem_cmd_t __attribute__((section (".smif_struct")))
+S25FL512S_SlaveSlot_0_readCmd =
+{
+ /* The 8-bit command. 1 x I/O read command. */
+ .command = 0xECU,
+ /* The width of the command transfer. */
+ .cmdWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The width of the address transfer. */
+ .addrWidth = CY_SMIF_WIDTH_QUAD,
+ /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present. */
+ .mode = 0x01U,
+ /* The width of the mode command transfer. */
+ .modeWidth = CY_SMIF_WIDTH_QUAD,
+ /* The number of dummy cycles. A zero value suggests no dummy cycles. */
+ .dummyCycles = 4U,
+ /* The width of the data transfer. */
+ .dataWidth = CY_SMIF_WIDTH_QUAD,
+#if (CY_IP_MXSMIF_VERSION >= 3)
+ /* The Data rate of data */
+ .dataRate = CY_SMIF_SDR,
+ /* This specifies the presence of the dummy field */
+ .dummyCyclesPresence = CY_SMIF_PRESENT_1BYTE,
+ /* This specifies the presence of the mode field */
+ .modePresence = CY_SMIF_PRESENT_1BYTE,
+ /* The high byte of a 16-bit mode. This value is 0x0 when there is no higher byte mode present */
+ .modeH = 0x00,
+ /* The Data rate of mode */
+ .modeRate = CY_SMIF_SDR,
+ /* The Data rate of address */
+ .addrRate = CY_SMIF_SDR,
+ /* This specifies the width of the command field */
+ .cmdPresence = CY_SMIF_PRESENT_1BYTE,
+ /* The high byte of a 16-bit command. This value is 0x0 when there is no higher byte command present */
+ .commandH = 0x00,
+ /* The Data rate of command */
+ .cmdRate = CY_SMIF_SDR
+#endif /* CY_IP_MXSMIF_VERSION */
+};
+
+const cy_stc_smif_mem_cmd_t __attribute__((section (".smif_struct")))
+S25FL512S_SlaveSlot_0_writeEnCmd =
+{
+ /* The 8-bit command. 1 x I/O read command. */
+ .command = 0x06U,
+ /* The width of the command transfer. */
+ .cmdWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The width of the address transfer. */
+ .addrWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present. */
+ .mode = 0xFFFFFFFFU,
+ /* The width of the mode command transfer. */
+ .modeWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The number of dummy cycles. A zero value suggests no dummy cycles. */
+ .dummyCycles = 0U,
+ /* The width of the data transfer. */
+ .dataWidth = CY_SMIF_WIDTH_SINGLE,
+#if (CY_IP_MXSMIF_VERSION >= 3)
+ /* The Data rate of data */
+ .dataRate = CY_SMIF_SDR,
+ /* This specifies the presence of the dummy field */
+ .dummyCyclesPresence = CY_SMIF_NOT_PRESENT,
+ /* This specifies the presence of the mode field */
+ .modePresence = CY_SMIF_NOT_PRESENT,
+ /* The high byte of a 16-bit mode. This value is 0x0 when there is no higher byte mode present */
+ .modeH = 0x00,
+ /* The Data rate of mode */
+ .modeRate = CY_SMIF_SDR,
+ /* The Data rate of address */
+ .addrRate = CY_SMIF_SDR,
+ /* This specifies the width of the command field */
+ .cmdPresence = CY_SMIF_PRESENT_1BYTE,
+ /* The high byte of a 16-bit command. This value is 0x0 when there is no higher byte command present */
+ .commandH = 0x00,
+ /* The Data rate of command */
+ .cmdRate = CY_SMIF_SDR
+#endif /* CY_IP_MXSMIF_VERSION */
+};
+
+const cy_stc_smif_mem_cmd_t __attribute__((section (".smif_struct")))
+S25FL512S_SlaveSlot_0_writeDisCmd =
+{
+ /* The 8-bit command. 1 x I/O read command. */
+ .command = 0x04U,
+ /* The width of the command transfer. */
+ .cmdWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The width of the address transfer. */
+ .addrWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present. */
+ .mode = 0xFFFFFFFFU,
+ /* The width of the mode command transfer. */
+ .modeWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The number of dummy cycles. A zero value suggests no dummy cycles. */
+ .dummyCycles = 0U,
+ /* The width of the data transfer. */
+ .dataWidth = CY_SMIF_WIDTH_SINGLE,
+#if (CY_IP_MXSMIF_VERSION >= 3)
+ /* The Data rate of data */
+ .dataRate = CY_SMIF_SDR,
+ /* This specifies the presence of the dummy field */
+ .dummyCyclesPresence = CY_SMIF_NOT_PRESENT,
+ /* This specifies the presence of the mode field */
+ .modePresence = CY_SMIF_NOT_PRESENT,
+ /* The high byte of a 16-bit mode. This value is 0x0 when there is no higher byte mode present */
+ .modeH = 0x00,
+ /* The Data rate of mode */
+ .modeRate = CY_SMIF_SDR,
+ /* The Data rate of address */
+ .addrRate = CY_SMIF_SDR,
+ /* This specifies the width of the command field */
+ .cmdPresence = CY_SMIF_PRESENT_1BYTE,
+ /* The high byte of a 16-bit command. This value is 0x0 when there is no higher byte command present */
+ .commandH = 0x00,
+ /* The Data rate of command */
+ .cmdRate = CY_SMIF_SDR
+#endif /* CY_IP_MXSMIF_VERSION */
+};
+
+const cy_stc_smif_mem_cmd_t __attribute__((section (".smif_struct")))
+S25FL512S_SlaveSlot_0_eraseCmd =
+{
+ /* The 8-bit command. 1 x I/O read command. */
+ .command = 0xDCU,
+ /* The width of the command transfer. */
+ .cmdWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The width of the address transfer. */
+ .addrWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present. */
+ .mode = 0xFFFFFFFFU,
+ /* The width of the mode command transfer. */
+ .modeWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The number of dummy cycles. A zero value suggests no dummy cycles. */
+ .dummyCycles = 0U,
+ /* The width of the data transfer. */
+ .dataWidth = CY_SMIF_WIDTH_SINGLE,
+#if (CY_IP_MXSMIF_VERSION >= 3)
+ /* The Data rate of data */
+ .dataRate = CY_SMIF_SDR,
+ /* This specifies the presence of the dummy field */
+ .dummyCyclesPresence = CY_SMIF_NOT_PRESENT,
+ /* This specifies the presence of the mode field */
+ .modePresence = CY_SMIF_NOT_PRESENT,
+ /* The high byte of a 16-bit mode. This value is 0x0 when there is no higher byte mode present */
+ .modeH = 0x00,
+ /* The Data rate of mode */
+ .modeRate = CY_SMIF_SDR,
+ /* The Data rate of address */
+ .addrRate = CY_SMIF_SDR,
+ /* This specifies the width of the command field */
+ .cmdPresence = CY_SMIF_PRESENT_1BYTE,
+ /* The high byte of a 16-bit command. This value is 0x0 when there is no higher byte command present */
+ .commandH = 0x00,
+ /* The Data rate of command */
+ .cmdRate = CY_SMIF_SDR
+#endif /* CY_IP_MXSMIF_VERSION */
+};
+
+const cy_stc_smif_mem_cmd_t __attribute__((section (".smif_struct")))
+S25FL512S_SlaveSlot_0_chipEraseCmd =
+{
+ /* The 8-bit command. 1 x I/O read command. */
+ .command = 0x60U,
+ /* The width of the command transfer. */
+ .cmdWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The width of the address transfer. */
+ .addrWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present. */
+ .mode = 0xFFFFFFFFU,
+ /* The width of the mode command transfer. */
+ .modeWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The number of dummy cycles. A zero value suggests no dummy cycles. */
+ .dummyCycles = 0U,
+ /* The width of the data transfer. */
+ .dataWidth = CY_SMIF_WIDTH_SINGLE,
+#if (CY_IP_MXSMIF_VERSION >= 3)
+ /* The Data rate of data */
+ .dataRate = CY_SMIF_SDR,
+ /* This specifies the presence of the dummy field */
+ .dummyCyclesPresence = CY_SMIF_NOT_PRESENT,
+ /* This specifies the presence of the mode field */
+ .modePresence = CY_SMIF_NOT_PRESENT,
+ /* The high byte of a 16-bit mode. This value is 0x0 when there is no higher byte mode present */
+ .modeH = 0x00,
+ /* The Data rate of mode */
+ .modeRate = CY_SMIF_SDR,
+ /* The Data rate of address */
+ .addrRate = CY_SMIF_SDR,
+ /* This specifies the width of the command field */
+ .cmdPresence = CY_SMIF_PRESENT_1BYTE,
+ /* The high byte of a 16-bit command. This value is 0x0 when there is no higher byte command present */
+ .commandH = 0x00,
+ /* The Data rate of command */
+ .cmdRate = CY_SMIF_SDR
+#endif /* CY_IP_MXSMIF_VERSION */
+};
+
+const cy_stc_smif_mem_cmd_t __attribute__((section (".smif_struct")))
+S25FL512S_SlaveSlot_0_programCmd =
+{
+ /* The 8-bit command. 1 x I/O read command. */
+ .command = 0x34U,
+ /* The width of the command transfer. */
+ .cmdWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The width of the address transfer. */
+ .addrWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present. */
+ .mode = 0xFFFFFFFFU,
+ /* The width of the mode command transfer. */
+ .modeWidth = CY_SMIF_WIDTH_QUAD,
+ /* The number of dummy cycles. A zero value suggests no dummy cycles. */
+ .dummyCycles = 0U,
+ /* The width of the data transfer. */
+ .dataWidth = CY_SMIF_WIDTH_QUAD,
+#if (CY_IP_MXSMIF_VERSION >= 3)
+ /* The Data rate of data */
+ .dataRate = CY_SMIF_SDR,
+ /* This specifies the presence of the dummy field */
+ .dummyCyclesPresence = CY_SMIF_NOT_PRESENT,
+ /* This specifies the presence of the mode field */
+ .modePresence = CY_SMIF_NOT_PRESENT,
+ /* The high byte of a 16-bit mode. This value is 0x0 when there is no higher byte mode present */
+ .modeH = 0x00,
+ /* The Data rate of mode */
+ .modeRate = CY_SMIF_SDR,
+ /* The Data rate of address */
+ .addrRate = CY_SMIF_SDR,
+ /* This specifies the width of the command field */
+ .cmdPresence = CY_SMIF_PRESENT_1BYTE,
+ /* The high byte of a 16-bit command. This value is 0x0 when there is no higher byte command present */
+ .commandH = 0x00,
+ /* The Data rate of command */
+ .cmdRate = CY_SMIF_SDR
+#endif /* CY_IP_MXSMIF_VERSION */
+};
+
+const cy_stc_smif_mem_cmd_t __attribute__((section (".smif_struct")))
+S25FL512S_SlaveSlot_0_readStsRegQeCmd =
+{
+ /* The 8-bit command. 1 x I/O read command. */
+ .command = 0x35U,
+ /* The width of the command transfer. */
+ .cmdWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The width of the address transfer. */
+ .addrWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present. */
+ .mode = 0xFFFFFFFFU,
+ /* The width of the mode command transfer. */
+ .modeWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The number of dummy cycles. A zero value suggests no dummy cycles. */
+ .dummyCycles = 0U,
+ /* The width of the data transfer. */
+ .dataWidth = CY_SMIF_WIDTH_SINGLE,
+#if (CY_IP_MXSMIF_VERSION >= 3)
+ /* The Data rate of data */
+ .dataRate = CY_SMIF_SDR,
+ /* This specifies the presence of the dummy field */
+ .dummyCyclesPresence = CY_SMIF_NOT_PRESENT,
+ /* This specifies the presence of the mode field */
+ .modePresence = CY_SMIF_NOT_PRESENT,
+ /* The high byte of a 16-bit mode. This value is 0x0 when there is no higher byte mode present */
+ .modeH = 0x00,
+ /* The Data rate of mode */
+ .modeRate = CY_SMIF_SDR,
+ /* The Data rate of address */
+ .addrRate = CY_SMIF_SDR,
+ /* This specifies the width of the command field */
+ .cmdPresence = CY_SMIF_PRESENT_1BYTE,
+ /* The high byte of a 16-bit command. This value is 0x0 when there is no higher byte command present */
+ .commandH = 0x00,
+ /* The Data rate of command */
+ .cmdRate = CY_SMIF_SDR
+#endif /* CY_IP_MXSMIF_VERSION */
+};
+
+const cy_stc_smif_mem_cmd_t __attribute__((section (".smif_struct")))
+S25FL512S_SlaveSlot_0_readStsRegWipCmd =
+{
+ /* The 8-bit command. 1 x I/O read command. */
+ .command = 0x05U,
+ /* The width of the command transfer. */
+ .cmdWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The width of the address transfer. */
+ .addrWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present. */
+ .mode = 0xFFFFFFFFU,
+ /* The width of the mode command transfer. */
+ .modeWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The number of dummy cycles. A zero value suggests no dummy cycles. */
+ .dummyCycles = 0U,
+ /* The width of the data transfer. */
+ .dataWidth = CY_SMIF_WIDTH_SINGLE,
+#if (CY_IP_MXSMIF_VERSION >= 3)
+ /* The Data rate of data */
+ .dataRate = CY_SMIF_SDR,
+ /* This specifies the presence of the dummy field */
+ .dummyCyclesPresence = CY_SMIF_NOT_PRESENT,
+ /* This specifies the presence of the mode field */
+ .modePresence = CY_SMIF_NOT_PRESENT,
+ /* The high byte of a 16-bit mode. This value is 0x0 when there is no higher byte mode present */
+ .modeH = 0x00,
+ /* The Data rate of mode */
+ .modeRate = CY_SMIF_SDR,
+ /* The Data rate of address */
+ .addrRate = CY_SMIF_SDR,
+ /* This specifies the width of the command field */
+ .cmdPresence = CY_SMIF_PRESENT_1BYTE,
+ /* The high byte of a 16-bit command. This value is 0x0 when there is no higher byte command present */
+ .commandH = 0x00,
+ /* The Data rate of command */
+ .cmdRate = CY_SMIF_SDR
+#endif /* CY_IP_MXSMIF_VERSION */
+};
+
+const cy_stc_smif_mem_cmd_t __attribute__((section (".smif_struct")))
+S25FL512S_SlaveSlot_0_writeStsRegQeCmd =
+{
+ /* The 8-bit command. 1 x I/O read command. */
+ .command = 0x01U,
+ /* The width of the command transfer. */
+ .cmdWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The width of the address transfer. */
+ .addrWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present. */
+ .mode = 0xFFFFFFFFU,
+ /* The width of the mode command transfer. */
+ .modeWidth = CY_SMIF_WIDTH_SINGLE,
+ /* The number of dummy cycles. A zero value suggests no dummy cycles. */
+ .dummyCycles = 0U,
+ /* The width of the data transfer. */
+ .dataWidth = CY_SMIF_WIDTH_SINGLE,
+#if (CY_IP_MXSMIF_VERSION >= 3)
+ /* The Data rate of data */
+ .dataRate = CY_SMIF_SDR,
+ /* This specifies the presence of the dummy field */
+ .dummyCyclesPresence = CY_SMIF_NOT_PRESENT,
+ /* This specifies the presence of the mode field */
+ .modePresence = CY_SMIF_NOT_PRESENT,
+ /* The high byte of a 16-bit mode. This value is 0x0 when there is no higher byte mode present */
+ .modeH = 0x00,
+ /* The Data rate of mode */
+ .modeRate = CY_SMIF_SDR,
+ /* The Data rate of address */
+ .addrRate = CY_SMIF_SDR,
+ /* This specifies the width of the command field */
+ .cmdPresence = CY_SMIF_PRESENT_1BYTE,
+ /* The high byte of a 16-bit command. This value is 0x0 when there is no higher byte command present */
+ .commandH = 0x00,
+ /* The Data rate of command */
+ .cmdRate = CY_SMIF_SDR
+#endif /* CY_IP_MXSMIF_VERSION */
+};
+
+const cy_stc_smif_mem_device_cfg_t __attribute__((section (".smif_struct")))
+deviceCfg_S25FL512S_SlaveSlot_0 =
+{
+ /* Specifies the number of address bytes used by the memory slave device. */
+ .numOfAddrBytes = 0x04U,
+ /* The size of the memory. */
+ .memSize = 0x04000000U,
+ /* Specifies the Read command. */
+ .readCmd = (cy_stc_smif_mem_cmd_t*)&S25FL512S_SlaveSlot_0_readCmd,
+ /* Specifies the Write Enable command. */
+ .writeEnCmd = (cy_stc_smif_mem_cmd_t*)&S25FL512S_SlaveSlot_0_writeEnCmd,
+ /* Specifies the Write Disable command. */
+ .writeDisCmd = (cy_stc_smif_mem_cmd_t*)&S25FL512S_SlaveSlot_0_writeDisCmd,
+ /* Specifies the Erase command. */
+ .eraseCmd = (cy_stc_smif_mem_cmd_t*)&S25FL512S_SlaveSlot_0_eraseCmd,
+ /* Specifies the sector size of each erase. */
+ .eraseSize = 0x00040000U,
+ /* Specifies the Chip Erase command. */
+ .chipEraseCmd = (cy_stc_smif_mem_cmd_t*)&S25FL512S_SlaveSlot_0_chipEraseCmd,
+ /* Specifies the Program command. */
+ .programCmd = (cy_stc_smif_mem_cmd_t*)&S25FL512S_SlaveSlot_0_programCmd,
+ /* Specifies the page size for programming. */
+ .programSize = 0x00000200U,
+ /* Specifies the command to read the QE-containing status register. */
+ .readStsRegQeCmd = (cy_stc_smif_mem_cmd_t*)&S25FL512S_SlaveSlot_0_readStsRegQeCmd,
+ /* Specifies the command to read the WIP-containing status register. */
+ .readStsRegWipCmd = (cy_stc_smif_mem_cmd_t*)&S25FL512S_SlaveSlot_0_readStsRegWipCmd,
+ /* Specifies the command to write into the QE-containing status register. */
+ .writeStsRegQeCmd = (cy_stc_smif_mem_cmd_t*)&S25FL512S_SlaveSlot_0_writeStsRegQeCmd,
+ /* The mask for the status register. */
+ .stsRegBusyMask = 0x01U,
+ /* The mask for the status register. */
+ .stsRegQuadEnableMask = 0x02U,
+ /* The max time for the erase type-1 cycle-time in ms. */
+ .eraseTime = 2600U,
+ /* The max time for the chip-erase cycle-time in ms. */
+ .chipEraseTime = 460000U,
+ /* The max time for the page-program cycle-time in us. */
+ .programTime = 1300U,
+#if (CY_SMIF_DRV_VERSION_MAJOR > 1) || (CY_SMIF_DRV_VERSION_MINOR >= 50)
+ /* Points to NULL or to structure with info about sectors for hybrid memory. */
+ .hybridRegionCount = 0U,
+ .hybridRegionInfo = NULL
+#endif
+};
+
+const cy_stc_smif_mem_config_t __attribute__((section (".smif_struct")))
+S25FL512S_SlaveSlot_0 =
+{
+ /* Determines the slot number where the memory device is placed. */
+ .slaveSelect = CY_SMIF_SLAVE_SELECT_0,
+ /* Flags. */
+#if (CY_IP_MXSMIF_VERSION >= 3)
+ .flags = CY_SMIF_FLAG_SMIF_REV_3 | CY_SMIF_FLAG_MEMORY_MAPPED | CY_SMIF_FLAG_WR_EN,
+#else
+ .flags = CY_SMIF_FLAG_MEMORY_MAPPED | CY_SMIF_FLAG_WR_EN,
+#endif /* CY_IP_MXSMIF_VERSION */
+ /* The data-line selection options for a slave device. */
+ .dataSelect = CY_SMIF_DATA_SEL0,
+ /* The base address the memory slave is mapped to in the PSoC memory map.
+ Valid when the memory-mapped mode is enabled. */
+ .baseAddress = 0x18000000U,
+ /* The size allocated in the PSoC memory map, for the memory slave device.
+ The size is allocated from the base address. Valid when the memory mapped mode is enabled. */
+ .memMappedSize = 0x400000U,
+ /* If this memory device is one of the devices in the dual quad SPI configuration.
+ Valid when the memory mapped mode is enabled. */
+ .dualQuadSlots = 0,
+ /* The configuration of the device. */
+ .deviceCfg = (cy_stc_smif_mem_device_cfg_t*)&deviceCfg_S25FL512S_SlaveSlot_0,
+#if (CY_IP_MXSMIF_VERSION >= 3)
+ /** Continous transfer merge timeout.
+ * After this period the memory device is deselected. A later transfer, even from a
+ * continuous address, starts with the overhead phases (command, address, mode, dummy cycles).
+ * This configuration parameter is available for CAT1B devices. */
+ .mergeTimeout = CY_SMIF_MERGE_TIMEOUT_1_CYCLE
+#endif /* CY_IP_MXSMIF_VERSION */
+};
+
+const cy_stc_smif_mem_config_t* const __attribute__((section (".smif_struct")))
+smifMemConfigs[CY_SMIF_DEVICE_NUM] = {
+ &S25FL512S_SlaveSlot_0
+};
+
+const cy_stc_smif_block_config_t __attribute__((section (".smif_struct")))
+smifBlockConfig =
+{
+ /* The number of SMIF memories defined. */
+ .memCount = CY_SMIF_DEVICE_NUM,
+ /* The pointer to the array of memory config structures of size memCount. */
+ .memConfig = (cy_stc_smif_mem_config_t**)smifMemConfigs,
+ /* The version of the SMIF driver. */
+ .majorVersion = CY_SMIF_DRV_VERSION_MAJOR,
+ /* The version of the SMIF driver. */
+ .minorVersion = CY_SMIF_DRV_VERSION_MINOR
+};
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/smif_cfg_dbg/cycfg_qspi_memslot.h b/boot/cypress/cy_flash_pal/flash_psoc6/smif_cfg_dbg/cycfg_qspi_memslot.h
new file mode 100644
index 0000000..884be8f
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/smif_cfg_dbg/cycfg_qspi_memslot.h
@@ -0,0 +1,65 @@
+/*******************************************************************************
+* File Name: cycfg_qspi_memslot.h
+*
+* Description:
+* Provides declarations of the SMIF-driver memory configuration.
+* This file was automatically generated and should not be modified.
+* QSPI Configurator 3.0.0.5613
+*
+********************************************************************************
+* Copyright 2022 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#ifndef CYCFG_QSPI_MEMSLOT_H
+#define CYCFG_QSPI_MEMSLOT_H
+#include "cy_smif_memslot.h"
+
+#define CY_SMIF_CFG_TOOL_VERSION (300)
+
+/* Supported QSPI Driver version */
+#define CY_SMIF_DRV_VERSION_REQUIRED (100)
+
+#if !defined(CY_SMIF_DRV_VERSION)
+ #define CY_SMIF_DRV_VERSION (100)
+#endif
+
+/* Check the used Driver version */
+#if (CY_SMIF_DRV_VERSION_REQUIRED > CY_SMIF_DRV_VERSION)
+ #error The QSPI Configurator requires a newer version of the PDL. Update the PDL in your project.
+#endif
+
+#define CY_SMIF_DEVICE_NUM 1
+
+extern const cy_stc_smif_mem_cmd_t S25FL512S_SlaveSlot_0_readCmd;
+extern const cy_stc_smif_mem_cmd_t S25FL512S_SlaveSlot_0_writeEnCmd;
+extern const cy_stc_smif_mem_cmd_t S25FL512S_SlaveSlot_0_writeDisCmd;
+extern const cy_stc_smif_mem_cmd_t S25FL512S_SlaveSlot_0_eraseCmd;
+extern const cy_stc_smif_mem_cmd_t S25FL512S_SlaveSlot_0_chipEraseCmd;
+extern const cy_stc_smif_mem_cmd_t S25FL512S_SlaveSlot_0_programCmd;
+extern const cy_stc_smif_mem_cmd_t S25FL512S_SlaveSlot_0_readStsRegQeCmd;
+extern const cy_stc_smif_mem_cmd_t S25FL512S_SlaveSlot_0_readStsRegWipCmd;
+extern const cy_stc_smif_mem_cmd_t S25FL512S_SlaveSlot_0_writeStsRegQeCmd;
+
+extern const cy_stc_smif_mem_device_cfg_t deviceCfg_S25FL512S_SlaveSlot_0;
+
+extern const cy_stc_smif_mem_config_t S25FL512S_SlaveSlot_0;
+
+extern const cy_stc_smif_mem_config_t* const smifMemConfigs[CY_SMIF_DEVICE_NUM];
+
+extern const cy_stc_smif_block_config_t smifBlockConfig;
+
+
+#endif /*CYCFG_QSPI_MEMSLOT_H*/
diff --git a/boot/cypress/cy_flash_pal/flash_psoc6/smif_cfg_dbg/qspi_config.cfg b/boot/cypress/cy_flash_pal/flash_psoc6/smif_cfg_dbg/qspi_config.cfg
new file mode 100644
index 0000000..96ff76a
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_psoc6/smif_cfg_dbg/qspi_config.cfg
@@ -0,0 +1,28 @@
+################################################################################
+# File Name: qspi_config.cfg
+#
+# Description:
+# This file contains a SMIF Bank layout for use with OpenOCD.
+# This file was automatically generated and should not be modified.
+# QSPI Configurator: 3.0.0.5613
+#
+################################################################################
+# Copyright 2022 Cypress Semiconductor Corporation
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+################################################################################
+
+set SMIF_BANKS {
+ 0 {addr 0x18000000 size 0x400000 psize 0x00000200 esize 0x00040000}
+}
diff --git a/boot/cypress/cy_flash_pal/sysflash/sysflash.h b/boot/cypress/cy_flash_pal/sysflash/sysflash.h
new file mode 100644
index 0000000..dfe015f
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/sysflash/sysflash.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2020 Cypress Semiconductor Corporation
+ * Copyright (c) 2022 Infineon Technologies AG
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+#ifndef SYSFLASH_H
+#define SYSFLASH_H
+
+#include <stdint.h>
+#include "cy_syslib.h"
+
+#ifndef MCUBOOT_IMAGE_NUMBER
+#ifdef MCUBootApp
+#warning Undefined MCUBOOT_IMAGE_NUMBER. Assuming 1 (single-image).
+#endif /* MCUBootApp */
+#define MCUBOOT_IMAGE_NUMBER 1
+#endif /* MCUBOOT_IMAGE_NUMBER */
+
+#if (MCUBOOT_IMAGE_NUMBER < 1 || MCUBOOT_IMAGE_NUMBER > 4)
+#error Unsupported MCUBOOT_IMAGE_NUMBER. Set it to between 1 and 4.
+#endif /* (MCUBOOT_IMAGE_NUMBER < 1 || MCUBOOT_IMAGE_NUMBER > 4) */
+
+#define FLASH_AREA_BOOTLOADER ( 0u)
+
+#define FLASH_AREA_IMG_1_PRIMARY ( 1u)
+#define FLASH_AREA_IMG_1_SECONDARY ( 2u)
+
+#define FLASH_AREA_IMAGE_SCRATCH ( 3u)
+
+#if MCUBOOT_IMAGE_NUMBER >= 2
+#define FLASH_AREA_IMG_2_PRIMARY ( 4u)
+#define FLASH_AREA_IMG_2_SECONDARY ( 5u)
+#endif /* MCUBOOT_IMAGE_NUMBER >= 2 */
+
+#define FLASH_AREA_IMAGE_SWAP_STATUS ( 7u)
+
+#if MCUBOOT_IMAGE_NUMBER >= 3
+#define FLASH_AREA_IMG_3_PRIMARY ( 8u)
+#define FLASH_AREA_IMG_3_SECONDARY ( 9u)
+#endif /* MCUBOOT_IMAGE_NUMBER >= 3 */
+
+#if MCUBOOT_IMAGE_NUMBER == 4
+#define FLASH_AREA_IMG_4_PRIMARY (10u)
+#define FLASH_AREA_IMG_4_SECONDARY (11u)
+#endif /* MCUBOOT_IMAGE_NUMBER == 4 */
+
+#define FLASH_AREA_ERROR 255u /* Invalid flash area */
+
+#ifdef PSOC6
+#define CY_SMIF_BASE_MEM_OFFSET 0x18000000u
+#endif /* PSOC6 */
+
+/* This defines if External Flash (SMIF) will be used for Upgrade Slots */
+#ifdef CYW20829
+#define CY_FLASH_BASE CY_XIP_BASE
+#define CY_SMIF_BASE_MEM_OFFSET CY_FLASH_BASE
+#define CY_FLASH_SIZEOF_ROW 4096u
+#endif /* CYW20829 */
+
+/* use PDL-defined offset or one from SMIF config */
+#define CY_SMIF_BASE (CY_XIP_BASE)
+
+#define CY_FLASH_ALIGN (CY_FLASH_SIZEOF_ROW)
+#define CY_FLASH_DEVICE_BASE (CY_FLASH_BASE)
+
+#define CY_IMG_HDR_SIZE 0x400
+#define BOOT_MAX_SWAP_STATUS_SECTORS (64)
+
+__STATIC_INLINE uint8_t FLASH_AREA_IMAGE_PRIMARY(uint32_t img_idx)
+{
+ uint8_t result = FLASH_AREA_ERROR;
+
+ if (img_idx < (uint32_t)MCUBOOT_IMAGE_NUMBER) {
+ static const uint8_t areas[] = {
+ FLASH_AREA_IMG_1_PRIMARY,
+#if MCUBOOT_IMAGE_NUMBER >= 2
+ FLASH_AREA_IMG_2_PRIMARY,
+#endif /* MCUBOOT_IMAGE_NUMBER >= 2 */
+#if MCUBOOT_IMAGE_NUMBER >= 3
+ FLASH_AREA_IMG_3_PRIMARY,
+#endif /* MCUBOOT_IMAGE_NUMBER >= 3 */
+#if MCUBOOT_IMAGE_NUMBER == 4
+ FLASH_AREA_IMG_4_PRIMARY
+#endif /* MCUBOOT_IMAGE_NUMBER == 4 */
+ };
+
+ result = areas[img_idx];
+ }
+
+ return result;
+}
+
+__STATIC_INLINE uint8_t FLASH_AREA_IMAGE_SECONDARY(uint32_t img_idx)
+{
+ uint8_t result = FLASH_AREA_ERROR;
+
+ if (img_idx < (uint32_t)MCUBOOT_IMAGE_NUMBER) {
+ static const uint8_t areas[] = {
+ FLASH_AREA_IMG_1_SECONDARY,
+#if MCUBOOT_IMAGE_NUMBER >= 2
+ FLASH_AREA_IMG_2_SECONDARY,
+#endif /* MCUBOOT_IMAGE_NUMBER >= 2 */
+#if MCUBOOT_IMAGE_NUMBER >= 3
+ FLASH_AREA_IMG_3_SECONDARY,
+#endif /* MCUBOOT_IMAGE_NUMBER >= 3 */
+#if MCUBOOT_IMAGE_NUMBER == 4
+ FLASH_AREA_IMG_4_SECONDARY
+#endif /* MCUBOOT_IMAGE_NUMBER == 4 */
+ };
+
+ result = areas[img_idx];
+ }
+
+ return result;
+}
+
+#endif /* SYSFLASH_H */
diff --git a/boot/cypress/host.mk b/boot/cypress/host.mk
index 6b6851e..a1f6ef8 100644
--- a/boot/cypress/host.mk
+++ b/boot/cypress/host.mk
@@ -46,3 +46,12 @@
endif
PRJ_DIR=$(call get_os_path, $(CURDIR))
+
+###############################################################################
+# Print debug information about all settings used and/or set in this file
+ifeq ($(VERBOSE), 1)
+$(info #### host.mk ####)
+$(info CURDIR <-- $(CURDIR))
+$(info HOST_OS <-- $(HOST_OS))
+$(info UNAME_S <-> $(UNAME_S))
+endif
diff --git a/boot/cypress/libs/core-lib b/boot/cypress/libs/core-lib
index a0f53cd..7e6892e 160000
--- a/boot/cypress/libs/core-lib
+++ b/boot/cypress/libs/core-lib
@@ -1 +1 @@
-Subproject commit a0f53cdda39a373c45cdbf9f853c8018c1172461
+Subproject commit 7e6892ee1eeabc8f6c25fbf02cb00ff43bd3ac73
diff --git a/boot/cypress/libs/mtb-hal-cat1 b/boot/cypress/libs/mtb-hal-cat1
new file mode 160000
index 0000000..708a6b2
--- /dev/null
+++ b/boot/cypress/libs/mtb-hal-cat1
@@ -0,0 +1 @@
+Subproject commit 708a6b2542f0d8814c129a3141e78fd265826a0b
diff --git a/boot/cypress/libs/mtb-pdl-cat1 b/boot/cypress/libs/mtb-pdl-cat1
index 55b5a54..3c6aebd 160000
--- a/boot/cypress/libs/mtb-pdl-cat1
+++ b/boot/cypress/libs/mtb-pdl-cat1
@@ -1 +1 @@
-Subproject commit 55b5a5457195ad2a2a02e0a98ca72a9333e26397
+Subproject commit 3c6aebd2f3238b578329bfb8a6c5a0e138bd5c7b
diff --git a/boot/cypress/libs/pdl/psoc6pdl b/boot/cypress/libs/pdl/psoc6pdl
deleted file mode 160000
index 0e38b78..0000000
--- a/boot/cypress/libs/pdl/psoc6pdl
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 0e38b78ef9ae3ce5db0563bdcde80a028c5fc38a
diff --git a/boot/cypress/libs/psoc6hal b/boot/cypress/libs/psoc6hal
deleted file mode 160000
index a0d6c08..0000000
--- a/boot/cypress/libs/psoc6hal
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit a0d6c08f1178750e29967999860485878fac09f9
diff --git a/boot/cypress/libs/retarget-io b/boot/cypress/libs/retarget-io
index bd88e66..a61cd7c 160000
--- a/boot/cypress/libs/retarget-io
+++ b/boot/cypress/libs/retarget-io
@@ -1 +1 @@
-Subproject commit bd88e66fc6976de49694382a5ce5dc7613f12ace
+Subproject commit a61cd7c5f4b2808c949248f05287c09e6578abfc
diff --git a/boot/cypress/libs/retarget_io_pdl/cy_retarget_io_pdl.c b/boot/cypress/libs/retarget_io_pdl/cy_retarget_io_pdl.c
index 0472f3e..2c02df8 100644
--- a/boot/cypress/libs/retarget_io_pdl/cy_retarget_io_pdl.c
+++ b/boot/cypress/libs/retarget_io_pdl/cy_retarget_io_pdl.c
@@ -36,15 +36,33 @@
/* Tracks the previous character sent to output stream */
#ifdef CY_RETARGET_IO_CONVERT_LF_TO_CRLF
-static char cy_retarget_io_stdout_prev_char = 0;
+static char cy_retarget_io_stdout_prev_char = '\0';
#endif /* CY_RETARGET_IO_CONVERT_LF_TO_CRLF */
-cy_stc_scb_uart_context_t CYBSP_UART_context;
+static cy_stc_scb_uart_context_t CYBSP_UART_context;
static uint8_t cy_retarget_io_getchar(void);
static void cy_retarget_io_putchar(char c);
#if defined(__ARMCC_VERSION) /* ARM-MDK */
+
+int fputc(int ch, FILE *f);
+int fgetc(FILE *f);
+
+#elif defined (__ICCARM__) /* IAR */
+
+size_t __write(int handle, const unsigned char * buffer, size_t size);
+size_t __read(int handle, unsigned char * buffer, size_t size);
+
+#else /* (__GNUC__) GCC */
+
+int _write(int fd, const char *ptr, int len);
+int _read(int fd, char *ptr, int len);
+
+#endif /* defined(__ARMCC_VERSION) */
+
+
+#if defined(__ARMCC_VERSION) /* ARM-MDK */
/***************************************************************************
* Function Name: fputc
***************************************************************************/
@@ -96,13 +114,10 @@
return (nChars);
}
#else /* (__GNUC__) GCC */
- /* Add an explicit reference to the floating point printf library to allow
- the usage of floating point conversion specifier. */
- __asm (".global _printf_float");
/***************************************************************************
* Function Name: _write
***************************************************************************/
- __attribute__((weak)) int _write (int fd, const char *ptr, int len)
+ __attribute__((weak)) int _write(int fd, const char *ptr, int len)
{
int nChars = 0;
(void)fd;
@@ -118,13 +133,13 @@
cy_retarget_io_stdout_prev_char = *ptr;
#endif /* CY_RETARGET_IO_CONVERT_LF_TO_CRLF */
- cy_retarget_io_putchar((uint32_t)*ptr);
+ cy_retarget_io_putchar(*ptr);
++ptr;
}
}
return (nChars);
}
-#endif
+#endif /* defined(__ARMCC_VERSION) */
#if defined(__ARMCC_VERSION) /* ARM-MDK */
@@ -152,16 +167,13 @@
}
}
#else /* (__GNUC__) GCC */
- /* Add an explicit reference to the floating point scanf library to allow
- the usage of floating point conversion specifier. */
- __asm (".global _scanf_float");
- __attribute__((weak)) int _read (int fd, char *ptr, int len)
+ __attribute__((weak)) int _read(int fd, char *ptr, int len)
{
int nChars = 0;
(void)fd;
if (ptr != NULL)
{
- for(/* Empty */;nChars < len;++ptr)
+ while (nChars < len)
{
*ptr = (char)cy_retarget_io_getchar();
++nChars;
@@ -169,11 +181,12 @@
{
break;
}
+ ++ptr;
}
}
return (nChars);
}
-#endif
+#endif /* defined(__ARMCC_VERSION) */
static uint8_t cy_retarget_io_getchar(void)
{
@@ -188,10 +201,10 @@
static void cy_retarget_io_putchar(char c)
{
- uint32_t count = 0;
- while (count == 0)
+ uint32_t count = 0U;
+ while (count == 0U)
{
- count = Cy_SCB_UART_Put(CYBSP_UART_HW, c);
+ count = Cy_SCB_UART_Put(CYBSP_UART_HW, (uint8_t)c);
}
}
@@ -199,24 +212,24 @@
{
cy_rslt_t result = CY_RSLT_TYPE_ERROR;
- uint8_t oversample_value = 8u;
- uint8_t frac_bits = 0u;
+ uint8_t oversample_value = 8U;
+ uint8_t frac_bits = 0U;
uint32_t divider;
Cy_SCB_UART_Disable(base, NULL);
result = (cy_rslt_t) Cy_SysClk_PeriphDisableDivider(CY_SYSCLK_DIV_16_BIT, 0);
- divider = ((Cy_SysClk_ClkPeriGetFrequency() * (1 << frac_bits)) + ((baudrate * oversample_value) / 2)) / (baudrate * oversample_value) - 1;
+ divider = ((Cy_SysClk_ClkPeriGetFrequency() * (1UL << frac_bits)) + ((baudrate * oversample_value) / 2U)) / (baudrate * oversample_value) - 1U;
if (result == CY_RSLT_SUCCESS)
{
- result = (cy_rslt_t) Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_16_BIT, 0u, divider);
+ result = (cy_rslt_t) Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_16_BIT, 0U, divider);
}
if (result == CY_RSLT_SUCCESS)
{
- result = Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_16_BIT, 0u);
+ result = Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_16_BIT, 0U);
}
Cy_SCB_UART_Enable(base);
@@ -249,18 +262,18 @@
*/
void cy_retarget_io_wait_tx_complete(CySCB_Type *base, uint32_t tries_count)
{
- while(tries_count > 0)
+ while(tries_count > 0U)
{
if (!Cy_SCB_UART_IsTxComplete(base)) {
- Cy_SysLib_DelayCycles(10 * cy_delayFreqKhz);
- tries_count -= 1;
+ Cy_SysLib_DelayCycles(10U * cy_delayFreqKhz);
+ tries_count -= 1U;
} else {
return;
}
}
}
-void cy_retarget_io_pdl_deinit()
+void cy_retarget_io_pdl_deinit(void)
{
Cy_SCB_UART_DeInit(CYBSP_UART_HW);
}
diff --git a/boot/cypress/libs/retarget_io_pdl/cy_retarget_io_pdl.h b/boot/cypress/libs/retarget_io_pdl/cy_retarget_io_pdl.h
index f0c8733..4ebfdef 100644
--- a/boot/cypress/libs/retarget_io_pdl/cy_retarget_io_pdl.h
+++ b/boot/cypress/libs/retarget_io_pdl/cy_retarget_io_pdl.h
@@ -29,6 +29,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
+#ifndef CY_RETARGET_IO_PDL_H
+#define CY_RETARGET_IO_PDL_H
#pragma once
@@ -60,3 +62,4 @@
}
#endif
+#endif /* CY_RETARGET_IO_PDL_H */
diff --git a/boot/cypress/libs/watchdog/watchdog.c b/boot/cypress/libs/watchdog/watchdog.c
index 286e9c3..96200ab 100644
--- a/boot/cypress/libs/watchdog/watchdog.c
+++ b/boot/cypress/libs/watchdog/watchdog.c
@@ -28,6 +28,7 @@
#include <stdbool.h>
#include "watchdog.h"
+#include "cy_sysclk.h"
#include "cy_wdt.h"
#include "cy_utils.h"
@@ -36,31 +37,31 @@
#endif
#if defined(COMPONENT_PSOC6)
-#define _cy_wdg_lock() Cy_WDT_Lock()
-#define _cy_wdg_unlock() Cy_WDT_Unlock()
+#define cy_wdg_lock() Cy_WDT_Lock()
+#define cy_wdg_unlock() Cy_WDT_Unlock()
#else
-#define _cy_wdg_lock()
-#define _cy_wdg_unlock()
+#define cy_wdg_lock()
+#define cy_wdg_unlock()
#endif
// ((2^16 * 2) + (2^16 - 1)) * .030518 ms
/** Maximum WDT timeout in milliseconds */
-#define _cy_wdg_MAX_TIMEOUT_MS 6000
+#define cy_wdg_MAX_TIMEOUT_MS 6000U
/** Maximum number of ignore bits */
-#define _cy_wdg_MAX_IGNORE_BITS 12
+#define cy_wdg_MAX_IGNORE_BITS 12U
typedef struct {
uint16_t min_period_ms; // Minimum period in milliseconds that can be represented with this many ignored bits
uint16_t round_threshold_ms; // Timeout threshold in milliseconds from which to round up to the minimum period
-} _cy_wdg_ignore_bits_data_t;
+} cy_wdg_ignore_bits_data_t;
// ILO Frequency = 32768 Hz
// ILO Period = 1 / 32768 Hz = .030518 ms
// WDT Reset Period (timeout_ms) = .030518 ms * (2 * 2^(16 - ignore_bits) + match)
// ignore_bits range: 0 - 12
// match range: 0 - (2^(16 - ignore_bits) - 1)
-static const _cy_wdg_ignore_bits_data_t _cy_wdg_ignore_data[] = {
+static const cy_wdg_ignore_bits_data_t cy_wdg_ignore_data[] = {
{4001, 3001}, // 0 bits: min period: 4001ms, max period: 6000ms, round up from 3001+ms
{2001, 1500}, // 1 bit: min period: 2001ms, max period: 3000ms, round up from 1500+ms
{1001, 750}, // 2 bits: min period: 1001ms, max period: 1499ms, round up from 750+ms
@@ -76,106 +77,103 @@
{1, 1} // 12 bits: min period: 1ms, max period: 1ms
};
-static bool _cy_wdg_initialized = false;
-static bool _cy_wdg_pdl_initialized = false;
-static uint16_t _cy_wdg_initial_timeout_ms = 0;
-static uint8_t _cy_wdg_initial_ignore_bits = 0;
+static bool cy_wdg_initialized = false;
+static bool cy_wdg_pdl_initialized = false;
+static uint16_t cy_wdg_initial_timeout_ms = 0;
+static uint8_t cy_wdg_initial_ignore_bits = 0;
-static __INLINE uint32_t _cy_wdg_timeout_to_ignore_bits(uint32_t *timeout_ms) {
- for (uint32_t i = 0; i <= _cy_wdg_MAX_IGNORE_BITS; i++)
- {
- if (*timeout_ms >= _cy_wdg_ignore_data[i].round_threshold_ms)
- {
- if (*timeout_ms < _cy_wdg_ignore_data[i].min_period_ms)
- *timeout_ms = _cy_wdg_ignore_data[i].min_period_ms;
+static __INLINE uint8_t cy_wdg_timeout_to_ignore_bits(uint16_t *timeout_ms)
+{
+ for (uint8_t i = 0; i <= cy_wdg_MAX_IGNORE_BITS; i++) {
+ if (*timeout_ms >= cy_wdg_ignore_data[i].round_threshold_ms) {
+ if (*timeout_ms < cy_wdg_ignore_data[i].min_period_ms) {
+ *timeout_ms = cy_wdg_ignore_data[i].min_period_ms;
+ }
return i;
}
}
- return _cy_wdg_MAX_IGNORE_BITS; // Should never reach this
+ return cy_wdg_MAX_IGNORE_BITS; // Should never reach this
}
-static __INLINE uint16_t _cy_wdg_timeout_to_match(uint16_t timeout_ms, uint16_t ignore_bits)
+static __INLINE uint16_t cy_wdg_timeout_to_match(uint16_t timeout_ms, uint16_t ignore_bits)
{
- // match = (timeout_ms / .030518 ms) - (2 * 2^(16 - ignore_bits))
- return (uint16_t)(timeout_ms / .030518) - (1UL << (17 - ignore_bits)) + Cy_WDT_GetCount();
+ uint32_t timeout = (uint32_t)timeout_ms * CY_SYSCLK_ILO_FREQ / 1000U;
+ return (uint16_t)(timeout - (1UL << (17U - ignore_bits)) + Cy_WDT_GetCount());
}
/* Start API implementing */
-cy_rslt_t cy_wdg_init(uint32_t timeout_ms)
+cy_rslt_t cy_wdg_init(uint16_t timeout_ms)
{
- if (timeout_ms == 0 || timeout_ms > _cy_wdg_MAX_TIMEOUT_MS)
- {
- return -1;
+ if (timeout_ms == 0U || timeout_ms > cy_wdg_MAX_TIMEOUT_MS) {
+ return ~CY_RSLT_SUCCESS;
}
- if (_cy_wdg_initialized)
- {
- return -1;
+ if (cy_wdg_initialized) {
+ return ~CY_RSLT_SUCCESS;
}
- _cy_wdg_initialized = true;
+ cy_wdg_initialized = true;
- if (!_cy_wdg_pdl_initialized)
- {
+ if (!cy_wdg_pdl_initialized) {
Cy_WDT_Enable();
Cy_WDT_MaskInterrupt();
- _cy_wdg_pdl_initialized = true;
+ cy_wdg_pdl_initialized = true;
}
cy_wdg_stop();
- _cy_wdg_initial_timeout_ms = timeout_ms;
- uint8_t ignore_bits = _cy_wdg_timeout_to_ignore_bits(&timeout_ms);
- _cy_wdg_initial_ignore_bits = ignore_bits;
+ cy_wdg_initial_timeout_ms = timeout_ms;
+ uint8_t ignore_bits = cy_wdg_timeout_to_ignore_bits(&timeout_ms);
+ cy_wdg_initial_ignore_bits = ignore_bits;
Cy_WDT_SetIgnoreBits(ignore_bits);
- Cy_WDT_SetMatch(_cy_wdg_timeout_to_match(timeout_ms, ignore_bits));
+ Cy_WDT_SetMatch(cy_wdg_timeout_to_match(timeout_ms, ignore_bits));
cy_wdg_start();
return CY_RSLT_SUCCESS;
}
-void cy_wdg_free()
+void cy_wdg_free(void)
{
cy_wdg_stop();
- _cy_wdg_initialized = false;
+ cy_wdg_initialized = false;
}
-void cy_wdg_kick()
+void cy_wdg_kick(void)
{
/* Clear to prevent reset from WDT */
Cy_WDT_ClearWatchdog();
- _cy_wdg_unlock();
- Cy_WDT_SetMatch(_cy_wdg_timeout_to_match(_cy_wdg_initial_timeout_ms, _cy_wdg_initial_ignore_bits));
- _cy_wdg_lock();
+ cy_wdg_unlock();
+ Cy_WDT_SetMatch(cy_wdg_timeout_to_match(cy_wdg_initial_timeout_ms, cy_wdg_initial_ignore_bits));
+ cy_wdg_lock();
}
-void cy_wdg_start()
+void cy_wdg_start(void)
{
- _cy_wdg_unlock();
+ cy_wdg_unlock();
Cy_WDT_Enable();
- _cy_wdg_lock();
+ cy_wdg_lock();
}
-void cy_wdg_stop()
+void cy_wdg_stop(void)
{
- _cy_wdg_unlock();
+ cy_wdg_unlock();
Cy_WDT_Disable();
}
-uint32_t cy_wdg_get_timeout_ms()
+uint32_t cy_wdg_get_timeout_ms(void)
{
- return _cy_wdg_initial_timeout_ms;
+ return cy_wdg_initial_timeout_ms;
}
uint32_t cy_wdg_get_max_timeout_ms(void)
{
- return _cy_wdg_MAX_TIMEOUT_MS;
+ return cy_wdg_MAX_TIMEOUT_MS;
}
#if defined(__cplusplus)
diff --git a/boot/cypress/libs/watchdog/watchdog.h b/boot/cypress/libs/watchdog/watchdog.h
index 0d45f82..494326a 100644
--- a/boot/cypress/libs/watchdog/watchdog.h
+++ b/boot/cypress/libs/watchdog/watchdog.h
@@ -1,3 +1,5 @@
+#ifndef WATCHDOG_H
+#define WATCHDOG_H
/***************************************************************************//**
* \file cy_wdg.h
*
@@ -43,7 +45,7 @@
*
* Returns CY_RSLT_SUCCESS if the operation was successfull.
*/
-cy_rslt_t cy_wdg_init(uint32_t timeout_ms);
+cy_rslt_t cy_wdg_init(uint16_t timeout_ms);
/** Free the WDT
*
@@ -52,32 +54,32 @@
* cy_wdg_init().
*/
-void cy_wdg_free();
+void cy_wdg_free(void);
/** Resets the WDT
*
* This function should be called periodically to prevent the WDT from timing out and resetting the device.
*/
-void cy_wdg_kick();
+void cy_wdg_kick(void);
/** Start (enable) the WDT
*
* @return The status of the start request
*/
-void cy_wdg_start();
+void cy_wdg_start(void);
/** Stop (disable) the WDT
*
* @return The status of the stop request
*/
-void cy_wdg_stop();
+void cy_wdg_stop(void);
/** Get the WDT timeout
*
* Gets the time in milliseconds before the WDT times out.
* @return The time in milliseconds before the WDT times out
*/
-uint32_t cy_wdg_get_timeout_ms();
+uint32_t cy_wdg_get_timeout_ms(void);
/** Gets the maximum WDT timeout in milliseconds
*
@@ -88,3 +90,5 @@
#if defined(__cplusplus)
}
#endif
+
+#endif /* WATCHDOG_H */
diff --git a/boot/cypress/platforms.mk b/boot/cypress/platforms.mk
index 39fd34a..281c34c 100644
--- a/boot/cypress/platforms.mk
+++ b/boot/cypress/platforms.mk
@@ -25,54 +25,39 @@
include host.mk
-# Target platform is built for. PSOC_062_2M is set by default
-# Supported:
-# - PSOC_062_2M
-# - PSOC_062_1M
-# - PSOC_062_512K
-
-# default PLATFORM
-PLATFORM ?= PSOC_062_2M
-
# supported platforms
-PLATFORMS := PSOC_062_2M PSOC_062_1M PSOC_062_512K
+PLATFORMS := PSOC_062_2M PSOC_062_1M PSOC_062_512K CYW20829
ifneq ($(filter $(PLATFORM), $(PLATFORMS)),)
else
$(error Not supported platform: '$(PLATFORM)')
endif
-# For which core this application is built
-CORE ?= CM0P
-
-# MCU device selection, based on target device.
-# Default chips are used for supported platforms
-# This can be redefined in case of other chip usage
-ifeq ($(PLATFORM), PSOC_062_2M)
-# base kit CY8CPROTO-062-4343W
-DEVICE ?= CY8C624ABZI-D44
-PLATFORM_SUFFIX := 02
-else ifeq ($(PLATFORM), PSOC_062_1M)
-# base kit CY8CKIT-062-WIFI-BT
-DEVICE ?= CY8C6247BZI-D54
-PLATFORM_SUFFIX := 01
-else ifeq ($(PLATFORM), PSOC_062_512K)
-# base kit CY8CPROTO-062S3-4343W
-DEVICE ?= CY8C6245LQI-S3D72
-PLATFORM_SUFFIX := 03
+ifeq ($(PLATFORM), $(filter $(PLATFORM), PSOC_062_2M PSOC_062_1M PSOC_062_512K))
+FAMILY := PSOC6
+else ifeq ($(PLATFORM), CYW20829)
+FAMILY := CYW20829
endif
-# Add device name to defines
-DEFINES += $(DEVICE)
+# include family related makefile into build
+include platforms/$(FAMILY)/$(FAMILY).mk
+
DEFINES += $(PLATFORM)
+DEFINES += $(FAMILY)
# Convert defines to regular -DMY_NAME style
ifneq ($(DEFINES),)
- DEFINES_PLATFORM :=$(addprefix -D, $(subst -,_,$(DEFINES)))
+ PLATFORM_DEFINES := $(addprefix -D, $(subst -,_,$(DEFINES)))
endif
-ifeq ($(MAKEINFO) , 1)
-$(info $(PLATFORM_SUFFIX))
-$(info $(DEVICE))
-$(info $(DEFINES_PLATFORM))
+###############################################################################
+# Print debug information about all settings used and/or set in this file
+ifeq ($(VERBOSE), 1)
+$(info #### platforms.mk ####)
+$(info DEFINES <-> $(DEFINES))
+$(info FAMILY <-> $(FAMILY))
+$(info PLATFORM <-- $(PLATFORM))
+$(info PLATFORMS <-> $(PLATFORMS))
+$(info PLATFORM_DEFINES <-> $(PLATFORM_DEFINES))
+$(info PLATFORM_SUFFIX <-- $(PLATFORM_SUFFIX))
endif
diff --git a/boot/cypress/platforms/CYW20829/CYW20829.md b/boot/cypress/platforms/CYW20829/CYW20829.md
new file mode 100644
index 0000000..4d591c6
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/CYW20829.md
@@ -0,0 +1,198 @@
+## CYW20829 platform description
+
+### Prerequisites
+
+#### Cysecuretools
+
+The CYW20829 chip has a set of security features. The special tool called `cysecuretools` is required to use most of them.
+
+Cysecuretools is a Python3 package, which can be installed using the conventional `python pip` packet manager:
+
+ python -m pip install cysecuretools
+
+Cysecuretools is used for reprovisioning of the chip, revocation of keys, security counter updates, image encryption and more. For more details on functionality, go to https://pypi.org/project/cysecuretools/
+
+Invocation of cysecuretools is build-in post build jobs for `MCUBootApp` and `BlinkyApp`, so the user gets ready to use images after build.
+
+### MCUBootApp specifics
+
+### Default memory map
+
+This repository provides a set of predefined memory maps in JSON files. They are located in `cy_flash_pal/flash_%platform_name%/flashmap`. One can use the predefined flash map or define its own using the predefined file as a template.
+
+### Encrypted image support
+
+CYW20829 does not have internal flash memory, so both primary and secondary images are located in external memory.
+
+To protect the firmware from read, place it in external memory in the encrypted form.
+
+CYW20829 can execute encrypted firmware directly using the onboard hardware interface (SMIF) with special mode XIP (eXecute-In-Place). In this mode all code is decrypted transparently by AES algorithm.
+
+MCUboot has its own Encrypted image mode to encrypt the firmware and transfer it with the AES session key included in the HKDF data block.
+
+**MCUboot image validation flow**
+
+- Decrypt the AES key / initial vector (IV) from HKDF
+- Set up AES IV + CTR nonce (Image addr = base_addr + header_size)
+- Read slot data by MMIO
+- Decrypt the image in the slot using MCUboot internal functionality
+- Calculate and verify hash from decrypted data
+- Validate the slot image by hash and sign it
+
+**MCUboot image upgrade flow**
+
+- Read slot 1 sector data using MMIO
+- Skip data decryption
+- Write data to the primary slot using MMIO
+
+**MCUboot Application Run**
+- Set up SMIF registers
+- Set the AES key
+- Set AES IV
+- Set SMIF mode to XIP
+- Go to the application entry point
+
+MCUBootApp and BlinkyApp can be built with an encrypted image plus encrypted XIP support using special build flags `ENC_IMG=1`. That flag will automatically enable XIP mode.
+
+Example build command for MCUBootApp:
+
+ make clean app APP_NAME=MCUBootApp PLATFORM=CYW20829 BUILDCFG=Debug FLASH_MAP=cy_flash_pal/flash_cyw208xx/flashmap/cyw20829_xip_swap_single.json ENC_IMG=1
+
+Example build command for BlinkyApp:
+
+ make clean app APP_NAME=BlinkyApp PLATFORM=CYW20829 BUILDCFG=Debug FLASH_MAP=cy_flash_pal/flash_cyw208xx/flashmap/cyw20829_xip_swap_single.json ENC_IMG=1
+
+### Rollback protection Support
+
+The CYW20829 platform has a hardware-supported feature - a non-volatile counter (NV-counter). This feature is used by the MCUboot library to implement the rollback counter (security counter) protection. NV-counter on CYW20829 is implemented as an Efuse-type region that can only be incremented. This means, that each time a new counter value is updated - a corresponding number of Efuse is burned.
+
+The initial value of the rollback counter is programmed into the chip at the provisioning stage. The provisioning policy for Secure mode contains a corresponding field:
+
+
+ "reprovisioning":
+ {
+ "nv_counter": {
+ "description": "Anti-rollback counter (supports up to 32 updates)",
+ "value": 0
+ },
+
+If the `nv_counter` value is left untouched, any image with counters higher than 0 and less than (or equal to) 32 can be programmed into the chip.
+
+When preparing an image for MCUBootApp with the rollback counter support, sign it with `cysecuretools` using `policy/policy_reprovisioning_secure.json` supplied with it. The `nv_counter` value remains the same as one in the chip or set higher. When signing image `cysecuretools` places the `nv-counter` value and the reprovisioning packet in TLVs with tags 0x50 (plain value of counter) and 0x51 (reprovisioning packet). MCUBootApp then parses these tags and compares the value supplied with the image against the one stored in the Efuse counter.
+
+#### NV-counter update
+
+The CYW20829 chip is designed so that the first stage bootloader called `BootROM` has most of the rights to modify the system - it is executed in the privileged protection context. Only BootROM can modify the content of Efuse where the NV counter is stored. BootROM supports the special type of service applications used when the user needs to modify the system. These apps are also provided with `cysecuretools` under `targets/cyw20829/packets/apps`. The `reprovisioning` application is used for NV-counter update.
+
+To enable the rollback counter feaure, one have to use a JSON flash map with the `"service_app"` section. Sample flash maps are located in `boot/cypress/cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot`.
+
+The service application is supplied as a precompiled binary executed from RAM by BootROM. User should program either `cyapp_reprovisioning_signed.hex` (located at `./MCUBootApp/out/CYW20829/Debug/cyapp_reprovisioning_signed.hex`) or similar binary `./packets/apps/reprovisioning/cyapp_reprovisioning_signed.bin` (with the `"address"` specified in the `"service_app"` section of JSON flash map). Some other data is required for BootROM to execute the service app - this data is prepared by MCUBootApp.
+
+When MCUBootApp detects that the rollback counter must be updated on CYW20829, it executes the function, which prepares input data and service application descriptor data and places it in flash at addresses `"params_address"` and `"desc_address"`, respectively (see the `"service_app"` section in JSON flash map). Then, it sets the special flag in the service register, which signalizes BootROM to launch the service application and calls a system reset. BootROM is then detects the service app with its data, copies it to the corresponding addresses in RAM and executes it. Reprovisioning app then updates the `nv-counter` value in Efuse. An automatic reset can (and for convenience should) be initiated after that. To allow this value, `sys_reset_req` is set to `true` (`false` by default).
+
+ "sys_reset_req": {
+ "description": "Resets a device after RAM application finishes execution.",
+ "value": true
+ }
+
+For more details on BootROM service applications, refer to the CYW20829 documentation.
+
+#### Rollback counter behavior
+
+**Case 1**
+
+An image is singed using the `policy_reprovisioning_secure.json` policy with `nv-counter` field value set to 1; the current value of NV-counter in chip is `0` and programmed to the primary slot of MCUBootApp.
+
+MCUBootApp validates the image in the primary slot and initiates a rollback counter update. The image in the primary slot is started after that.
+
+**Case 2**
+
+An image is signed using the `policy_reprovisioning_secure.json` policy with `nv-counter`, the field value is set to 2; the current value of NV-counter in the chip is `1` and programmed into the secondary slot of MCUBootApp. The ugrade type is swap using the status partition.
+
+MCUBootApp validates the image in the secondary slot and initiates a firmware upgrade. After swapping the primary and
+secondary images, the firmware from the primary slot is executed immediately after upgrade.
+
+- If upgraded firmware operates correctly - starts its execution and sets the confirmation flag (read more in the design.md file), then, after a next reset, MCUBootApp updates the rollback counter value as in Case 1.
+
+- If upgraded firmware operates incorrectly - does not start or does not set the confirmation flag, the watchdog initiates a system reset and MCUBootApp performs the `revert` operation - copies back the previous firmware from the secondary to the primary slot, marks the image in the secondary slot as invalid and executes the original firmware from the primary slot. **The rollback counter is not updated in this case.**
+
+**Case 3**
+
+An image is signed with the `policy_reprovisioning_secure.json` policy with `nv-counter`, the field value is set to 3; the current value of NV-counter in chip is `4` and programmed to the secondary or primary slot of MCUBootApp. The upgrade type is swap using the status partition.
+
+MCUBootApp tries to validate the image, detects that the value of the rollback counter stored in the chip is greater than the one provided with the image, and rejects such an image. The firmware in the primary slot will not start and upgrade will not be initiated.
+
+When the reprovisioning packet TLV is absent in the primary or secondary image TLVs, MCUBootApp marks such an image as invalid.
+
+**Multi image case**
+
+Since there is only one physical security counter available on `CYW20829` in multi image use case, all images in system should have the same value of security counter.
+
+For example two images are programmed to their corresponding BOOT slots with security counter value of 2. Value of security counter stored in chip is also 2. In case one of images requires update and its value of security counter is increased to 3 - second image should also be updated with counter value of 3. This is required because `BootROM` will update security image counter stored in chip to 3 per first upgrade image. After that - second image would become invalid sice it still contains security counter of 2.
+
+An example of the build command for MCUBootApp with the rollback counter support:
+
+ make clean app APP_NAME=MCUBootApp PLATFORM=CYW20829 BUILDCFG=Debug FLASH_MAP=cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot/cyw20829_xip_swap_single.json
+
+An example of the build command for BlinkyApp with TLVs containing rollback counter data:
+
+ make clean app APP_NAME=BlinkyApp PLATFORM=CYW20829 BUILDCFG=Debug APP_DEFAULT_POLICY=./policy/policy_reprovisioning_secure.json FLASH_MAP=cy_flash_pal/flash_cyw208xx/flashmap/hw_rollback_prot/cyw20829_xip_swap_single.json
+
+### Build environment preparation
+
+For cysecuretools environment setup, the MCUboot `boot/cypress` folder is used.
+
+To create common CYW20829 configuration, use:
+
+ cysecuretools -t cyw20829 init
+
+To configure an OpenOCD package patch (via ModusToolbox™ by default):
+
+ cysecuretools set-ocd --name openocd --path C:/Users/%USERNAME%/ModusToolbox/tools_2.4/openocd
+
+This is enough for a NORMAL_NO_SECURE lifecycle. But for SECURE `LCS`, a few more steps are necessary.
+
+You will need to generate an RSA key pair (or copy it to keys folder, if it was generated previously), in order to provision a silicon in Secure mode:
+
+ cysecuretools -t cyw20829 -p policy/policy_secure.json create-key -k N
+
+where N is the key number, zero or one.
+
+To get access to the chip after provisioning, a debug certificate is required:
+
+ cysecuretools -t cyw20829 -p policy/policy_secure.json debug-certificate -t packets/debug_cert.json -o packets/debug_cert.bin -k N
+
+where N is the key number, zero or one.
+
+### CYW20829 provisioning
+
+For the first provision of CYW20829 chip, use:
+
+ cysecuretools -t cyw20829 -p policy/policy_%LCS%.json provision-device
+
+or
+
+ cysecuretools -t cyw20829 -p policy/policy_reprovisioning_%LCS%.json reprovision-device [--key-id N]
+
+for the following reprovision procedure.
+
+For more details on the CYW20829 environment setup and provisioning, go to the cysecuretools `README_CYW20829.md` file.
+
+### Programming applications
+
+#### Using OpenOCD from command line
+
+The following instruction assume the usage of one of Cypress KitProg3 devices and a development board.
+
+Connect the board to your computer. Switch Kitprog3 to DAP-BULK mode by clicking the `SW3 MODE` button until `LED2 STATUS` constantly shines.
+
+Open the terminal application and execute the following command after substitution of the `PATH_TO_APPLICATION` and `OPENOCD` variables:
+
+ export OPENOCD=/Applications/ModusToolbox/tools_2.4/openocd
+
+ $OPENOCD_PATH/bin/openocd -s $OPENOCD_PATH/scripts -c "set ENABLE_ACQUIRE 0" -f $OPENOCD_PATH/scripts/interface/kitprog3.cfg -c "set SMIF_BANKS { 0 {addr 0x60000000 size 0x4000000 psize 0x1000 esize 0x40000} }" -f $OPENOCD_PATH/scripts/target/cyw20829.cfg -c "init; reset init; cmsis_flash init; flash write_image %PATH_TO_APPLICATION%/BlinkyApp.hex; shutdown"
+
+**Warning**
+
+The application slot is erased by `flash erase_address` before executing the `flash write_image` command.
+
diff --git a/boot/cypress/platforms/CYW20829/CYW20829.mk b/boot/cypress/platforms/CYW20829/CYW20829.mk
new file mode 100644
index 0000000..902ede3
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/CYW20829.mk
@@ -0,0 +1,329 @@
+################################################################################
+# \file CYW20829.mk
+# \version 1.0
+#
+# \brief
+# This file is dedicated for CYW20829 platform
+#
+################################################################################
+# \copyright
+# Copyright 2018-2019 Cypress Semiconductor Corporation
+# SPDX-License-Identifier: Apache-2.0
+#
+# 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.
+################################################################################
+
+include host.mk
+
+# Default core name of platform
+CORE := CM33
+CORE_SUFFIX := m33
+
+# PDL category suffix to resolve common path in pdl
+PDL_CAT_SUFFIX := 1B
+
+# MCU device selection, based on target device.
+# Default chips are used for supported platforms
+# This can be redefined in case of other chip usage
+DEVICE ?= CYW20829A0LKML
+# If PSVP build is required
+ifeq ($(CYW20829_PSVP), 1)
+DEVICE := CYW20829_PSVP
+SERVICE_APP_PLATFORM_SUFFIX := _psvp
+endif
+
+PLATFORM_SUFFIX ?= cyw20829
+
+# Add device name to defines
+DEFINES += $(DEVICE)
+
+# Default upgrade method
+PLATFORM_DEFAULT_USE_OVERWRITE ?= 0
+
+# Device flash start
+FLASH_START := 0x60000000
+FLASH_XIP_START := 0x08000000
+
+# Bootloader size
+PLATFORM_BOOTLOADER_SIZE ?= 0x20000
+
+###############################################################################
+# Application specific libraries
+###############################################################################
+# MCUBootApp
+###############################################################################
+THIS_APP_PATH = $(PRJ_DIR)/libs
+
+ifeq ($(APP_NAME), MCUBootApp)
+
+PLATFORM_INCLUDE_DIRS_FLASH := $(PRJ_DIR)/cy_flash_pal
+PLATFORM_INCLUDE_DIRS_FLASH += $(PRJ_DIR)/cy_flash_pal/flash_cyw208xx/flash_qspi
+PLATFORM_INCLUDE_DIRS_FLASH += $(PRJ_DIR)/cy_flash_pal/flash_cyw208xx/include
+# INCLUDE_DIRS_APP += $(addprefix -I, $(PRJ_DIR)/cy_flash_pal/flash_cyw208xx/include/flash_map_backend)
+PLATFORM_SOURCES_FLASH := $(wildcard $(PRJ_DIR)/cy_flash_pal/flash_cyw208xx/*.c)
+PLATFORM_SOURCES_FLASH += $(wildcard $(PRJ_DIR)/cy_flash_pal/flash_cyw208xx/flash_qspi/*.c)
+
+# Platform dependend utils files
+PLATFORM_APP_SOURCES := $(PRJ_DIR)/platforms/$(FAMILY)/utils/cyw_20829_utils.c
+PLATFORM_INCLUDE_DIRS_UTILS := $(PRJ_DIR)/platforms/$(FAMILY)/utils
+
+# mbedTLS hardware acceleration settings
+ifeq ($(USE_CRYPTO_HW), 1)
+# cy-mbedtls-acceleration related include directories
+INCLUDE_DIRS_MBEDTLS_CRYPTOLITE := $(PRJ_DIR)/platforms/$(FAMILY)/mbedtls_Cryptolite
+# Collect source files for MbedTLS acceleration
+SOURCES_MBEDTLS_CRYPTOLITE := $(wildcard $(PRJ_DIR)/platforms/$(FAMILY)/mbedtls_Cryptolite/*.c)
+#
+INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_MBEDTLS_CRYPTOLITE))
+# Collected source files for libraries
+SOURCES_LIBS += $(SOURCES_MBEDTLS_CRYPTOLITE)
+endif
+
+###############################################################################
+# Application dependent definitions
+# MCUBootApp
+# Default settings
+USE_EXTERNAL_FLASH := 1
+PROVISION_PATH ?= $(PRJ_DIR)
+LCS ?= NORMAL_NO_SECURE
+APPTYPE ?= flash
+SIGN_TYPE ?= bootrom_next_app
+SMIF_CRYPTO_CONFIG ?= NONE
+
+ifeq ($(LCS), NORMAL_NO_SECURE)
+APP_DEFAULT_POLICY ?= $(PRJ_DIR)/policy/policy_no_secure.json
+else
+APP_DEFAULT_POLICY ?= $(PRJ_DIR)/policy/policy_secure.json
+endif
+
+# Define MCUBootApp specific parameters
+PLATFORM_MAX_IMG_SECTORS = 32U
+
+###############################################################################
+# MCUBootApp flash map custom settings
+###############################################################################
+# Set this flag to 1 to enable custom settings in MCUBootApp
+USE_CUSTOM_MEMORY_MAP ?= 1
+
+PLATFORM_CY_MAX_EXT_FLASH_ERASE_SIZE ?= 4096U
+PLATFORM_CHUNK_SIZE := 4096U
+###############################################################################
+
+###############################################################################
+# MCUBootApp service app definitions
+###############################################################################
+# Service app is only used in SECURE lifecycle
+ifeq ($(LCS), SECURE)
+# Service app path and file name
+SERVICE_APP_PATH := $(PRJ_DIR)/packets/apps/reprovisioning$(SERVICE_APP_PLATFORM_SUFFIX)
+SERVICE_APP_NAME := cyapp_reprovisioning_signed_icv0
+
+# Service app size is calculated here and converted to hex format
+PLATFORM_SERVICE_APP_SIZE ?= 0x$(shell printf "%x" `wc -c < $(SERVICE_APP_PATH)/$(SERVICE_APP_NAME).bin`)
+else
+ifeq ($(USE_HW_ROLLBACK_PROT), 1)
+$(warning Hardware rollback protection USE_HW_ROLLBACK_PROT=1 is only valid for LCS=SECURE mode)
+endif
+endif
+###############################################################################
+
+# Post build job to execute for platform
+post_build: $(OUT_CFG)/$(APP_NAME).elf
+ifeq ($(POST_BUILD_ENABLE), 1)
+ $(info [TOC2_Generate] - Execute toc2 generator script for $(APP_NAME))
+ @echo $(SHELL) $(PRJ_DIR)/run_toc2_generator.sh $(LCS) $(OUT_CFG) $(APP_NAME) $(APPTYPE) $(PROVISION_PATH) $(SMIF_CRYPTO_CONFIG) $(TOOLCHAIN_PATH) $(APP_DEFAULT_POLICY) $(PLATFORM_BOOTLOADER_SIZE) $(ENC_IMG) $(PLATFORM_SERVICE_APP_DESC_OFFSET)
+ $(shell $(PRJ_DIR)/run_toc2_generator.sh $(LCS) $(OUT_CFG) $(APP_NAME) $(APPTYPE) $(PROVISION_PATH) $(SMIF_CRYPTO_CONFIG) $(TOOLCHAIN_PATH) $(APP_DEFAULT_POLICY) $(PLATFORM_BOOTLOADER_SIZE) $(ENC_IMG) $(PLATFORM_SERVICE_APP_DESC_OFFSET))
+
+ # Convert binary to hex and rename
+ $(shell mv -f $(OUT_CFG)/$(APP_NAME).final.bin $(OUT_CFG)/$(APP_NAME).bin || rm -f $(OUT_CFG)/$(APP_NAME).bin)
+
+ $(GCC_PATH)/bin/arm-none-eabi-objcopy --change-address=$(FLASH_START) -I binary -O ihex $(OUT_CFG)/$(APP_NAME).bin $(OUT_CFG)/$(APP_NAME).hex
+ifeq ($(USE_HW_ROLLBACK_PROT), 1)
+ $(GCC_PATH)/bin/arm-none-eabi-objcopy --change-address=$$(($(FLASH_START)+$(PLATFORM_SERVICE_APP_OFFSET))) -I binary -O ihex $(SERVICE_APP_PATH)/$(SERVICE_APP_NAME).bin $(OUT_CFG)/$(SERVICE_APP_NAME).hex
+endif
+ $(GCC_PATH)/bin/arm-none-eabi-objdump -s $(OUT_CFG)/$(APP_NAME).hex > $(OUT_CFG)/$(APP_NAME).objdump
+else
+ $(info Post build is disabled by POST_BUILD_ENABLE parameter)
+endif # POST_BUILD_ENABLE
+endif ## MCUBootApp
+
+###############################################################################
+# BlinkyApp
+###############################################################################
+ifeq ($(APP_NAME), BlinkyApp)
+
+# Basic settings
+LCS ?= NORMAL_NO_SECURE
+APPTYPE ?= flash
+SIGN_TYPE ?= mcuboot_user_app
+SMIF_CRYPTO_CONFIG ?= NONE
+
+ifeq ($(LCS), NORMAL_NO_SECURE)
+APP_DEFAULT_POLICY ?= $(PRJ_DIR)/policy/policy_no_secure.json
+else
+APP_DEFAULT_POLICY ?= $(PRJ_DIR)/policy/policy_secure.json
+endif
+
+PLATFORM_DEFAULT_ERASED_VALUE := 0xff
+
+# Define start of application
+PLATFORM_USER_APP_START ?= $(shell echo $$(($(PRIMARY_IMG_START)-$(FLASH_START)+$(FLASH_XIP_START))))
+# Define RAM start and size, slot size
+PLATFORM_DEFAULT_RAM_START ?= 0x2000C000
+PLATFORM_DEFAULT_RAM_SIZE ?= 0x10000
+
+PLATFORM_DEFINES_APP += -DUSER_APP_START_OFF=0x20000
+
+PLATFORM_INCLUDE_DIRS_FLASH := $(PRJ_DIR)/cy_flash_pal
+PLATFORM_INCLUDE_DIRS_FLASH += $(PRJ_DIR)/cy_flash_pal/flash_cyw208xx/flash_qspi
+PLATFORM_INCLUDE_DIRS_FLASH += $(PRJ_DIR)/cy_flash_pal/flash_cyw208xx/include
+PLATFORM_SOURCES_FLASH += $(wildcard $(PRJ_DIR)/cy_flash_pal/flash_cyw208xx/flash_qspi/*.c)
+
+PLATFORM_DEFAULT_IMG_VER_ARG ?=
+
+PLATFORM_SIGN_ARGS := --image-format $(SIGN_TYPE) -i $(OUT_CFG)/$(APP_NAME).final.bin -o $(OUT_CFG)/$(APP_NAME)$(UPGRADE_SUFFIX).bin --key-path $(PRJ_DIR)/keys/cypress-test-ec-p256.pem --update-key-path $(PRJ_DIR)/keys/priv_oem_0.pem --slot-size $(SLOT_SIZE) --align 1
+
+# Use encryption and random initial vector for image
+ifeq ($(ENC_IMG), 1)
+ PLATFORM_SIGN_ARGS += --encrypt --enckey ../../$(ENC_KEY_FILE).pem
+ PLATFORM_SIGN_ARGS += --app-addr=$(PLATFORM_USER_APP_START)
+endif
+
+post_build: $(OUT_CFG)/$(APP_NAME).bin
+ifeq ($(POST_BUILD_ENABLE), 1)
+ $(info [POST BUILD] - Executing post build script for $(APP_NAME))
+ $(info [TOC2_Generate] - Execute toc2 generator script for $(APP_NAME))
+ $(shell $(PRJ_DIR)/run_toc2_generator.sh $(LCS) $(OUT_CFG) $(APP_NAME) $(APPTYPE) $(PRJ_DIR) $(SMIF_CRYPTO_CONFIG) $(TOOLCHAIN_PATH))
+
+ $(shell cysecuretools -q -t cyw20829 -p $(APP_DEFAULT_POLICY) sign-image $(SIGN_ARGS))
+
+ $(GCC_PATH)/bin/arm-none-eabi-objcopy --change-address=$(HEADER_OFFSET) -I binary -O ihex $(OUT_CFG)/$(APP_NAME)$(UPGRADE_SUFFIX).bin $(OUT_CFG)/$(APP_NAME)$(UPGRADE_SUFFIX).hex
+ $(GCC_PATH)/bin/arm-none-eabi-objdump -s $(OUT_CFG)/$(APP_NAME)$(UPGRADE_SUFFIX).hex > $(OUT_CFG)/$(APP_NAME)$(UPGRADE_SUFFIX).objdump
+else
+ $(info Post build is disabled by POST_BUILD_ENABLE parameter)
+endif # POST_BUILD_ENABLE
+endif ## BlinkyApp
+
+###############################################################################
+# Toolchain
+###############################################################################
+# Define build flags specific to a certain platform
+# Define build flags specific to a certain platform
+CFLAGS_PLATFORM := -c -mcpu=cortex-m33+nodsp --specs=nano.specs
+
+###############################################################################
+# Common libraries
+###############################################################################
+PLATFORM_SYSTEM_FILE_NAME := non-secure/ns_system_$(PLATFORM_SUFFIX).c
+PLATFORM_SOURCES_PDL_STARTUP := non-secure/ns_start_$(PLATFORM_SUFFIX).c
+PLATFORM_SOURCES_PDL_RUNTIME := non-secure/ns_runtime_$(PLATFORM_SUFFIX).c
+
+PLATFORM_SOURCES_RETARGET_IO := $(wildcard $(PRJ_DIR)/libs/retarget-io/*.c)
+
+PLATFORM_SOURCES_HAL := $(PRJ_DIR)/libs/mtb-hal-cat1/COMPONENT_CAT$(PDL_CAT_SUFFIX)/source/pin_packages/cyhal_cyw20829_56_qfn.c
+PLATFORM_SOURCES_HAL += $(PRJ_DIR)/libs/mtb-hal-cat1/COMPONENT_CAT$(PDL_CAT_SUFFIX)/source/triggers/cyhal_triggers_cyw20829.c
+PLATFORM_SOURCES_HAL += $(wildcard $(PRJ_DIR)/libs/mtb-hal-cat1/source/*.c)
+
+PLATFORM_INCLUDE_DIRS_PDL_STARTUP := $(PRJ_DIR)/libs/mtb-pdl-cat1/devices/COMPONENT_CAT$(PDL_CAT_SUFFIX)/templates/COMPONENT_MTB/COMPONENT_$(CORE)/$(HEADER_FILES)
+
+PLATFORM_INCLUDE_DIRS_RETARGET_IO := $(PRJ_DIR)/libs/retarget-io
+
+PLATFORM_INCLUDE_DIRS_HAL := $(PRJ_DIR)/libs/mtb-hal-cat1/include
+PLATFORM_INCLUDE_DIRS_HAL += $(PRJ_DIR)/libs/mtb-hal-cat1/include_pvt
+PLATFORM_INCLUDE_DIRS_HAL += $(PRJ_DIR)/libs/mtb-hal-cat1/COMPONENT_CAT$(PDL_CAT_SUFFIX)/include/
+PLATFORM_INCLUDE_DIRS_HAL += $(PRJ_DIR)/libs/mtb-hal-cat1/COMPONENT_CAT$(PDL_CAT_SUFFIX)/include/pin_packages
+#PLATFORM_INCLUDE_DIRS_HAL += $(PRJ_DIR)/libs/mtb-hal-cat1/COMPONENT_CAT$(PDL_CAT_SUFFIX)/include/triggers
+
+PLATFORM_DEFINES_LIBS := -DCY_USING_HAL
+PLATFORM_DEFINES_LIBS += -DCOMPONENT_CM33
+PLATFORM_DEFINES_LIBS += -DCOMPONENT_PSOC6HAL
+PLATFORM_DEFINES_LIBS += -DCOMPONENT_PSVP_CYW20829
+PLATFORM_DEFINES_LIBS += -DCOMPONENT_SOFTFP
+PLATFORM_DEFINES_LIBS += -DFLASH_BOOT
+
+###############################################################################
+# Print debug information about all settings used and/or set in this file
+ifeq ($(VERBOSE), 1)
+$(info #### CYW20829.mk ####)
+$(info APPTYPE <-> $(APPTYPE))
+$(info APP_DEFAULT_POLICY <-> $(APP_DEFAULT_POLICY))
+$(info APP_NAME <-- $(APP_NAME))
+$(info CFLAGS_PLATFORM --> $(CFLAGS_PLATFORM))
+$(info CORE <-> $(CORE))
+$(info CORE_SUFFIX --> $(CORE_SUFFIX))
+$(info CYW20829_PSVP <-- $(CYW20829_PSVP))
+$(info DEFINES --> $(DEFINES))
+$(info DEVICE <-> $(DEVICE))
+$(info ENC_IMG <-- $(ENC_IMG))
+$(info ENC_KEY_FILE <-- $(ENC_KEY_FILE))
+$(info FAMILY <-- $(FAMILY))
+$(info FLASH_START <-> $(FLASH_START))
+$(info FLASH_XIP_START <-> $(FLASH_XIP_START))
+$(info GCC_PATH <-- $(GCC_PATH))
+$(info HEADER_FILES <-- $(HEADER_FILES))
+$(info HEADER_OFFSET <-- $(HEADER_OFFSET))
+$(info INCLUDE_DIRS_LIBS --> $(INCLUDE_DIRS_LIBS))
+$(info INCLUDE_DIRS_MBEDTLS_CRYPTOLITE <-> $(INCLUDE_DIRS_MBEDTLS_CRYPTOLITE))
+$(info LCS <-> $(LCS))
+$(info OUT_CFG <-- $(OUT_CFG))
+$(info PDL_CAT_SUFFIX <-> $(PDL_CAT_SUFFIX))
+$(info PLATFORM_APP_SOURCES --> $(PLATFORM_APP_SOURCES))
+$(info PLATFORM_BOOTLOADER_SIZE <-> $(PLATFORM_BOOTLOADER_SIZE))
+$(info PLATFORM_CHUNK_SIZE --> $(PLATFORM_CHUNK_SIZE))
+$(info PLATFORM_CY_MAX_EXT_FLASH_ERASE_SIZE --> $(PLATFORM_CY_MAX_EXT_FLASH_ERASE_SIZE))
+$(info PLATFORM_DEFAULT_ERASED_VALUE --> $(PLATFORM_DEFAULT_ERASED_VALUE))
+$(info PLATFORM_DEFAULT_IMG_VER_ARG --> $(PLATFORM_DEFAULT_IMG_VER_ARG))
+$(info PLATFORM_DEFAULT_RAM_SIZE --> $(PLATFORM_DEFAULT_RAM_SIZE))
+$(info PLATFORM_DEFAULT_RAM_START --> $(PLATFORM_DEFAULT_RAM_START))
+$(info PLATFORM_DEFAULT_USE_OVERWRITE --> $(PLATFORM_DEFAULT_USE_OVERWRITE))
+$(info PLATFORM_DEFINES_APP --> $(PLATFORM_DEFINES_APP))
+$(info PLATFORM_DEFINES_LIBS --> $(PLATFORM_DEFINES_LIBS))
+$(info PLATFORM_INCLUDE_DIRS_FLASH --> $(PLATFORM_INCLUDE_DIRS_FLASH))
+$(info PLATFORM_INCLUDE_DIRS_HAL --> $(PLATFORM_INCLUDE_DIRS_HAL))
+$(info PLATFORM_INCLUDE_DIRS_PDL_STARTUP --> $(PLATFORM_INCLUDE_DIRS_PDL_STARTUP))
+$(info PLATFORM_INCLUDE_DIRS_RETARGET_IO --> $(PLATFORM_INCLUDE_DIRS_RETARGET_IO))
+$(info PLATFORM_INCLUDE_DIRS_UTILS --> $(PLATFORM_INCLUDE_DIRS_UTILS))
+$(info PLATFORM_SERVICE_APP_DESC_OFFSET <-- $(PLATFORM_SERVICE_APP_DESC_OFFSET))
+$(info PLATFORM_SERVICE_APP_OFFSET <-- $(PLATFORM_SERVICE_APP_OFFSET))
+$(info PLATFORM_SERVICE_APP_SIZE --> $(PLATFORM_SERVICE_APP_SIZE))
+$(info PLATFORM_SIGN_ARGS --> $(PLATFORM_SIGN_ARGS))
+$(info PLATFORM_SOURCES_FLASH --> $(PLATFORM_SOURCES_FLASH))
+$(info PLATFORM_SOURCES_HAL --> $(PLATFORM_SOURCES_HAL))
+$(info PLATFORM_SOURCES_PDL_RUNTIME --> $(PLATFORM_SOURCES_PDL_RUNTIME))
+$(info PLATFORM_SOURCES_PDL_STARTUP --> $(PLATFORM_SOURCES_PDL_STARTUP))
+$(info PLATFORM_SOURCES_RETARGET_IO --> $(PLATFORM_SOURCES_RETARGET_IO))
+$(info PLATFORM_SUFFIX <-> $(PLATFORM_SUFFIX))
+$(info PLATFORM_SYSTEM_FILE_NAME --> $(PLATFORM_SYSTEM_FILE_NAME))
+$(info PLATFORM_USER_APP_START <-> $(PLATFORM_USER_APP_START))
+$(info POST_BUILD_ENABLE <-- $(POST_BUILD_ENABLE))
+$(info PRIMARY_IMG_START <-- $(PRIMARY_IMG_START))
+$(info PRJ_DIR <-- $(PRJ_DIR))
+$(info PROVISION_PATH <-> $(PROVISION_PATH))
+$(info SERVICE_APP_NAME <-> $(SERVICE_APP_NAME))
+$(info SERVICE_APP_OFFSET <-- $(SERVICE_APP_OFFSET))
+$(info SERVICE_APP_PATH <-> $(SERVICE_APP_PATH))
+$(info SERVICE_APP_PLATFORM_SUFFIX <-> $(SERVICE_APP_PLATFORM_SUFFIX))
+$(info SHELL <-- $(SHELL))
+$(info SIGN_ARGS <-- $(SIGN_ARGS))
+$(info SIGN_TYPE <-> $(SIGN_TYPE))
+$(info SLOT_SIZE <-- $(SLOT_SIZE))
+$(info SMIF_CRYPTO_CONFIG <-> $(SMIF_CRYPTO_CONFIG))
+$(info SOURCES_LIBS --> $(SOURCES_LIBS))
+$(info SOURCES_MBEDTLS_CRYPTOLITE <-> $(SOURCES_MBEDTLS_CRYPTOLITE))
+$(info TOOLCHAIN_PATH <-- $(TOOLCHAIN_PATH))
+$(info UPGRADE_SUFFIX <-- $(UPGRADE_SUFFIX))
+$(info USE_CRYPTO_HW <-- $(USE_CRYPTO_HW))
+$(info USE_CUSTOM_MEMORY_MAP --> $(USE_CUSTOM_MEMORY_MAP))
+$(info USE_EXTERNAL_FLASH --> $(USE_EXTERNAL_FLASH))
+$(info USE_HW_ROLLBACK_PROT <-- $(USE_HW_ROLLBACK_PROT))
+endif
diff --git a/boot/cypress/platforms/CYW20829/crypto/mbedtls_Cryptolite/sha256_alt.c b/boot/cypress/platforms/CYW20829/crypto/mbedtls_Cryptolite/sha256_alt.c
new file mode 100644
index 0000000..6adee83
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/crypto/mbedtls_Cryptolite/sha256_alt.c
@@ -0,0 +1,281 @@
+/*
+ * mbed Microcontroller Library
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright (c) 2021 Infineon Technologies AG
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ */
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#else
+#include "config.h"
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+
+#include "mbedtls/sha256.h"
+#include "mbedtls/platform_util.h"
+
+#if defined(MBEDTLS_SHA256_ALT)
+
+/* Uncomment for distinct error codes */
+/* #define MAP_SPECIFIC_ERROR_CODES */
+
+/* Cy_Cryptolite_Sha256_Update() fails with CY_CRYPTOLITE_BUS_ERROR for data
+ * from Flash, if length is 64 bytes or more.
+ */
+#define CYW20829_SHA256_FLASH_WORKAROUND
+
+/* Parameter validation macros based on platform_util.h */
+#define SHA256_VALIDATE_RET(cond) \
+ MBEDTLS_INTERNAL_VALIDATE_RET((cond), MBEDTLS_ERR_SHA256_BAD_INPUT_DATA)
+
+#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE(cond)
+
+#ifdef CYW20829_SHA256_FLASH_WORKAROUND
+
+#ifndef CYW20829
+#error Workaround is only for CYW20829!
+#endif /* CYW20829 */
+
+#include "cyw20829_partition.h"
+
+/* Largest safe length for Cy_Cryptolite_Sha256_Update() */
+#define CYW20829_SHA256_SAFE_CHUNK_SIZE 63u
+
+#endif /* CYW20829_SHA256_FLASH_WORKAROUND */
+
+/**
+ * \brief Map Cryptolite status to mbed TLS error code.
+ *
+ * \param status The \c CY_CRYPTOLITE_??? function status.
+ * \return \c 0 on success.
+ * \return A negative error code on failure.
+ */
+static
+#ifndef MAP_SPECIFIC_ERROR_CODES
+inline __attribute__((always_inline))
+#endif /* MAP_SPECIFIC_ERROR_CODES */
+int cryptolite_to_mbedtls(cy_en_cryptolite_status_t status)
+{
+ int rc = -1;
+
+ switch (status) {
+ case CY_CRYPTOLITE_SUCCESS:
+ rc = 0;
+ break;
+
+#ifdef MAP_SPECIFIC_ERROR_CODES
+ case CY_CRYPTOLITE_BAD_PARAMS:
+ rc = MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
+ break;
+
+ case CY_CRYPTOLITE_HW_BUSY:
+ case CY_CRYPTOLITE_BUS_ERROR:
+ rc = MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+ break;
+#endif /* MAP_SPECIFIC_ERROR_CODES */
+
+ default:
+ break;
+ }
+
+ return rc;
+}
+
+/**
+ * \brief Zeroize memory block. There is no Cy_Crypto_Core_MemSet() in
+ * Cryptolite, and no memset_s() in newlib-nano.
+ *
+ * \param buf The buffer to zeroize.
+ * \param len The length of the buffer in Bytes.
+ */
+static inline __attribute__((always_inline))
+void zeroize(void *buf, size_t len)
+{
+ volatile uint8_t *p = (volatile uint8_t *)buf;
+
+ while (len > 0u) {
+ *p++ = 0u;
+ len--;
+ }
+}
+
+/**
+ * \brief This function initializes a SHA-256 context.
+ *
+ * \param ctx The SHA-256 context to initialize. This must not be \c NULL.
+ */
+void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
+{
+ cy_en_cryptolite_status_t status;
+
+ SHA256_VALIDATE(ctx != NULL);
+ zeroize(ctx, sizeof(*ctx));
+
+ /* There is some chance crypto HW might be busy here */
+ do {
+ status = Cy_Cryptolite_Sha256_Init(CRYPTO, ctx);
+ } while (CY_CRYPTOLITE_HW_BUSY == status);
+
+ SHA256_VALIDATE(CY_CRYPTOLITE_SUCCESS == status);
+}
+
+/**
+ * \brief This function clears a SHA-256 context.
+ *
+ * \param ctx The SHA-256 context to clear. This may be \c NULL, in which
+ * case this function returns immediately. If it is not \c NULL,
+ * it must point to an initialized SHA-256 context.
+ */
+void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
+{
+ if (ctx != NULL) {
+ (void)Cy_Cryptolite_Sha256_Free(CRYPTO, ctx);
+ zeroize(ctx, sizeof(*ctx));
+ }
+}
+
+/**
+ * \brief This function clones the state of a SHA-256 context.
+ *
+ * \param dst The destination context. This must be initialized.
+ * \param src The context to clone. This must be initialized.
+ */
+void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
+ const mbedtls_sha256_context *src)
+{
+ SHA256_VALIDATE(dst != NULL);
+ SHA256_VALIDATE(src != NULL);
+
+ *dst = *src;
+}
+
+/**
+ * \brief This function starts a SHA-224 or SHA-256 checksum
+ * calculation.
+ * WARNING: SHA-224 is NOT supported by Cryptolite!
+ *
+ * \param ctx The context to use. This must be initialized.
+ * \param is224 This determines which function to use. This must be
+ * either \c 0 for SHA-256, or \c 1 for SHA-224.
+ *
+ * \return \c 0 on success.
+ * \return A negative error code on failure.
+ */
+int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
+{
+ SHA256_VALIDATE_RET(ctx != NULL);
+ SHA256_VALIDATE_RET(0u == is224);
+
+ (void)is224;
+
+ return cryptolite_to_mbedtls(
+ Cy_Cryptolite_Sha256_Start(CRYPTO, ctx));
+}
+
+/**
+ * \brief This function feeds an input buffer into an ongoing
+ * SHA-256 checksum calculation.
+ *
+ * \param ctx The SHA-256 context. This must be initialized
+ * and have a hash operation started.
+ * \param input The buffer holding the data. This must be a readable
+ * buffer of length \p ilen Bytes.
+ * \param ilen The length of the input data in Bytes.
+ *
+ * \return \c 0 on success.
+ * \return A negative error code on failure.
+ */
+int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx,
+ const unsigned char *input,
+ size_t ilen)
+{
+ size_t offs = 0;
+ SHA256_VALIDATE_RET(ctx != NULL);
+ SHA256_VALIDATE_RET(0u == ilen || input != NULL);
+
+#ifdef CYW20829_SHA256_FLASH_WORKAROUND
+ /* Apply workaround only for data from Flash */
+ if ((uintptr_t)input >= XIP_NS_CBUS &&
+ (uintptr_t)(input + ilen) <= XIP_NS_CBUS + XIP_SIZE) {
+
+ while (ilen > CYW20829_SHA256_SAFE_CHUNK_SIZE) {
+ cy_en_cryptolite_status_t status =
+ Cy_Cryptolite_Sha256_Update(CRYPTO,
+ (uint8_t const *)input + offs,
+ CYW20829_SHA256_SAFE_CHUNK_SIZE,
+ ctx);
+
+ if (CY_CRYPTOLITE_SUCCESS != status) {
+ return cryptolite_to_mbedtls(status);
+ }
+
+ offs += CYW20829_SHA256_SAFE_CHUNK_SIZE;
+ ilen -= CYW20829_SHA256_SAFE_CHUNK_SIZE;
+ }
+ }
+#endif /* CYW20829_SHA256_FLASH_WORKAROUND */
+
+ return cryptolite_to_mbedtls(
+ Cy_Cryptolite_Sha256_Update(CRYPTO, (uint8_t const *)input + offs,
+ (uint32_t)ilen, ctx));
+}
+
+/**
+ * \brief This function finishes the SHA-256 operation, and writes
+ * the result to the output buffer.
+ *
+ * \param ctx The SHA-256 context. This must be initialized
+ * and have a hash operation started.
+ * \param output The SHA-224 or SHA-256 checksum result.
+ * This must be a writable buffer of length \c 32 Bytes.
+ *
+ * \return \c 0 on success.
+ * \return A negative error code on failure.
+ */
+int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx,
+ unsigned char output[32])
+{
+ SHA256_VALIDATE_RET(ctx != NULL);
+ SHA256_VALIDATE_RET((unsigned char *)output != NULL);
+
+ return cryptolite_to_mbedtls(
+ Cy_Cryptolite_Sha256_Finish(CRYPTO, (uint8_t *)output, ctx));
+}
+
+/**
+ * \brief This function processes a single data block within
+ * the ongoing SHA-256 computation. This function is for
+ * internal use only.
+ *
+ * \param ctx The SHA-256 context. This must be initialized.
+ * \param data The buffer holding one block of data. This must
+ * be a readable buffer of length \c 64 Bytes.
+ *
+ * \return \c 0 on success.
+ * \return A negative error code on failure.
+ */
+int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
+ const unsigned char data[64])
+{
+ return mbedtls_sha256_update_ret(ctx,
+ data,
+ CY_CRYPTOLITE_SHA256_BLOCK_SIZE);
+}
+
+#endif /* MBEDTLS_SHA256_ALT */
+
+#endif /* MBEDTLS_SHA256_C */
diff --git a/boot/cypress/platforms/CYW20829/crypto/mbedtls_Cryptolite/sha256_alt.h b/boot/cypress/platforms/CYW20829/crypto/mbedtls_Cryptolite/sha256_alt.h
new file mode 100644
index 0000000..f919246
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/crypto/mbedtls_Cryptolite/sha256_alt.h
@@ -0,0 +1,37 @@
+/*
+ * mbed Microcontroller Library
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright (c) 2021 Infineon Technologies AG
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ */
+
+#if !defined(SHA256_ALT_H)
+#define SHA256_ALT_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#else
+#include "config.h"
+#endif
+
+#if defined(MBEDTLS_SHA256_ALT)
+
+#include "cy_cryptolite.h"
+
+typedef cy_stc_cryptolite_context_sha_t mbedtls_sha256_context;
+
+#endif /* MBEDTLS_SHA256_ALT */
+
+#endif /* (SHA256_ALT_H) */
diff --git a/boot/cypress/platforms/CYW20829/cy_security_cnt_platform.c b/boot/cypress/platforms/CYW20829/cy_security_cnt_platform.c
new file mode 100644
index 0000000..cd39f2d
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cy_security_cnt_platform.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2020 Arm Limited.
+ * Copyright (c) 2021 Infineon Technologies AG
+ *
+ * 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.
+ */
+#include <stdint.h>
+
+#include "sysflash/sysflash.h"
+#include "cy_efuse.h"
+
+#include "cy_security_cnt_platform.h"
+#include "cy_service_app.h"
+
+#if defined MCUBootApp && defined MCUBOOT_HW_ROLLBACK_PROT
+
+#define TEST_BIT(var, pos) (0U != ((var) & (1UL << (pos))))
+
+#define NV_COUNTER_EFUSE_OFFSET 0x60
+
+/**
+ * Efuse stores nv counter value as a consequent bits. This means
+ * NV counter set to 5 in policy would be written as 0x1F. This function
+ * converts efuse value to integer value.
+ *
+ * @param val Value of security counter from which came from efuse
+ * which needs to converted in a number
+ *
+ * @return Security counter value in number form encoded in complex type on success;
+ * FIH_FAILURE on failure.
+ */
+static fih_uint convert_efuse_val(fih_uint val)
+{
+ uint32_t i = 0U;
+ uint32_t j = MAX_SEC_COUNTER_VAL - 1U;
+
+ while (TEST_BIT(fih_uint_decode(val), i++)) {
+ j--;
+ }
+
+ if ((MAX_SEC_COUNTER_VAL - j) == i) {
+ return fih_uint_encode(i - 1U);
+ }
+ else {
+ return (fih_uint)FIH_FAILURE;
+ }
+}
+
+/**
+ * Reads a data corresponding to security counter which is stored in
+ * efuses of chip and converts it actual value of security counter
+ *
+ * @param security_cnt Pointer to a variable, where security counter value would be stored
+ *
+ * @return FIH_SUCESS on success; FIH_FAILURE on failure.
+ */
+fih_int platform_security_counter_get(fih_uint *security_cnt) {
+
+ fih_int fih_ret = FIH_FAILURE;
+ cy_en_efuse_status_t efuse_stat = CY_EFUSE_ERR_UNC;
+ uint32_t nv_counter = 0;
+ fih_uint nv_counter_secure = (fih_uint)FIH_FAILURE;
+
+ /* Init also enables Efuse block */
+ efuse_stat = Cy_EFUSE_Init(EFUSE);
+
+ if (efuse_stat == CY_EFUSE_SUCCESS) {
+
+ efuse_stat = Cy_EFUSE_ReadWord(EFUSE, &nv_counter, NV_COUNTER_EFUSE_OFFSET);
+
+ if (efuse_stat == CY_EFUSE_SUCCESS){
+ /* Read value of counter from efuse twice to ensure value is not compromised */
+ nv_counter_secure = fih_uint_encode(nv_counter);
+ nv_counter = 0U;
+ efuse_stat = Cy_EFUSE_ReadWord(EFUSE, &nv_counter, NV_COUNTER_EFUSE_OFFSET);
+ }
+ if (efuse_stat == CY_EFUSE_SUCCESS){
+
+ if (fih_uint_eq(nv_counter_secure, fih_uint_encode(nv_counter))) {
+
+ *security_cnt = convert_efuse_val(nv_counter);
+ fih_ret = FIH_SUCCESS;
+
+ }
+ }
+
+ Cy_EFUSE_Disable(EFUSE);
+ Cy_EFUSE_DeInit(EFUSE);
+ }
+
+ FIH_RET(fih_ret);
+}
+
+/**
+ * Updates the stored value of a given image's security counter with a new
+ * security counter value if the new one is greater.
+ *
+ * @param reprov_packet Pointer to a reprovisioning packet containing NV counter.
+ * @param packet_len Length of a packet
+ * @param img_security_cnt Security counter value of image
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+int32_t platform_security_counter_update(uint32_t img_security_cnt, uint8_t * reprov_packet)
+{
+ int32_t rc = -1;
+ fih_uint security_cnt = (fih_uint) FIH_FAILURE;
+ fih_int fih_rc = FIH_FAILURE;
+
+ /* Read value of security counter stored in chips efuses.
+ * Only one security counter is available in system. Maximum value is 32.
+ */
+ FIH_CALL(platform_security_counter_get, fih_rc, &security_cnt);
+
+ if (true == fih_eq(fih_rc, FIH_SUCCESS)) {
+
+ /* Compare the new image's security counter value against the
+ * stored security counter value.
+ */
+ if ( (img_security_cnt > fih_uint_decode(security_cnt)) &&
+ (img_security_cnt <= MAX_SEC_COUNTER_VAL) ) {
+
+ /* Attention: This function initiates system reset */
+ call_service_app(reprov_packet);
+ /* Runtime should never get here. Panic statement added to secure
+ * sutiation when hacker initiates skip of call_service_app function.
+ */
+ FIH_PANIC;
+ }
+ else {
+ rc = 0;
+ }
+ }
+
+return rc;
+}
+
+#endif /* defined MCUBootApp && defined MCUBOOT_HW_ROLLBACK_PROT */
diff --git a/boot/cypress/platforms/CYW20829/cy_security_cnt_platform.h b/boot/cypress/platforms/CYW20829/cy_security_cnt_platform.h
new file mode 100644
index 0000000..d2e0e3c
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cy_security_cnt_platform.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2020 Arm Limited.
+ * Copyright (c) 2021 Infineon Technologies AG
+ *
+ * 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.
+ */
+
+#ifndef CY_SECURITY_CNT_PLATFORM_H
+#define CY_SECURITY_CNT_PLATFORM_H
+
+#ifdef CYW20829
+
+#include "bootutil/fault_injection_hardening.h"
+
+#define MAX_SEC_COUNTER_VAL (32U)
+
+/**
+ * Reads a data corresponding to security counter which is stored in
+ * efuses of chip and converts it actual value of security conter
+ *
+ * @param security_cnt Pointer to a variable, where security conter value would be stored
+ *
+ * @return FIH_SUCESS on success; FIH_FAILURE on failure.
+ */
+fih_int platform_security_counter_get(fih_uint *security_cnt);
+
+/**
+ * Updates the stored value of a given image's security counter with a new
+ * security counter value if the new one is greater.
+ *
+ * @param reprov_packet Pointer to a reprovisioning packet containing NV counter.
+ * @param packet_len Length of a packet
+ * @param img_security_cnt Security conter value of image
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+int32_t platform_security_counter_update(uint32_t img_security_cnt, uint8_t * reprov_packet);
+#endif /* CYW20829 */
+
+#endif /* CY_SECURITY_CNT_PLATFORM_H */
diff --git a/boot/cypress/platforms/CYW20829/cy_service_app.c b/boot/cypress/platforms/CYW20829/cy_service_app.c
new file mode 100644
index 0000000..2d2f2fb
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cy_service_app.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2021 Infineon Technologies AG
+ *
+ * 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.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "bootutil/image.h"
+#include "bootutil_priv.h"
+#include "sysflash/sysflash.h"
+
+#include "flash_qspi.h"
+#include "cy_smif_cyw20829.h"
+
+#include "cy_service_app.h"
+
+#if defined MCUBootApp && defined MCUBOOT_HW_ROLLBACK_PROT
+
+#ifndef CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE
+/* This is the value of external flash bytes after an erase */
+#define CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE (0xFFu)
+#endif /* CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE */
+
+/* Status code for the successful completion of the service application. */
+#define CYAPP_SUCCESS (0xF2A00001U)
+
+/*
+* Function is used to write data to external flash. Input address can be unaligned
+*/
+static int flash_write_packet(uint32_t address, uint8_t * data, uint32_t len)
+{
+ uint32_t row_addr = 0;
+
+ int32_t rc = -1;
+ cy_en_smif_status_t st = CY_SMIF_BAD_PARAM;
+ cy_stc_smif_mem_config_t *cfg = NULL;
+ SMIF_Type * smif_device = NULL;
+ uint32_t erase_size = 0U;
+ cy_stc_smif_context_t * smif_context = NULL;
+ uint8_t row_buff[CY_MAX_EXT_FLASH_ERASE_SIZE];
+
+ cfg = qspi_get_memory_config(0);
+ smif_device = qspi_get_device();
+ erase_size = qspi_get_erase_size();
+ smif_context = qspi_get_context();
+
+ if ( (erase_size > CY_MAX_EXT_FLASH_ERASE_SIZE) ||
+ (((address % erase_size) + len) > erase_size) ) {
+
+ return rc;
+ }
+
+ if ( (NULL != cfg) && (NULL != smif_device) && (NULL != smif_context) ) {
+ uint32_t row_mask = erase_size /* is a power of 2 */ - 1U;
+
+ /* Accepting an arbitrary address */
+ row_addr = (address - CY_XIP_BASE) & ~row_mask;
+
+ /* Preserving the block */
+ st = Cy_SMIF_MemRead(smif_device, cfg, row_addr, row_buff, erase_size, smif_context);
+
+ if (CY_SMIF_SUCCESS == st) {
+ /* Modifying target bytes */
+ (void)memcpy(row_buff + (address & row_mask), data, len);
+
+ /* Programming the updated block back */
+ st = Cy_SMIF_MemEraseSector(smif_device, cfg, row_addr, erase_size, smif_context);
+
+ if (CY_SMIF_SUCCESS == st) {
+ st = Cy_SMIF_MemWrite(smif_device, cfg, row_addr, row_buff, erase_size, smif_context);
+
+ if (CY_SMIF_SUCCESS == st) {
+ rc = 0;
+ }
+ }
+ }
+ }
+
+ return rc;
+}
+
+/*
+* Reads data from the external flash by arbitrary address.
+*/
+static int32_t flash_read(uint32_t address, uint8_t * data, uint32_t len)
+{
+ int32_t rc = -1;
+ cy_en_smif_status_t st = CY_SMIF_BAD_PARAM;
+ cy_stc_smif_mem_config_t *cfg = NULL;
+ SMIF_Type * smif_device = NULL;
+ cy_stc_smif_context_t * smif_context = NULL;
+
+ cfg = qspi_get_memory_config(0);
+ smif_device = qspi_get_device();
+ smif_context = qspi_get_context();
+
+ if ( (NULL != cfg) && (NULL != smif_device) && (NULL != smif_context) && (NULL != data) &&
+ (address >= CY_XIP_BASE) ) {
+ st = Cy_SMIF_MemRead(smif_device, cfg, (address - CY_XIP_BASE), data, len, smif_context);
+
+ if (CY_SMIF_SUCCESS == st) {
+ rc = 0;
+ }
+ }
+
+ return rc;
+}
+
+/*
+* In CYW20829 security counter can only be updated using special service application,
+* which is executed by BootROM. Function initializes suplement data for service app and
+* triggers system reset. BootROM is then runs service app, which performs actual update
+* of security counter value in chips efuse.
+*/
+void call_service_app(uint8_t * reprov_packet)
+{
+ int32_t rc = -1;
+ service_app_desc_type reprov_app_desc;
+
+ /* Initialize service app descriptor */
+ reprov_app_desc.service_app_descr_size = SERVICE_APP_DESC_SIZE;
+ reprov_app_desc.service_app_addr = SERVICE_APP_OFFSET;
+ reprov_app_desc.service_app_size = SERVICE_APP_SIZE;
+ reprov_app_desc.input_param_addr = SERVICE_APP_INPUT_PARAMS_OFFSET;
+ reprov_app_desc.input_param_size = REPROV_PACK_SIZE;
+
+ /* Put service app suplement data in flash */
+ if (NULL != reprov_packet)
+ {
+ /* Write input params */
+ rc = flash_write_packet((CY_XIP_BASE + SERVICE_APP_INPUT_PARAMS_OFFSET),
+ reprov_packet, REPROV_PACK_SIZE);
+ if (0 == rc) {
+ /* Write application descriptor. The address of the application
+ * descriptor is already present in the TOC2 (offset 0x8). */
+ rc = flash_write_packet((CY_XIP_BASE + SERVICE_APP_DESC_OFFSET),
+ (uint8_t *)&reprov_app_desc, sizeof(reprov_app_desc));
+ if (0 == rc) {
+ /* Set code to tell BootROM to launch a service app downloaded to RAM from an external memory */
+ SRSS->TST_DEBUG_CTL = CYBOOT_REQUEST_EXT_APP;
+ /* Trigger device reset */
+ __NVIC_SystemReset();
+ }
+ }
+ }
+}
+
+/*
+* Checks the service application completion status.
+*
+* Reads the service app descriptor from the flash. If it is populated, erases the service app
+* descriptor and verifies that the application status in the TST_DEBUG_STATUS register
+* contains the CYAPP_SUCCESS value.
+* Function limitations:
+* - assumes that the service app descriptor is located in external flash;
+* - erases the entire sector where the service app descriptor is located.
+*
+* Returns 0 if the service app descriptor is empty or TST_DEBUG_STATUS register
+* contains the CYAPP_SUCCESS value. Otherwise it returns -1.
+*/
+int32_t check_service_app_status(void)
+{
+ int32_t rc = -1;
+ uint8_t reprov_app_desc[sizeof(service_app_desc_type)] = {0};
+
+ rc = flash_read((CY_XIP_BASE + SERVICE_APP_DESC_OFFSET),
+ reprov_app_desc, sizeof(reprov_app_desc));
+ if (0 == rc) {
+ if (bootutil_buffer_is_filled(reprov_app_desc, CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE, sizeof(reprov_app_desc))) {
+ rc = 0;
+ }
+ else {
+ rc = cyw20829_smif_erase((CY_XIP_BASE + SERVICE_APP_DESC_OFFSET), qspi_get_erase_size());
+ if (0 == rc) {
+ if (CYAPP_SUCCESS == SRSS->TST_DEBUG_STATUS) {
+ rc = 0;
+ }
+ else {
+ rc = -1;
+ }
+ }
+ }
+ }
+
+ return rc;
+}
+
+#endif /* MCUBootApp && MCUBOOT_HW_ROLLBACK_PROT */
diff --git a/boot/cypress/platforms/CYW20829/cy_service_app.h b/boot/cypress/platforms/CYW20829/cy_service_app.h
new file mode 100644
index 0000000..c306bfa
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cy_service_app.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2021 Infineon Technologies AG
+ *
+ * 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.
+ */
+
+#if !defined(CY_SERVICE_APP)
+#define CY_SERVICE_APP
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined(MCUBootApp) && defined(MCUBOOT_HW_ROLLBACK_PROT)
+
+#include <stdint.h>
+
+#ifndef SERVICE_APP_DESC_SIZE
+#define SERVICE_APP_DESC_SIZE 0x14
+#endif /* SERVICE_APP_DESC_SIZE */
+
+#ifndef SERVICE_APP_SIZE
+#error "Size of service application is undefined!"
+#endif /* SERVICE_APP_SIZE */
+
+#define CYBOOT_REQUEST_EXT_APP (3UL)
+
+/*
+ * Service application regions in external flash
+ *
+0x60070000 -------------------------
+ | |
+ | |
+ | Service App Binary |
+ | |
+ | |
+ | |
+ | |
+0x60078000 -------------------------
+ | |
+ | Service App Input |
+ | Params |
+ | |
+0x60078400 -------------------------
+ | |
+ | Service App |
+ | Descriptor Addr |
+ | |
+0x60078420 -------------------------
+*/
+
+#ifndef SERVICE_APP_OFFSET
+#error "Service application offset is undefined!"
+#endif
+
+#ifndef SERVICE_APP_INPUT_PARAMS_OFFSET
+#error "Service application input parameters offset is undefined!"
+#endif
+
+#ifndef SERVICE_APP_DESC_OFFSET
+#error "Service application descriptor offset is undefined!"
+#endif
+
+/*
+ * 0x00 SERVICE_APP_DESCR_SIZE Service application descriptor object size,
+ * includes size entry (hardcoded value 20 bytes).
+ * 0x04 SERVICE_APP_ADDR Start address of service application in the external memory (offset).
+ * 0x08 SERVICE_APP_SIZE Service application image size.
+ * 0x0C INPUT_PARAM_ADDR Address of input parameters for service application in the
+ * external memory (offset).
+ * 0x10 INPUT_PARAM_SIZE Input parameters size.
+*/
+typedef struct
+{
+ uint32_t service_app_descr_size;
+ uint32_t service_app_addr;
+ uint32_t service_app_size;
+ uint32_t input_param_addr;
+ uint32_t input_param_size;
+} service_app_desc_type;
+
+/*
+* Function initilizes data required for service app execution and triggers system reset
+* to initiate service app execution
+*/
+void call_service_app(uint8_t * reprov_packet);
+
+/*
+* Returns completion status of the service application
+*/
+int32_t check_service_app_status(void);
+
+#endif /* MCUBootApp */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* CY_SERVICE_APP && MCUBOOT_HW_ROLLBACK_PROT */
diff --git a/boot/cypress/platforms/CYW20829/cybsp.c b/boot/cypress/platforms/CYW20829/cybsp.c
new file mode 100644
index 0000000..e8407b7
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cybsp.c
@@ -0,0 +1,151 @@
+/***************************************************************************//**
+* \file cybsp.c
+*
+* Description:
+* Provides initialization code for starting up the hardware contained on the
+* Cypress board.
+*
+********************************************************************************
+* \copyright
+* Copyright 2018-2021 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+*******************************************************************************/
+
+#include <stdlib.h>
+#include "cy_syspm.h"
+#include "cy_sysclk.h"
+#include "cybsp.h"
+#if defined(CY_USING_HAL)
+#include "cyhal_hwmgr.h"
+#include "cyhal_syspm.h"
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+// The sysclk deep sleep callback is recommended to be the last callback that is executed before
+// entry into deep sleep mode and the first one upon exit the deep sleep mode.
+// Doing so minimizes the time spent on low power mode entry and exit.
+#ifndef CYBSP_SYSCLK_PM_CALLBACK_ORDER
+ #define CYBSP_SYSCLK_PM_CALLBACK_ORDER (255u)
+#endif
+
+#if defined(CYBSP_WIFI_CAPABLE) && defined(CY_USING_HAL)
+static cyhal_sdio_t sdio_obj;
+
+//--------------------------------------------------------------------------------------------------
+// cybsp_get_wifi_sdio_obj
+//--------------------------------------------------------------------------------------------------
+cyhal_sdio_t* cybsp_get_wifi_sdio_obj(void)
+{
+ return &sdio_obj;
+}
+
+
+#endif // if defined(CYBSP_WIFI_CAPABLE) && defined(CY_USING_HAL)
+
+//--------------------------------------------------------------------------------------------------
+// cybsp_register_sysclk_pm_callback
+//
+// Registers a power management callback that prepares the clock system for entering deep sleep mode
+// and restore the clocks upon wakeup from deep sleep.
+// NOTE: This is called automatically as part of \ref cybsp_init
+//--------------------------------------------------------------------------------------------------
+static cy_rslt_t cybsp_register_sysclk_pm_callback(void)
+{
+ cy_rslt_t result = CY_RSLT_SUCCESS;
+ static cy_stc_syspm_callback_params_t cybsp_sysclk_pm_callback_param = { NULL, NULL };
+ static cy_stc_syspm_callback_t cybsp_sysclk_pm_callback =
+ {
+ .callback = &Cy_SysClk_DeepSleepCallback,
+ .type = CY_SYSPM_DEEPSLEEP,
+ .callbackParams = &cybsp_sysclk_pm_callback_param,
+ .order = CYBSP_SYSCLK_PM_CALLBACK_ORDER
+ };
+
+ if (!Cy_SysPm_RegisterCallback(&cybsp_sysclk_pm_callback))
+ {
+ result = CYBSP_RSLT_ERR_SYSCLK_PM_CALLBACK;
+ }
+ return result;
+}
+
+
+//--------------------------------------------------------------------------------------------------
+// cybsp_init
+//--------------------------------------------------------------------------------------------------
+cy_rslt_t cybsp_init(void)
+{
+ // Setup hardware manager to track resource usage then initialize all system (clock/power) board
+ // configuration
+ #if defined(CY_USING_HAL)
+ cy_rslt_t result = cyhal_hwmgr_init();
+
+ if (CY_RSLT_SUCCESS == result)
+ {
+ result = cyhal_syspm_init();
+ }
+
+ #ifdef CY_CFG_PWR_VDDA_MV
+ if (CY_RSLT_SUCCESS == result)
+ {
+ cyhal_syspm_set_supply_voltage(CYHAL_VOLTAGE_SUPPLY_VDDA, CY_CFG_PWR_VDDA_MV);
+ }
+ #endif
+
+ #else // if defined(CY_USING_HAL)
+ cy_rslt_t result = CY_RSLT_SUCCESS;
+ #endif // if defined(CY_USING_HAL)
+
+ #if defined(COMPONENT_BSP_DESIGN_MODUS) || defined(COMPONENT_CUSTOM_DESIGN_MODUS)
+ init_cycfg_all();
+ #endif
+
+ if (CY_RSLT_SUCCESS == result)
+ {
+ result = cybsp_register_sysclk_pm_callback();
+ }
+
+ #if defined(CYBSP_WIFI_CAPABLE) && defined(CY_USING_HAL)
+ // Initialize SDIO interface. This must be done before other HAL API calls as some SDIO
+ // implementations require specific peripheral instances.
+ // NOTE: The full WiFi interface still needs to be initialized via cybsp_wifi_init_primary().
+ // This is typically done when starting up WiFi.
+ if (CY_RSLT_SUCCESS == result)
+ {
+ // Reserves: CYBSP_WIFI_SDIO, CYBSP_WIFI_SDIO_D0, CYBSP_WIFI_SDIO_D1, CYBSP_WIFI_SDIO_D2,
+ // CYBSP_WIFI_SDIO_D3, CYBSP_WIFI_SDIO_CMD and CYBSP_WIFI_SDIO_CLK.
+ result = cyhal_sdio_init(
+ &sdio_obj,
+ CYBSP_WIFI_SDIO_CMD,
+ CYBSP_WIFI_SDIO_CLK,
+ CYBSP_WIFI_SDIO_D0,
+ CYBSP_WIFI_SDIO_D1,
+ CYBSP_WIFI_SDIO_D2,
+ CYBSP_WIFI_SDIO_D3);
+ }
+ #endif // defined(CYBSP_WIFI_CAPABLE)
+
+ // CYHAL_HWMGR_RSLT_ERR_INUSE error code could be returned if any needed for BSP resource was
+ // reserved by user previously. Please review the Device Configurator (design.modus) and the BSP
+ // reservation list (cyreservedresources.list) to make sure no resources are reserved by both.
+ return result;
+}
+
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/boot/cypress/platforms/CYW20829/cybsp.h b/boot/cypress/platforms/CYW20829/cybsp.h
new file mode 100644
index 0000000..6d5d663
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cybsp.h
@@ -0,0 +1,83 @@
+#ifndef CYBSP_H
+#define CYBSP_H
+/***********************************************************************************************//**
+ * \file cybsp.h
+ *
+ * \brief
+ * Basic API for setting up boards containing a Cypress MCU.
+ *
+ ***************************************************************************************************
+ * \copyright
+ * Copyright 2018-2021 Cypress Semiconductor Corporation
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ **************************************************************************************************/
+
+#pragma once
+
+#include "cy_result.h"
+#include "cybsp_types.h"
+#if defined(CYBSP_WIFI_CAPABLE) && defined(CY_USING_HAL)
+#include "cyhal_sdio.h"
+#endif
+#if defined(COMPONENT_WICED_BLE) || defined(COMPONENT_WICED_DUALMODE)
+#include "cybsp_bt_config.h"
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/**
+ * \addtogroup group_bsp_errors Error Codes
+ * \{
+ * Error codes specific to the board.
+ */
+
+/** Failed to configure sysclk power management callback */
+#define CYBSP_RSLT_ERR_SYSCLK_PM_CALLBACK \
+ (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_BSP, 0))
+
+/** \} group_bsp_errors */
+
+/**
+ * \addtogroup group_bsp_functions Functions
+ * \{
+ * All functions exposed by the board.
+ */
+
+/**
+ * \brief Initialize all hardware on the board
+ * \returns CY_RSLT_SUCCESS if the board is successfully initialized, if there is
+ * a problem initializing any hardware it returns an error code specific
+ * to the hardware module that had a problem.
+ */
+cy_rslt_t cybsp_init(void);
+
+#if defined(CYBSP_WIFI_CAPABLE) && defined(CY_USING_HAL)
+/**
+ * \brief Get the initialized sdio object used for communicating with the WiFi Chip.
+ * \note This function should only be called after cybsp_init();
+ * \returns The initialized sdio object.
+ */
+cyhal_sdio_t* cybsp_get_wifi_sdio_obj(void);
+#endif // defined(CYBSP_WIFI_CAPABLE)
+
+/** \} group_bsp_functions */
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif /* CYBSP_H */
diff --git a/boot/cypress/platforms/CYW20829/cybsp_doc.h b/boot/cypress/platforms/CYW20829/cybsp_doc.h
new file mode 100644
index 0000000..dec68e1
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cybsp_doc.h
@@ -0,0 +1,842 @@
+#ifndef CYBSP_DOC_H
+#define CYBSP_DOC_H
+/***********************************************************************************************//**
+ * \copyright
+ * Copyright 2018-2021 Cypress Semiconductor Corporation
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ **************************************************************************************************/
+
+#pragma once
+
+#if defined(CY_USING_HAL)
+#include "cyhal_pin_package.h"
+#endif
+#if defined(COMPONENT_BSP_DESIGN_MODUS) || defined(COMPONENT_CUSTOM_DESIGN_MODUS)
+#include "cycfg.h"
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/**
+ * \addtogroup group_bsp_pins Pin Mappings
+ * \{
+ * Macro definitions for common peripheral pins on the board.
+ */
+
+#if defined(CYBSP_USER_LED)
+/**
+ * \addtogroup group_bsp_pins_led LED Pins
+ * \{
+ * Pins connected to user LEDs on the board.
+ */
+
+#ifdef CYBSP_LED_RGB_RED
+/** RGB LED - Red \def CYBSP_LED_RGB_RED
+ */
+#endif
+#ifdef CYBSP_LED_RGB_GREEN
+/** RGB LED - Green \def CYBSP_LED_RGB_GREEN
+ */
+#endif
+#ifdef CYBSP_LED_RGB_BLUE
+/** RGB LED - Blue \def CYBSP_LED_RGB_BLUE
+ */
+#endif
+#ifdef CYBSP_USER_LED
+/** User LED \def CYBSP_USER_LED
+ */
+#endif
+#ifdef CYBSP_USER_LED1
+/** User LED1 \def CYBSP_USER_LED1
+ */
+#endif
+#ifdef CYBSP_USER_LED2
+/** User LED2 \def CYBSP_USER_LED2
+ */
+#endif
+#ifdef CYBSP_USER_LED3
+/** User LED3 \def CYBSP_USER_LED3
+ */
+#endif
+#ifdef CYBSP_USER_LED4
+/** User LED 4 \def CYBSP_USER_LED4
+ */
+#endif
+#ifdef CYBSP_USER_LED5
+/** User LED 5 \def CYBSP_USER_LED5
+ */
+#endif
+#ifdef CYBSP_USER_LED6
+/** User LED 6 \def CYBSP_USER_LED6
+ */
+#endif
+#ifdef CYBSP_USER_LED7
+/** User LED 7 \def CYBSP_USER_LED7
+ */
+#endif
+#ifdef CYBSP_USER_LED8
+/** User LED 8 \def CYBSP_USER_LED8
+ */
+#endif
+#ifdef CYBSP_USER_LED9
+/** User LED 9 \def CYBSP_USER_LED9
+ */
+#endif
+#ifdef CYBSP_USER_LED10
+/** User LED 10 \def CYBSP_USER_LED10
+ */
+#endif
+#ifdef CYBSP_LED1
+/** LED 1 \def CYBSP_LED1
+ */
+#endif
+#ifdef CYBSP_LED2
+/** LED 2 \def CYBSP_LED2
+ */
+#endif
+#ifdef CYBSP_LED3
+/** LED 3 \def CYBSP_LED3
+ */
+#endif
+#ifdef CYBSP_LED3_RGB_RED
+/** LED 3: RGB LED - Red \def CYBSP_LED3_RGB_RED
+ */
+#endif
+#ifdef CYBSP_LED3_RGB_GREEN
+/** LED 3: RGB LED - Green \def CYBSP_LED3_RGB_GREEN
+ */
+#endif
+#ifdef CYBSP_LED3_RGB_BLUE
+/** LED 3: RGB LED - Blue \def CYBSP_LED3_RGB_BLUE
+ */
+#endif
+#ifdef CYBSP_LED4
+/** LED 4 \def CYBSP_LED4
+ */
+#endif
+#ifdef CYBSP_LED5
+/** LED 5 \def CYBSP_LED5
+ */
+#endif
+#ifdef CYBSP_LED6
+/** LED 6 \def CYBSP_LED6
+ */
+#endif
+#ifdef CYBSP_LED7
+/** LED 7 \def CYBSP_LED7
+ */
+#endif
+#ifdef CYBSP_LED8
+/** LED 8 \def CYBSP_LED8
+ */
+#endif
+#ifdef CYBSP_LED9
+/** LED 9 \def CYBSP_LED9
+ */
+#endif
+#ifdef CYBSP_LED10
+/** LED 10 \def CYBSP_LED10
+ */
+#endif
+#ifdef CYBSP_LED11
+/** LED 11 \def CYBSP_LED11
+ */
+#endif
+#ifdef CYBSP_LED12
+/** LED 12 \def CYBSP_LED12
+ */
+#endif
+#ifdef CYBSP_LED13
+/** LED 13 \def CYBSP_LED13
+ */
+#endif
+#ifdef CYBSP_LED_SLD0
+/** Slider LED 0 \def CYBSP_LED_SLD0
+ */
+#endif
+#ifdef CYBSP_LED_SLD1
+/** Slider LED 1 \def CYBSP_LED_SLD1
+ */
+#endif
+#ifdef CYBSP_LED_SLD2
+/** Slider LED 2 \def CYBSP_LED_SLD2
+ */
+#endif
+#ifdef CYBSP_LED_SLD3
+/** Slider LED 3 \def CYBSP_LED_SLD3
+ */
+#endif
+#ifdef CYBSP_LED_SLD4
+/** Slider LED 4 \def CYBSP_LED_SLD4
+ */
+#endif
+#ifdef CYBSP_LED_SLD5
+/** LED 10; Slider LED 5 \def CYBSP_LED_SLD5
+ */
+#endif
+#ifdef CYBSP_LED_BTN0
+/** Button LED 0 \def CYBSP_LED_BTN0
+ */
+#endif
+#ifdef CYBSP_LED_BTN1
+/** Button LED 1 \def CYBSP_LED_BTN1
+ */
+#endif
+#ifdef CYBSP_LED_BTN2
+/** Button LED 2 \def CYBSP_LED_BTN2
+ */
+#endif
+
+/** \} group_bsp_pins_led */
+#endif // defined(CYBSP_USER_LED)
+
+#if defined(CYBSP_USER_BTN)
+/**
+ * \addtogroup group_bsp_pins_btn Button Pins
+ * \{
+ * Pins connected to user buttons on the board.
+ */
+
+#ifdef CYBSP_SW1
+/** Switch 1 \def CYBSP_SW1
+ */
+#endif
+#ifdef CYBSP_SW2
+/** Switch 2 \def CYBSP_SW2
+ */
+#endif
+#ifdef CYBSP_SW3
+/** Switch 3 \def CYBSP_SW3
+ */
+#endif
+#ifdef CYBSP_SW4
+/** Switch 4 \def CYBSP_SW4
+ */
+#endif
+#ifdef CYBSP_USER_BTN
+/** User Button 1 \def CYBSP_USER_BTN
+ */
+#endif
+#ifdef CYBSP_USER_BTN1
+/** User Button 1 \def CYBSP_USER_BTN1
+ */
+#endif
+#ifdef CYBSP_USER_BTN2
+/** User Button 2 \def CYBSP_USER_BTN2
+ */
+#endif
+#ifdef CYBSP_POTENTIOMETER_INPUT
+/** Potentiometer input \def CYBSP_POTENTIOMETER_INPUT
+ */
+#endif
+
+/** \} group_bsp_pins_btn */
+#endif // defined(CYBSP_USER_BTN)
+
+#if defined(CYBSP_DEBUG_UART_RX) || defined(CYBSP_SWDIO)
+/**
+ * \addtogroup group_bsp_pins_comm Communication Pins
+ * \{
+ * Pins associated with connections on the board for communication interfaces (UART/I2C/SPI/...)
+ */
+
+#ifdef CYBSP_DEBUG_UART_RX
+/** Pin: UART RX \def CYBSP_DEBUG_UART_RX
+ */
+#endif
+#ifdef CYBSP_DEBUG_UART_TX
+/** Pin: UART TX \def CYBSP_DEBUG_UART_TX
+ */
+#endif
+#ifdef CYBSP_I2C_SCL
+/** Pin: I2C SCL \def CYBSP_I2C_SCL
+ */
+#endif
+#ifdef CYBSP_I2C_SDA
+/** Pin: I2C SDA \def CYBSP_I2C_SDA
+ */
+#endif
+#ifdef CYBSP_SWDIO
+/** Pin: SWDIO \def CYBSP_SWDIO
+ */
+#endif
+#ifdef CYBSP_SWDCK
+/** Pin: SWDCK \def CYBSP_SWDCK
+ */
+#endif
+#ifdef CYBSP_SPI_MOSI
+/** Pin: SPI MOSI \def CYBSP_SPI_MOSI
+ */
+#endif
+#ifdef CYBSP_SPI_MISO
+/** Pin: SPI MISO \def CYBSP_SPI_MISO
+ */
+#endif
+#ifdef CYBSP_SPI_CLK
+/** Pin: SPI CLK \def CYBSP_SPI_CLK
+ */
+#endif
+#ifdef CYBSP_SPI_CS
+/** Pin: SPI CS \def CYBSP_SPI_CS
+ */
+#endif
+#ifdef CYBSP_SWO
+/** Pin: SWO \def CYBSP_SWO
+ */
+#endif
+#ifdef CYBSP_QSPI_SS
+/** Pin: QUAD SPI SS \def CYBSP_QSPI_SS
+ */
+#endif
+#ifdef CYBSP_QSPI_D3
+/** Pin: QUAD SPI D3 \def CYBSP_QSPI_D3
+ */
+#endif
+#ifdef CYBSP_QSPI_D2
+/** Pin: QUAD SPI D2 \def CYBSP_QSPI_D2
+ */
+#endif
+#ifdef CYBSP_QSPI_D1
+/** Pin: QUAD SPI D1 \def CYBSP_QSPI_D1
+ */
+#endif
+#ifdef CYBSP_QSPI_D0
+/** Pin: QUAD SPI D0 \def CYBSP_QSPI_D0
+ */
+#endif
+#ifdef CYBSP_QSPI_SCK
+/** Pin: QUAD SPI SCK \def CYBSP_QSPI_SCK
+ */
+#endif
+#ifdef CYBSP_WIFI_SDIO_D0
+/** Pin: WIFI SDIO D0 \def CYBSP_WIFI_SDIO_D0
+ */
+#endif
+#ifdef CYBSP_WIFI_SDIO_D1
+/** Pin: WIFI SDIO D1 \def CYBSP_WIFI_SDIO_D1
+ */
+#endif
+#ifdef CYBSP_WIFI_SDIO_D2
+/** Pin: WIFI SDIO D2 \def CYBSP_WIFI_SDIO_D2
+ */
+#endif
+#ifdef CYBSP_WIFI_SDIO_D3
+/** Pin: WIFI SDIO D3 \def CYBSP_WIFI_SDIO_D3
+ */
+#endif
+#ifdef CYBSP_WIFI_SDIO_CMD
+/** Pin: WIFI SDIO CMD \def CYBSP_WIFI_SDIO_CMD
+ */
+#endif
+#ifdef CYBSP_WIFI_SDIO_CLK
+/** Pin: WIFI SDIO CLK \def CYBSP_WIFI_SDIO_CLK
+ */
+#endif
+#ifdef CYBSP_WIFI_WL_REG_ON
+/** Pin: WIFI ON \def CYBSP_WIFI_WL_REG_ON
+ */
+#endif
+#ifdef CYBSP_WIFI_HOST_WAKE
+/** Pin: WIFI Host Wakeup \def CYBSP_WIFI_HOST_WAKE
+ */
+
+/** WiFi host-wake GPIO drive mode */
+#define CYBSP_WIFI_HOST_WAKE_GPIO_DM (CYHAL_GPIO_DRIVE_ANALOG)
+/** WiFi host-wake IRQ event */
+#define CYBSP_WIFI_HOST_WAKE_IRQ_EVENT (CYHAL_GPIO_IRQ_RISE)
+#endif
+#ifdef CYBSP_BT_UART_RX
+/** Pin: BT UART RX \def CYBSP_BT_UART_RX
+ */
+#endif
+#ifdef CYBSP_BT_UART_TX
+/** Pin: BT UART TX \def CYBSP_BT_UART_TX
+ */
+#endif
+#ifdef CYBSP_BT_UART_RTS
+/** Pin: BT UART RTS \def CYBSP_BT_UART_RTS
+ */
+#endif
+#ifdef CYBSP_BT_UART_CTS
+/** Pin: BT UART CTS \def CYBSP_BT_UART_CTS
+ */
+#endif
+#ifdef CYBSP_BT_POWER
+/** Pin: BT Power \def CYBSP_BT_POWER
+ */
+#endif
+#ifdef CYBSP_BT_HOST_WAKE
+/** Pin: BT Host Wakeup \def CYBSP_BT_HOST_WAKE
+ */
+/** BT host-wake GPIO drive mode */
+#define CYBSP_BT_HOST_WAKE_GPIO_DM (CYHAL_GPIO_DRIVE_NONE)
+/** BT host wake IRQ event */
+#define CYBSP_BT_HOST_WAKE_IRQ_EVENT (CYHAL_GPIO_IRQ_FALL)
+#endif
+#ifdef CYBSP_BT_DEVICE_WAKE
+/** Pin: BT Device Wakeup \def CYBSP_BT_DEVICE_WAKE
+ */
+/** BT device wakeup GPIO drive mode */
+#define CYBSP_BT_DEVICE_WAKE_GPIO_DM (CYHAL_GPIO_DRIVE_STRONG)
+/** BT device wakeup polarity */
+#define CYBSP_BT_DEVICE_WAKE_POLARITY (0u)
+#endif
+#ifdef CYBSP_PDM_CLK
+/** Pin: PDM PCM CLK \def CYBSP_PDM_CLK
+ */
+#endif
+#ifdef CYBSP_PDM_DATA
+/** Pin PDM PCM DATA \def CYBSP_PDM_DATA
+ */
+#endif
+#ifdef CYBSP_I2S_MCLK
+/** Pin: I2S MCLK \def CYBSP_I2S_MCLK
+ */
+#endif
+#ifdef CYBSP_I2S_TX_SCK
+/** Pin: I2S TX SCK \def CYBSP_I2S_TX_SCK
+ */
+#endif
+#ifdef CYBSP_I2S_TX_WS
+/** Pin: I2S TX WS \def CYBSP_I2S_TX_WS
+ */
+#endif
+#ifdef CYBSP_I2S_TX_DATA
+/** Pin: I2S TX DATA \def CYBSP_I2S_TX_DATA
+ */
+#endif
+#ifdef CYBSP_I2S_RX_SCK
+/** Pin: I2S RX SCK \def CYBSP_I2S_RX_SCK
+ */
+#endif
+#ifdef CYBSP_I2S_RX_WS
+/** Pin: I2S RX WS \def CYBSP_I2S_RX_WS
+ */
+#endif
+#ifdef CYBSP_I2S_RX_DATA
+/** Pin: I2S RX DATA \def CYBSP_I2S_RX_DATA
+ */
+#endif
+#ifdef CYBSP_DEBUG_UART_RTS
+/** Pin: UART RX \def CYBSP_DEBUG_UART_RTS
+ */
+#endif
+#ifdef CYBSP_DEBUG_UART_CTS
+/** Pin: UART TX \def CYBSP_DEBUG_UART_CTS
+ */
+#endif
+#ifdef CYBSP_UART_RX
+/** Pin: UART RX \def CYBSP_UART_RX
+ */
+#endif
+#ifdef CYBSP_UART_TX
+/** Pin: UART TX \def CYBSP_UART_TX
+ */
+#endif
+#ifdef CYBSP_TDO_SWO
+/** Pin: \def CYBSP_TDO_SWO
+ */
+#endif
+#ifdef CYBSP_TMS_SWDIO
+/** Pin: \def CYBSP_TMS_SWDIO
+ */
+#endif
+#ifdef CYBSP_SWCLK
+/** Pin: \def CYBSP_SWCLK
+ */
+#endif
+
+/** \} group_bsp_pins_comm */
+#endif // defined(CYBSP_DEBUG_UART_RX) || defined(CYBSP_SWDIO)
+
+#if defined(CYBSP_A0)
+/**
+ * \addtogroup group_bsp_pins_arduino Arduino Header Pins
+ * \{
+ * Pins mapped to the Arduino header on the board.
+ */
+
+#ifdef CYBSP_A0
+/** Arduino A0 \def CYBSP_A0
+ */
+#endif
+#ifdef CYBSP_A1
+/** Arduino A1 \def CYBSP_A1
+ */
+#endif
+#ifdef CYBSP_A2
+/** Arduino A2 \def CYBSP_A2
+ */
+#endif
+#ifdef CYBSP_A3
+/** Arduino A3 \def CYBSP_A3
+ */
+#endif
+#ifdef CYBSP_A4
+/** Arduino A4 \def CYBSP_A4
+ */
+#endif
+#ifdef CYBSP_A5
+/** Arduino A5 \def CYBSP_A5
+ */
+#endif
+#ifdef CYBSP_D0
+/** Arduino D0 \def CYBSP_D0
+ */
+#endif
+#ifdef CYBSP_D1
+/** Arduino D1 \def CYBSP_D1
+ */
+#endif
+#ifdef CYBSP_D2
+/** Arduino D2 \def CYBSP_D2
+ */
+#endif
+#ifdef CYBSP_D3
+/** Arduino D3 \def CYBSP_D3
+ */
+#endif
+#ifdef CYBSP_D4
+/** Arduino D4 \def CYBSP_D4
+ */
+#endif
+#ifdef CYBSP_D5
+/** Arduino D5 \def CYBSP_D5
+ */
+#endif
+#ifdef CYBSP_D6
+/** Arduino D6 \def CYBSP_D6
+ */
+#endif
+#ifdef CYBSP_D7
+/** Arduino D7 \def CYBSP_D7
+ */
+#endif
+#ifdef CYBSP_D8
+/** Arduino D8 \def CYBSP_D8
+ */
+#endif
+#ifdef CYBSP_D9
+/** Arduino D9 \def CYBSP_D9
+ */
+#endif
+#ifdef CYBSP_D10
+/** Arduino D10 \def CYBSP_D10
+ */
+#endif
+#ifdef CYBSP_D11
+/** Arduino D11 \def CYBSP_D11
+ */
+#endif
+#ifdef CYBSP_D12
+/** Arduino D12 \def CYBSP_D12
+ */
+#endif
+#ifdef CYBSP_D13
+/** Arduino D13 \def CYBSP_D13
+ */
+#endif
+#ifdef CYBSP_D14
+/** Arduino D14 \def CYBSP_D14
+ */
+#endif
+#ifdef CYBSP_D15
+/** Arduino D15 \def CYBSP_D15
+ */
+#endif
+
+/** \} group_bsp_pins_arduino */
+#endif // defined(CYBSP_A0)
+
+#if defined(CYBSP_J2_1)
+/**
+ * \addtogroup group_bsp_pins_j2 J2 Header Pins
+ * \{
+ * Pins mapped to the J2 header on the board.
+ */
+
+#ifdef CYBSP_J2_1
+/** Cypress J2 Header pin 1 \def CYBSP_J2_1
+ */
+#endif
+#ifdef CYBSP_J2_2
+/** Cypress J2 Header pin 2 \def CYBSP_J2_2
+ */
+#endif
+#ifdef CYBSP_J2_3
+/** Cypress J2 Header pin 3 \def CYBSP_J2_3
+ */
+#endif
+#ifdef CYBSP_J2_4
+/** Cypress J2 Header pin 4 \def CYBSP_J2_4
+ */
+#endif
+#ifdef CYBSP_J2_5
+/** Cypress J2 Header pin 5 \def CYBSP_J2_5
+ */
+#endif
+#ifdef CYBSP_J2_7
+/** Cypress J2 Header pin 7 \def CYBSP_J2_7
+ */
+#endif
+#ifdef CYBSP_J2_8
+/** Cypress J2 Header pin 8 \def CYBSP_J2_8
+ */
+#endif
+#ifdef CYBSP_J2_9
+/** Cypress J2 Header pin 9 \def CYBSP_J2_9
+ */
+#endif
+#ifdef CYBSP_J2_10
+/** Cypress J2 Header pin 10 \def CYBSP_J2_10
+ */
+#endif
+#ifdef CYBSP_J2_11
+/** Cypress J2 Header pin 11 \def CYBSP_J2_11
+ */
+#endif
+#ifdef CYBSP_J2_12
+/** Cypress J2 Header pin 12 \def CYBSP_J2_12
+ */
+#endif
+#ifdef CYBSP_J2_13
+/** Cypress J2 Header pin 13 \def CYBSP_J2_13
+ */
+#endif
+#ifdef CYBSP_J2_15
+/** Cypress J2 Header pin 15 \def CYBSP_J2_15
+ */
+#endif
+#ifdef CYBSP_J2_16
+/** Cypress J2 Header pin 16 \def CYBSP_J2_16
+ */
+#endif
+#ifdef CYBSP_J2_16
+/** Cypress J2 Header pin 16 \def CYBSP_J2_16
+ */
+#endif
+#ifdef CYBSP_J2_6
+/** Cypress J2 Header pin 6 \def CYBSP_J2_6
+ */
+#endif
+#ifdef CYBSP_J2_17
+/** Cypress J2 Header pin 17 \def CYBSP_J2_17
+ */
+#endif
+#ifdef CYBSP_J2_18
+/** Cypress J2 Header pin 18 \def CYBSP_J2_18
+ */
+#endif
+#ifdef CYBSP_J2_19
+/** Cypress J2 Header pin 19 \def CYBSP_J2_19
+ */
+#endif
+#ifdef CYBSP_J2_20
+/** Cypress J2 Header pin 20 \def CYBSP_J2_20
+ */
+#endif
+#ifdef CYBSP_J2_14
+/** Cypress J2 Header pin 14 \def CYBSP_J2_14
+ */
+#endif
+
+/** \} group_bsp_pins_j2 */
+#endif // defined(CYBSP_J2_1)
+
+#if defined(CYBSP_J6_1)
+/**
+ * \addtogroup group_bsp_pins_j6 J6 Header Pins
+ * \{
+ * Pins mapped to the J6 header on the board.
+ */
+
+#ifdef CYBSP_J6_1
+/** Cypress J6 Header pin 1 \def CYBSP_J6_1
+ */
+#endif
+#ifdef CYBSP_J6_2
+/** Cypress J6 Header pin 2 \def CYBSP_J6_2
+ */
+#endif
+#ifdef CYBSP_J6_3
+/** Cypress J6 Header pin 3 \def CYBSP_J6_3
+ */
+#endif
+#ifdef CYBSP_J6_4
+/** Cypress J6 Header pin 4 \def CYBSP_J6_4
+ */
+#endif
+#ifdef CYBSP_J6_5
+/** Cypress J6 Header pin 5 \def CYBSP_J6_5
+ */
+#endif
+#ifdef CYBSP_J6_6
+/** Cypress J6 Header pin 6 \def CYBSP_J6_6
+ */
+#endif
+#ifdef CYBSP_J6_7
+/** Cypress J6 Header pin 7 \def CYBSP_J6_7
+ */
+#endif
+#ifdef CYBSP_J6_8
+/** Cypress J6 Header pin 8 \def CYBSP_J6_8
+ */
+#endif
+#ifdef CYBSP_J6_9
+/** Cypress J6 Header pin 9 \def CYBSP_J6_9
+ */
+#endif
+#ifdef CYBSP_J6_10
+/** Cypress J6 Header pin 10 \def CYBSP_J6_10
+ */
+#endif
+#ifdef CYBSP_J6_11
+/** Cypress J6 Header pin 11 \def CYBSP_J6_11
+ */
+#endif
+#ifdef CYBSP_J6_12
+/** Cypress J6 Header pin 12 \def CYBSP_J6_12
+ */
+#endif
+#ifdef CYBSP_J6_13
+/** Cypress J6 Header pin 13 \def CYBSP_J6_13
+ */
+#endif
+#ifdef CYBSP_J6_14
+/** Cypress J6 Header pin 14 \def CYBSP_J6_14
+ */
+#endif
+#ifdef CYBSP_J6_15
+/** Cypress J6 Header pin 15 \def CYBSP_J6_15
+ */
+#endif
+#ifdef CYBSP_J6_16
+/** Cypress J6 Header pin 16 \def CYBSP_J6_16
+ */
+#endif
+
+/** \} group_bsp_pins_j6 */
+#endif // defined(CYBSP_J6_1)
+
+#if defined(CYBSP_CMOD) || defined(CYBSP_CINA) || defined(CYBSP_CINTA)
+/**
+ * \addtogroup group_bsp_pins_capsense Capsense
+ * \{
+ * Pins connected to CapSense sensors on the board.
+ */
+
+#ifdef CYBSP_CSD_TX
+/** Pin: CapSesnse TX \def CYBSP_CSD_TX
+ */
+#endif
+#ifdef CYBSP_CINA
+/** Pin: CapSesnse CINA \def CYBSP_CINA
+ */
+#endif
+#ifdef CYBSP_CINTA
+/** Pin: CapSesnse CINTA \def CYBSP_CINTA
+ */
+#endif
+#ifdef CYBSP_CINB
+/** Pin: CapSesnse CINB \def CYBSP_CINB
+ */
+#endif
+#ifdef CYBSP_CINTB
+/** Pin: CapSesnse CINTB \def CYBSP_CINTB
+ */
+#endif
+#ifdef CYBSP_CMOD
+/** Pin: CapSesnse CMOD \def CYBSP_CMOD
+ */
+#endif
+#ifdef CYBSP_CSD_BTN0
+/** Pin: CapSesnse Button 0 \def CYBSP_CSD_BTN0
+ */
+#endif
+#ifdef CYBSP_CSD_BTN1
+/** Pin: CapSesnse Button 1 \def CYBSP_CSD_BTN1
+ */
+#endif
+#ifdef CYBSP_CSD_SLD0
+/** Pin: CapSesnse Slider 0 \def CYBSP_CSD_SLD0
+ */
+#endif
+#ifdef CYBSP_CSD_SLD1
+/** Pin: CapSesnse Slider 1 \def CYBSP_CSD_SLD1
+ */
+#endif
+#ifdef CYBSP_CSD_SLD2
+/** Pin: CapSesnse Slider 2 \def CYBSP_CSD_SLD2
+ */
+#endif
+#ifdef CYBSP_CSD_SLD3
+/** Pin: CapSesnse Slider 3 \def CYBSP_CSD_SLD3
+ */
+#endif
+#ifdef CYBSP_CSD_SLD4
+/** Pin: CapSesnse Slider 4 \def CYBSP_CSD_SLD4
+ */
+#endif
+#ifdef CYBSP_CSD_SLD5
+/** Pin: CapSesnse Slider 5 \def CYBSP_CSD_SLD5
+ */
+#endif
+#ifdef CYBSP_CSX_BTN_TX
+/** Pin: CapSesnse Button TX \def CYBSP_CSX_BTN_TX
+ */
+#endif
+#ifdef CYBSP_CSX_BTN0
+/** Pin: CapSesnse Button 0 \def CYBSP_CSX_BTN0
+ */
+#endif
+#ifdef CYBSP_CSX_BTN1
+/** Pin: CapSesnse Button 1 \def CYBSP_CSX_BTN1
+ */
+#endif
+#ifdef CYBSP_CSX_BTN2
+/** Pin: CapSesnse Button 2 \def CYBSP_CSX_BTN2
+ */
+#endif
+
+/** \} group_bsp_pins_capsense */
+#endif // defined(CYBSP_CMOD) || defined(CYBSP_CINA) || defined(CYBSP_CINTA)
+
+#if defined(CYBSP_WCO_IN)
+/**
+ * \addtogroup group_bsp_pins_wco WCO
+ * \{
+ * Pins connected to the WCO on the board.
+ */
+#ifdef CYBSP_WCO_IN
+/** Pin: WCO input \def CYBSP_WCO_IN
+ */
+#endif
+#ifdef CYBSP_WCO_OUT
+/** Pin: WCO output \def CYBSP_WCO_OUT
+ */
+#endif
+
+/** \} group_bsp_pins_wco */
+#endif // defined(CYBSP_WCO_IN)
+
+/** \} group_bsp_pins */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* CYBSP_DOC */
diff --git a/boot/cypress/platforms/CYW20829/cybsp_types.h b/boot/cypress/platforms/CYW20829/cybsp_types.h
new file mode 100644
index 0000000..eded7dd
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cybsp_types.h
@@ -0,0 +1,56 @@
+#ifndef CYBSP_TYPES_H
+#define CYBSP_TYPES_H
+/***********************************************************************************************//**
+ * \copyright
+ * Copyright 2018-2021 Cypress Semiconductor Corporation
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ **************************************************************************************************/
+
+#pragma once
+
+#include "cybsp_doc.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/**
+ * \addtogroup group_bsp_pin_state Pin States
+ * \{
+ * Macros to abstract out whether the LEDs & Buttons are wired high or active low.
+ */
+/** Pin state for the LED on. */
+#ifndef CYBSP_LED_STATE_ON
+#define CYBSP_LED_STATE_ON (0U)
+#endif
+/** Pin state for the LED off. */
+#ifndef CYBSP_LED_STATE_OFF
+#define CYBSP_LED_STATE_OFF (1U)
+#endif
+/** Pin state for when a button is pressed. */
+#ifndef CYBSP_BTN_PRESSED
+#define CYBSP_BTN_PRESSED (0U)
+#endif
+/** Pin state for when a button is released. */
+#ifndef CYBSP_BTN_OFF
+#define CYBSP_BTN_OFF (1U)
+#endif
+/** \} group_bsp_pin_state */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* CYBSP_TYPES_H */
diff --git a/boot/cypress/platforms/cycfg_routing.h b/boot/cypress/platforms/CYW20829/cycfg.c
similarity index 60%
copy from boot/cypress/platforms/cycfg_routing.h
copy to boot/cypress/platforms/CYW20829/cycfg.c
index bfb2998..d668910 100644
--- a/boot/cypress/platforms/cycfg_routing.h
+++ b/boot/cypress/platforms/CYW20829/cycfg.c
@@ -1,14 +1,16 @@
/*******************************************************************************
-* File Name: cycfg_routing.h
+* File Name: cycfg.c
*
* Description:
-* Establishes all necessary connections between hardware elements.
+* Wrapper function to initialize all generated code.
* This file was automatically generated and should not be modified.
-* Device Configurator: 2.0.0.1483
-* Device Support Library (../../../psoc6pdl): 1.4.0.1889
+* Tools Package 2.2.1.3040
+* integration_mxs40sv2-LATEST 3.0.0.5994
+* personalities 3.0.0.0
+* udd 3.0.0.775
*
********************************************************************************
-* Copyright 2017-2019 Cypress Semiconductor Corporation
+* Copyright 2021 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,23 +26,9 @@
* limitations under the License.
********************************************************************************/
-#if !defined(CYCFG_ROUTING_H)
-#define CYCFG_ROUTING_H
+#include "cycfg.h"
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-void init_cycfg_routing(void);
-
-#define init_cycfg_connectivity() init_cycfg_routing()
-
-#define ioss_0_port_5_pin_0_HSIOM P5_0_SCB5_UART_RX
-#define ioss_0_port_5_pin_1_HSIOM P5_1_SCB5_UART_TX
-
-#if defined(__cplusplus)
+void init_cycfg_all(void)
+{
+ init_cycfg_system();
}
-#endif
-
-
-#endif /* CYCFG_ROUTING_H */
diff --git a/boot/cypress/platforms/cycfg_routing.h b/boot/cypress/platforms/CYW20829/cycfg.h
similarity index 65%
copy from boot/cypress/platforms/cycfg_routing.h
copy to boot/cypress/platforms/CYW20829/cycfg.h
index bfb2998..a8ed6ad 100644
--- a/boot/cypress/platforms/cycfg_routing.h
+++ b/boot/cypress/platforms/CYW20829/cycfg.h
@@ -1,14 +1,16 @@
/*******************************************************************************
-* File Name: cycfg_routing.h
+* File Name: cycfg.h
*
* Description:
-* Establishes all necessary connections between hardware elements.
+* Simple wrapper header containing all generated files.
* This file was automatically generated and should not be modified.
-* Device Configurator: 2.0.0.1483
-* Device Support Library (../../../psoc6pdl): 1.4.0.1889
+* Tools Package 2.2.1.3040
+* integration_mxs40sv2-LATEST 3.0.0.5994
+* personalities 3.0.0.0
+* udd 3.0.0.775
*
********************************************************************************
-* Copyright 2017-2019 Cypress Semiconductor Corporation
+* Copyright 2021 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,23 +26,23 @@
* limitations under the License.
********************************************************************************/
-#if !defined(CYCFG_ROUTING_H)
-#define CYCFG_ROUTING_H
+#if !defined(CYCFG_H)
+#define CYCFG_H
#if defined(__cplusplus)
extern "C" {
#endif
-void init_cycfg_routing(void);
+#include "cycfg_notices.h"
+#include "cycfg_system.h"
+#include "cycfg_pins.h"
-#define init_cycfg_connectivity() init_cycfg_routing()
+void init_cycfg_all(void);
-#define ioss_0_port_5_pin_0_HSIOM P5_0_SCB5_UART_RX
-#define ioss_0_port_5_pin_1_HSIOM P5_1_SCB5_UART_TX
#if defined(__cplusplus)
}
#endif
-#endif /* CYCFG_ROUTING_H */
+#endif /* CYCFG_H */
diff --git a/boot/cypress/platforms/CYW20829/cycfg_connectivity_bt.c b/boot/cypress/platforms/CYW20829/cycfg_connectivity_bt.c
new file mode 100644
index 0000000..954b06f
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cycfg_connectivity_bt.c
@@ -0,0 +1,30 @@
+/*******************************************************************************
+* File Name: cycfg_connectivity_bt.c
+*
+* Description:
+* Connectivity BT configuration
+* This file was automatically generated and should not be modified.
+* Tools Package 2.2.0.2790
+* latest-v2.X 2.0.0.6211
+* personalities 3.0.0.0
+* udd 3.0.0.562
+*
+********************************************************************************
+* Copyright 2020 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#include "cycfg_connectivity_bt.h"
+
diff --git a/boot/cypress/platforms/CYW20829/cycfg_connectivity_bt.h b/boot/cypress/platforms/CYW20829/cycfg_connectivity_bt.h
new file mode 100644
index 0000000..545ebcc
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cycfg_connectivity_bt.h
@@ -0,0 +1,54 @@
+/*******************************************************************************
+* File Name: cycfg_connectivity_bt.h
+*
+* Description:
+* Connectivity BT configuration
+* This file was automatically generated and should not be modified.
+* Tools Package 2.2.0.2790
+* latest-v2.X 2.0.0.6211
+* personalities 3.0.0.0
+* udd 3.0.0.562
+*
+********************************************************************************
+* Copyright 2020 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#if !defined(CYCFG_CONNECTIVITY_BT_H)
+#define CYCFG_CONNECTIVITY_BT_H
+
+#include "cycfg_notices.h"
+#include "cycfg_pins.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define bt_0_power_0_ENABLED 1U
+#define CYCFG_BT_LP_ENABLED (1u)
+#define CYCFG_BT_WAKE_EVENT_ACTIVE_LOW (0)
+#define CYCFG_BT_WAKE_EVENT_ACTIVE_HIGH (1)
+#define CYCFG_BT_HOST_WAKE_GPIO CYBSP_BT_HOST_WAKE
+#define CYCFG_BT_HOST_WAKE_IRQ_EVENT CYBT_WAKE_ACTIVE_LOW
+#define CYCFG_BT_DEV_WAKE_GPIO CYBSP_BT_DEVICE_WAKE
+#define CYCFG_BT_DEV_WAKE_POLARITY CYBT_WAKE_ACTIVE_LOW
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif /* CYCFG_CONNECTIVITY_BT_H */
diff --git a/boot/cypress/platforms/cycfg_routing.h b/boot/cypress/platforms/CYW20829/cycfg_notices.h
similarity index 60%
copy from boot/cypress/platforms/cycfg_routing.h
copy to boot/cypress/platforms/CYW20829/cycfg_notices.h
index bfb2998..bcaadf2 100644
--- a/boot/cypress/platforms/cycfg_routing.h
+++ b/boot/cypress/platforms/CYW20829/cycfg_notices.h
@@ -1,14 +1,17 @@
/*******************************************************************************
-* File Name: cycfg_routing.h
+* File Name: cycfg_notices.h
*
* Description:
-* Establishes all necessary connections between hardware elements.
+* Contains warnings and errors that occurred while generating code for the
+* design.
* This file was automatically generated and should not be modified.
-* Device Configurator: 2.0.0.1483
-* Device Support Library (../../../psoc6pdl): 1.4.0.1889
+* Tools Package 2.2.1.3040
+* integration_mxs40sv2-LATEST 3.0.0.5994
+* personalities 3.0.0.0
+* udd 3.0.0.775
*
********************************************************************************
-* Copyright 2017-2019 Cypress Semiconductor Corporation
+* Copyright 2021 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,23 +27,8 @@
* limitations under the License.
********************************************************************************/
-#if !defined(CYCFG_ROUTING_H)
-#define CYCFG_ROUTING_H
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-void init_cycfg_routing(void);
-
-#define init_cycfg_connectivity() init_cycfg_routing()
-
-#define ioss_0_port_5_pin_0_HSIOM P5_0_SCB5_UART_RX
-#define ioss_0_port_5_pin_1_HSIOM P5_1_SCB5_UART_TX
-
-#if defined(__cplusplus)
-}
-#endif
+#if !defined(CYCFG_NOTICES_H)
+#define CYCFG_NOTICES_H
-#endif /* CYCFG_ROUTING_H */
+#endif /* CYCFG_NOTICES_H */
diff --git a/boot/cypress/platforms/CYW20829/cycfg_pins.c b/boot/cypress/platforms/CYW20829/cycfg_pins.c
new file mode 100644
index 0000000..2042372
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cycfg_pins.c
@@ -0,0 +1,30 @@
+/*******************************************************************************
+* File Name: cycfg_pins.c
+*
+* Description:
+* Pin configuration
+* This file was automatically generated and should not be modified.
+* Tools Package 2.2.1.3040
+* integration_mxs40sv2-LATEST 3.0.0.5994
+* personalities 3.0.0.0
+* udd 3.0.0.775
+*
+********************************************************************************
+* Copyright 2021 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#include "cycfg_pins.h"
+
diff --git a/boot/cypress/platforms/CYW20829/cycfg_pins.h b/boot/cypress/platforms/CYW20829/cycfg_pins.h
new file mode 100644
index 0000000..71f7e79
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cycfg_pins.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+* File Name: cycfg_pins.h
+*
+* Description:
+* Pin configuration
+* This file was automatically generated and should not be modified.
+* Tools Package 2.2.1.3040
+* integration_mxs40sv2-LATEST 3.0.0.5994
+* personalities 3.0.0.0
+* udd 3.0.0.775
+*
+********************************************************************************
+* Copyright 2021 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#if !defined(CYCFG_PINS_H)
+#define CYCFG_PINS_H
+
+#include "cycfg_notices.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined (CY_USING_HAL)
+ #define CYBSP_USER_LED1 (P0_0)
+ #define CYBSP_USER_LED CYBSP_USER_LED1
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ #define CYBSP_USER_BTN1 (P0_1)
+ #define CYBSP_USER_BTN CYBSP_USER_BTN1
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ #define CYBSP_SWO (P1_0)
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ #define CYBSP_SWDIO (P1_2)
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ #define CYBSP_SWDCK (P1_3)
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ #define CYBSP_DEBUG_UART_RX (P3_2)
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ #define CYBSP_DEBUG_UART_TX (P3_3)
+#endif //defined (CY_USING_HAL)
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif /* CYCFG_PINS_H */
diff --git a/boot/cypress/platforms/CYW20829/cycfg_routing.c b/boot/cypress/platforms/CYW20829/cycfg_routing.c
new file mode 100644
index 0000000..0b66046
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cycfg_routing.c
@@ -0,0 +1,43 @@
+/*******************************************************************************
+* File Name: cycfg_routing.c
+*
+* Description:
+* Establishes all necessary connections between hardware elements.
+* This file was automatically generated and should not be modified.
+* Tools Package 2.2.0.2790
+* latest-v2.X 2.0.0.6211
+* personalities 3.0.0.0
+* udd 3.0.0.562
+*
+********************************************************************************
+* Copyright 2020 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#include "cycfg_routing.h"
+
+#include "cy_device_headers.h"
+
+void init_cycfg_routing(void)
+{
+ HSIOM->AMUX_SPLIT_CTL[2] = HSIOM_AMUX_SPLIT_CTL_SWITCH_AA_SL_Msk |
+ HSIOM_AMUX_SPLIT_CTL_SWITCH_AA_SR_Msk |
+ HSIOM_AMUX_SPLIT_CTL_SWITCH_BB_SL_Msk |
+ HSIOM_AMUX_SPLIT_CTL_SWITCH_BB_SR_Msk;
+ HSIOM->AMUX_SPLIT_CTL[4] = HSIOM_AMUX_SPLIT_CTL_SWITCH_AA_SL_Msk |
+ HSIOM_AMUX_SPLIT_CTL_SWITCH_AA_SR_Msk |
+ HSIOM_AMUX_SPLIT_CTL_SWITCH_BB_SL_Msk |
+ HSIOM_AMUX_SPLIT_CTL_SWITCH_BB_SR_Msk;
+}
diff --git a/boot/cypress/platforms/CYW20829/cycfg_routing.h b/boot/cypress/platforms/CYW20829/cycfg_routing.h
new file mode 100644
index 0000000..ea1de77
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cycfg_routing.h
@@ -0,0 +1,61 @@
+/*******************************************************************************
+* File Name: cycfg_routing.h
+*
+* Description:
+* Establishes all necessary connections between hardware elements.
+* This file was automatically generated and should not be modified.
+* Tools Package 2.2.0.2790
+* latest-v2.X 2.0.0.6211
+* personalities 3.0.0.0
+* udd 3.0.0.562
+*
+********************************************************************************
+* Copyright 2020 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#if !defined(CYCFG_ROUTING_H)
+#define CYCFG_ROUTING_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "cycfg_notices.h"
+void init_cycfg_routing(void);
+#define init_cycfg_connectivity() init_cycfg_routing()
+#define ioss_0_port_0_pin_0_ANALOG P0_0_SRSS_WCO_IN
+#define ioss_0_port_0_pin_1_ANALOG P0_1_SRSS_WCO_OUT
+#define ioss_0_port_1_pin_0_HSIOM HSIOM_SEL_AMUXA
+#define ioss_0_port_6_pin_4_HSIOM P6_4_CPUSS_SWJ_SWO_TDO
+#define ioss_0_port_6_pin_6_HSIOM P6_6_CPUSS_SWJ_SWDIO_TMS
+#define ioss_0_port_6_pin_7_HSIOM P6_7_CPUSS_SWJ_SWCLK_TCLK
+#define ioss_0_port_7_pin_1_HSIOM HSIOM_SEL_AMUXA
+#define ioss_0_port_7_pin_2_HSIOM HSIOM_SEL_AMUXA
+#define ioss_0_port_7_pin_7_HSIOM HSIOM_SEL_AMUXA
+#define ioss_0_port_8_pin_1_HSIOM HSIOM_SEL_AMUXA
+#define ioss_0_port_8_pin_2_HSIOM HSIOM_SEL_AMUXA
+#define ioss_0_port_8_pin_3_HSIOM HSIOM_SEL_AMUXA
+#define ioss_0_port_8_pin_4_HSIOM HSIOM_SEL_AMUXA
+#define ioss_0_port_8_pin_5_HSIOM HSIOM_SEL_AMUXA
+#define ioss_0_port_8_pin_6_HSIOM HSIOM_SEL_AMUXA
+#define ioss_0_port_8_pin_7_HSIOM HSIOM_SEL_AMUXA
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif /* CYCFG_ROUTING_H */
diff --git a/boot/cypress/platforms/CYW20829/cycfg_system.c b/boot/cypress/platforms/CYW20829/cycfg_system.c
new file mode 100644
index 0000000..c388dc9
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cycfg_system.c
@@ -0,0 +1,376 @@
+/*******************************************************************************
+* File Name: cycfg_system.c
+*
+* Description:
+* System configuration
+* This file was automatically generated and should not be modified.
+* Tools Package 2.2.1.3040
+* integration_mxs40sv2-LATEST 3.0.0.5994
+* personalities 3.0.0.0
+* udd 3.0.0.775
+*
+********************************************************************************
+* Copyright 2021 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#include "cycfg_system.h"
+
+#define CY_CFG_SYSCLK_ECO_ERROR 1
+#define CY_CFG_SYSCLK_ALTHF_ERROR 2
+#define CY_CFG_SYSCLK_FLL_ERROR 4
+#define CY_CFG_SYSCLK_WCO_ERROR 5
+#define CY_CFG_SYSCLK_FLL_ENABLED 1
+#define CY_CFG_SYSCLK_FLL_MULT 504U
+#define CY_CFG_SYSCLK_FLL_REFDIV 42U
+#define CY_CFG_SYSCLK_FLL_CCO_RANGE CY_SYSCLK_FLL_CCO_RANGE2
+#define CY_CFG_SYSCLK_FLL_ENABLE_OUTDIV true
+#define CY_CFG_SYSCLK_FLL_LOCK_TOLERANCE 10U
+#define CY_CFG_SYSCLK_FLL_IGAIN 8U
+#define CY_CFG_SYSCLK_FLL_PGAIN 7U
+#define CY_CFG_SYSCLK_FLL_SETTLING_COUNT 8U
+#define CY_CFG_SYSCLK_FLL_OUTPUT_MODE CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT
+#define CY_CFG_SYSCLK_FLL_CCO_FREQ 198U
+#define CY_CFG_SYSCLK_FLL_OUT_FREQ 48000000
+#define CY_CFG_SYSCLK_CLKHF0_ENABLED 1
+#define CY_CFG_SYSCLK_CLKHF0_DIVIDER CY_SYSCLK_CLKHF_NO_DIVIDE
+#define CY_CFG_SYSCLK_CLKHF0_FREQ_MHZ 48UL
+#define CY_CFG_SYSCLK_CLKHF0_CLKPATH CY_SYSCLK_CLKHF_IN_CLKPATH0
+#define CY_CFG_SYSCLK_CLKHF1_ENABLED 1
+#define CY_CFG_SYSCLK_CLKHF1_DIVIDER CY_SYSCLK_CLKHF_NO_DIVIDE
+#define CY_CFG_SYSCLK_CLKHF1_FREQ_MHZ 8UL
+#define CY_CFG_SYSCLK_CLKHF1_CLKPATH CY_SYSCLK_CLKHF_IN_CLKPATH1
+#define CY_CFG_SYSCLK_IMO_ENABLED 1
+#define CY_CFG_SYSCLK_CLKPATH0_ENABLED 1
+#define CY_CFG_SYSCLK_CLKPATH0_SOURCE CY_SYSCLK_CLKPATH_IN_IMO
+#define CY_CFG_SYSCLK_CLKPATH0_SOURCE_NUM 0UL
+#define CY_CFG_SYSCLK_CLKPATH1_ENABLED 1
+#define CY_CFG_SYSCLK_CLKPATH1_SOURCE CY_SYSCLK_CLKPATH_IN_IMO
+#define CY_CFG_SYSCLK_CLKPATH1_SOURCE_NUM 0UL
+#define CY_CFG_SYSCLK_CLKPATH2_ENABLED 1
+#define CY_CFG_SYSCLK_CLKPATH2_SOURCE CY_SYSCLK_CLKPATH_IN_IMO
+#define CY_CFG_SYSCLK_CLKPATH2_SOURCE_NUM 0UL
+#define CY_CFG_SYSCLK_CLKPATH3_ENABLED 1
+#define CY_CFG_SYSCLK_CLKPATH3_SOURCE CY_SYSCLK_CLKPATH_IN_IMO
+#define CY_CFG_SYSCLK_CLKPATH3_SOURCE_NUM 0UL
+#define CY_CFG_SYSCLK_CLKTIMER_ENABLED 1
+#define CY_CFG_SYSCLK_CLKTIMER_SOURCE CY_SYSCLK_CLKTIMER_IN_IMO
+#define CY_CFG_SYSCLK_CLKTIMER_DIVIDER 0U
+
+void cycfg_ClockStartupError(uint32_t error);
+
+#if defined (CY_USING_HAL)
+ const cyhal_resource_inst_t srss_0_clock_0_pathmux_0_obj =
+ {
+ .type = CYHAL_RSC_CLKPATH,
+ .block_num = 0U,
+ .channel_num = 0U,
+ };
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ const cyhal_resource_inst_t srss_0_clock_0_pathmux_1_obj =
+ {
+ .type = CYHAL_RSC_CLKPATH,
+ .block_num = 1U,
+ .channel_num = 0U,
+ };
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ const cyhal_resource_inst_t srss_0_clock_0_pathmux_2_obj =
+ {
+ .type = CYHAL_RSC_CLKPATH,
+ .block_num = 2U,
+ .channel_num = 0U,
+ };
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ const cyhal_resource_inst_t srss_0_clock_0_pathmux_3_obj =
+ {
+ .type = CYHAL_RSC_CLKPATH,
+ .block_num = 3U,
+ .channel_num = 0U,
+ };
+#endif //defined (CY_USING_HAL)
+
+__WEAK void cycfg_ClockStartupError(uint32_t error)
+{
+ (void)error; /* Suppress the compiler warning */
+ while (true) {}
+}
+__STATIC_INLINE void Cy_SysClk_FllInit(void)
+{
+ Cy_SysClk_FllOutputDividerEnable(false);
+
+ if (CY_SYSCLK_SUCCESS != Cy_SysClk_FllEnable(0UL))
+ {
+ cycfg_ClockStartupError(CY_CFG_SYSCLK_FLL_ERROR);
+ }
+}
+__STATIC_INLINE void Cy_SysClk_ClkHf0Init(void)
+{
+ (void)Cy_SysClk_ClkHfSetSource(0U, CY_CFG_SYSCLK_CLKHF0_CLKPATH);
+ (void)Cy_SysClk_ClkHfSetDivider(0U, CY_SYSCLK_CLKHF_NO_DIVIDE);
+}
+__STATIC_INLINE void Cy_SysClk_ClkHf1Init(void)
+{
+ (void)Cy_SysClk_ClkHfSetSource(CY_CFG_SYSCLK_CLKHF1, CY_CFG_SYSCLK_CLKHF1_CLKPATH);
+ (void)Cy_SysClk_ClkHfSetDivider(CY_CFG_SYSCLK_CLKHF1, CY_SYSCLK_CLKHF_NO_DIVIDE);
+ (void)Cy_SysClk_ClkHfEnable(CY_CFG_SYSCLK_CLKHF1);
+}
+__STATIC_INLINE void Cy_SysClk_ClkPath0Init(void)
+{
+ (void)Cy_SysClk_ClkPathSetSource(0U, CY_CFG_SYSCLK_CLKPATH0_SOURCE);
+}
+__STATIC_INLINE void Cy_SysClk_ClkPath1Init(void)
+{
+ (void)Cy_SysClk_ClkPathSetSource(1U, CY_CFG_SYSCLK_CLKPATH1_SOURCE);
+}
+__STATIC_INLINE void Cy_SysClk_ClkPath2Init(void)
+{
+ (void)Cy_SysClk_ClkPathSetSource(2U, CY_CFG_SYSCLK_CLKPATH2_SOURCE);
+}
+__STATIC_INLINE void Cy_SysClk_ClkPath3Init(void)
+{
+ (void)Cy_SysClk_ClkPathSetSource(3U, CY_CFG_SYSCLK_CLKPATH3_SOURCE);
+}
+
+
+void init_cycfg_system(void)
+{
+
+ /* Set worst case memory wait states (! ultra low power, 150 MHz), will update at the end */
+ Cy_SysLib_SetWaitStates(false, 150UL);
+ #ifdef CY_CFG_PWR_ENABLED
+ #ifdef CY_CFG_PWR_INIT
+ init_cycfg_power();
+ #else
+ #warning Power system will not be configured. Update power personality to v1.20 or later.
+ #endif /* CY_CFG_PWR_INIT */
+ #endif /* CY_CFG_PWR_ENABLED */
+
+ /* Reset the core clock path to default and disable all the FLLs*/
+ (void)Cy_SysClk_ClkHfSetDivider(0U, CY_SYSCLK_CLKHF_NO_DIVIDE);
+ (void)Cy_SysClk_ClkPathSetSource((uint32_t)CY_SYSCLK_CLKHF_IN_CLKPATH1, CY_SYSCLK_CLKPATH_IN_IMO);
+
+ if ((CY_SYSCLK_CLKHF_IN_CLKPATH0 == Cy_SysClk_ClkHfGetSource(0UL)) &&
+ (CY_SYSCLK_CLKPATH_IN_WCO == Cy_SysClk_ClkPathGetSource((uint32_t)CY_SYSCLK_CLKHF_IN_CLKPATH0)))
+ {
+ (void)Cy_SysClk_ClkHfSetSource(0U, CY_SYSCLK_CLKHF_IN_CLKPATH1);
+ }
+
+ (void)Cy_SysClk_FllDisable();
+ (void)Cy_SysClk_ClkPathSetSource((uint32_t)CY_SYSCLK_CLKHF_IN_CLKPATH0, CY_SYSCLK_CLKPATH_IN_IMO);
+ (void)Cy_SysClk_ClkHfSetSource(0UL, CY_SYSCLK_CLKHF_IN_CLKPATH0);
+ #ifdef CY_IP_MXBLESS
+ (void)Cy_BLE_EcoReset();
+ #endif
+
+
+ /* Enable all source clocks */
+ #ifdef CY_CFG_SYSCLK_PILO_ENABLED
+ Cy_SysClk_PiloInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_WCO_ENABLED
+ Cy_SysClk_WcoInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_CLKLF_ENABLED
+ Cy_SysClk_ClkLfInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_ALTHF_ENABLED
+ Cy_SysClk_AltHfInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_ECO_ENABLED
+ Cy_SysClk_EcoInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_EXTCLK_ENABLED
+ Cy_SysClk_ExtClkInit();
+ #endif
+
+ #if ((CY_CFG_SYSCLK_CLKPATH0_SOURCE_NUM == 0x6UL) && (CY_CFG_SYSCLK_CLKHF0_CLKPATH_NUM == 0U))
+ /* Configure HFCLK0 to temporarily run from IMO to initialize other clocks */
+ (void)Cy_SysClk_ClkPathSetSource(1UL, CY_SYSCLK_CLKPATH_IN_IMO);
+ (void)Cy_SysClk_ClkHfSetSource(0UL, CY_SYSCLK_CLKHF_IN_CLKPATH1);
+ #else
+ #ifdef CY_CFG_SYSCLK_CLKPATH1_ENABLED
+ Cy_SysClk_ClkPath1Init();
+ #endif
+ #endif
+
+ /* Configure Path Clocks */
+ #ifdef CY_CFG_SYSCLK_CLKPATH0_ENABLED
+ Cy_SysClk_ClkPath0Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH2_ENABLED
+ Cy_SysClk_ClkPath2Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH3_ENABLED
+ Cy_SysClk_ClkPath3Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH4_ENABLED
+ Cy_SysClk_ClkPath4Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH5_ENABLED
+ Cy_SysClk_ClkPath5Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH6_ENABLED
+ Cy_SysClk_ClkPath6Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH7_ENABLED
+ Cy_SysClk_ClkPath7Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH8_ENABLED
+ Cy_SysClk_ClkPath8Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH9_ENABLED
+ Cy_SysClk_ClkPath9Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH10_ENABLED
+ Cy_SysClk_ClkPath10Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH11_ENABLED
+ Cy_SysClk_ClkPath11Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH12_ENABLED
+ Cy_SysClk_ClkPath12Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH13_ENABLED
+ Cy_SysClk_ClkPath13Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH14_ENABLED
+ Cy_SysClk_ClkPath14Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH15_ENABLED
+ Cy_SysClk_ClkPath15Init();
+ #endif
+
+ /* Configure and enable FLL */
+ #ifdef CY_CFG_SYSCLK_FLL_ENABLED
+ Cy_SysClk_FllInit();
+ #endif
+
+ Cy_SysClk_ClkHf0Init();
+
+ #if ((CY_CFG_SYSCLK_CLKPATH0_SOURCE_NUM == 0x6UL) && (CY_CFG_SYSCLK_CLKHF0_CLKPATH_NUM == 0U))
+ #ifdef CY_CFG_SYSCLK_CLKPATH1_ENABLED
+ /* Apply the ClkPath1 user setting */
+ Cy_SysClk_ClkPath1Init();
+ #endif
+ #endif
+
+ /* Configure HF clocks */
+ #ifdef CY_CFG_SYSCLK_CLKHF1_ENABLED
+ Cy_SysClk_ClkHf1Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF2_ENABLED
+ Cy_SysClk_ClkHf2Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF3_ENABLED
+ Cy_SysClk_ClkHf3Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF4_ENABLED
+ Cy_SysClk_ClkHf4Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF5_ENABLED
+ Cy_SysClk_ClkHf5Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF6_ENABLED
+ Cy_SysClk_ClkHf6Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF7_ENABLED
+ Cy_SysClk_ClkHf7Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF8_ENABLED
+ Cy_SysClk_ClkHf8Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF9_ENABLED
+ Cy_SysClk_ClkHf9Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF10_ENABLED
+ Cy_SysClk_ClkHf10Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF11_ENABLED
+ Cy_SysClk_ClkHf11Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF12_ENABLED
+ Cy_SysClk_ClkHf12Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF13_ENABLED
+ Cy_SysClk_ClkHf13Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF14_ENABLED
+ Cy_SysClk_ClkHf14Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF15_ENABLED
+ Cy_SysClk_ClkHf15Init();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_CLKALTSYSTICK_ENABLED
+ Cy_SysClk_ClkAltSysTickInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_CLKPUMP_ENABLED
+ Cy_SysClk_ClkPumpInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_CLKBAK_ENABLED
+ Cy_SysClk_ClkBakInit();
+ #endif
+
+ /* Configure default enabled clocks */
+ #ifdef CY_CFG_SYSCLK_ILO_ENABLED
+ Cy_SysClk_IloInit();
+ #endif
+
+ #ifndef CY_CFG_SYSCLK_IMO_ENABLED
+ #error the IMO must be enabled for proper chip operation
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_MFO_ENABLED
+ Cy_SysClk_MfoInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_CLKMF_ENABLED
+ Cy_SysClk_ClkMfInit();
+ #endif
+
+ /* Set accurate flash wait states */
+ #if (defined (CY_CFG_PWR_ENABLED) && defined (CY_CFG_SYSCLK_CLKHF0_ENABLED))
+ Cy_SysLib_SetWaitStates(CY_CFG_PWR_USING_ULP != 0, CY_CFG_SYSCLK_CLKHF0_FREQ_MHZ);
+ #endif
+
+ /* Update System Core Clock values for correct Cy_SysLib_Delay functioning */
+ SystemCoreClockUpdate();
+
+#if defined (CY_USING_HAL)
+ (void)cyhal_hwmgr_reserve(&srss_0_clock_0_pathmux_0_obj);
+#endif //defined (CY_USING_HAL)
+
+#if defined (CY_USING_HAL)
+ (void)cyhal_hwmgr_reserve(&srss_0_clock_0_pathmux_1_obj);
+#endif //defined (CY_USING_HAL)
+
+#if defined (CY_USING_HAL)
+ (void)cyhal_hwmgr_reserve(&srss_0_clock_0_pathmux_2_obj);
+#endif //defined (CY_USING_HAL)
+
+#if defined (CY_USING_HAL)
+ (void)cyhal_hwmgr_reserve(&srss_0_clock_0_pathmux_3_obj);
+#endif //defined (CY_USING_HAL)
+}
diff --git a/boot/cypress/platforms/CYW20829/cycfg_system.h b/boot/cypress/platforms/CYW20829/cycfg_system.h
new file mode 100644
index 0000000..34b2a67
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/cycfg_system.h
@@ -0,0 +1,80 @@
+/*******************************************************************************
+* File Name: cycfg_system.h
+*
+* Description:
+* System configuration
+* This file was automatically generated and should not be modified.
+* Tools Package 2.2.1.3040
+* integration_mxs40sv2-LATEST 3.0.0.5994
+* personalities 3.0.0.0
+* udd 3.0.0.775
+*
+********************************************************************************
+* Copyright 2021 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#if !defined(CYCFG_SYSTEM_H)
+#define CYCFG_SYSTEM_H
+
+#include "cycfg_notices.h"
+#include "cy_sysclk.h"
+#include "cy_pra.h"
+#include "cy_pra_cfg.h"
+#if defined (CY_USING_HAL)
+ #include "cyhal_hwmgr.h"
+#endif //defined (CY_USING_HAL)
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define srss_0_clock_0_ENABLED 1U
+#define srss_0_clock_0_fll_0_ENABLED 1U
+#define srss_0_clock_0_hfclk_0_ENABLED 1U
+#define CY_CFG_SYSCLK_CLKHF0 0UL
+#define CY_CFG_SYSCLK_CLKHF0_CLKPATH_NUM 0UL
+#define srss_0_clock_0_hfclk_1_ENABLED 1U
+#define CY_CFG_SYSCLK_CLKHF1 1UL
+#define CY_CFG_SYSCLK_CLKHF1_CLKPATH_NUM 1UL
+#define srss_0_clock_0_iho_0_ENABLED 1U
+#define srss_0_clock_0_imo_0_ENABLED 1U
+#define srss_0_clock_0_pathmux_0_ENABLED 1U
+#define srss_0_clock_0_pathmux_1_ENABLED 1U
+#define srss_0_clock_0_pathmux_2_ENABLED 1U
+#define srss_0_clock_0_pathmux_3_ENABLED 1U
+#define srss_0_clock_0_timerclk_0_ENABLED 1U
+
+#if defined (CY_USING_HAL)
+ extern const cyhal_resource_inst_t srss_0_clock_0_pathmux_0_obj;
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ extern const cyhal_resource_inst_t srss_0_clock_0_pathmux_1_obj;
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ extern const cyhal_resource_inst_t srss_0_clock_0_pathmux_2_obj;
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ extern const cyhal_resource_inst_t srss_0_clock_0_pathmux_3_obj;
+#endif //defined (CY_USING_HAL)
+
+void init_cycfg_system(void);
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif /* CYCFG_SYSTEM_H */
diff --git a/boot/cypress/platforms/CYW20829/img_confirm/set_img_ok.c b/boot/cypress/platforms/CYW20829/img_confirm/set_img_ok.c
new file mode 100644
index 0000000..89bdd89
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/img_confirm/set_img_ok.c
@@ -0,0 +1,121 @@
+/********************************************************************************
+* Copyright 2021 Infineon Technologies AG
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#if !(SWAP_DISABLED) && defined(UPGRADE_IMAGE)
+
+#include "set_img_ok.h"
+
+static uint8_t row_buff[FLASH_ROW_BUF_SZ];
+
+/**
+ * @brief Function reads value of img_ok flag from address.
+ *
+ * @param address - address of img_ok flag in primary img trailer
+ * @return int - value at address
+ */
+static int read_img_ok_value(uint32_t address)
+{
+ uint32_t row_mask = qspi_get_erase_size() /* is a power of 2 */ - 1u;
+ uint32_t row_addr = (address - CY_XIP_BASE) & ~row_mask;
+
+ cy_stc_smif_mem_config_t *cfg = qspi_get_memory_config(0);
+ cy_en_smif_status_t st = Cy_SMIF_MemRead(qspi_get_device(), cfg,
+ row_addr, row_buff, qspi_get_erase_size(),
+ qspi_get_context());
+ if (CY_SMIF_SUCCESS == st) {
+ return row_buff[address & row_mask];
+ }
+
+ return -1;
+}
+
+/**
+ * @brief Function sets img_ok flag value to primary image trailer.
+ *
+ * @param address - address of img_ok flag in primary img trailer
+ * @param value - value corresponding to img_ok set
+ *
+ * @return - operation status. 0 - set succesfully, -1 - failed to set.
+ */
+static int write_img_ok_value(uint32_t address, uint8_t src)
+{
+ int rc = -1;
+ uint32_t row_addr = 0;
+
+ cy_stc_smif_mem_config_t *cfg = qspi_get_memory_config(0);
+ uint32_t row_mask = qspi_get_erase_size() /* is a power of 2 */ - 1u;
+ cy_en_smif_status_t st;
+
+ /* Accepting an arbitrary address */
+ row_addr = (address - CY_XIP_BASE) & ~row_mask;
+
+ /* Preserving the block */
+ st = Cy_SMIF_MemRead(qspi_get_device(), cfg,
+ row_addr, row_buff, qspi_get_erase_size(),
+ qspi_get_context());
+
+ if (CY_SMIF_SUCCESS == st) {
+ /* Modifying the target byte */
+ row_buff[address & row_mask] = src;
+
+ /* Programming the updated block back */
+ st = Cy_SMIF_MemEraseSector(qspi_get_device(), cfg,
+ row_addr, qspi_get_erase_size(),
+ qspi_get_context());
+
+ if (CY_SMIF_SUCCESS == st) {
+ st = Cy_SMIF_MemWrite(qspi_get_device(), cfg,
+ row_addr, row_buff, qspi_get_erase_size(),
+ qspi_get_context());
+ }
+ }
+
+ if (CY_SMIF_SUCCESS == st) {
+ rc = 0;
+ }
+
+ return rc;
+}
+
+/**
+ * @brief Public function to confirm that upgraded application is operable
+ * after swap. Should be called from main code of user application.
+ * It sets mcuboot flag img_ok in primary (boot) image trailer.
+ * MCUBootApp checks img_ok flag at first reset after upgrade and
+ * validates successful swap.
+ *
+ * @param address - address of img_ok flag in primary img trailer
+ * @param value - value corresponding to img_ok set
+ *
+ * @return - operation status. 1 - already set, 0 - set succesfully,
+ * -1 - failed to set.
+ */
+int set_img_ok(uint32_t address, uint8_t value)
+{
+ int32_t rc = -1;
+
+ if (read_img_ok_value(address) != value) {
+ rc = write_img_ok_value(address, value);
+ }
+ else {
+ rc = IMG_OK_ALREADY_SET;
+ }
+
+ return rc;
+}
+
+#endif /* !(SWAP_DISABLED) && defined(UPGRADE_IMAGE) */
diff --git a/boot/cypress/platforms/CYW20829/qspi_config.cfg b/boot/cypress/platforms/CYW20829/qspi_config.cfg
new file mode 100644
index 0000000..8858f3f
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/qspi_config.cfg
@@ -0,0 +1,29 @@
+################################################################################
+# File Name: qspi_config.cfg
+#
+# Description:
+# This file contains a SMIF Bank layout for use with OpenOCD.
+# This file was automatically generated and should not be modified.
+# QSPI Configurator: 2.30.0.4366
+#
+################################################################################
+# Copyright 2021 Cypress Semiconductor Corporation
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+################################################################################
+
+set SMIF_BANKS {
+ 0 {addr 0x60000000 size 0x4000000 psize 0x00000200 esize 0x00040000}
+}
+
diff --git a/boot/cypress/platforms/CYW20829/utils/cyw_20829_utils.c b/boot/cypress/platforms/CYW20829/utils/cyw_20829_utils.c
new file mode 100644
index 0000000..5778fc1
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/utils/cyw_20829_utils.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 2021 Infineon Technologies AG
+ *
+ * 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.
+ */
+
+#include "cyw_20829_utils.h"
+
+/* Cypress pdl headers */
+#include "cy_pdl.h"
+
+#include "bootutil/bootutil.h"
+#include "bootutil/bootutil_log.h"
+#include "flash_map_backend/flash_map_backend.h"
+
+#include <string.h>
+
+#include "flash_qspi.h"
+
+#ifdef CYW20829
+
+#define CY_GET_XIP_REMAP_ADDR(addr) ((addr) - CY_XIP_BASE + CY_XIP_REMAP_OFFSET)
+#define CY_GET_XIP_REMAP_ADDR_FIH(addr) fih_uint_encode(fih_uint_decode((addr)) - CY_XIP_BASE + CY_XIP_REMAP_OFFSET)
+
+#define CY_GET_SRAM0_REMAP_ADDR(addr) ((addr) - CY_SRAM0_BASE + CY_SRAM0_REMAP_OFFSET)
+
+/* TOC2 */
+#define TOC2_SIZE 16u
+#define TOC2_SIZE_IDX 0u
+/* is followed by L1 Application Descriptor */
+#define L1_APP_DESCR_SIZE 28u
+#define L1_APP_DESCR_SIZE_IDX 0u
+#define BOOTSTRAP_SRC_ADDR_IDX 1u /* points to Non-Secure Vector Table */
+#define BOOTSTRAP_DST_ADDR_IDX 2u
+#define BOOTSTRAP_SIZE_IDX 3u
+
+/* Non-Secure Vector Table */
+#define NS_VECTOR_TABLE_SIZE 340u
+#define NS_VECTOR_TABLE_ALIGNMENT 0x200u /* NS_VECTOR_TABLE_SIZE rounded up to the power of 2 */
+#define L1_APP_STACK_POINTER_IDX 0u
+#define L1_APP_RESET_HANDLER_IDX 1u
+
+/* Valid memory address range 0x2000_4000 - 0x2002_0000 */
+#define BOOTSTRAP_PROHIBITED 0x4000u
+#define BOOTSTRAP_SRAM0_ADDR (CY_SRAM0_BASE + BOOTSTRAP_PROHIBITED)
+#define BOOTSTRAP_SRAM0_SIZE (CY_SRAM0_SIZE - BOOTSTRAP_PROHIBITED)
+
+#define Q(x) #x
+#define QUOTE(x) Q(x)
+
+/*
+ * Check whether data fits into the specified memory area.
+ */
+static inline __attribute__((always_inline))
+bool fits_into(uintptr_t data, size_t data_size,
+ uintptr_t area, size_t area_size)
+{
+ uintptr_t end = data + data_size;
+ return data >= area &&
+ data_size <= area_size &&
+ end <= area + area_size &&
+ end >= data; /* overflow check */
+}
+
+/*
+ * Check whether pointer is aligned to the specified power of 2 boundary.
+ */
+static inline __attribute__((always_inline))
+bool is_aligned(uintptr_t ptr, uint32_t align)
+{
+ if ((align == 0u) || ((align & (align - 1u)) != 0u)) {
+ return false;
+ }
+ else {
+ return (ptr & (align - 1u)) == 0u;
+ }
+}
+
+/*
+ * Get an indexed word from the fih_uint-pointed array.
+ */
+static inline __attribute__((always_inline))
+uint32_t fih_ptr_word(fih_uint fih_ptr, uint32_t index)
+{
+ return ((const uint32_t *)fih_uint_decode(fih_ptr))[index];
+}
+
+#ifdef MCUBOOT_ENC_IMAGES_XIP
+/*
+ * AES-CTR buffer encryption/decryption for SMIF XIP mode
+ */
+static int mbedtls_aes_crypt_ctr_xip(mbedtls_aes_context *ctx,
+ size_t length,
+ uint32_t *nc_off,
+ uint8_t nonce_counter[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE],
+ uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE],
+ const uint8_t *input,
+ uint8_t *output)
+{
+ int rc = 0;
+ uint32_t xip_addr = 0;
+ uint32_t i;
+
+ if (length % BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE != 0u) {
+ return BOOT_EBADARGS;
+ }
+
+ (void)nc_off;
+
+ while (length > 0u) {
+ rc = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
+
+ if (rc != 0) {
+ break;
+ }
+
+ (void)memcpy((uint8_t*)&xip_addr, nonce_counter, sizeof(xip_addr));
+ xip_addr += BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE;
+ (void)memcpy(nonce_counter, (uint8_t*)&xip_addr, sizeof(xip_addr));
+
+ for (i = 0; i < BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE; i++) {
+ uint8_t c = *input++;
+ *output++ = c ^ stream_block[i];
+ }
+
+ length -= BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE;
+ }
+
+ return rc;
+}
+
+int
+bootutil_img_encrypt(struct enc_key_data *enc_state, int image_index,
+ struct image_header *hdr, const struct flash_area *fap, uint32_t off, uint32_t sz,
+ uint32_t blk_off, uint8_t *buf)
+{
+ struct enc_key_data *enc;
+ uint8_t nonce[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
+ uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
+ int slot = 0;
+ int rc = -1;
+ uint32_t fa_addr = 0u;
+ uintptr_t flash_base = 0u;
+
+ rc = flash_device_base(fap->fa_device_id, &flash_base);
+
+ if (0 == rc) {
+
+ fa_addr = flash_base + fap->fa_off;
+
+ (void)hdr;
+
+ /* boot_copy_region will call boot_encrypt with sz = 0 when skipping over
+ the TLVs. */
+ if (sz > 0u) {
+
+ slot = flash_area_id_to_multi_image_slot(image_index, (int)fap->fa_id);
+
+ if (slot > 0) {
+ uint8_t id_pri = FLASH_AREA_IMAGE_PRIMARY((uint32_t)image_index);
+ const struct flash_area *fa_pri = NULL;
+
+ if (flash_area_open(id_pri, &fa_pri) < 0) {
+ return BOOT_EFLASH;
+ }
+ else {
+ fa_addr = flash_base + fa_pri->fa_off;
+ flash_area_close(fa_pri);
+ }
+ }
+ else if (slot < 0) {
+ return -1;
+ }
+ else {
+ /* No action required */
+ }
+
+ enc = &enc_state[slot];
+ if (enc->valid == 1u) {
+
+ off += CY_GET_XIP_REMAP_ADDR(fa_addr);
+
+ (void)memcpy(nonce, (uint8_t*)&off, sizeof(off));
+ (void)memcpy(nonce + 4u, enc->aes_iv, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE - 4u);
+
+ rc = mbedtls_aes_crypt_ctr_xip(&enc->aes_ctr, sz, &blk_off, nonce, stream_block, buf, buf);
+ }
+ }
+ }
+
+ return rc;
+}
+#endif
+
+static __NO_RETURN void hang(void)
+{
+ FIH_PANIC;
+}
+
+/* End of cyw20829_RunAppFinish() */
+extern uint8_t hsiniFppAnuR_92802wyc[];
+
+CY_RAMFUNC_BEGIN
+static __NO_RETURN __attribute__((naked))
+void cyw20829_RunAppFinish(uintptr_t bootstrap_dst,
+ uintptr_t bootstrap_src,
+ uint32_t bootstrap_size)
+{
+ /* MCUBoot is over! The code below depends on the linker script. Assuming
+ * stack is located at the very beginning, followed by code and data, and
+ * heap is located at the end. cyw20829_RunAppFinish is located as low as
+ * possible, ideally following the MCUBoot's Vector Table in RAM, to save
+ * max space for the application (the goal is to fit below 0x20004000).
+ * First we wipe SRAM from the end of cyw20829_RunAppFinish to the end of
+ * heap. Then bootstrap is copied to its place. Then, after the necessary
+ * setup, we wipe SRAM from the stack limit to the wiping loop itself. So
+ * only 6 launcher's instructions are left. Note that the app's bootstrap
+ * is copied to the area cleaned at the start, so self-destruction cannot
+ * affect it. Also, we have to remap code addresses from C-bus to S-AHB.
+ */
+ asm volatile(
+ " cpsid i\n" /* Disable interrupts */
+ /* Wipe MCUBoot's RAM to prevent information leakage (Pt. 1) */
+ " mov r0, #0\n"
+ " ldr r1, =(hsiniFppAnuR_92802wyc-" /* Should be remapped from */
+ QUOTE(CY_SRAM0_REMAP_OFFSET)"+" /* C-bus to S-AHB! */
+ QUOTE(CY_SRAM0_BASE)")\n" /* Avoid self-destruction */
+ " ldr r2, =__HeapLimit\n"
+ "1: str r0, [r1]\n"
+ " add r1, #4\n"
+ " cmp r1, r2\n"
+ " blo 1b\n"
+ /* Copy most of bootstrap by doublewords */
+ " mov r2, %0\n"
+ "2: cmp %2, #8\n"
+ " blo 3f\n" /* Note: bootstrap_size cannot be 0 */
+ " ldmia %1!, {r0, r1}\n"
+ " stmia r2!, {r0, r1}\n"
+ " subs %2, #8\n"
+ " beq 4f\n" /* The whole bootstrap is copied */
+ " b 2b\n"
+ /* Copy rest of bootstrap by bytes (if any) */
+ "3: ldrb r0, [%1]\n"
+ " add %1, #1\n"
+ " strb r0, [r2]\n"
+ " add r2, #1\n"
+ " subs %2, #1\n"
+ " bne 3b\n"
+ "4: dmb sy\n"
+ /* Relocate Vector Table */
+ " str %0, [%3]\n" /* Bootstrap starts with Vector Table */
+ " str %0, [%4]\n" /* (%0 points to it) */
+ /* Prepare stack */
+ " ldr r0, ="QUOTE(CY_SRAM0_BASE)"\n"
+ " msr msplim, r0\n"
+ " ldr r0, [%0]\n"
+ " msr msp, r0\n"
+ /* Reset handler */
+ " ldr lr, [%0, #4]\n"
+ /* Wipe MCUBoot's RAM to prevent information leakage (Pt. 2) */
+ " mov r0, #0\n"
+ " ldr r1, =__StackLimit\n"
+ " ldr r2, =(5f-" /* Should be remapped from C-bus to S-AHB! */
+ QUOTE(CY_SRAM0_REMAP_OFFSET)"+"
+ QUOTE(CY_SRAM0_BASE)")\n" /* Final self-destruction */
+ " b 5f\n" /* Skip the constant pool */
+ /* Put the constant pool here (to avoid premature self-destruction) */
+ " .ltorg\n"
+ "5: str r0, [r1]\n"
+ " add r1, #4\n"
+ " cmp r1, r2\n"
+ " blo 5b\n"
+ /* Wipe general-purpose registers just in case */
+ " Ldmdb r1, {r1-r12}\n" /* Load GPRs from the zeroed memory */
+ /* Launch bootstrap */
+ " bx lr\n"
+ "hsiniFppAnuR_92802wyc:\n" /* End of function code */
+ : /* no output */
+ : /* input %0 */ "r" (bootstrap_dst),
+ /* input %1 */ "r" (bootstrap_src),
+ /* input %2 */ "r" (bootstrap_size),
+ /* input %3 */ "r" (&MXCM33->CM33_NS_VECTOR_TABLE_BASE),
+ /* input %4 */ "r" (&SCB->VTOR)
+ : /* clobbered */ "cc", "r0", "r1", "r2");
+}
+CY_RAMFUNC_END
+
+CY_RAMFUNC_BEGIN
+__NO_RETURN void cyw20829_RunApp(fih_uint toc2_addr, uint32_t *key, uint32_t *iv)
+{
+ fih_uint l1_app_descr_addr = (fih_uint)FIH_FAILURE;
+ fih_uint ns_vect_tbl_addr = (fih_uint)FIH_FAILURE;
+
+ uint32_t bootstrap_src_addr = 0u;
+ uint32_t bootstrap_dst_addr = 0u;
+ uint32_t bootstrap_size = 0u;
+
+ uint32_t stack_pointer = 0u;
+ uint32_t reset_handler = (uint32_t)&hang;
+
+#ifdef MCUBOOT_ENC_IMAGES_XIP
+ if (key != NULL && iv != NULL) {
+ SMIF_Type *smif_device = qspi_get_device();
+
+ Cy_SMIF_SetCryptoKey(smif_device, key);
+ Cy_SMIF_SetCryptoIV(smif_device, iv);
+
+ // TODO: Check for other Slave select ID
+ if (Cy_SMIF_SetCryptoEnable(smif_device, CY_SMIF_SLAVE_SELECT_0) != CY_SMIF_SUCCESS) {
+ FIH_PANIC;
+ }
+
+ Cy_SMIF_SetMode(smif_device, CY_SMIF_MEMORY);
+
+ /* Clean up key and IV */
+ (void)memset(key, 0, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE);
+ (void)memset(iv, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
+ }
+#else
+ (void)key;
+ (void)iv;
+#endif /* MCUBOOT_ENC_IMAGES_XIP */
+
+ /* Validate TOC2 in external memory (non-remapped) */
+ if (!is_aligned((uintptr_t)fih_uint_decode(toc2_addr), 4u) ||
+ !fits_into((uintptr_t)fih_uint_decode(toc2_addr), TOC2_SIZE,
+ (uintptr_t)CY_XIP_BASE, CY_XIP_SIZE) ||
+ fih_ptr_word(CY_GET_XIP_REMAP_ADDR_FIH(fih_uint_decode(toc2_addr)), TOC2_SIZE_IDX) != TOC2_SIZE) {
+
+ FIH_PANIC;
+ }
+
+ /* TOC2 is followed by L1 Application Descriptor */
+ l1_app_descr_addr = CY_GET_XIP_REMAP_ADDR_FIH(fih_uint_decode(toc2_addr) + TOC2_SIZE);
+
+ /* Validate L1 Application Descriptor in external memory */
+ if (!is_aligned((uintptr_t)fih_uint_decode(l1_app_descr_addr), 4u) ||
+ !fits_into((uintptr_t)fih_uint_decode(l1_app_descr_addr), L1_APP_DESCR_SIZE,
+ (uintptr_t)CY_XIP_REMAP_OFFSET, CY_XIP_SIZE) ||
+ fih_ptr_word(l1_app_descr_addr, L1_APP_DESCR_SIZE_IDX) != L1_APP_DESCR_SIZE) {
+
+ FIH_PANIC;
+ }
+
+ /* Extract L1 Application Descriptor fields */
+ bootstrap_src_addr = fih_ptr_word(l1_app_descr_addr, BOOTSTRAP_SRC_ADDR_IDX);
+ bootstrap_dst_addr = fih_ptr_word(l1_app_descr_addr, BOOTSTRAP_DST_ADDR_IDX);
+ bootstrap_size = fih_ptr_word(l1_app_descr_addr, BOOTSTRAP_SIZE_IDX);
+
+#ifndef NDEBUG
+ /* Make sure bootstrap and launcher do not overlap. Checks the validity of
+ * the linker script, the runtime check is below (BOOTSTRAP_SRAM0_ADDR).
+ */
+ if (fits_into((uintptr_t)bootstrap_dst_addr, 0,
+ (uintptr_t)cyw20829_RunAppFinish,
+ (uintptr_t)hsiniFppAnuR_92802wyc - (uintptr_t)cyw20829_RunAppFinish) ||
+ fits_into((uintptr_t)bootstrap_dst_addr + bootstrap_size, 0,
+ (uintptr_t)cyw20829_RunAppFinish,
+ (uintptr_t)hsiniFppAnuR_92802wyc - (uintptr_t)cyw20829_RunAppFinish)) {
+
+ FIH_PANIC;
+ }
+#endif /* !NDEBUG */
+
+ /* Validate bootstrap destination in SRAM (starts with the NS Vector Table) */
+ if (bootstrap_size < NS_VECTOR_TABLE_SIZE ||
+ !is_aligned((uintptr_t)bootstrap_dst_addr, NS_VECTOR_TABLE_ALIGNMENT) ||
+ !fits_into((uintptr_t)bootstrap_dst_addr, bootstrap_size,
+ (uintptr_t)BOOTSTRAP_SRAM0_ADDR, BOOTSTRAP_SRAM0_SIZE)) {
+
+ FIH_PANIC;
+ }
+
+ /* Bootstrap source in external memory starts with the image of NS Vector Table) */
+ ns_vect_tbl_addr = CY_GET_XIP_REMAP_ADDR_FIH(fih_uint_decode(toc2_addr) + bootstrap_src_addr);
+
+ /* Validate bootstrap source image in external memory */
+ if (!is_aligned((uintptr_t)fih_uint_decode(ns_vect_tbl_addr), 4u) ||
+ !fits_into((uintptr_t)fih_uint_decode(ns_vect_tbl_addr), bootstrap_size,
+ (uintptr_t)CY_XIP_REMAP_OFFSET, CY_XIP_SIZE)) {
+
+ FIH_PANIC;
+ }
+
+ /* Extract app's Stack Pointer from the image of NS Vector Table and validate it */
+ stack_pointer = fih_ptr_word(ns_vect_tbl_addr, L1_APP_STACK_POINTER_IDX);
+
+ if (!is_aligned((uintptr_t)stack_pointer, 8u) ||
+ !fits_into((uintptr_t)stack_pointer, 0u,
+ (uintptr_t)CY_SRAM0_BASE, CY_SRAM0_SIZE)) {
+
+ FIH_PANIC;
+ }
+
+ /* Extract app's Reset Handler from the image of NS Vector Table and validate it */
+ reset_handler = fih_ptr_word(ns_vect_tbl_addr, L1_APP_RESET_HANDLER_IDX);
+
+ if ((reset_handler & 1u) != 1u /* i.e., thumb function */ ||
+ !fits_into((uintptr_t)(reset_handler & ~1u), 2u, /* should lay in the remapped SRAM */
+ (uintptr_t)CY_GET_SRAM0_REMAP_ADDR(bootstrap_dst_addr), bootstrap_size)) {
+
+ FIH_PANIC;
+ }
+
+ /* MCUBoot is over */
+ cyw20829_RunAppFinish((uintptr_t)bootstrap_dst_addr,
+ (uintptr_t)fih_uint_decode(ns_vect_tbl_addr),
+ bootstrap_size);
+}
+CY_RAMFUNC_END
+
+#endif /* CYW20829 */
diff --git a/boot/cypress/platforms/CYW20829/utils/cyw_20829_utils.h b/boot/cypress/platforms/CYW20829/utils/cyw_20829_utils.h
new file mode 100644
index 0000000..ecaf9d1
--- /dev/null
+++ b/boot/cypress/platforms/CYW20829/utils/cyw_20829_utils.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2021 Infineon Technologies AG
+ *
+ * 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.
+ */
+
+#ifndef CYW_20829_UTILS_H
+#define CYW_20829_UTILS_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "sysflash/sysflash.h"
+
+#include "bootutil/image.h"
+#include "bootutil/enc_key.h"
+#include "bootutil/fault_injection_hardening.h"
+
+#ifdef CYW20829
+
+extern const volatile uint32_t __data_start__[];
+extern const volatile uint32_t __data_end__[];
+
+extern const volatile uint32_t __bss_start__[];
+extern const volatile uint32_t __bss_end__[];
+
+extern const volatile uint32_t __HeapBase[];
+extern const volatile uint32_t __HeapLimit[];
+
+extern const volatile uint32_t __StackLimit[];
+extern const volatile uint32_t __StackTop[];
+
+__NO_RETURN void cyw20829_RunApp(fih_uint toc2_addr, uint32_t *key, uint32_t *iv);
+#endif
+
+#endif /* CYW_20829_UTILS_H */
+
diff --git a/boot/cypress/platforms/PSOC6/PSOC6.md b/boot/cypress/platforms/PSOC6/PSOC6.md
new file mode 100644
index 0000000..8cbe47f
--- /dev/null
+++ b/boot/cypress/platforms/PSOC6/PSOC6.md
@@ -0,0 +1,98 @@
+## PSoC™ 6 platform description
+
+### MCUBootApp specifics
+
+### Default memory map
+
+This repository provides a set of predefined memory maps in JSON files. They are located in `cy_flash_pal/flash_psoc6/flashmap`. One can use the predefined flash map or define its own using the predefined file as a template.
+
+### JSON flash map
+As absolute addresses are used in JSON flash maps, the placement of flash area in internal or external memory is derived from its address. For instance:
+```
+ "application_1": {
+ "address": {
+ "description": "Address of the application primary slot",
+ "value": "0x10018000"
+ },
+ "size": {
+ "description": "Size of the application primary slot",
+ "value": "0x10000"
+ },
+ "upgrade_address": {
+ "description": "Address of the application secondary slot",
+ "value": "0x18030200"
+ },
+ "upgrade_size": {
+ "description": "Size of the application secondary slot",
+ "value": "0x10000"
+ }
+ }
+```
+declares primary slot in the internal Flash, and secondary slot in the external Flash.
+
+##### Shared secondary slot
+Some Flash ICs have large erase block. For SEMPER™ Secure NOR Flash it is 256 kilobytes, so placing each image trailer in a separate erase block seems a waste.
+
+Specific technique is needed to place all trailers of the shared secondary slot in the single erase block. Since the whole erase block with trailer is occasionally cleared by MCUBoot, image padding is required to place trailers at different addresses and to avoid unintended erasing of image bytes.
+```
+ /| |-----------| |
+ / | | | |
+ / |-----------| | |
+ / | | | |
+ / | | Image 2 |-----------|
+ / | Image 1 | | |
+ / : : : Image 3 :
+ / | | | |
+ / |-----------|-----------|-----------|
+ Shared | Trailer | Padding | |\
+Secondary |0x200 bytes|0x200 bytes| Padding | \
+ Slot |-----------|-----------| | \
+ \ | | Trailer |0x400 bytes| \
+ \ | |0x200 bytes| | Erase
+ \ | |-----------|-----------| block
+ \ | | | Trailer | 256 K
+ \ | | |0x200 bytes| /
+ \ | | |-----------| /
+ \ : : : : /
+ \ | | | |/
+ \|-----------|-----------|-----------|
+```
+The pre-build script issues messages, such as
+```
+Note: application_2 (secondary slot) requires 512 padding bytes before trailer
+```
+to remind about the necessary padding.
+
+### Encrypted Image Support
+
+To protect the user's image from unwanted read, Upgrade Image Encryption can be applied. The ECDH/HKDF with the EC256 scheme is used in a given solution as well as mbedTLS as a crypto provider.
+
+To enable the image encryption support, use the `ENC_IMG=1` build flag (BlinkyApp should also be built with this flash set 1).
+
+The user is also responsible for providing corresponding binary key data in `enc_priv_key[]` (file `\MCUBootApp\keys.c`). The public part will be used by `imgtool` when signing and encrypting upgrade image. Signing image with encryption is described in [BlinkyApp.md](../../BlinkyApp/BlinkyApp.md).
+
+After MCUBootApp is built with these settings, unencrypted and encrypted images will be accepted in the secondary (upgrade) slot.
+
+An example of the command:
+
+ make app APP_NAME=MCUBootApp PLATFORM=PSOC_062_2M BUILDCFG=Debug FLASH_MAP=cy_flash_pal/flash_psoc6/flashmap/psoc62_swap_single.json ENC_IMG=1
+
+NOTE: Debug configuration of MCUBootApp with Multi-image encrypted upgrades in external flash (built with flags `BUILDCFG=Debug` `MCUBOOT_IMG_NUMBER=2 USE_EXTERNAL_FLASH=1 ENC_IMG=1`) is set to use optimization level `-O2 -g3` to fit into `0x18000` allocated for `MCUBootApp`.
+
+### Programming applications
+
+#### Using OpenOCD from command line
+
+The following instructions assume the usage of one of Cypress development kits `CY8CPROTO_062_4343W`.
+
+Connect the board to your computer. Switch Kitprog3 to DAP-BULK mode by clicking the `SW3 MODE` button until `LED2 STATUS` constantly shines.
+
+Open the terminal application and execute the following command after substitution of the `PATH_TO_APPLICATION.hex` and `OPENOCD` paths:
+
+ export OPENOCD=/Applications/ModusToolbox/tools_2.4/openocd
+
+ ${OPENOCD}/bin/openocd -s ${OPENOCD}/scripts \
+ -f ${OPENOCD}/scripts/interface/kitprog3.cfg \
+ -f ${OPENOCD}/scripts/target/psoc6_2m.cfg \
+ -c "init; reset init; program PATH_TO_APPLICATION.hex" \
+ -c "resume; reset; exit"
diff --git a/boot/cypress/platforms/PSOC6/PSOC6.mk b/boot/cypress/platforms/PSOC6/PSOC6.mk
new file mode 100644
index 0000000..b4b0c20
--- /dev/null
+++ b/boot/cypress/platforms/PSOC6/PSOC6.mk
@@ -0,0 +1,300 @@
+################################################################################
+# \file PSOC6.mk
+# \version 1.0
+#
+# \brief
+# Makefile to describe supported boards and platforms for Cypress MCUBoot based applications.
+#
+################################################################################
+# \copyright
+# Copyright 2018-2019 Cypress Semiconductor Corporation
+# SPDX-License-Identifier: Apache-2.0
+#
+# 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.
+################################################################################
+
+include host.mk
+
+# PDL category suffix to resolve common path in pdl
+PDL_CAT_SUFFIX := 1A
+
+# MCU device selection, based on target device.
+# Default chips are used for supported platforms
+# This can be redefined in case of other chip usage
+ifeq ($(PLATFORM), PSOC_062_2M)
+# base kit CY8CPROTO-062-4343W
+DEVICE ?= CY8C624ABZI_S2D44
+PLATFORM_SUFFIX := 02
+else ifeq ($(PLATFORM), PSOC_062_1M)
+# base kit CY8CKIT-062-WIFI-BT
+DEVICE ?= CY8C6247BZI-D54
+PLATFORM_SUFFIX := 01
+else ifeq ($(PLATFORM), PSOC_062_512K)
+# base kit CY8CPROTO-062S3-4343W
+DEVICE ?= CY8C6245LQI-S3D72
+PLATFORM_SUFFIX := 03
+endif
+
+# Add device name to defines
+DEFINES += $(DEVICE)
+
+# Default upgrade method
+PLATFORM_DEFAULT_USE_OVERWRITE ?= 0
+
+###############################################################################
+# Application specific libraries
+###############################################################################
+# MCUBootApp
+###############################################################################
+THIS_APP_PATH = $(PRJ_DIR)/libs
+
+ifeq ($(APP_NAME), MCUBootApp)
+
+CORE := CM0P
+CORE_SUFFIX = m0plus
+
+# Add retartget IO implementation using pdl
+PLATFORM_SOURCES_RETARGET_IO_PDL := $(wildcard $(THIS_APP_PATH)/retarget_io_pdl/*.c)
+
+# Collect dirrectories containing headers for PLATFORM
+PLATFORM_INCLUDE_RETARGET_IO_PDL := $(THIS_APP_PATH)/retarget_io_pdl
+
+# PSOC6HAL source files
+PLATFORM_SOURCES_HAL_MCUB := $(THIS_APP_PATH)/mtb-hal-cat1/source/cyhal_crypto_common.c
+PLATFORM_SOURCES_HAL_MCUB += $(THIS_APP_PATH)/mtb-hal-cat1/source/cyhal_hwmgr.c
+
+# needed for Crypto HW Acceleration and headers inclusion, do not use for peripherals
+# peripherals should be accessed
+PLATFORM_INCLUDE_DIRS_HAL_MCUB := $(THIS_APP_PATH)/mtb-hal-cat1/COMPONENT_CAT1A/include
+PLATFORM_INCLUDE_DIRS_HAL_MCUB += $(THIS_APP_PATH)/mtb-hal-cat1/include
+PLATFORM_INCLUDE_DIRS_HAL_MCUB += $(THIS_APP_PATH)/mtb-hal-cat1/include_pvt
+PLATFORM_INCLUDE_DIRS_HAL_MCUB += $(THIS_APP_PATH)/mtb-hal-cat1/COMPONENT_CAT1A/include/pin_packages
+
+# mbedTLS hardware acceleration settings
+ifeq ($(USE_CRYPTO_HW), 1)
+# cy-mbedtls-acceleration related include directories
+INCLUDE_DIRS_MBEDTLS_MXCRYPTO := $(THIS_APP_PATH)/cy-mbedtls-acceleration/mbedtls_MXCRYPTO
+# Collect source files for MbedTLS acceleration
+SOURCES_MBEDTLS_MXCRYPTO := $(wildcard $(THIS_APP_PATH)/cy-mbedtls-acceleration/mbedtls_MXCRYPTO/*.c)
+#
+INCLUDE_DIRS_LIBS += $(addprefix -I,$(INCLUDE_DIRS_MBEDTLS_MXCRYPTO))
+# Collected source files for libraries
+SOURCES_LIBS += $(SOURCES_MBEDTLS_MXCRYPTO)
+endif
+
+###############################################################################
+# Application dependent definitions
+# MCUBootApp default settings
+# 0 by default until mbedtls.3.0 support
+USE_CRYPTO_HW ?= 0
+
+# Bootloader size
+PLATFORM_BOOTLOADER_SIZE ?= 0x18000
+###############################################################################
+
+PLATFORM_INCLUDE_DIRS_FLASH := $(PRJ_DIR)/cy_flash_pal
+PLATFORM_INCLUDE_DIRS_FLASH += $(PRJ_DIR)/cy_flash_pal/flash_psoc6/flash_qspi
+PLATFORM_INCLUDE_DIRS_FLASH += $(PRJ_DIR)/cy_flash_pal/flash_psoc6/include
+# INCLUDE_DIRS_APP += $(addprefix -I, $(PRJ_DIR)/cy_flash_pal/flash_psoc/include/flash_map_backend)
+PLATFORM_SOURCES_FLASH := $(wildcard $(PRJ_DIR)/cy_flash_pal/flash_psoc6/*.c)
+PLATFORM_SOURCES_FLASH += $(wildcard $(PRJ_DIR)/cy_flash_pal/flash_psoc6/flash_qspi/*.c)
+
+ifeq ($(USE_EXTERNAL_FLASH), 1)
+ifeq ($(BUILDCFG), Debug)
+# Include files with statically defined SMIF configuration to enable
+# OpenOCD debugging of external memory
+PLATFORM_SOURCES_FLASH += cy_serial_flash_prog.c
+PLATFORM_SOURCES_FLASH += $(PRJ_DIR)/cy_flash_pal/flash_psoc6/smif_cfg_dbg/cycfg_qspi_memslot.c
+PLATFORM_INCLUDE_DIRS_FLASH += $(PRJ_DIR)/cy_flash_pal/flash_psoc6/smif_cfg_dbg
+endif
+endif
+
+# Post build job to execute for platform
+post_build: $(OUT_CFG)/$(APP_NAME)_unsigned.hex
+ifeq ($(POST_BUILD_ENABLE), 1)
+ $(info [POST BUILD] - Executing post build script for $(APP_NAME))
+ $(shell cp -f $(OUT_CFG)/$(APP_NAME)_unsigned.hex $(OUT_CFG)/$(APP_NAME).hex)
+ $(GCC_PATH)/bin/arm-none-eabi-objdump -s $(OUT_CFG)/$(APP_NAME).hex > $(OUT_CFG)/$(APP_NAME).objdump
+else
+ $(info Post build is disabled by POST_BUILD_ENABLE parameter)
+endif # POST_BUILD_ENABLE
+endif ## MCUBootApp
+
+###############################################################################
+# BlinkyApp
+###############################################################################
+ifeq ($(APP_NAME), BlinkyApp)
+
+CORE := CM4
+CORE_SUFFIX = m4
+
+ifeq ($(USE_EXTERNAL_FLASH), 1)
+PLATFORM_DEFAULT_ERASED_VALUE := 0xff
+else
+PLATFORM_DEFAULT_ERASED_VALUE := 0
+endif
+
+# Define start of application, RAM start and size, slot size
+ifeq ($(PLATFORM), PSOC_062_2M)
+ifeq ($(USE_XIP), 1)
+ PLATFORM_DEFAULT_RAM_START ?= 0x08020000
+ PLATFORM_DEFAULT_RAM_SIZE ?= 0xE0000
+else
+ PLATFORM_DEFAULT_RAM_START ?= 0x08040000
+ PLATFORM_DEFAULT_RAM_SIZE ?= 0x10000
+endif
+else ifeq ($(PLATFORM), PSOC_062_1M)
+ifeq ($(USE_XIP), 1)
+ PLATFORM_DEFAULT_RAM_START ?= 0x08000800
+ PLATFORM_DEFAULT_RAM_SIZE ?= 0x47800
+else
+ PLATFORM_DEFAULT_RAM_START ?= 0x08020000
+ PLATFORM_DEFAULT_RAM_SIZE ?= 0x10000
+endif
+else ifeq ($(PLATFORM), PSOC_062_512K)
+ifeq ($(USE_XIP), 1)
+ PLATFORM_DEFAULT_RAM_START ?= 0x08000800
+ PLATFORM_DEFAULT_RAM_SIZE ?= 0x3F800
+else
+ PLATFORM_DEFAULT_RAM_START ?= 0x08020000
+ PLATFORM_DEFAULT_RAM_SIZE ?= 0x10000
+endif
+endif
+# Default start address of application (boot)
+PLATFORM_USER_APP_START ?= $(PRIMARY_IMG_START)
+# For PSOC6 platform PRIMARY_IMG_START start is the same as USER_APP_START
+# This parameter can be different in cases when code is resided in
+# flash mapped to one address range, but executed using different bus
+# for access with another address range. For example, execution of code
+# from external memory in XIP mode.
+PLATFORM_DEFAULT_PRIMARY_IMG_START ?= $(PLATFORM_DEFAULT_USER_APP_START)
+
+PLATFORM_INCLUDE_DIRS_FLASH := $(PRJ_DIR)/cy_flash_pal
+PLATFORM_INCLUDE_DIRS_FLASH += $(PRJ_DIR)/cy_flash_pal/flash_psoc6/flash_qspi
+PLATFORM_INCLUDE_DIRS_FLASH += $(PRJ_DIR)/cy_flash_pal/flash_psoc6/include
+PLATFORM_SOURCES_FLASH += $(wildcard $(PRJ_DIR)/cy_flash_pal/flash_psoc6/flash_qspi/*.c)
+
+# We still need this for MCUBoot apps signing
+IMGTOOL_PATH ?= ../../scripts/imgtool.py
+
+PLATFORM_DEFAULT_IMG_VER_ARG ?= -v "1.0.0"
+
+PLATFORM_SIGN_ARGS := sign --header-size 1024 --pad-header --align 8 -M 512
+
+# Set parameters needed for signing
+ifeq ($(IMG_TYPE), UPGRADE)
+ # Use encryption and random initial vector for image
+ ifeq ($(ENC_IMG), 1)
+ PLATFORM_SIGN_ARGS += --encrypt ../../$(ENC_KEY_FILE).pem
+ PLATFORM_SIGN_ARGS += --use-random-iv
+ endif
+endif
+
+# Post build action to execute after main build job
+post_build: $(OUT_CFG)/$(APP_NAME).bin
+ifeq ($(POST_BUILD_ENABLE), 1)
+ $(info [POST BUILD] - Executing post build script for $(APP_NAME))
+ $(shell mv -f $(OUT_CFG)/$(APP_NAME).bin $(OUT_CFG)/$(APP_NAME)_unsigned.bin)
+ $(PYTHON_PATH) $(IMGTOOL_PATH) $(SIGN_ARGS) -S $(SLOT_SIZE) -R $(ERASED_VALUE) $(UPGRADE_TYPE) -k keys/$(SIGN_KEY_FILE).pem $(OUT_CFG)/$(APP_NAME)_unsigned.bin $(OUT_CFG)/$(APP_NAME)$(UPGRADE_SUFFIX).hex --hex-addr=$(HEADER_OFFSET)
+ $(GCC_PATH)/bin/arm-none-eabi-objdump -s $(OUT_CFG)/$(APP_NAME)$(UPGRADE_SUFFIX).hex > $(OUT_CFG)/$(APP_NAME)$(UPGRADE_SUFFIX).objdump
+else
+ $(info Post build is disabled by POST_BUILD_ENABLE parameter)
+endif # POST_BUILD_ENABLE
+endif ## BlinkyApp
+
+
+###############################################################################
+# Toolchain
+###############################################################################
+# Define build flags specific to a certain platform
+CFLAGS_PLATFORM := -mcpu=cortex-$(CORE_SUFFIX) -mfloat-abi=soft -fno-stack-protector -fstrict-aliasing
+
+###############################################################################
+# Common libraries
+###############################################################################
+PLATFORM_SYSTEM_FILE_NAME := system_psoc6_c$(CORE_SUFFIX).c
+PLATFORM_STARTUP_FILE := $(PRJ_DIR)/libs/mtb-pdl-cat1/devices/COMPONENT_CAT1A/templates/COMPONENT_MTB/COMPONENT_$(CORE)/TOOLCHAIN_$(COMPILER)/startup_psoc6_$(PLATFORM_SUFFIX)_c$(CORE_SUFFIX).S
+
+PLATFORM_INCLUDE_DIRS_PDL_STARTUP := $(PRJ_DIR)/libs/mtb-pdl-cat1/devices/COMPONENT_CAT$(PDL_CAT_SUFFIX)/templates/COMPONENT_MTB
+
+###############################################################################
+# Print debug information about all settings used and/or set in this file
+ifeq ($(VERBOSE), 1)
+$(info #### PSOC6.mk ####)
+$(info APP_NAME <-- $(APP_NAME))
+$(info CFLAGS_PLATFORM <-> $(CFLAGS_PLATFORM))
+$(info COMPILER <-- $(COMPILER))
+$(info CORE <-> $(CORE))
+$(info CORE_SUFFIX <-- $(CORE_SUFFIX))
+$(info DEFINES <-> $(DEFINES))
+$(info DEVICE <-> $(DEVICE))
+$(info ENC_IMG <-- $(ENC_IMG))
+$(info ENC_KEY_FILE <-- $(ENC_KEY_FILE))
+$(info ERASED_VALUE <-- $(ERASED_VALUE))
+$(info FAMILY <-- $(FAMILY))
+$(info GCC_PATH <-- $(GCC_PATH))
+$(info HEADER_OFFSET <-- $(HEADER_OFFSET))
+$(info IMGTOOL_PATH <-> $(IMGTOOL_PATH))
+$(info IMG_TYPE <-- $(IMG_TYPE))
+$(info INCLUDE_DIRS_LIBS <-> $(INCLUDE_DIRS_LIBS))
+$(info INCLUDE_DIRS_MBEDTLS_MXCRYPTO <-> $(INCLUDE_DIRS_MBEDTLS_MXCRYPTO))
+$(info MCUBOOT_IMAGE_NUMBER <-- $(MCUBOOT_IMAGE_NUMBER))
+$(info OUT_CFG <-- $(OUT_CFG))
+$(info PDL_CAT_SUFFIX <-> $(PDL_CAT_SUFFIX))
+$(info PLATFORM <-- $(PLATFORM))
+$(info PLATFORM_APP_SOURCES <-> $(PLATFORM_APP_SOURCES))
+$(info PLATFORM_BOOTLOADER_SIZE <-> $(PLATFORM_BOOTLOADER_SIZE))
+$(info PLATFORM_DEFAULT_ERASED_VALUE <-> $(PLATFORM_DEFAULT_ERASED_VALUE))
+$(info PLATFORM_DEFAULT_RAM_SIZE <-> $(PLATFORM_DEFAULT_RAM_SIZE))
+$(info PLATFORM_DEFAULT_RAM_START <-> $(PLATFORM_DEFAULT_RAM_START))
+$(info PLATFORM_DEFAULT_SLOT_SIZE <-> $(PLATFORM_DEFAULT_SLOT_SIZE))
+$(info PLATFORM_DEFAULT_USER_APP_START <-> $(PLATFORM_DEFAULT_USER_APP_START))
+$(info PLATFORM_DEFAULT_PRIMARY_IMG_START <-> $(PLATFORM_DEFAULT_PRIMARY_IMG_START))
+$(info PLATFORM_DEFAULT_USE_OVERWRITE <-> $(PLATFORM_DEFAULT_USE_OVERWRITE))
+$(info PLATFORM_DEFINES <-- $(PLATFORM_DEFINES))
+$(info PLATFORM_EXTERNAL_FLASH_SCRATCH_OFFSET <-> $(PLATFORM_EXTERNAL_FLASH_SCRATCH_OFFSET))
+$(info PLATFORM_EXTERNAL_FLASH_SECONDARY_1_OFFSET <-> $(PLATFORM_EXTERNAL_FLASH_SECONDARY_1_OFFSET))
+$(info PLATFORM_EXTERNAL_FLASH_SECONDARY_2_OFFSET <-> $(PLATFORM_EXTERNAL_FLASH_SECONDARY_2_OFFSET))
+$(info PLATFORM_IMAGE_1_SLOT_SIZE <-> $(PLATFORM_IMAGE_1_SLOT_SIZE))
+$(info PLATFORM_IMAGE_2_SLOT_SIZE <-> $(PLATFORM_IMAGE_2_SLOT_SIZE))
+$(info PLATFORM_INCLUDE_DIRS_FLASH <-> $(PLATFORM_INCLUDE_DIRS_FLASH))
+$(info PLATFORM_INCLUDE_DIRS_HAL_MCUB <-> $(PLATFORM_INCLUDE_DIRS_HAL_MCUB))
+$(info PLATFORM_INCLUDE_DIRS_PDL_STARTUP <-> $(PLATFORM_INCLUDE_DIRS_PDL_STARTUP))
+$(info PLATFORM_INCLUDE_RETARGET_IO_PDL <-> $(PLATFORM_INCLUDE_RETARGET_IO_PDL))
+$(info PLATFORM_SCRATCH_SIZE <-> $(PLATFORM_SCRATCH_SIZE))
+$(info PLATFORM_DEFAULT_IMG_VER_ARG <-> $(PLATFORM_DEFAULT_IMG_VER_ARG))
+$(info PLATFORM_SIGN_ARGS <-> $(PLATFORM_SIGN_ARGS))
+$(info PLATFORM_SOURCES_FLASH <-> $(PLATFORM_SOURCES_FLASH))
+$(info PLATFORM_SOURCES_HAL_MCUB <-> $(PLATFORM_SOURCES_HAL_MCUB))
+$(info PLATFORM_SOURCES_RETARGET_IO_PDL <-> $(PLATFORM_SOURCES_RETARGET_IO_PDL))
+$(info PLATFORM_STARTUP_FILE <-> $(PLATFORM_STARTUP_FILE))
+$(info PLATFORM_SUFFIX <-> $(PLATFORM_SUFFIX))
+$(info PLATFORM_SYSTEM_FILE_NAME <-> $(PLATFORM_SYSTEM_FILE_NAME))
+$(info POST_BUILD_ENABLE <-- $(POST_BUILD_ENABLE))
+$(info PRJ_DIR <-- $(PRJ_DIR))
+$(info PYTHON_PATH <-- $(PYTHON_PATH))
+$(info SIGN_ARGS <-- $(SIGN_ARGS))
+$(info SIGN_KEY_FILE <-- $(SIGN_KEY_FILE))
+$(info SLOT_SIZE <-- $(SLOT_SIZE))
+$(info SOURCES_LIBS <-> $(SOURCES_LIBS))
+$(info SOURCES_MBEDTLS_MXCRYPTO <-> $(SOURCES_MBEDTLS_MXCRYPTO))
+$(info THIS_APP_PATH <-- $(THIS_APP_PATH))
+$(info UPGRADE_SUFFIX <-- $(UPGRADE_SUFFIX))
+$(info UPGRADE_TYPE <-- $(UPGRADE_TYPE))
+$(info USER_APP_START <-- $(USER_APP_START))
+$(info USE_CRYPTO_HW <-> $(USE_CRYPTO_HW))
+$(info USE_CUSTOM_MEMORY_MAP <-> $(USE_CUSTOM_MEMORY_MAP))
+$(info USE_EXTERNAL_FLASH <-> $(USE_EXTERNAL_FLASH))
+$(info USE_OVERWRITE <-- $(USE_OVERWRITE))
+$(info USE_XIP <-- $(USE_XIP))
+endif
diff --git a/boot/cypress/platforms/PSOC6/bsp.h b/boot/cypress/platforms/PSOC6/bsp.h
new file mode 100644
index 0000000..078594f
--- /dev/null
+++ b/boot/cypress/platforms/PSOC6/bsp.h
@@ -0,0 +1,79 @@
+/*
+********************************************************************************
+* Copyright 2021 Infineon Technologies AG
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#if !defined(BSP_H)
+#define BSP_H
+
+#include "custom_debug_uart_cfg.h"
+
+/*https://wiki.sei.cmu.edu/confluence/display/c/PRE05-C.+Understand+macro+replacement+when+concatenating+tokens+or+performing+stringification*/
+#define JOIN(x, y) JOIN_AGAIN(x, y)
+#define JOIN_AGAIN(x, y) x ## y
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* If this flash is set use user defined HW */
+#if defined(USE_CUSTOM_DEBUG_UART)
+
+#ifndef CUSTOM_UART_HW
+#error "Option USE_CUSTOM_DEBUG_UART turned on, but CUSTOM_UART_HW is undefined \r\n";
+#else
+#define BSP_UART_HW CUSTOM_UART_HW
+#endif /* CUSTOM_UART_HW */
+
+#ifndef CUSTOM_UART_SCB_NUMBER
+#error "Option USE_CUSTOM_DEBUG_UART turned on, but CUSTOM_UART_SCB_NUMBER is undefined \r\n";
+#else
+#define BSP_UART_SCB_NUMBER CUSTOM_UART_SCB_NUMBER
+#endif /* CUSTOM_UART_SCB_NUMBER */
+
+#ifndef CUSTOM_UART_PORT
+#error "Option USE_CUSTOM_DEBUG_UART turned on, but CUSTOM_UART_PORT is undefined \r\n";
+#else
+#define BSP_UART_PORT CUSTOM_UART_PORT
+#endif /* CUSTOM_UART_PORT */
+
+#ifndef CUSTOM_UART_RX_PIN
+#error "Option USE_CUSTOM_DEBUG_UART turned on, but CUSTOM_UART_RX_PIN is undefined \r\n";
+#else
+#define BSP_UART_RX_PIN CUSTOM_UART_RX_PIN
+#endif /* CUSTOM_UART_RX_PIN */
+
+#ifndef CUSTOM_UART_TX_PIN
+#error "Option USE_CUSTOM_DEBUG_UART turned on, but CUSTOM_UART_TX_PIN is undefined \r\n";
+#else
+#define BSP_UART_TX_PIN CUSTOM_UART_TX_PIN
+#endif /* CUSTOM_UART_TX_PIN */
+
+/* Use default HW, which is commonly used on Infineon kits */
+#else
+
+#define BSP_UART_HW SCB5
+#define BSP_UART_SCB_NUMBER 5
+#define BSP_UART_PORT 5
+#define BSP_UART_RX_PIN 0
+#define BSP_UART_TX_PIN 1
+
+#endif /* USE_CUSTOM_DEBUG_UART */
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* BSP_H */
diff --git a/boot/cypress/platforms/cycfg.c b/boot/cypress/platforms/PSOC6/cycfg.c
similarity index 100%
rename from boot/cypress/platforms/cycfg.c
rename to boot/cypress/platforms/PSOC6/cycfg.c
diff --git a/boot/cypress/platforms/cycfg.h b/boot/cypress/platforms/PSOC6/cycfg.h
similarity index 100%
rename from boot/cypress/platforms/cycfg.h
rename to boot/cypress/platforms/PSOC6/cycfg.h
diff --git a/boot/cypress/platforms/cycfg_clocks.c b/boot/cypress/platforms/PSOC6/cycfg_clocks.c
similarity index 74%
rename from boot/cypress/platforms/cycfg_clocks.c
rename to boot/cypress/platforms/PSOC6/cycfg_clocks.c
index 7f720f7..48c1497 100644
--- a/boot/cypress/platforms/cycfg_clocks.c
+++ b/boot/cypress/platforms/PSOC6/cycfg_clocks.c
@@ -27,21 +27,21 @@
#include "cycfg_clocks.h"
#if defined (CY_USING_HAL)
- const cyhal_resource_inst_t CYBSP_CSD_CLK_DIV_obj =
- {
- .type = CYHAL_RSC_CLOCK,
- .block_num = CYBSP_CSD_CLK_DIV_HW,
- .channel_num = CYBSP_CSD_CLK_DIV_NUM,
- };
+ const cyhal_resource_inst_t CYBSP_CSD_CLK_DIV_obj =
+ {
+ .type = CYHAL_RSC_CLOCK,
+ .block_num = CYBSP_CSD_CLK_DIV_HW,
+ .channel_num = CYBSP_CSD_CLK_DIV_NUM,
+ };
#endif //defined (CY_USING_HAL)
void init_cycfg_clocks(void)
{
- Cy_SysClk_PeriphDisableDivider(CY_SYSCLK_DIV_8_BIT, 0U);
- Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, 0U, 0U);
- Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, 0U);
+ (void)Cy_SysClk_PeriphDisableDivider(CY_SYSCLK_DIV_8_BIT, 0U);
+ (void)Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, 0U, 0U);
+ (void)Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, 0U);
#if defined (CY_USING_HAL)
- cyhal_hwmgr_reserve(&CYBSP_CSD_CLK_DIV_obj);
+ cyhal_hwmgr_reserve(&CYBSP_CSD_CLK_DIV_obj);
#endif //defined (CY_USING_HAL)
}
diff --git a/boot/cypress/platforms/cycfg_clocks.h b/boot/cypress/platforms/PSOC6/cycfg_clocks.h
similarity index 100%
rename from boot/cypress/platforms/cycfg_clocks.h
rename to boot/cypress/platforms/PSOC6/cycfg_clocks.h
diff --git a/boot/cypress/platforms/PSOC6/cycfg_peripherals.c b/boot/cypress/platforms/PSOC6/cycfg_peripherals.c
new file mode 100644
index 0000000..2e423ef
--- /dev/null
+++ b/boot/cypress/platforms/PSOC6/cycfg_peripherals.c
@@ -0,0 +1,73 @@
+/*******************************************************************************
+* File Name: cycfg_peripherals.c
+*
+* Description:
+* Peripheral Hardware Block configuration
+* This file was automatically generated and should not be modified.
+* Device Configurator: 2.0.0.1483
+* Device Support Library (../../../psoc6pdl): 1.3.1.1499
+*
+********************************************************************************
+* Copyright 2017-2019 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#include "cycfg_peripherals.h"
+
+const cy_stc_scb_uart_config_t CYBSP_UART_config =
+{
+ .uartMode = CY_SCB_UART_STANDARD,
+ .enableMutliProcessorMode = false,
+ .smartCardRetryOnNack = false,
+ .irdaInvertRx = false,
+ .irdaEnableLowPowerReceiver = false,
+ .oversample = 8,
+ .enableMsbFirst = false,
+ .dataWidth = 8UL,
+ .parity = CY_SCB_UART_PARITY_NONE,
+ .stopBits = CY_SCB_UART_STOP_BITS_1,
+ .enableInputFilter = false,
+ .breakWidth = 11UL,
+ .dropOnFrameError = false,
+ .dropOnParityError = false,
+ .receiverAddress = 0x0UL,
+ .receiverAddressMask = 0x0UL,
+ .acceptAddrInFifo = false,
+ .enableCts = false,
+ .ctsPolarity = CY_SCB_UART_ACTIVE_LOW,
+ .rtsRxFifoLevel = 0UL,
+ .rtsPolarity = CY_SCB_UART_ACTIVE_LOW,
+ .rxFifoTriggerLevel = 0UL,
+ .rxFifoIntEnableMask = 0UL,
+ .txFifoTriggerLevel = 63UL,
+ .txFifoIntEnableMask = 0UL,
+};
+#if defined (CY_USING_HAL)
+ const cyhal_resource_inst_t CYBSP_UART_obj =
+ {
+ .type = CYHAL_RSC_SCB,
+ .block_num = 5U,
+ .channel_num = 0U,
+ };
+#endif //defined (CY_USING_HAL)
+
+
+void init_cycfg_peripherals(void)
+{
+ (void)Cy_SysClk_PeriphAssignDivider(PCLK_SCBx_CLOCK, CY_SYSCLK_DIV_16_BIT, 0U);
+#if defined (CY_USING_HAL)
+ cyhal_hwmgr_reserve(&CYBSP_UART_obj);
+#endif //defined (CY_USING_HAL)
+}
diff --git a/boot/cypress/platforms/cycfg_peripherals.h b/boot/cypress/platforms/PSOC6/cycfg_peripherals.h
similarity index 82%
rename from boot/cypress/platforms/cycfg_peripherals.h
rename to boot/cypress/platforms/PSOC6/cycfg_peripherals.h
index 41a0383..09aabfb 100644
--- a/boot/cypress/platforms/cycfg_peripherals.h
+++ b/boot/cypress/platforms/PSOC6/cycfg_peripherals.h
@@ -31,20 +31,23 @@
#include "cy_scb_uart.h"
#include "cy_sysclk.h"
#if defined (CY_USING_HAL)
- #include "cyhal_hwmgr.h"
+ #include "cyhal_hwmgr.h"
#endif //defined (CY_USING_HAL)
+#include "bsp.h"
+
#if defined(__cplusplus)
extern "C" {
#endif
-#define CYBSP_UART_ENABLED 1U
-#define CYBSP_UART_HW SCB5
-#define CYBSP_UART_IRQ scb_5_interrupt_IRQn
+#define CYBSP_UART_ENABLED 1U
+#define CYBSP_UART_HW BSP_UART_HW
+#define CYBSP_UART_IRQ JOIN(JOIN(scb_, USE_UART_SCB_NUMBER), _interrupt_IRQn)
+#define PCLK_SCBx_CLOCK JOIN(JOIN(PCLK_SCB, BSP_UART_SCB_NUMBER), _CLOCK)
extern const cy_stc_scb_uart_config_t CYBSP_UART_config;
#if defined (CY_USING_HAL)
- extern const cyhal_resource_inst_t CYBSP_UART_obj;
+ extern const cyhal_resource_inst_t CYBSP_UART_obj;
#endif //defined (CY_USING_HAL)
void init_cycfg_peripherals(void);
diff --git a/boot/cypress/platforms/PSOC6/cycfg_pins.c b/boot/cypress/platforms/PSOC6/cycfg_pins.c
new file mode 100644
index 0000000..e29a86c
--- /dev/null
+++ b/boot/cypress/platforms/PSOC6/cycfg_pins.c
@@ -0,0 +1,89 @@
+/*******************************************************************************
+* File Name: cycfg_pins.c
+*
+* Description:
+* Pin configuration
+* This file was automatically generated and should not be modified.
+* Device Configurator: 2.0.0.1483
+* Device Support Library (../../../psoc6pdl): 1.3.1.1499
+*
+********************************************************************************
+* Copyright 2017-2019 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#include "cycfg_pins.h"
+
+const cy_stc_gpio_pin_config_t CYBSP_UART_RX_config =
+{
+ .outVal = 1,
+ .driveMode = CY_GPIO_DM_HIGHZ,
+ .hsiom = CYBSP_UART_RX_HSIOM,
+ .intEdge = CY_GPIO_INTR_DISABLE,
+ .intMask = 0UL,
+ .vtrip = CY_GPIO_VTRIP_CMOS,
+ .slewRate = CY_GPIO_SLEW_FAST,
+ .driveSel = CY_GPIO_DRIVE_1_2,
+ .vregEn = 0UL,
+ .ibufMode = 0UL,
+ .vtripSel = 0UL,
+ .vrefSel = 0UL,
+ .vohSel = 0UL,
+};
+#if defined (CY_USING_HAL)
+ const cyhal_resource_inst_t CYBSP_UART_RX_obj =
+ {
+ .type = CYHAL_RSC_GPIO,
+ .block_num = CYBSP_UART_RX_PORT_NUM,
+ .channel_num = CYBSP_UART_RX_PIN,
+ };
+#endif //defined (CY_USING_HAL)
+const cy_stc_gpio_pin_config_t CYBSP_UART_TX_config =
+{
+ .outVal = 1,
+ .driveMode = CY_GPIO_DM_STRONG_IN_OFF,
+ .hsiom = CYBSP_UART_TX_HSIOM,
+ .intEdge = CY_GPIO_INTR_DISABLE,
+ .intMask = 0UL,
+ .vtrip = CY_GPIO_VTRIP_CMOS,
+ .slewRate = CY_GPIO_SLEW_FAST,
+ .driveSel = CY_GPIO_DRIVE_1_2,
+ .vregEn = 0UL,
+ .ibufMode = 0UL,
+ .vtripSel = 0UL,
+ .vrefSel = 0UL,
+ .vohSel = 0UL,
+};
+#if defined (CY_USING_HAL)
+ const cyhal_resource_inst_t CYBSP_UART_TX_obj =
+ {
+ .type = CYHAL_RSC_GPIO,
+ .block_num = CYBSP_UART_TX_PORT_NUM,
+ .channel_num = CYBSP_UART_TX_PIN,
+ };
+#endif //defined (CY_USING_HAL)
+
+void init_cycfg_pins(void)
+{
+ (void)Cy_GPIO_Pin_Init(CYBSP_UART_RX_PORT, CYBSP_UART_RX_PIN, &CYBSP_UART_RX_config);
+#if defined (CY_USING_HAL)
+ cyhal_hwmgr_reserve(&CYBSP_UART_RX_obj);
+#endif //defined (CY_USING_HAL)
+
+ (void)Cy_GPIO_Pin_Init(CYBSP_UART_TX_PORT, CYBSP_UART_TX_PIN, &CYBSP_UART_TX_config);
+#if defined (CY_USING_HAL)
+ cyhal_hwmgr_reserve(&CYBSP_UART_TX_obj);
+#endif //defined (CY_USING_HAL)
+}
diff --git a/boot/cypress/platforms/PSOC6/cycfg_pins.h b/boot/cypress/platforms/PSOC6/cycfg_pins.h
new file mode 100644
index 0000000..e844400
--- /dev/null
+++ b/boot/cypress/platforms/PSOC6/cycfg_pins.h
@@ -0,0 +1,116 @@
+/*******************************************************************************
+* File Name: cycfg_pins.h
+*
+* Description:
+* Pin configuration
+* This file was automatically generated and should not be modified.
+* Device Configurator: 2.0.0.1483
+* Device Support Library (../../../psoc6pdl): 1.3.1.1499
+*
+********************************************************************************
+* Copyright 2017-2019 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#if !defined(CYCFG_PINS_H)
+#define CYCFG_PINS_H
+
+#include "cy_gpio.h"
+#if defined (CY_USING_HAL)
+ #include "cyhal_hwmgr.h"
+#endif //defined (CY_USING_HAL)
+#include "cycfg_routing.h"
+
+#include "bsp.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define CYBSP_UART_RX_ENABLED 1U
+#define CYBSP_UART_RX_PORT JOIN(GPIO_PRT, BSP_UART_PORT)
+#define CYBSP_UART_RX_PORT_NUM BSP_UART_PORT
+#define CYBSP_UART_RX_PIN BSP_UART_RX_PIN
+#define CYBSP_UART_RX_NUM BSP_UART_RX_PIN
+#define CYBSP_UART_RX_DRIVEMODE CY_GPIO_DM_HIGHZ
+#define CYBSP_UART_RX_INIT_DRIVESTATE 1U
+/*#ifndef ioss_0_port_10_pin_0_HSIOM
+ #define ioss_0_port_10_pin_0_HSIOM HSIOM_SEL_GPIO
+#endif*/
+
+#define CYBSP_UART_RX_HSIOM ioss_port_pin_rx_HSIOM
+#define CYBSP_UART_RX_IRQ JOIN(JOIN(ioss_interrupts_gpio_, BSP_UART_PORT), _IRQn)
+
+#if defined (CY_USING_HAL)
+ #define CYBSP_UART_RX_HAL_PORT_PIN JOIN(JOIN(JOIN(P, BSP_UART_PORT), _), BSP_UART_RX_PIN)
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ #define CYBSP_UART_RX_HAL_IRQ CYHAL_GPIO_IRQ_NONE
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ #define CYBSP_UART_RX_HAL_DIR CYHAL_GPIO_DIR_INPUT
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ #define CYBSP_UART_RX_HAL_DRIVEMODE CYHAL_GPIO_DRIVE_NONE
+#endif //defined (CY_USING_HAL)
+#define CYBSP_UART_TX_ENABLED 1U
+#define CYBSP_UART_TX_PORT JOIN(GPIO_PRT, BSP_UART_PORT)
+#define CYBSP_UART_TX_PORT_NUM BSP_UART_PORT
+#define CYBSP_UART_TX_PIN BSP_UART_TX_PIN
+#define CYBSP_UART_TX_NUM BSP_UART_TX_PIN
+#define CYBSP_UART_TX_DRIVEMODE CY_GPIO_DM_STRONG_IN_OFF
+#define CYBSP_UART_TX_INIT_DRIVESTATE 1
+/*#ifndef ioss_0_port_10_pin_1_HSIOM
+ #define ioss_0_port_10_pin_1_HSIOM HSIOM_SEL_GPIO
+#endif*/
+#define CYBSP_UART_TX_HSIOM ioss_port_pin_tx_HSIOM
+#define CYBSP_UART_TX_IRQ JOIN(JOIN(ioss_interrupts_gpio_, BSP_UART_PORT), _IRQn)
+#if defined (CY_USING_HAL)
+ #define CYBSP_UART_TX_HAL_PORT_PIN JOIN(JOIN(JOIN(P, BSP_UART_PORT), _), BSP_UART_TX_PIN)
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ #define CYBSP_UART_TX_HAL_IRQ CYHAL_GPIO_IRQ_NONE
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ #define CYBSP_UART_TX_HAL_DIR CYHAL_GPIO_DIR_OUTPUT
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ #define CYBSP_UART_TX_HAL_DRIVEMODE CYHAL_GPIO_DRIVE_STRONG
+#endif //defined (CY_USING_HAL)
+
+#if defined (CY_USING_HAL)
+ extern const cyhal_resource_inst_t CYBSP_WCO_IN_obj;
+#endif //defined (CY_USING_HAL)
+
+#if defined (CY_USING_HAL)
+ extern const cyhal_resource_inst_t CYBSP_WCO_OUT_obj;
+#endif //defined (CY_USING_HAL)
+extern const cy_stc_gpio_pin_config_t CYBSP_UART_RX_config;
+#if defined (CY_USING_HAL)
+ extern const cyhal_resource_inst_t CYBSP_UART_RX_obj;
+#endif //defined (CY_USING_HAL)
+extern const cy_stc_gpio_pin_config_t CYBSP_UART_TX_config;
+#if defined (CY_USING_HAL)
+ extern const cyhal_resource_inst_t CYBSP_UART_TX_obj;
+#endif //defined (CY_USING_HAL)
+
+void init_cycfg_pins(void);
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif /* CYCFG_PINS_H */
diff --git a/boot/cypress/platforms/cycfg_routing.c b/boot/cypress/platforms/PSOC6/cycfg_routing.c
similarity index 100%
rename from boot/cypress/platforms/cycfg_routing.c
rename to boot/cypress/platforms/PSOC6/cycfg_routing.c
diff --git a/boot/cypress/platforms/cycfg_routing.h b/boot/cypress/platforms/PSOC6/cycfg_routing.h
similarity index 82%
rename from boot/cypress/platforms/cycfg_routing.h
rename to boot/cypress/platforms/PSOC6/cycfg_routing.h
index bfb2998..41c6c60 100644
--- a/boot/cypress/platforms/cycfg_routing.h
+++ b/boot/cypress/platforms/PSOC6/cycfg_routing.h
@@ -27,6 +27,8 @@
#if !defined(CYCFG_ROUTING_H)
#define CYCFG_ROUTING_H
+#include "bsp.h"
+
#if defined(__cplusplus)
extern "C" {
#endif
@@ -35,8 +37,8 @@
#define init_cycfg_connectivity() init_cycfg_routing()
-#define ioss_0_port_5_pin_0_HSIOM P5_0_SCB5_UART_RX
-#define ioss_0_port_5_pin_1_HSIOM P5_1_SCB5_UART_TX
+#define ioss_port_pin_rx_HSIOM JOIN(JOIN(JOIN(JOIN(JOIN(JOIN(P, BSP_UART_PORT), _), BSP_UART_RX_PIN), _SCB), BSP_UART_SCB_NUMBER), _UART_RX)
+#define ioss_port_pin_tx_HSIOM JOIN(JOIN(JOIN(JOIN(JOIN(JOIN(P, BSP_UART_PORT), _), BSP_UART_TX_PIN), _SCB), BSP_UART_SCB_NUMBER), _UART_TX)
#if defined(__cplusplus)
}
diff --git a/boot/cypress/platforms/PSOC6/cycfg_system.c b/boot/cypress/platforms/PSOC6/cycfg_system.c
new file mode 100644
index 0000000..cf3f4e7
--- /dev/null
+++ b/boot/cypress/platforms/PSOC6/cycfg_system.c
@@ -0,0 +1,540 @@
+/*******************************************************************************
+* File Name: cycfg_system.c
+*
+* Description:
+* System configuration
+* This file was automatically generated and should not be modified.
+* Device Configurator: 2.0.0.1483
+* Device Support Library (../../../../output/libs/COMPONENT_PSOC6/psoc6pdl): 1.5.0.1837
+*
+********************************************************************************
+* Copyright 2017-2019 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#include "cycfg_system.h"
+
+#define CY_CFG_SYSCLK_ECO_ERROR 1
+#define CY_CFG_SYSCLK_ALTHF_ERROR 2
+#define CY_CFG_SYSCLK_PLL_ERROR 3
+#define CY_CFG_SYSCLK_FLL_ERROR 4
+#define CY_CFG_SYSCLK_WCO_ERROR 5
+#define CY_CFG_SYSCLK_CLKALTSYSTICK_ENABLED 1
+#define CY_CFG_SYSCLK_CLKBAK_ENABLED 1
+#define CY_CFG_SYSCLK_CLKFAST_ENABLED 1
+#define CY_CFG_SYSCLK_FLL_ENABLED 1
+#define CY_CFG_SYSCLK_CLKHF0_ENABLED 1
+#define CY_CFG_SYSCLK_CLKHF0_FREQ_MHZ 100UL
+#define CY_CFG_SYSCLK_CLKHF0_CLKPATH CY_SYSCLK_CLKHF_IN_CLKPATH0
+#define CY_CFG_SYSCLK_CLKHF2_ENABLED 1
+#define CY_CFG_SYSCLK_CLKHF2_FREQ_MHZ 50UL
+#define CY_CFG_SYSCLK_CLKHF2_CLKPATH CY_SYSCLK_CLKHF_IN_CLKPATH0
+#define CY_CFG_SYSCLK_CLKHF3_ENABLED 1
+#define CY_CFG_SYSCLK_CLKHF3_FREQ_MHZ 100UL
+#define CY_CFG_SYSCLK_CLKHF3_CLKPATH CY_SYSCLK_CLKHF_IN_CLKPATH0
+#define CY_CFG_SYSCLK_CLKHF4_ENABLED 1
+#define CY_CFG_SYSCLK_CLKHF4_FREQ_MHZ 100UL
+#define CY_CFG_SYSCLK_CLKHF4_CLKPATH CY_SYSCLK_CLKHF_IN_CLKPATH0
+#define CY_CFG_SYSCLK_ILO_ENABLED 1
+#define CY_CFG_SYSCLK_IMO_ENABLED 1
+#define CY_CFG_SYSCLK_CLKLF_ENABLED 1
+#define CY_CFG_SYSCLK_CLKPATH0_ENABLED 1
+#define CY_CFG_SYSCLK_CLKPATH0_SOURCE CY_SYSCLK_CLKPATH_IN_IMO
+#define CY_CFG_SYSCLK_CLKPATH1_ENABLED 1
+#define CY_CFG_SYSCLK_CLKPATH1_SOURCE CY_SYSCLK_CLKPATH_IN_IMO
+#define CY_CFG_SYSCLK_CLKPATH2_ENABLED 1
+#define CY_CFG_SYSCLK_CLKPATH2_SOURCE CY_SYSCLK_CLKPATH_IN_IMO
+#define CY_CFG_SYSCLK_CLKPERI_ENABLED 1
+#define CY_CFG_SYSCLK_PLL0_ENABLED 1
+#define CY_CFG_SYSCLK_PLL1_ENABLED 1
+#define CY_CFG_SYSCLK_CLKSLOW_ENABLED 1
+#define CY_CFG_SYSCLK_CLKTIMER_ENABLED 1
+#define CY_CFG_SYSCLK_WCO_ENABLED 1
+
+void cycfg_ClockStartupError(uint32_t error);
+
+static const cy_stc_fll_manual_config_t srss_0_clock_0_fll_0_fllConfig =
+{
+ .fllMult = 500U,
+ .refDiv = 20U,
+ .ccoRange = CY_SYSCLK_FLL_CCO_RANGE4,
+ .enableOutputDiv = true,
+ .lockTolerance = 10U,
+ .igain = 9U,
+ .pgain = 5U,
+ .settlingCount = 8U,
+ .outputMode = CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT,
+ .cco_Freq = 355U,
+};
+#if defined (CY_USING_HAL)
+ const cyhal_resource_inst_t srss_0_clock_0_pathmux_0_obj =
+ {
+ .type = CYHAL_RSC_CLKPATH,
+ .block_num = 0U,
+ .channel_num = 0U,
+ };
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ const cyhal_resource_inst_t srss_0_clock_0_pathmux_1_obj =
+ {
+ .type = CYHAL_RSC_CLKPATH,
+ .block_num = 1U,
+ .channel_num = 0U,
+ };
+#endif //defined (CY_USING_HAL)
+#if defined (CY_USING_HAL)
+ const cyhal_resource_inst_t srss_0_clock_0_pathmux_2_obj =
+ {
+ .type = CYHAL_RSC_CLKPATH,
+ .block_num = 2U,
+ .channel_num = 0U,
+ };
+#endif //defined (CY_USING_HAL)
+static const cy_stc_pll_manual_config_t srss_0_clock_0_pll_0_pllConfig =
+{
+ .feedbackDiv = 36,
+ .referenceDiv = 1,
+ .outputDiv = 2,
+ .lfMode = false,
+ .outputMode = CY_SYSCLK_FLLPLL_OUTPUT_AUTO,
+};
+static const cy_stc_pll_manual_config_t srss_0_clock_0_pll_1_pllConfig =
+{
+ .feedbackDiv = 30,
+ .referenceDiv = 1,
+ .outputDiv = 5,
+ .lfMode = false,
+ .outputMode = CY_SYSCLK_FLLPLL_OUTPUT_AUTO,
+};
+
+__WEAK void cycfg_ClockStartupError(uint32_t error)
+{
+ (void)error; /* Suppress the compiler warning */
+ while (true) {}
+}
+__STATIC_INLINE void Cy_SysClk_ClkAltSysTickInit(void)
+{
+ Cy_SysTick_SetClockSource(CY_SYSTICK_CLOCK_SOURCE_CLK_LF);
+}
+__STATIC_INLINE void Cy_SysClk_ClkBakInit(void)
+{
+ Cy_SysClk_ClkBakSetSource(CY_SYSCLK_BAK_IN_CLKLF);
+}
+__STATIC_INLINE void Cy_SysClk_ClkFastInit(void)
+{
+ Cy_SysClk_ClkFastSetDivider(0U);
+}
+__STATIC_INLINE void Cy_SysClk_FllInit(void)
+{
+ if (CY_SYSCLK_SUCCESS != Cy_SysClk_FllManualConfigure(&srss_0_clock_0_fll_0_fllConfig))
+ {
+ cycfg_ClockStartupError(CY_CFG_SYSCLK_FLL_ERROR);
+ }
+ if (CY_SYSCLK_SUCCESS != Cy_SysClk_FllEnable(200000UL))
+ {
+ cycfg_ClockStartupError(CY_CFG_SYSCLK_FLL_ERROR);
+ }
+}
+__STATIC_INLINE void Cy_SysClk_ClkHf0Init(void)
+{
+ (void)Cy_SysClk_ClkHfSetSource(0U, CY_CFG_SYSCLK_CLKHF0_CLKPATH);
+ (void)Cy_SysClk_ClkHfSetDivider(0U, CY_SYSCLK_CLKHF_NO_DIVIDE);
+}
+__STATIC_INLINE void Cy_SysClk_ClkHf2Init(void)
+{
+ (void)Cy_SysClk_ClkHfSetSource(CY_CFG_SYSCLK_CLKHF2, CY_CFG_SYSCLK_CLKHF2_CLKPATH);
+ (void)Cy_SysClk_ClkHfSetDivider(CY_CFG_SYSCLK_CLKHF2, CY_SYSCLK_CLKHF_DIVIDE_BY_2);
+ (void)Cy_SysClk_ClkHfEnable(CY_CFG_SYSCLK_CLKHF2);
+}
+__STATIC_INLINE void Cy_SysClk_ClkHf3Init(void)
+{
+ (void)Cy_SysClk_ClkHfSetSource(CY_CFG_SYSCLK_CLKHF3, CY_CFG_SYSCLK_CLKHF3_CLKPATH);
+ (void)Cy_SysClk_ClkHfSetDivider(CY_CFG_SYSCLK_CLKHF3, CY_SYSCLK_CLKHF_NO_DIVIDE);
+ (void)Cy_SysClk_ClkHfEnable(CY_CFG_SYSCLK_CLKHF3);
+}
+__STATIC_INLINE void Cy_SysClk_ClkHf4Init(void)
+{
+ (void)Cy_SysClk_ClkHfSetSource(CY_CFG_SYSCLK_CLKHF4, CY_CFG_SYSCLK_CLKHF4_CLKPATH);
+ (void)Cy_SysClk_ClkHfSetDivider(CY_CFG_SYSCLK_CLKHF4, CY_SYSCLK_CLKHF_NO_DIVIDE);
+ (void)Cy_SysClk_ClkHfEnable(CY_CFG_SYSCLK_CLKHF4);
+}
+__STATIC_INLINE void Cy_SysClk_IloInit(void)
+{
+ /* The WDT is unlocked in the default startup code */
+ Cy_SysClk_IloEnable();
+ Cy_SysClk_IloHibernateOn(true);
+}
+__STATIC_INLINE void Cy_SysClk_ClkLfInit(void)
+{
+ /* The WDT is unlocked in the default startup code */
+ Cy_SysClk_ClkLfSetSource(CY_SYSCLK_CLKLF_IN_WCO);
+}
+__STATIC_INLINE void Cy_SysClk_ClkPath0Init(void)
+{
+ (void)Cy_SysClk_ClkPathSetSource(0U, CY_CFG_SYSCLK_CLKPATH0_SOURCE);
+}
+__STATIC_INLINE void Cy_SysClk_ClkPath1Init(void)
+{
+ (void)Cy_SysClk_ClkPathSetSource(1U, CY_CFG_SYSCLK_CLKPATH1_SOURCE);
+}
+__STATIC_INLINE void Cy_SysClk_ClkPath2Init(void)
+{
+ (void)Cy_SysClk_ClkPathSetSource(2U, CY_CFG_SYSCLK_CLKPATH2_SOURCE);
+}
+__STATIC_INLINE void Cy_SysClk_ClkPeriInit(void)
+{
+ Cy_SysClk_ClkPeriSetDivider(1U);
+}
+__STATIC_INLINE void Cy_SysClk_Pll0Init(void)
+{
+ if (CY_SYSCLK_SUCCESS != Cy_SysClk_PllManualConfigure(1U, &srss_0_clock_0_pll_0_pllConfig))
+ {
+ cycfg_ClockStartupError(CY_CFG_SYSCLK_PLL_ERROR);
+ }
+ if (CY_SYSCLK_SUCCESS != Cy_SysClk_PllEnable(1U, 10000u))
+ {
+ cycfg_ClockStartupError(CY_CFG_SYSCLK_PLL_ERROR);
+ }
+}
+__STATIC_INLINE void Cy_SysClk_Pll1Init(void)
+{
+ if (CY_SYSCLK_SUCCESS != Cy_SysClk_PllManualConfigure(2U, &srss_0_clock_0_pll_1_pllConfig))
+ {
+ cycfg_ClockStartupError(CY_CFG_SYSCLK_PLL_ERROR);
+ }
+ if (CY_SYSCLK_SUCCESS != Cy_SysClk_PllEnable(2U, 10000u))
+ {
+ cycfg_ClockStartupError(CY_CFG_SYSCLK_PLL_ERROR);
+ }
+}
+__STATIC_INLINE void Cy_SysClk_ClkSlowInit(void)
+{
+ Cy_SysClk_ClkSlowSetDivider(0U);
+}
+__STATIC_INLINE void Cy_SysClk_ClkTimerInit(void)
+{
+ Cy_SysClk_ClkTimerDisable();
+ Cy_SysClk_ClkTimerSetSource(CY_SYSCLK_CLKTIMER_IN_IMO);
+ Cy_SysClk_ClkTimerSetDivider(0U);
+ Cy_SysClk_ClkTimerEnable();
+}
+__STATIC_INLINE void Cy_SysClk_WcoInit(void)
+{
+ (void)Cy_GPIO_Pin_FastInit(GPIO_PRT0, 0U, 0x00U, 0x00U, HSIOM_SEL_GPIO);
+ (void)Cy_GPIO_Pin_FastInit(GPIO_PRT0, 1U, 0x00U, 0x00U, HSIOM_SEL_GPIO);
+ if (CY_SYSCLK_SUCCESS != Cy_SysClk_WcoEnable(1000000UL))
+ {
+ cycfg_ClockStartupError(CY_CFG_SYSCLK_WCO_ERROR);
+ }
+}
+
+
+void init_cycfg_system(void)
+{
+ /* Set worst case memory wait states (! ultra low power, 150 MHz), will update at the end */
+ Cy_SysLib_SetWaitStates(false, 150UL);
+ #ifdef CY_CFG_PWR_ENABLED
+ #ifdef CY_CFG_PWR_INIT
+ init_cycfg_power();
+ #else
+ #warning Power system will not be configured. Update power personality to v1.20 or later.
+ #endif /* CY_CFG_PWR_INIT */
+ #endif /* CY_CFG_PWR_ENABLED */
+
+ /* Reset the core clock path to default and disable all the FLLs/PLLs */
+ (void)Cy_SysClk_ClkHfSetDivider(0U, CY_SYSCLK_CLKHF_NO_DIVIDE);
+ Cy_SysClk_ClkFastSetDivider(0U);
+ Cy_SysClk_ClkPeriSetDivider(1U);
+ Cy_SysClk_ClkSlowSetDivider(0U);
+ for (uint32_t pll = CY_SRSS_NUM_PLL; pll > 0UL; --pll) /* PLL 1 is the first PLL. 0 is invalid. */
+ {
+ (void)Cy_SysClk_PllDisable(pll);
+ }
+ (void)Cy_SysClk_ClkPathSetSource(CY_SYSCLK_CLKHF_IN_CLKPATH1, CY_SYSCLK_CLKPATH_IN_IMO);
+
+ if ((CY_SYSCLK_CLKHF_IN_CLKPATH0 == Cy_SysClk_ClkHfGetSource(0UL)) &&
+ (CY_SYSCLK_CLKPATH_IN_WCO == Cy_SysClk_ClkPathGetSource(CY_SYSCLK_CLKHF_IN_CLKPATH0)))
+ {
+ (void)Cy_SysClk_ClkHfSetSource(0U, CY_SYSCLK_CLKHF_IN_CLKPATH1);
+ }
+
+ (void)Cy_SysClk_FllDisable();
+ (void)Cy_SysClk_ClkPathSetSource(CY_SYSCLK_CLKHF_IN_CLKPATH0, CY_SYSCLK_CLKPATH_IN_IMO);
+ (void)Cy_SysClk_ClkHfSetSource(0UL, CY_SYSCLK_CLKHF_IN_CLKPATH0);
+ #ifdef CY_IP_MXBLESS
+ (void)Cy_BLE_EcoReset();
+ #endif
+
+
+ /* Enable all source clocks */
+ #ifdef CY_CFG_SYSCLK_PILO_ENABLED
+ Cy_SysClk_PiloInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_WCO_ENABLED
+ Cy_SysClk_WcoInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_CLKLF_ENABLED
+ Cy_SysClk_ClkLfInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_ALTHF_ENABLED
+ Cy_SysClk_AltHfInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_ECO_ENABLED
+ Cy_SysClk_EcoInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_EXTCLK_ENABLED
+ Cy_SysClk_ExtClkInit();
+ #endif
+
+ /* Configure CPU clock dividers */
+ #ifdef CY_CFG_SYSCLK_CLKFAST_ENABLED
+ Cy_SysClk_ClkFastInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_CLKPERI_ENABLED
+ Cy_SysClk_ClkPeriInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_CLKSLOW_ENABLED
+ Cy_SysClk_ClkSlowInit();
+ #endif
+
+ #if ((CY_CFG_SYSCLK_CLKPATH0_SOURCE == CY_SYSCLK_CLKPATH_IN_WCO) && (CY_CFG_SYSCLK_CLKHF0_CLKPATH == CY_SYSCLK_CLKHF_IN_CLKPATH0))
+ /* Configure HFCLK0 to temporarily run from IMO to initialize other clocks */
+ (void)Cy_SysClk_ClkPathSetSource(1UL, CY_SYSCLK_CLKPATH_IN_IMO);
+ (void)Cy_SysClk_ClkHfSetSource(0UL, CY_SYSCLK_CLKHF_IN_CLKPATH1);
+ #else
+ #ifdef CY_CFG_SYSCLK_CLKPATH1_ENABLED
+ Cy_SysClk_ClkPath1Init();
+ #endif
+ #endif
+
+ /* Configure Path Clocks */
+ #ifdef CY_CFG_SYSCLK_CLKPATH0_ENABLED
+ Cy_SysClk_ClkPath0Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH2_ENABLED
+ Cy_SysClk_ClkPath2Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH3_ENABLED
+ Cy_SysClk_ClkPath3Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH4_ENABLED
+ Cy_SysClk_ClkPath4Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH5_ENABLED
+ Cy_SysClk_ClkPath5Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH6_ENABLED
+ Cy_SysClk_ClkPath6Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH7_ENABLED
+ Cy_SysClk_ClkPath7Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH8_ENABLED
+ Cy_SysClk_ClkPath8Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH9_ENABLED
+ Cy_SysClk_ClkPath9Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH10_ENABLED
+ Cy_SysClk_ClkPath10Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH11_ENABLED
+ Cy_SysClk_ClkPath11Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH12_ENABLED
+ Cy_SysClk_ClkPath12Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH13_ENABLED
+ Cy_SysClk_ClkPath13Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH14_ENABLED
+ Cy_SysClk_ClkPath14Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKPATH15_ENABLED
+ Cy_SysClk_ClkPath15Init();
+ #endif
+
+ /* Configure and enable FLL */
+ #ifdef CY_CFG_SYSCLK_FLL_ENABLED
+ Cy_SysClk_FllInit();
+ #endif
+
+ Cy_SysClk_ClkHf0Init();
+
+ #if ((CY_CFG_SYSCLK_CLKPATH0_SOURCE == CY_SYSCLK_CLKPATH_IN_WCO) && (CY_CFG_SYSCLK_CLKHF0_CLKPATH == CY_SYSCLK_CLKHF_IN_CLKPATH0))
+ #ifdef CY_CFG_SYSCLK_CLKPATH1_ENABLED
+ /* Apply the ClkPath1 user setting */
+ Cy_SysClk_ClkPath1Init();
+ #endif
+ #endif
+
+
+ /* Configure and enable PLLs */
+ #ifdef CY_CFG_SYSCLK_PLL0_ENABLED
+ Cy_SysClk_Pll0Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_PLL1_ENABLED
+ Cy_SysClk_Pll1Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_PLL2_ENABLED
+ Cy_SysClk_Pll2Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_PLL3_ENABLED
+ Cy_SysClk_Pll3Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_PLL4_ENABLED
+ Cy_SysClk_Pll4Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_PLL5_ENABLED
+ Cy_SysClk_Pll5Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_PLL6_ENABLED
+ Cy_SysClk_Pll6Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_PLL7_ENABLED
+ Cy_SysClk_Pll7Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_PLL8_ENABLED
+ Cy_SysClk_Pll8Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_PLL9_ENABLED
+ Cy_SysClk_Pll9Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_PLL10_ENABLED
+ Cy_SysClk_Pll10Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_PLL11_ENABLED
+ Cy_SysClk_Pll11Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_PLL12_ENABLED
+ Cy_SysClk_Pll12Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_PLL13_ENABLED
+ Cy_SysClk_Pll13Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_PLL14_ENABLED
+ Cy_SysClk_Pll14Init();
+ #endif
+
+ /* Configure HF clocks */
+ #ifdef CY_CFG_SYSCLK_CLKHF1_ENABLED
+ Cy_SysClk_ClkHf1Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF2_ENABLED
+ Cy_SysClk_ClkHf2Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF3_ENABLED
+ Cy_SysClk_ClkHf3Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF4_ENABLED
+ Cy_SysClk_ClkHf4Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF5_ENABLED
+ Cy_SysClk_ClkHf5Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF6_ENABLED
+ Cy_SysClk_ClkHf6Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF7_ENABLED
+ Cy_SysClk_ClkHf7Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF8_ENABLED
+ Cy_SysClk_ClkHf8Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF9_ENABLED
+ Cy_SysClk_ClkHf9Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF10_ENABLED
+ Cy_SysClk_ClkHf10Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF11_ENABLED
+ Cy_SysClk_ClkHf11Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF12_ENABLED
+ Cy_SysClk_ClkHf12Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF13_ENABLED
+ Cy_SysClk_ClkHf13Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF14_ENABLED
+ Cy_SysClk_ClkHf14Init();
+ #endif
+ #ifdef CY_CFG_SYSCLK_CLKHF15_ENABLED
+ Cy_SysClk_ClkHf15Init();
+ #endif
+
+ /* Configure miscellaneous clocks */
+ #ifdef CY_CFG_SYSCLK_CLKTIMER_ENABLED
+ Cy_SysClk_ClkTimerInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_CLKALTSYSTICK_ENABLED
+ Cy_SysClk_ClkAltSysTickInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_CLKPUMP_ENABLED
+ Cy_SysClk_ClkPumpInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_CLKBAK_ENABLED
+ Cy_SysClk_ClkBakInit();
+ #endif
+
+ /* Configure default enabled clocks */
+ #ifdef CY_CFG_SYSCLK_ILO_ENABLED
+ Cy_SysClk_IloInit();
+ #else
+ Cy_SysClk_IloDisable();
+ #endif
+
+ #ifndef CY_CFG_SYSCLK_IMO_ENABLED
+ #error the IMO must be enabled for proper chip operation
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_MFO_ENABLED
+ Cy_SysClk_MfoInit();
+ #endif
+
+ #ifdef CY_CFG_SYSCLK_CLKMF_ENABLED
+ Cy_SysClk_ClkMfInit();
+ #endif
+
+ /* Set accurate flash wait states */
+ #if (defined (CY_CFG_PWR_ENABLED) && defined (CY_CFG_SYSCLK_CLKHF0_ENABLED))
+ Cy_SysLib_SetWaitStates(CY_CFG_PWR_USING_ULP != 0, CY_CFG_SYSCLK_CLKHF0_FREQ_MHZ);
+ #endif
+
+ /* Update System Core Clock values for correct Cy_SysLib_Delay functioning */
+ SystemCoreClockUpdate();
+
+#if defined (CY_USING_HAL)
+ cyhal_hwmgr_reserve(&srss_0_clock_0_pathmux_0_obj);
+#endif //defined (CY_USING_HAL)
+
+#if defined (CY_USING_HAL)
+ cyhal_hwmgr_reserve(&srss_0_clock_0_pathmux_1_obj);
+#endif //defined (CY_USING_HAL)
+
+#if defined (CY_USING_HAL)
+ cyhal_hwmgr_reserve(&srss_0_clock_0_pathmux_2_obj);
+#endif //defined (CY_USING_HAL)
+}
diff --git a/boot/cypress/platforms/cycfg_system.h b/boot/cypress/platforms/PSOC6/cycfg_system.h
similarity index 100%
rename from boot/cypress/platforms/cycfg_system.h
rename to boot/cypress/platforms/PSOC6/cycfg_system.h
diff --git a/boot/cypress/platforms/PSOC6/img_confirm/set_img_ok.c b/boot/cypress/platforms/PSOC6/img_confirm/set_img_ok.c
new file mode 100644
index 0000000..220f86c
--- /dev/null
+++ b/boot/cypress/platforms/PSOC6/img_confirm/set_img_ok.c
@@ -0,0 +1,239 @@
+/********************************************************************************
+* Copyright 2021 Infineon Technologies AG
+* SPDX-License-Identifier: Apache-2.0
+*
+* 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.
+********************************************************************************/
+
+#if !(SWAP_DISABLED) && defined(UPGRADE_IMAGE)
+
+#include "set_img_ok.h"
+
+static uint8_t row_buff[FLASH_ROW_BUF_SZ];
+
+#ifndef USE_XIP
+
+/**
+ * @brief Function reads value of img_ok flag from address.
+ *
+ * @param address - address of img_ok flag in primary img trailer
+ * @return int - value at address
+ */
+static int read_img_ok_value(uint32_t address)
+{
+ return *(volatile uint8_t *)address;
+}
+
+/**
+ * @brief Function sets img_ok flag value to primary image trailer.
+ *
+ * @param address - address of img_ok flag in primary img trailer
+ * @param value - value corresponding to img_ok set
+ *
+ * @return - operation status. 0 - set succesfully, -1 - failed to set.
+ */
+static int write_img_ok_value(uint32_t address, uint8_t value)
+{
+ int rc = -1;
+ uint32_t row_addr = 0;
+
+ uint32_t row_mask = CY_FLASH_SIZEOF_ROW /* is a power of 2 */ - 1u;
+ cy_en_flashdrv_status_t st;
+
+ /* Accepting an arbitrary address */
+ row_addr = address & ~row_mask;
+
+ /* Preserving the row */
+ (void)memcpy(row_buff, (void *)row_addr, sizeof(row_buff));
+
+ /* Modifying the target byte */
+ row_buff[address & row_mask] = value;
+
+ /* Programming the updated row back */
+ st = Cy_Flash_WriteRow(row_addr, (const uint32_t *)row_buff);
+
+ if (CY_FLASH_DRV_SUCCESS == st) {
+ rc = 0;
+ }
+
+ return rc;
+}
+
+#else
+
+extern cy_stc_smif_block_config_t smifBlockConfig_sfdp;
+extern cy_stc_smif_mem_config_t *mems_sfdp[1];
+extern cy_stc_smif_mem_config_t mem_sfdp_0;
+extern cy_stc_smif_mem_device_cfg_t dev_sfdp_0;
+
+/**
+ * @brief Function sets img_ok value to primary slot trailer
+ * when application is executed from external memory
+ * in XIP mode. This function is executed from RAM since
+ * it reconfigures SMIF block from XIP to MMIO mode, then
+ * writes img_ok set value and switches back to XIP mode.
+ *
+ * @param address - address of img_ok flag in primary img trailer
+ * @param value - value corresponding to img_ok set
+ *
+ * @return - operation status. 1 - already set, 0 - set succesfully,
+ * -1 - failed to set.
+ */
+CY_RAMFUNC_BEGIN
+static int set_img_ok_ram(uint32_t address, uint8_t value)
+{
+ int32_t rc = IMG_OK_SET_FAILED;
+ uint32_t try_count = 10U;
+
+ cy_en_smif_status_t stat = CY_SMIF_BUSY;
+ SMIF_Type *QSPIPort = SMIF0;
+ cy_stc_smif_context_t QSPI_context;
+ cy_en_smif_mode_t mode = CY_SMIF_NORMAL;
+
+ Cy_SMIF_SetMode(SMIF0, CY_SMIF_NORMAL);
+ mode = Cy_SMIF_GetMode(QSPIPort);
+
+ if (mode != CY_SMIF_NORMAL) {
+ CY_HALT();
+ }
+
+ for (try_count = 0U; try_count < 10U; try_count++) {
+
+ stat = Cy_SMIF_MemInit(QSPIPort, &smifBlockConfig_sfdp, &QSPI_context);
+
+ if (CY_SMIF_SUCCESS == stat) {
+ break;
+ }
+
+ Cy_SysLib_Delay(500U);
+ }
+
+ if (stat == CY_SMIF_SUCCESS) {
+
+ cy_stc_smif_mem_config_t *cfg = smifBlockConfig_sfdp.memConfig[0];
+ /* Determine row start address, where image trailer is allocated */
+ uint32_t erase_len = cfg->deviceCfg->eraseSize;
+ uint32_t row_mask = erase_len /* is a power of two */ - 1u;
+ uint32_t row_addr = (address - CY_XIP_BASE) & ~row_mask;
+ /* Determine start address of image trailer
+ * The minimum erase size area is allocated
+ * for trailer, but reading the whole area is
+ * not nessesary since data is only located at
+ * first 0x200 bytes. Trailer size is taken as 0x200
+ * to keep consistency with internal memory
+ * implementation, where min_erase_size is 0x200
+ */
+ uint32_t img_trailer_addr = address - CY_XIP_BASE + USER_SWAP_IMAGE_OK_OFFS - IMG_TRAILER_SZ;
+ uint32_t img_ok_mask = FLASH_ROW_BUF_SZ /* is a power of 2 */ - 1u;
+
+ cy_en_smif_status_t st = Cy_SMIF_MemRead(QSPIPort, cfg,
+ img_trailer_addr, row_buff, FLASH_ROW_BUF_SZ,
+ &QSPI_context);
+
+ if (CY_SMIF_SUCCESS == st) {
+
+ if (row_buff[address & img_ok_mask] != value) {
+
+ row_buff[address & img_ok_mask] = value;
+
+ /* Programming the updated block back */
+ st = Cy_SMIF_MemEraseSector(QSPIPort, cfg,
+ row_addr, erase_len,
+ &QSPI_context);
+
+ if (CY_SMIF_SUCCESS == st) {
+ st = Cy_SMIF_MemWrite(QSPIPort, cfg,
+ img_trailer_addr, row_buff, FLASH_ROW_BUF_SZ,
+ &QSPI_context);
+ if (CY_SMIF_SUCCESS == st) {
+ rc = IMG_OK_SET_SUCCESS;
+ }
+ }
+ else {
+ rc = IMG_OK_SET_FAILED;
+ }
+ }
+ else {
+ rc = IMG_OK_ALREADY_SET;
+ }
+ }
+ else {
+ rc = IMG_OK_SET_FAILED;
+ }
+
+ stat = Cy_SMIF_CacheEnable(QSPIPort, CY_SMIF_CACHE_FAST);
+
+ if (CY_SMIF_SUCCESS == stat) {
+ Cy_SMIF_SetMode(QSPIPort, CY_SMIF_MEMORY);
+ mode = Cy_SMIF_GetMode(QSPIPort);
+
+ if (mode != CY_SMIF_MEMORY) {
+ CY_HALT();
+ }
+ }
+ }
+ else {
+ /* do nothing */
+ }
+
+ return rc;
+}
+CY_RAMFUNC_END
+
+#endif /* USE_XIP */
+
+/**
+ * @brief Public function to confirm that upgraded application is operable
+ * after swap. Should be called from main code of user application.
+ * It sets mcuboot flag img_ok in primary (boot) image trailer.
+ * MCUBootApp checks img_ok flag at first reset after upgrade and
+ * validates successful swap.
+ *
+ * @param address - address of img_ok flag in primary img trailer
+ * @param value - value corresponding to img_ok set
+ *
+ * @return - operation status. 1 - already set, 0 - set succesfully,
+ * -1 - failed to set.
+ */
+int set_img_ok(uint32_t address, uint8_t value)
+{
+ int32_t rc = -1;
+
+ /* Write Image OK flag to the slot trailer, so MCUBoot-loader
+ * will not revert new image
+ */
+#ifdef USE_XIP
+ /*
+ * When switching from XIP execution mode to RAM function
+ * it is required to clear and disable SMIF cache. set_img_ok_ram
+ * is then turns cache on before return. If it is not done - return
+ * to execution from RAM to XIP hangs indefinitely.
+ */
+ Cy_SMIF_CacheDisable(SMIF0, CY_SMIF_CACHE_FAST);
+ Cy_SMIF_CacheInvalidate(SMIF0, CY_SMIF_CACHE_FAST);
+ rc = set_img_ok_ram(address, value);
+
+#else
+
+ if (read_img_ok_value(address) != value) {
+ rc = write_img_ok_value(address, value);
+ }
+ else {
+ rc = IMG_OK_ALREADY_SET;
+ }
+#endif /* USE_XIP */
+
+ return rc;
+}
+
+#endif /* !(SWAP_DISABLED) && defined(UPGRADE_IMAGE) */
diff --git a/boot/cypress/platforms/PSOC6/secure/cy_security_cnt_platform.c b/boot/cypress/platforms/PSOC6/secure/cy_security_cnt_platform.c
new file mode 100644
index 0000000..c918656
--- /dev/null
+++ b/boot/cypress/platforms/PSOC6/secure/cy_security_cnt_platform.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2020 Arm Limited.
+ * Copyright (c) 2021 Infineon Technologies AG
+ *
+ * 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.
+ */
+#include <stdint.h>
+
+#include "sysflash/sysflash.h"
+#include "bootutil/bootutil_log.h"
+
+#include "cy_security_cnt_platform.h"
+
+#if defined MCUBootApp && defined MCUBOOT_HW_ROLLBACK_PROT
+
+/*
+ * Reads a data corresponding to security counter which is stored in
+ * efuses of chip and converts it actual value of security conter
+ *
+ * @param security_cnt Pointer to a variable, where security conter value would be stored
+ *
+ * @return FIH_SUCESS on success; FIH_FAILURE on failure.
+ */
+fih_int platform_security_counter_get(fih_uint *security_cnt) {
+
+ (void)security_cnt;
+
+ BOOT_LOG_ERR("Hardware security conter is not supported on PSOC6 platform.");
+
+ FIH_RET(FIH_FAILURE);
+}
+
+/**
+ * Updates the stored value of a given image's security counter with a new
+ * security counter value if the new one is greater.
+ *
+ * @param reprov_packet Pointer to a reprovisioning packet containing NV counter.
+ * @param packet_len Length of a packet
+ * @param img_security_cnt Security conter value of image
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+int32_t platform_security_counter_update(uint32_t img_security_cnt, void * custom_data)
+{
+ (void)img_security_cnt;
+ (void)custom_data;
+
+ BOOT_LOG_ERR("Hardware security conter is not supported on PSOC6 platform.");
+
+ return -1;
+}
+
+#endif /* defined MCUBootApp && defined MCUBOOT_HW_ROLLBACK_PROT */
diff --git a/boot/cypress/platforms/PSOC6/secure/cy_security_cnt_platform.h b/boot/cypress/platforms/PSOC6/secure/cy_security_cnt_platform.h
new file mode 100644
index 0000000..b7cca56
--- /dev/null
+++ b/boot/cypress/platforms/PSOC6/secure/cy_security_cnt_platform.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2020 Arm Limited.
+ * Copyright (c) 2021 Infineon Technologies AG
+ *
+ * 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.
+ */
+
+#ifndef CY_SECURITY_CNT_PLATFORM_H
+#define CY_SECURITY_CNT_PLATFORM_H
+
+#ifdef PSOC6
+
+#include "bootutil/fault_injection_hardening.h"
+
+/**
+ * Reads a data corresponding to security counter which is stored in
+ * efuses of chip and converts it actual value of security conter
+ *
+ * @param security_cnt Pointer to a variable, where security conter value would be stored
+ *
+ * @return FIH_SUCESS on success; FIH_FAILURE on failure.
+ */
+fih_int platform_security_counter_get(fih_uint *security_cnt);
+
+/**
+ * Updates the stored value of a given image's security counter with a new
+ * security counter value if the new one is greater.
+ *
+ * @param reprov_packet Pointer to a reprovisioning packet containing NV counter.
+ * @param packet_len Length of a packet
+ * @param img_security_cnt Security conter value of image
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+int32_t platform_security_counter_update(uint32_t img_security_cnt, void * custom_data);
+#endif /* PSOC6 */
+
+#endif /* CY_SECURITY_CNT_PLATFORM_H */
\ No newline at end of file
diff --git a/boot/cypress/platforms/cycfg_peripherals.c b/boot/cypress/platforms/cycfg_peripherals.c
deleted file mode 100644
index 1c55938..0000000
--- a/boot/cypress/platforms/cycfg_peripherals.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************
-* File Name: cycfg_peripherals.c
-*
-* Description:
-* Peripheral Hardware Block configuration
-* This file was automatically generated and should not be modified.
-* Device Configurator: 2.0.0.1483
-* Device Support Library (../../../psoc6pdl): 1.3.1.1499
-*
-********************************************************************************
-* Copyright 2017-2019 Cypress Semiconductor Corporation
-* SPDX-License-Identifier: Apache-2.0
-*
-* 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.
-********************************************************************************/
-
-#include "cycfg_peripherals.h"
-
-const cy_stc_scb_uart_config_t CYBSP_UART_config =
-{
- .uartMode = CY_SCB_UART_STANDARD,
- .enableMutliProcessorMode = false,
- .smartCardRetryOnNack = false,
- .irdaInvertRx = false,
- .irdaEnableLowPowerReceiver = false,
- .oversample = 8,
- .enableMsbFirst = false,
- .dataWidth = 8UL,
- .parity = CY_SCB_UART_PARITY_NONE,
- .stopBits = CY_SCB_UART_STOP_BITS_1,
- .enableInputFilter = false,
- .breakWidth = 11UL,
- .dropOnFrameError = false,
- .dropOnParityError = false,
- .receiverAddress = 0x0UL,
- .receiverAddressMask = 0x0UL,
- .acceptAddrInFifo = false,
- .enableCts = false,
- .ctsPolarity = CY_SCB_UART_ACTIVE_LOW,
- .rtsRxFifoLevel = 0UL,
- .rtsPolarity = CY_SCB_UART_ACTIVE_LOW,
- .rxFifoTriggerLevel = 0UL,
- .rxFifoIntEnableMask = 0UL,
- .txFifoTriggerLevel = 63UL,
- .txFifoIntEnableMask = 0UL,
-};
-#if defined (CY_USING_HAL)
- const cyhal_resource_inst_t CYBSP_UART_obj =
- {
- .type = CYHAL_RSC_SCB,
- .block_num = 5U,
- .channel_num = 0U,
- };
-#endif //defined (CY_USING_HAL)
-
-
-void init_cycfg_peripherals(void)
-{
- Cy_SysClk_PeriphAssignDivider(PCLK_SCB5_CLOCK, CY_SYSCLK_DIV_16_BIT, 0U);
-#if defined (CY_USING_HAL)
- cyhal_hwmgr_reserve(&CYBSP_UART_obj);
-#endif //defined (CY_USING_HAL)
-}
diff --git a/boot/cypress/platforms/cycfg_pins.c b/boot/cypress/platforms/cycfg_pins.c
deleted file mode 100644
index 771d772..0000000
--- a/boot/cypress/platforms/cycfg_pins.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*******************************************************************************
-* File Name: cycfg_pins.c
-*
-* Description:
-* Pin configuration
-* This file was automatically generated and should not be modified.
-* Device Configurator: 2.0.0.1483
-* Device Support Library (../../../psoc6pdl): 1.3.1.1499
-*
-********************************************************************************
-* Copyright 2017-2019 Cypress Semiconductor Corporation
-* SPDX-License-Identifier: Apache-2.0
-*
-* 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.
-********************************************************************************/
-
-#include "cycfg_pins.h"
-
-const cy_stc_gpio_pin_config_t CYBSP_UART_RX_config =
-{
- .outVal = 1,
- .driveMode = CY_GPIO_DM_HIGHZ,
- .hsiom = CYBSP_UART_RX_HSIOM,
- .intEdge = CY_GPIO_INTR_DISABLE,
- .intMask = 0UL,
- .vtrip = CY_GPIO_VTRIP_CMOS,
- .slewRate = CY_GPIO_SLEW_FAST,
- .driveSel = CY_GPIO_DRIVE_1_2,
- .vregEn = 0UL,
- .ibufMode = 0UL,
- .vtripSel = 0UL,
- .vrefSel = 0UL,
- .vohSel = 0UL,
-};
-#if defined (CY_USING_HAL)
- const cyhal_resource_inst_t CYBSP_UART_RX_obj =
- {
- .type = CYHAL_RSC_GPIO,
- .block_num = CYBSP_UART_RX_PORT_NUM,
- .channel_num = CYBSP_UART_RX_PIN,
- };
-#endif //defined (CY_USING_HAL)
-const cy_stc_gpio_pin_config_t CYBSP_UART_TX_config =
-{
- .outVal = 1,
- .driveMode = CY_GPIO_DM_STRONG_IN_OFF,
- .hsiom = CYBSP_UART_TX_HSIOM,
- .intEdge = CY_GPIO_INTR_DISABLE,
- .intMask = 0UL,
- .vtrip = CY_GPIO_VTRIP_CMOS,
- .slewRate = CY_GPIO_SLEW_FAST,
- .driveSel = CY_GPIO_DRIVE_1_2,
- .vregEn = 0UL,
- .ibufMode = 0UL,
- .vtripSel = 0UL,
- .vrefSel = 0UL,
- .vohSel = 0UL,
-};
-#if defined (CY_USING_HAL)
- const cyhal_resource_inst_t CYBSP_UART_TX_obj =
- {
- .type = CYHAL_RSC_GPIO,
- .block_num = CYBSP_UART_TX_PORT_NUM,
- .channel_num = CYBSP_UART_TX_PIN,
- };
-#endif //defined (CY_USING_HAL)
-
-void init_cycfg_pins(void)
-{
- Cy_GPIO_Pin_Init(CYBSP_UART_RX_PORT, CYBSP_UART_RX_PIN, &CYBSP_UART_RX_config);
-#if defined (CY_USING_HAL)
- cyhal_hwmgr_reserve(&CYBSP_UART_RX_obj);
-#endif //defined (CY_USING_HAL)
-
- Cy_GPIO_Pin_Init(CYBSP_UART_TX_PORT, CYBSP_UART_TX_PIN, &CYBSP_UART_TX_config);
-#if defined (CY_USING_HAL)
- cyhal_hwmgr_reserve(&CYBSP_UART_TX_obj);
-#endif //defined (CY_USING_HAL)
-}
diff --git a/boot/cypress/platforms/cycfg_pins.h b/boot/cypress/platforms/cycfg_pins.h
deleted file mode 100644
index c214826..0000000
--- a/boot/cypress/platforms/cycfg_pins.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*******************************************************************************
-* File Name: cycfg_pins.h
-*
-* Description:
-* Pin configuration
-* This file was automatically generated and should not be modified.
-* Device Configurator: 2.0.0.1483
-* Device Support Library (../../../psoc6pdl): 1.3.1.1499
-*
-********************************************************************************
-* Copyright 2017-2019 Cypress Semiconductor Corporation
-* SPDX-License-Identifier: Apache-2.0
-*
-* 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.
-********************************************************************************/
-
-#if !defined(CYCFG_PINS_H)
-#define CYCFG_PINS_H
-
-#include "cy_gpio.h"
-#if defined (CY_USING_HAL)
- #include "cyhal_hwmgr.h"
-#endif //defined (CY_USING_HAL)
-#include "cycfg_routing.h"
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#define CYBSP_UART_RX_ENABLED 1U
-#define CYBSP_UART_RX_PORT GPIO_PRT5
-#define CYBSP_UART_RX_PORT_NUM 5U
-#define CYBSP_UART_RX_PIN 0U
-#define CYBSP_UART_RX_NUM 0U
-#define CYBSP_UART_RX_DRIVEMODE CY_GPIO_DM_HIGHZ
-#define CYBSP_UART_RX_INIT_DRIVESTATE 1
-#ifndef ioss_0_port_5_pin_0_HSIOM
- #define ioss_0_port_5_pin_0_HSIOM HSIOM_SEL_GPIO
-#endif
-#define CYBSP_UART_RX_HSIOM ioss_0_port_5_pin_0_HSIOM
-#define CYBSP_UART_RX_IRQ ioss_interrupts_gpio_5_IRQn
-#if defined (CY_USING_HAL)
- #define CYBSP_UART_RX_HAL_PORT_PIN P5_0
-#endif //defined (CY_USING_HAL)
-#if defined (CY_USING_HAL)
- #define CYBSP_UART_RX_HAL_IRQ CYHAL_GPIO_IRQ_NONE
-#endif //defined (CY_USING_HAL)
-#if defined (CY_USING_HAL)
- #define CYBSP_UART_RX_HAL_DIR CYHAL_GPIO_DIR_INPUT
-#endif //defined (CY_USING_HAL)
-#if defined (CY_USING_HAL)
- #define CYBSP_UART_RX_HAL_DRIVEMODE CYHAL_GPIO_DRIVE_NONE
-#endif //defined (CY_USING_HAL)
-#define CYBSP_UART_TX_ENABLED 1U
-#define CYBSP_UART_TX_PORT GPIO_PRT5
-#define CYBSP_UART_TX_PORT_NUM 5U
-#define CYBSP_UART_TX_PIN 1U
-#define CYBSP_UART_TX_NUM 1U
-#define CYBSP_UART_TX_DRIVEMODE CY_GPIO_DM_STRONG_IN_OFF
-#define CYBSP_UART_TX_INIT_DRIVESTATE 1
-#ifndef ioss_0_port_5_pin_1_HSIOM
- #define ioss_0_port_5_pin_1_HSIOM HSIOM_SEL_GPIO
-#endif
-#define CYBSP_UART_TX_HSIOM ioss_0_port_5_pin_1_HSIOM
-#define CYBSP_UART_TX_IRQ ioss_interrupts_gpio_5_IRQn
-#if defined (CY_USING_HAL)
- #define CYBSP_UART_TX_HAL_PORT_PIN P5_1
-#endif //defined (CY_USING_HAL)
-#if defined (CY_USING_HAL)
- #define CYBSP_UART_TX_HAL_IRQ CYHAL_GPIO_IRQ_NONE
-#endif //defined (CY_USING_HAL)
-#if defined (CY_USING_HAL)
- #define CYBSP_UART_TX_HAL_DIR CYHAL_GPIO_DIR_OUTPUT
-#endif //defined (CY_USING_HAL)
-#if defined (CY_USING_HAL)
- #define CYBSP_UART_TX_HAL_DRIVEMODE CYHAL_GPIO_DRIVE_STRONG
-#endif //defined (CY_USING_HAL)
-
-extern const cy_stc_gpio_pin_config_t CYBSP_WCO_IN_config;
-#if defined (CY_USING_HAL)
- extern const cyhal_resource_inst_t CYBSP_WCO_IN_obj;
-#endif //defined (CY_USING_HAL)
-extern const cy_stc_gpio_pin_config_t CYBSP_WCO_OUT_config;
-#if defined (CY_USING_HAL)
- extern const cyhal_resource_inst_t CYBSP_WCO_OUT_obj;
-#endif //defined (CY_USING_HAL)
-extern const cy_stc_gpio_pin_config_t CYBSP_UART_RX_config;
-#if defined (CY_USING_HAL)
- extern const cyhal_resource_inst_t CYBSP_UART_RX_obj;
-#endif //defined (CY_USING_HAL)
-extern const cy_stc_gpio_pin_config_t CYBSP_UART_TX_config;
-#if defined (CY_USING_HAL)
- extern const cyhal_resource_inst_t CYBSP_UART_TX_obj;
-#endif //defined (CY_USING_HAL)
-
-void init_cycfg_pins(void);
-
-#if defined(__cplusplus)
-}
-#endif
-
-
-#endif /* CYCFG_PINS_H */
diff --git a/boot/cypress/platforms/cycfg_system.c b/boot/cypress/platforms/cycfg_system.c
deleted file mode 100644
index 57ab013..0000000
--- a/boot/cypress/platforms/cycfg_system.c
+++ /dev/null
@@ -1,537 +0,0 @@
-/*******************************************************************************
-* File Name: cycfg_system.c
-*
-* Description:
-* System configuration
-* This file was automatically generated and should not be modified.
-* Device Configurator: 2.0.0.1483
-* Device Support Library (../../../../output/libs/COMPONENT_PSOC6/psoc6pdl): 1.5.0.1837
-*
-********************************************************************************
-* Copyright 2017-2019 Cypress Semiconductor Corporation
-* SPDX-License-Identifier: Apache-2.0
-*
-* 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.
-********************************************************************************/
-
-#include "cycfg_system.h"
-
-#define CY_CFG_SYSCLK_ECO_ERROR 1
-#define CY_CFG_SYSCLK_ALTHF_ERROR 2
-#define CY_CFG_SYSCLK_PLL_ERROR 3
-#define CY_CFG_SYSCLK_FLL_ERROR 4
-#define CY_CFG_SYSCLK_WCO_ERROR 5
-#define CY_CFG_SYSCLK_CLKALTSYSTICK_ENABLED 1
-#define CY_CFG_SYSCLK_CLKBAK_ENABLED 1
-#define CY_CFG_SYSCLK_CLKFAST_ENABLED 1
-#define CY_CFG_SYSCLK_FLL_ENABLED 1
-#define CY_CFG_SYSCLK_CLKHF0_ENABLED 1
-#define CY_CFG_SYSCLK_CLKHF0_FREQ_MHZ 100UL
-#define CY_CFG_SYSCLK_CLKHF0_CLKPATH CY_SYSCLK_CLKHF_IN_CLKPATH0
-#define CY_CFG_SYSCLK_CLKHF2_ENABLED 1
-#define CY_CFG_SYSCLK_CLKHF2_FREQ_MHZ 50UL
-#define CY_CFG_SYSCLK_CLKHF2_CLKPATH CY_SYSCLK_CLKHF_IN_CLKPATH0
-#define CY_CFG_SYSCLK_CLKHF3_ENABLED 1
-#define CY_CFG_SYSCLK_CLKHF3_FREQ_MHZ 100UL
-#define CY_CFG_SYSCLK_CLKHF3_CLKPATH CY_SYSCLK_CLKHF_IN_CLKPATH0
-#define CY_CFG_SYSCLK_CLKHF4_ENABLED 1
-#define CY_CFG_SYSCLK_CLKHF4_FREQ_MHZ 100UL
-#define CY_CFG_SYSCLK_CLKHF4_CLKPATH CY_SYSCLK_CLKHF_IN_CLKPATH0
-#define CY_CFG_SYSCLK_ILO_ENABLED 1
-#define CY_CFG_SYSCLK_IMO_ENABLED 1
-#define CY_CFG_SYSCLK_CLKLF_ENABLED 1
-#define CY_CFG_SYSCLK_CLKPATH0_ENABLED 1
-#define CY_CFG_SYSCLK_CLKPATH0_SOURCE CY_SYSCLK_CLKPATH_IN_IMO
-#define CY_CFG_SYSCLK_CLKPATH1_ENABLED 1
-#define CY_CFG_SYSCLK_CLKPATH1_SOURCE CY_SYSCLK_CLKPATH_IN_IMO
-#define CY_CFG_SYSCLK_CLKPATH2_ENABLED 1
-#define CY_CFG_SYSCLK_CLKPATH2_SOURCE CY_SYSCLK_CLKPATH_IN_IMO
-#define CY_CFG_SYSCLK_CLKPERI_ENABLED 1
-#define CY_CFG_SYSCLK_PLL0_ENABLED 1
-#define CY_CFG_SYSCLK_PLL1_ENABLED 1
-#define CY_CFG_SYSCLK_CLKSLOW_ENABLED 1
-#define CY_CFG_SYSCLK_CLKTIMER_ENABLED 1
-#define CY_CFG_SYSCLK_WCO_ENABLED 1
-
-static const cy_stc_fll_manual_config_t srss_0_clock_0_fll_0_fllConfig =
-{
- .fllMult = 500U,
- .refDiv = 20U,
- .ccoRange = CY_SYSCLK_FLL_CCO_RANGE4,
- .enableOutputDiv = true,
- .lockTolerance = 10U,
- .igain = 9U,
- .pgain = 5U,
- .settlingCount = 8U,
- .outputMode = CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT,
- .cco_Freq = 355U,
-};
-#if defined (CY_USING_HAL)
- const cyhal_resource_inst_t srss_0_clock_0_pathmux_0_obj =
- {
- .type = CYHAL_RSC_CLKPATH,
- .block_num = 0U,
- .channel_num = 0U,
- };
-#endif //defined (CY_USING_HAL)
-#if defined (CY_USING_HAL)
- const cyhal_resource_inst_t srss_0_clock_0_pathmux_1_obj =
- {
- .type = CYHAL_RSC_CLKPATH,
- .block_num = 1U,
- .channel_num = 0U,
- };
-#endif //defined (CY_USING_HAL)
-#if defined (CY_USING_HAL)
- const cyhal_resource_inst_t srss_0_clock_0_pathmux_2_obj =
- {
- .type = CYHAL_RSC_CLKPATH,
- .block_num = 2U,
- .channel_num = 0U,
- };
-#endif //defined (CY_USING_HAL)
-static const cy_stc_pll_manual_config_t srss_0_clock_0_pll_0_pllConfig =
-{
- .feedbackDiv = 36,
- .referenceDiv = 1,
- .outputDiv = 2,
- .lfMode = false,
- .outputMode = CY_SYSCLK_FLLPLL_OUTPUT_AUTO,
-};
-static const cy_stc_pll_manual_config_t srss_0_clock_0_pll_1_pllConfig =
-{
- .feedbackDiv = 30,
- .referenceDiv = 1,
- .outputDiv = 5,
- .lfMode = false,
- .outputMode = CY_SYSCLK_FLLPLL_OUTPUT_AUTO,
-};
-
-__WEAK void cycfg_ClockStartupError(uint32_t error)
-{
- (void)error; /* Suppress the compiler warning */
- while(1);
-}
-__STATIC_INLINE void Cy_SysClk_ClkAltSysTickInit()
-{
- Cy_SysTick_SetClockSource(CY_SYSTICK_CLOCK_SOURCE_CLK_LF);
-}
-__STATIC_INLINE void Cy_SysClk_ClkBakInit()
-{
- Cy_SysClk_ClkBakSetSource(CY_SYSCLK_BAK_IN_CLKLF);
-}
-__STATIC_INLINE void Cy_SysClk_ClkFastInit()
-{
- Cy_SysClk_ClkFastSetDivider(0U);
-}
-__STATIC_INLINE void Cy_SysClk_FllInit()
-{
- if (CY_SYSCLK_SUCCESS != Cy_SysClk_FllManualConfigure(&srss_0_clock_0_fll_0_fllConfig))
- {
- cycfg_ClockStartupError(CY_CFG_SYSCLK_FLL_ERROR);
- }
- if (CY_SYSCLK_SUCCESS != Cy_SysClk_FllEnable(200000UL))
- {
- cycfg_ClockStartupError(CY_CFG_SYSCLK_FLL_ERROR);
- }
-}
-__STATIC_INLINE void Cy_SysClk_ClkHf0Init()
-{
- Cy_SysClk_ClkHfSetSource(0U, CY_CFG_SYSCLK_CLKHF0_CLKPATH);
- Cy_SysClk_ClkHfSetDivider(0U, CY_SYSCLK_CLKHF_NO_DIVIDE);
-}
-__STATIC_INLINE void Cy_SysClk_ClkHf2Init()
-{
- Cy_SysClk_ClkHfSetSource(CY_CFG_SYSCLK_CLKHF2, CY_CFG_SYSCLK_CLKHF2_CLKPATH);
- Cy_SysClk_ClkHfSetDivider(CY_CFG_SYSCLK_CLKHF2, CY_SYSCLK_CLKHF_DIVIDE_BY_2);
- Cy_SysClk_ClkHfEnable(CY_CFG_SYSCLK_CLKHF2);
-}
-__STATIC_INLINE void Cy_SysClk_ClkHf3Init()
-{
- Cy_SysClk_ClkHfSetSource(CY_CFG_SYSCLK_CLKHF3, CY_CFG_SYSCLK_CLKHF3_CLKPATH);
- Cy_SysClk_ClkHfSetDivider(CY_CFG_SYSCLK_CLKHF3, CY_SYSCLK_CLKHF_NO_DIVIDE);
- Cy_SysClk_ClkHfEnable(CY_CFG_SYSCLK_CLKHF3);
-}
-__STATIC_INLINE void Cy_SysClk_ClkHf4Init()
-{
- Cy_SysClk_ClkHfSetSource(CY_CFG_SYSCLK_CLKHF4, CY_CFG_SYSCLK_CLKHF4_CLKPATH);
- Cy_SysClk_ClkHfSetDivider(CY_CFG_SYSCLK_CLKHF4, CY_SYSCLK_CLKHF_NO_DIVIDE);
- Cy_SysClk_ClkHfEnable(CY_CFG_SYSCLK_CLKHF4);
-}
-__STATIC_INLINE void Cy_SysClk_IloInit()
-{
- /* The WDT is unlocked in the default startup code */
- Cy_SysClk_IloEnable();
- Cy_SysClk_IloHibernateOn(true);
-}
-__STATIC_INLINE void Cy_SysClk_ClkLfInit()
-{
- /* The WDT is unlocked in the default startup code */
- Cy_SysClk_ClkLfSetSource(CY_SYSCLK_CLKLF_IN_WCO);
-}
-__STATIC_INLINE void Cy_SysClk_ClkPath0Init()
-{
- Cy_SysClk_ClkPathSetSource(0U, CY_CFG_SYSCLK_CLKPATH0_SOURCE);
-}
-__STATIC_INLINE void Cy_SysClk_ClkPath1Init()
-{
- Cy_SysClk_ClkPathSetSource(1U, CY_CFG_SYSCLK_CLKPATH1_SOURCE);
-}
-__STATIC_INLINE void Cy_SysClk_ClkPath2Init()
-{
- Cy_SysClk_ClkPathSetSource(2U, CY_CFG_SYSCLK_CLKPATH2_SOURCE);
-}
-__STATIC_INLINE void Cy_SysClk_ClkPeriInit()
-{
- Cy_SysClk_ClkPeriSetDivider(1U);
-}
-__STATIC_INLINE void Cy_SysClk_Pll0Init()
-{
- if (CY_SYSCLK_SUCCESS != Cy_SysClk_PllManualConfigure(1U, &srss_0_clock_0_pll_0_pllConfig))
- {
- cycfg_ClockStartupError(CY_CFG_SYSCLK_PLL_ERROR);
- }
- if (CY_SYSCLK_SUCCESS != Cy_SysClk_PllEnable(1U, 10000u))
- {
- cycfg_ClockStartupError(CY_CFG_SYSCLK_PLL_ERROR);
- }
-}
-__STATIC_INLINE void Cy_SysClk_Pll1Init()
-{
- if (CY_SYSCLK_SUCCESS != Cy_SysClk_PllManualConfigure(2U, &srss_0_clock_0_pll_1_pllConfig))
- {
- cycfg_ClockStartupError(CY_CFG_SYSCLK_PLL_ERROR);
- }
- if (CY_SYSCLK_SUCCESS != Cy_SysClk_PllEnable(2U, 10000u))
- {
- cycfg_ClockStartupError(CY_CFG_SYSCLK_PLL_ERROR);
- }
-}
-__STATIC_INLINE void Cy_SysClk_ClkSlowInit()
-{
- Cy_SysClk_ClkSlowSetDivider(0U);
-}
-__STATIC_INLINE void Cy_SysClk_ClkTimerInit()
-{
- Cy_SysClk_ClkTimerDisable();
- Cy_SysClk_ClkTimerSetSource(CY_SYSCLK_CLKTIMER_IN_IMO);
- Cy_SysClk_ClkTimerSetDivider(0U);
- Cy_SysClk_ClkTimerEnable();
-}
-__STATIC_INLINE void Cy_SysClk_WcoInit()
-{
- (void)Cy_GPIO_Pin_FastInit(GPIO_PRT0, 0U, 0x00U, 0x00U, HSIOM_SEL_GPIO);
- (void)Cy_GPIO_Pin_FastInit(GPIO_PRT0, 1U, 0x00U, 0x00U, HSIOM_SEL_GPIO);
- if (CY_SYSCLK_SUCCESS != Cy_SysClk_WcoEnable(1000000UL))
- {
- cycfg_ClockStartupError(CY_CFG_SYSCLK_WCO_ERROR);
- }
-}
-
-
-void init_cycfg_system(void)
-{
- /* Set worst case memory wait states (! ultra low power, 150 MHz), will update at the end */
- Cy_SysLib_SetWaitStates(false, 150UL);
- #ifdef CY_CFG_PWR_ENABLED
- #ifdef CY_CFG_PWR_INIT
- init_cycfg_power();
- #else
- #warning Power system will not be configured. Update power personality to v1.20 or later.
- #endif /* CY_CFG_PWR_INIT */
- #endif /* CY_CFG_PWR_ENABLED */
-
- /* Reset the core clock path to default and disable all the FLLs/PLLs */
- Cy_SysClk_ClkHfSetDivider(0U, CY_SYSCLK_CLKHF_NO_DIVIDE);
- Cy_SysClk_ClkFastSetDivider(0U);
- Cy_SysClk_ClkPeriSetDivider(1U);
- Cy_SysClk_ClkSlowSetDivider(0U);
- for (uint32_t pll = CY_SRSS_NUM_PLL; pll > 0UL; --pll) /* PLL 1 is the first PLL. 0 is invalid. */
- {
- (void)Cy_SysClk_PllDisable(pll);
- }
- Cy_SysClk_ClkPathSetSource(CY_SYSCLK_CLKHF_IN_CLKPATH1, CY_SYSCLK_CLKPATH_IN_IMO);
-
- if ((CY_SYSCLK_CLKHF_IN_CLKPATH0 == Cy_SysClk_ClkHfGetSource(0UL)) &&
- (CY_SYSCLK_CLKPATH_IN_WCO == Cy_SysClk_ClkPathGetSource(CY_SYSCLK_CLKHF_IN_CLKPATH0)))
- {
- Cy_SysClk_ClkHfSetSource(0U, CY_SYSCLK_CLKHF_IN_CLKPATH1);
- }
-
- Cy_SysClk_FllDisable();
- Cy_SysClk_ClkPathSetSource(CY_SYSCLK_CLKHF_IN_CLKPATH0, CY_SYSCLK_CLKPATH_IN_IMO);
- Cy_SysClk_ClkHfSetSource(0UL, CY_SYSCLK_CLKHF_IN_CLKPATH0);
- #ifdef CY_IP_MXBLESS
- (void)Cy_BLE_EcoReset();
- #endif
-
-
- /* Enable all source clocks */
- #ifdef CY_CFG_SYSCLK_PILO_ENABLED
- Cy_SysClk_PiloInit();
- #endif
-
- #ifdef CY_CFG_SYSCLK_WCO_ENABLED
- Cy_SysClk_WcoInit();
- #endif
-
- #ifdef CY_CFG_SYSCLK_CLKLF_ENABLED
- Cy_SysClk_ClkLfInit();
- #endif
-
- #ifdef CY_CFG_SYSCLK_ALTHF_ENABLED
- Cy_SysClk_AltHfInit();
- #endif
-
- #ifdef CY_CFG_SYSCLK_ECO_ENABLED
- Cy_SysClk_EcoInit();
- #endif
-
- #ifdef CY_CFG_SYSCLK_EXTCLK_ENABLED
- Cy_SysClk_ExtClkInit();
- #endif
-
- /* Configure CPU clock dividers */
- #ifdef CY_CFG_SYSCLK_CLKFAST_ENABLED
- Cy_SysClk_ClkFastInit();
- #endif
-
- #ifdef CY_CFG_SYSCLK_CLKPERI_ENABLED
- Cy_SysClk_ClkPeriInit();
- #endif
-
- #ifdef CY_CFG_SYSCLK_CLKSLOW_ENABLED
- Cy_SysClk_ClkSlowInit();
- #endif
-
- #if ((CY_CFG_SYSCLK_CLKPATH0_SOURCE == CY_SYSCLK_CLKPATH_IN_WCO) && (CY_CFG_SYSCLK_CLKHF0_CLKPATH == CY_SYSCLK_CLKHF_IN_CLKPATH0))
- /* Configure HFCLK0 to temporarily run from IMO to initialize other clocks */
- Cy_SysClk_ClkPathSetSource(1UL, CY_SYSCLK_CLKPATH_IN_IMO);
- Cy_SysClk_ClkHfSetSource(0UL, CY_SYSCLK_CLKHF_IN_CLKPATH1);
- #else
- #ifdef CY_CFG_SYSCLK_CLKPATH1_ENABLED
- Cy_SysClk_ClkPath1Init();
- #endif
- #endif
-
- /* Configure Path Clocks */
- #ifdef CY_CFG_SYSCLK_CLKPATH0_ENABLED
- Cy_SysClk_ClkPath0Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKPATH2_ENABLED
- Cy_SysClk_ClkPath2Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKPATH3_ENABLED
- Cy_SysClk_ClkPath3Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKPATH4_ENABLED
- Cy_SysClk_ClkPath4Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKPATH5_ENABLED
- Cy_SysClk_ClkPath5Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKPATH6_ENABLED
- Cy_SysClk_ClkPath6Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKPATH7_ENABLED
- Cy_SysClk_ClkPath7Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKPATH8_ENABLED
- Cy_SysClk_ClkPath8Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKPATH9_ENABLED
- Cy_SysClk_ClkPath9Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKPATH10_ENABLED
- Cy_SysClk_ClkPath10Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKPATH11_ENABLED
- Cy_SysClk_ClkPath11Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKPATH12_ENABLED
- Cy_SysClk_ClkPath12Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKPATH13_ENABLED
- Cy_SysClk_ClkPath13Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKPATH14_ENABLED
- Cy_SysClk_ClkPath14Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKPATH15_ENABLED
- Cy_SysClk_ClkPath15Init();
- #endif
-
- /* Configure and enable FLL */
- #ifdef CY_CFG_SYSCLK_FLL_ENABLED
- Cy_SysClk_FllInit();
- #endif
-
- Cy_SysClk_ClkHf0Init();
-
- #if ((CY_CFG_SYSCLK_CLKPATH0_SOURCE == CY_SYSCLK_CLKPATH_IN_WCO) && (CY_CFG_SYSCLK_CLKHF0_CLKPATH == CY_SYSCLK_CLKHF_IN_CLKPATH0))
- #ifdef CY_CFG_SYSCLK_CLKPATH1_ENABLED
- /* Apply the ClkPath1 user setting */
- Cy_SysClk_ClkPath1Init();
- #endif
- #endif
-
- /* Configure and enable PLLs */
- #ifdef CY_CFG_SYSCLK_PLL0_ENABLED
- Cy_SysClk_Pll0Init();
- #endif
- #ifdef CY_CFG_SYSCLK_PLL1_ENABLED
- Cy_SysClk_Pll1Init();
- #endif
- #ifdef CY_CFG_SYSCLK_PLL2_ENABLED
- Cy_SysClk_Pll2Init();
- #endif
- #ifdef CY_CFG_SYSCLK_PLL3_ENABLED
- Cy_SysClk_Pll3Init();
- #endif
- #ifdef CY_CFG_SYSCLK_PLL4_ENABLED
- Cy_SysClk_Pll4Init();
- #endif
- #ifdef CY_CFG_SYSCLK_PLL5_ENABLED
- Cy_SysClk_Pll5Init();
- #endif
- #ifdef CY_CFG_SYSCLK_PLL6_ENABLED
- Cy_SysClk_Pll6Init();
- #endif
- #ifdef CY_CFG_SYSCLK_PLL7_ENABLED
- Cy_SysClk_Pll7Init();
- #endif
- #ifdef CY_CFG_SYSCLK_PLL8_ENABLED
- Cy_SysClk_Pll8Init();
- #endif
- #ifdef CY_CFG_SYSCLK_PLL9_ENABLED
- Cy_SysClk_Pll9Init();
- #endif
- #ifdef CY_CFG_SYSCLK_PLL10_ENABLED
- Cy_SysClk_Pll10Init();
- #endif
- #ifdef CY_CFG_SYSCLK_PLL11_ENABLED
- Cy_SysClk_Pll11Init();
- #endif
- #ifdef CY_CFG_SYSCLK_PLL12_ENABLED
- Cy_SysClk_Pll12Init();
- #endif
- #ifdef CY_CFG_SYSCLK_PLL13_ENABLED
- Cy_SysClk_Pll13Init();
- #endif
- #ifdef CY_CFG_SYSCLK_PLL14_ENABLED
- Cy_SysClk_Pll14Init();
- #endif
-
- /* Configure HF clocks */
- #ifdef CY_CFG_SYSCLK_CLKHF1_ENABLED
- Cy_SysClk_ClkHf1Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKHF2_ENABLED
- Cy_SysClk_ClkHf2Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKHF3_ENABLED
- Cy_SysClk_ClkHf3Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKHF4_ENABLED
- Cy_SysClk_ClkHf4Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKHF5_ENABLED
- Cy_SysClk_ClkHf5Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKHF6_ENABLED
- Cy_SysClk_ClkHf6Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKHF7_ENABLED
- Cy_SysClk_ClkHf7Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKHF8_ENABLED
- Cy_SysClk_ClkHf8Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKHF9_ENABLED
- Cy_SysClk_ClkHf9Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKHF10_ENABLED
- Cy_SysClk_ClkHf10Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKHF11_ENABLED
- Cy_SysClk_ClkHf11Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKHF12_ENABLED
- Cy_SysClk_ClkHf12Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKHF13_ENABLED
- Cy_SysClk_ClkHf13Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKHF14_ENABLED
- Cy_SysClk_ClkHf14Init();
- #endif
- #ifdef CY_CFG_SYSCLK_CLKHF15_ENABLED
- Cy_SysClk_ClkHf15Init();
- #endif
-
- /* Configure miscellaneous clocks */
- #ifdef CY_CFG_SYSCLK_CLKTIMER_ENABLED
- Cy_SysClk_ClkTimerInit();
- #endif
-
- #ifdef CY_CFG_SYSCLK_CLKALTSYSTICK_ENABLED
- Cy_SysClk_ClkAltSysTickInit();
- #endif
-
- #ifdef CY_CFG_SYSCLK_CLKPUMP_ENABLED
- Cy_SysClk_ClkPumpInit();
- #endif
-
- #ifdef CY_CFG_SYSCLK_CLKBAK_ENABLED
- Cy_SysClk_ClkBakInit();
- #endif
-
- /* Configure default enabled clocks */
- #ifdef CY_CFG_SYSCLK_ILO_ENABLED
- Cy_SysClk_IloInit();
- #else
- Cy_SysClk_IloDisable();
- #endif
-
- #ifndef CY_CFG_SYSCLK_IMO_ENABLED
- #error the IMO must be enabled for proper chip operation
- #endif
-
- #ifdef CY_CFG_SYSCLK_MFO_ENABLED
- Cy_SysClk_MfoInit();
- #endif
-
- #ifdef CY_CFG_SYSCLK_CLKMF_ENABLED
- Cy_SysClk_ClkMfInit();
- #endif
-
- /* Set accurate flash wait states */
- #if (defined (CY_CFG_PWR_ENABLED) && defined (CY_CFG_SYSCLK_CLKHF0_ENABLED))
- Cy_SysLib_SetWaitStates(CY_CFG_PWR_USING_ULP != 0, CY_CFG_SYSCLK_CLKHF0_FREQ_MHZ);
- #endif
-
- /* Update System Core Clock values for correct Cy_SysLib_Delay functioning */
- SystemCoreClockUpdate();
-
-#if defined (CY_USING_HAL)
- cyhal_hwmgr_reserve(&srss_0_clock_0_pathmux_0_obj);
-#endif //defined (CY_USING_HAL)
-
-#if defined (CY_USING_HAL)
- cyhal_hwmgr_reserve(&srss_0_clock_0_pathmux_1_obj);
-#endif //defined (CY_USING_HAL)
-
-#if defined (CY_USING_HAL)
- cyhal_hwmgr_reserve(&srss_0_clock_0_pathmux_2_obj);
-#endif //defined (CY_USING_HAL)
-}
diff --git a/boot/cypress/platforms/retarget_io_pdl/cy_retarget_io_pdl.c b/boot/cypress/platforms/retarget_io_pdl/cy_retarget_io_pdl.c
deleted file mode 100644
index 0472f3e..0000000
--- a/boot/cypress/platforms/retarget_io_pdl/cy_retarget_io_pdl.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/***************************************************************************//**
-* \file cy_retarget_io.c
-*
-* \brief
-* Provides APIs for retargeting stdio to UART hardware contained on the Cypress
-* kits.
-*
-********************************************************************************
-* \copyright
-* Copyright 2018-2019 Cypress Semiconductor Corporation
-* SPDX-License-Identifier: Apache-2.0
-*
-* 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.
-*******************************************************************************/
-
-#include "cy_retarget_io_pdl.h"
-
-#include "cycfg_peripherals.h"
-
-#include "cy_sysint.h"
-#include "cy_scb_uart.h"
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/* Tracks the previous character sent to output stream */
-#ifdef CY_RETARGET_IO_CONVERT_LF_TO_CRLF
-static char cy_retarget_io_stdout_prev_char = 0;
-#endif /* CY_RETARGET_IO_CONVERT_LF_TO_CRLF */
-
-cy_stc_scb_uart_context_t CYBSP_UART_context;
-
-static uint8_t cy_retarget_io_getchar(void);
-static void cy_retarget_io_putchar(char c);
-
-#if defined(__ARMCC_VERSION) /* ARM-MDK */
- /***************************************************************************
- * Function Name: fputc
- ***************************************************************************/
- __attribute__((weak)) int fputc(int ch, FILE *f)
- {
- (void)f;
- #ifdef CY_RETARGET_IO_CONVERT_LF_TO_CRLF
- if ((char)ch == '\n' && cy_retarget_io_stdout_prev_char != '\r')
- {
- cy_retarget_io_putchar('\r');
- }
-
- cy_retarget_io_stdout_prev_char = (char)ch;
- #endif /* CY_RETARGET_IO_CONVERT_LF_TO_CRLF */
- cy_retarget_io_putchar(ch);
- return (ch);
- }
-#elif defined (__ICCARM__) /* IAR */
- #include <yfuns.h>
-
- /***************************************************************************
- * Function Name: __write
- ***************************************************************************/
- __weak size_t __write(int handle, const unsigned char * buffer, size_t size)
- {
- size_t nChars = 0;
- /* This template only writes to "standard out", for all other file
- * handles it returns failure. */
- if (handle != _LLIO_STDOUT)
- {
- return (_LLIO_ERROR);
- }
- if (buffer != NULL)
- {
- for (/* Empty */; nChars < size; ++nChars)
- {
- #ifdef CY_RETARGET_IO_CONVERT_LF_TO_CRLF
- if (*buffer == '\n' && cy_retarget_io_stdout_prev_char != '\r')
- {
- cy_retarget_io_putchar('\r');
- }
-
- cy_retarget_io_stdout_prev_char = *buffer;
- #endif /* CY_RETARGET_IO_CONVERT_LF_TO_CRLF */
- cy_retarget_io_putchar(*buffer);
- ++buffer;
- }
- }
- return (nChars);
- }
-#else /* (__GNUC__) GCC */
- /* Add an explicit reference to the floating point printf library to allow
- the usage of floating point conversion specifier. */
- __asm (".global _printf_float");
- /***************************************************************************
- * Function Name: _write
- ***************************************************************************/
- __attribute__((weak)) int _write (int fd, const char *ptr, int len)
- {
- int nChars = 0;
- (void)fd;
- if (ptr != NULL)
- {
- for (/* Empty */; nChars < len; ++nChars)
- {
- #ifdef CY_RETARGET_IO_CONVERT_LF_TO_CRLF
- if (*ptr == '\n' && cy_retarget_io_stdout_prev_char != '\r')
- {
- cy_retarget_io_putchar('\r');
- }
-
- cy_retarget_io_stdout_prev_char = *ptr;
- #endif /* CY_RETARGET_IO_CONVERT_LF_TO_CRLF */
- cy_retarget_io_putchar((uint32_t)*ptr);
- ++ptr;
- }
- }
- return (nChars);
- }
-#endif
-
-
-#if defined(__ARMCC_VERSION) /* ARM-MDK */
- /***************************************************************************
- * Function Name: fgetc
- ***************************************************************************/
- __attribute__((weak)) int fgetc(FILE *f)
- {
- (void)f;
- return (cy_retarget_io_getchar());
- }
-#elif defined (__ICCARM__) /* IAR */
- __weak size_t __read(int handle, unsigned char * buffer, size_t size)
- {
- /* This template only reads from "standard in", for all other file
- handles it returns failure. */
- if ((handle != _LLIO_STDIN) || (buffer == NULL))
- {
- return (_LLIO_ERROR);
- }
- else
- {
- *buffer = cy_retarget_io_getchar();
- return (1);
- }
- }
-#else /* (__GNUC__) GCC */
- /* Add an explicit reference to the floating point scanf library to allow
- the usage of floating point conversion specifier. */
- __asm (".global _scanf_float");
- __attribute__((weak)) int _read (int fd, char *ptr, int len)
- {
- int nChars = 0;
- (void)fd;
- if (ptr != NULL)
- {
- for(/* Empty */;nChars < len;++ptr)
- {
- *ptr = (char)cy_retarget_io_getchar();
- ++nChars;
- if((*ptr == '\n') || (*ptr == '\r'))
- {
- break;
- }
- }
- }
- return (nChars);
- }
-#endif
-
-static uint8_t cy_retarget_io_getchar(void)
-{
- uint32_t read_value = Cy_SCB_UART_Get(CYBSP_UART_HW);
- while (read_value == CY_SCB_UART_RX_NO_DATA)
- {
- read_value = Cy_SCB_UART_Get(CYBSP_UART_HW);
- }
-
- return (uint8_t)read_value;
-}
-
-static void cy_retarget_io_putchar(char c)
-{
- uint32_t count = 0;
- while (count == 0)
- {
- count = Cy_SCB_UART_Put(CYBSP_UART_HW, c);
- }
-}
-
-static cy_rslt_t cy_retarget_io_pdl_setbaud(CySCB_Type *base, uint32_t baudrate)
-{
- cy_rslt_t result = CY_RSLT_TYPE_ERROR;
-
- uint8_t oversample_value = 8u;
- uint8_t frac_bits = 0u;
- uint32_t divider;
-
- Cy_SCB_UART_Disable(base, NULL);
-
- result = (cy_rslt_t) Cy_SysClk_PeriphDisableDivider(CY_SYSCLK_DIV_16_BIT, 0);
-
- divider = ((Cy_SysClk_ClkPeriGetFrequency() * (1 << frac_bits)) + ((baudrate * oversample_value) / 2)) / (baudrate * oversample_value) - 1;
-
- if (result == CY_RSLT_SUCCESS)
- {
- result = (cy_rslt_t) Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_16_BIT, 0u, divider);
- }
-
- if (result == CY_RSLT_SUCCESS)
- {
- result = Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_16_BIT, 0u);
- }
-
- Cy_SCB_UART_Enable(base);
-
- return result;
-}
-
-cy_rslt_t cy_retarget_io_pdl_init(uint32_t baudrate)
-{
- cy_rslt_t result = CY_RSLT_TYPE_ERROR;
-
- result = (cy_rslt_t)Cy_SCB_UART_Init(CYBSP_UART_HW, &CYBSP_UART_config, &CYBSP_UART_context);
-
- if (result == CY_RSLT_SUCCESS)
- {
- result = cy_retarget_io_pdl_setbaud(CYBSP_UART_HW, baudrate);
- }
-
- if (result == CY_RSLT_SUCCESS)
- {
- Cy_SCB_UART_Enable(CYBSP_UART_HW);
- }
-
- return result;
-}
-
-/**
- * @brief Wait while UART completes transfer. Try for tries_count times -
- * once each 10 millisecons.
- */
-void cy_retarget_io_wait_tx_complete(CySCB_Type *base, uint32_t tries_count)
-{
- while(tries_count > 0)
- {
- if (!Cy_SCB_UART_IsTxComplete(base)) {
- Cy_SysLib_DelayCycles(10 * cy_delayFreqKhz);
- tries_count -= 1;
- } else {
- return;
- }
- }
-}
-
-void cy_retarget_io_pdl_deinit()
-{
- Cy_SCB_UART_DeInit(CYBSP_UART_HW);
-}
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/boot/cypress/platforms/retarget_io_pdl/cy_retarget_io_pdl.h b/boot/cypress/platforms/retarget_io_pdl/cy_retarget_io_pdl.h
deleted file mode 100644
index f0c8733..0000000
--- a/boot/cypress/platforms/retarget_io_pdl/cy_retarget_io_pdl.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/***************************************************************************//**
-* \file cy_retarget_io.h
-*
-* \brief
-* Provides APIs for transmitting messages to or from the board via standard
-* printf/scanf functions. Messages are transmitted over a UART connection which
-* is generally connected to a host machine. Transmission is done at 115200 baud
-* using the tx and rx pins provided by the user of this library. The UART
-* instance is made available via cy_retarget_io_uart_obj in case any changes
-* to the default configuration are desired.
-* NOTE: If the application is built using newlib-nano, by default, floating
-* point format strings (%f) are not supported. To enable this support you must
-* add '-u _printf_float' to the linker command line.
-*
-********************************************************************************
-* \copyright
-* Copyright 2018-2019 Cypress Semiconductor Corporation
-* SPDX-License-Identifier: Apache-2.0
-*
-* 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.
-*******************************************************************************/
-
-#pragma once
-
-#include <stdio.h>
-#include "cy_result.h"
-#include "cy_pdl.h"
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/** UART baud rate */
-#define CY_RETARGET_IO_BAUDRATE (115200)
-
-/** Defining this macro enables conversion of line feed (LF) into carriage
- * return followed by line feed (CR & LF) on the output direction (STDOUT). You
- * can define this macro through the DEFINES variable in the application
- * Makefile.
- */
-#define CY_RETARGET_IO_CONVERT_LF_TO_CRLF
-
-cy_rslt_t cy_retarget_io_pdl_init(uint32_t baudrate);
-
-void cy_retarget_io_wait_tx_complete(CySCB_Type *base, uint32_t tries_count);
-
-void cy_retarget_io_pdl_deinit(void);
-
-#if defined(__cplusplus)
-}
-#endif
-
diff --git a/boot/cypress/run_toc2_generator.sh b/boot/cypress/run_toc2_generator.sh
new file mode 100755
index 0000000..4b47cba
--- /dev/null
+++ b/boot/cypress/run_toc2_generator.sh
@@ -0,0 +1,364 @@
+#!/bin/bash
+(set -o igncr) 2>/dev/null && set -o igncr; #keep this comment
+
+echo_run() { echo "\$ ${@/eval/}" ; "$@" ; }
+
+# set -vx
+
+# parameters
+# 1. secure/non-secure
+# 2. path to app
+# 3. app name
+# 4. app type
+# 5. path to keys
+# 6. smif config file
+
+# additional mcuboot makefile param
+# 7. gcc toolchain path
+# 8. path to policy
+# 9. default application slot size
+# 10. enable encryption
+# 11. service application descriptor address
+
+# Combined image configuration
+LCS=$1
+: ${LCS:="NORMAL_NO_SECURE"}
+
+# Path to the image and image name for programming (the extension must be bin)
+L1_USER_APP_BIN="$2/$3.bin"
+: ${L1_USER_APP_BIN:="blinky.bin"}
+
+if [ "$LCS" == "SECURE" ]; then
+L1_USER_APP_BIN_SIGN="$2/$3.signed.bin"
+: ${L1_USER_APP_BIN_SIGN:="blinky.signed.bin"}
+fi
+
+L1_USER_APP_ELF="$2/$3.elf"
+: ${L1_USER_APP_ELF:="blinky.elf"}
+
+FINAL_BIN_FILE="$2/$3.final.bin"
+: ${FINAL_BIN_FILE:="blinky.final.bin"}
+
+COMBINED_BIN_FILE="$2/$3.combined.bin"
+: ${L1_USER_APP_BIN:="blinky.combined.bin"}
+
+FINAL_HEX_FILE="$2/$3.final.hex"
+: ${FINAL_HEX_FILE:="blinky.final.hex"}
+
+AES_CTR_NONCE_FILE="$2/$3.signed_nonce.bin"
+
+ENCRYPTED_MCUBOOT_BIN_FILE="$2/$3.signed_encrypted.bin"
+
+TOC2_FILE="$2/toc2.bin"
+
+L1_DESC_TEMP="$2/l1_app_desc_temp.bin"
+
+L1_DESC_FILE="$2/l1_app_desc.bin"
+
+L1_USER_APP_HEADER_FILE="$2/l1_user_app_header.bin"
+
+APP_TYPE=$4
+: ${APP_TYPE:="l1ram"}
+
+PROVISION_PATH=$5
+: ${PROVISION_PATH:="."}
+
+# Path to the smif_crypto_cfg and its name for programming (the extension
+# must be bin)
+SMIF_CRYPTO_CFG=$6
+: ${SMIF_CRYPTO_CFG:="NONE"}
+
+# Full path to the default toolchain
+if [ "$7" == "" ];then
+ NM_TOOL=arm-none-eabi-nm
+else
+ NM_TOOL="$7"/bin/arm-none-eabi-nm
+fi
+
+POLICY_PATH=$8
+: ${POLICY_PATH:="$PROVISION_PATH/policy/policy_secure.json"}
+
+SLOT_SIZE=$9
+
+if [ "${10}" == "1" ];then
+ ENC_OPTION="--encrypt"
+else
+ ENC_OPTION=""
+fi
+
+SERVICE_APP_DESCR_ADDR=${11}
+: ${SERVICE_APP_DESCR_ADDR:=0x0}
+
+######################## Validate Input Args #################################
+if ! [ -f $L1_USER_APP_BIN ]; then
+ echo "ERROR: $L1_USER_APP_BIN not found"
+ exit 1
+fi
+
+if ! [ -f $L1_USER_APP_ELF ]; then
+ echo "ERROR: $L1_USER_APP_ELF not found"
+ exit 1
+fi
+
+if ! [ -d $PROVISION_PATH ]; then
+ echo "ERROR: $PROVISION_PATH not found"
+ exit 1
+fi
+
+if [ "$TOOLCHAIN" != "ARM" ]; then
+if ! [ -x $NM_TOOL ]; then
+ echo "ERROR: $NM_TOOL not found"
+ exit 1
+fi
+fi
+
+if ! [ -x "$(command -v awk)" ]; then
+ echo "ERROR: awk not found"
+ exit 1
+fi
+
+# if ! [ -x "$(command -v print)" ]; then
+# echo "ERROR: print not found"
+# exit 1
+# fi
+
+if [ "$LCS" == "SECURE" ]; then
+ if ! [ -x "$(command -v cysecuretools)" ]; then
+ echo "ERROR: cysecuretools not found"
+ exit 1
+ fi
+fi
+######################### Generate TOC2 ########################################
+
+# Hardcoded value bytes
+TOC2_SIZE=16
+
+# Hardcoded address in external memory
+TOC2_ADDR=0x0
+
+# TOC2 entries in hexadecimal
+L1_APP_DESCR_ADDR=0x10
+DEBUG_CERT_ADDR=0x0
+
+# Convert to hex string (without 0x prefix)
+TOC2_SIZE_HEX=$(printf "%08x" $TOC2_SIZE)
+L1_APP_DESCR_ADDR_HEX=$(printf "%08x" $(expr $L1_APP_DESCR_ADDR))
+SERVICE_APP_DESCR_ADDR_HEX=$(printf "%08x" $(expr $SERVICE_APP_DESCR_ADDR))
+DEBUG_CERT_ADDR_HEX=$(printf "%08x" $(expr $DEBUG_CERT_ADDR))
+
+# Write 4 bytes from hex string, LSB first
+printf "\x"${TOC2_SIZE_HEX:6:2} > $TOC2_FILE
+printf "\x"${TOC2_SIZE_HEX:4:2} >> $TOC2_FILE
+printf "\x"${TOC2_SIZE_HEX:2:2} >> $TOC2_FILE
+printf "\x"${TOC2_SIZE_HEX:0:2} >> $TOC2_FILE
+
+printf "\x"${L1_APP_DESCR_ADDR_HEX:6:2} >> $TOC2_FILE
+printf "\x"${L1_APP_DESCR_ADDR_HEX:4:2} >> $TOC2_FILE
+printf "\x"${L1_APP_DESCR_ADDR_HEX:2:2} >> $TOC2_FILE
+printf "\x"${L1_APP_DESCR_ADDR_HEX:0:2} >> $TOC2_FILE
+
+printf "\x"${SERVICE_APP_DESCR_ADDR_HEX:6:2} >> $TOC2_FILE
+printf "\x"${SERVICE_APP_DESCR_ADDR_HEX:4:2} >> $TOC2_FILE
+printf "\x"${SERVICE_APP_DESCR_ADDR_HEX:2:2} >> $TOC2_FILE
+printf "\x"${SERVICE_APP_DESCR_ADDR_HEX:0:2} >> $TOC2_FILE
+
+printf "\x"${DEBUG_CERT_ADDR_HEX:6:2} >> $TOC2_FILE
+printf "\x"${DEBUG_CERT_ADDR_HEX:4:2} >> $TOC2_FILE
+printf "\x"${DEBUG_CERT_ADDR_HEX:2:2} >> $TOC2_FILE
+printf "\x"${DEBUG_CERT_ADDR_HEX:0:2} >> $TOC2_FILE
+
+if [ ! -f "$TOC2_FILE" ]; then
+ echo "Error: $TOC2_FILE does not exist." > /dev/tty
+ exit -1
+fi
+######################### Generate L1_APP_DESCR ################################
+
+# Hardcoded value bytes
+L1_APP_DESCR_SIZE=28
+
+# Placed after the TOC2
+L1_APP_DESCR_ADDR=$(printf "0x%x" `expr $TOC2_SIZE`)
+BOOT_STRAP_DST_ADDR=0x20004000
+# L1_APP_DESCR entries in hexadecimal
+if [ "$LCS" == "NORMAL_NO_SECURE" ]; then
+ BOOT_STRAP_ADDR=0x50 # Fix address for un-signed image
+else
+ BOOT_STRAP_ADDR=0x30 # Fix address for signed image
+fi
+
+if [ "$APP_TYPE" == "l1ram" ]; then
+ BOOT_STRAP_SIZE=`wc -c ${L1_USER_APP_BIN} | awk '{print $1}'`
+ BOOT_STRAP_DST_ADDR_ELF=`${NM_TOOL} ${L1_USER_APP_ELF} | grep "__bootstrap_start_addr__" | awk '{print $1}'`
+ BOOT_STRAP_DST_ADDR=$(printf "%d" $((16#$BOOT_STRAP_DST_ADDR_ELF)))
+
+ if [ ! -f "$L1_USER_APP_BIN" ]; then
+ echo "Error: $L1_USER_APP_BIN does not exist." > /dev/tty
+ exit -1
+ fi
+else
+ BOOT_STRAP_SIZE_ELF=`${NM_TOOL} ${L1_USER_APP_ELF} | grep "__bootstrap_size__" | awk '{print $1}'`
+ BOOT_STRAP_SIZE=$(printf "%d" $((16#$BOOT_STRAP_SIZE_ELF)))
+ BOOT_STRAP_DST_ADDR_ELF=`${NM_TOOL} ${L1_USER_APP_ELF} | grep "__bootstrap_start_addr__" | awk '{print $1}'`
+ BOOT_STRAP_DST_ADDR=$(printf "%d" $((16#$BOOT_STRAP_DST_ADDR_ELF)))
+if [ "$TOOLCHAIN" == "ARM" ]; then
+# Reserving 0x3000 for bootstrap. This needs to be calculated based on the actual size
+ BOOT_STRAP_SIZE=12288
+fi
+fi
+
+# Convert to hex string (without 0x prefix)
+L1_APP_DESCR_SIZE_HEX=$(printf "%08x" $L1_APP_DESCR_SIZE)
+BOOT_STRAP_ADDR_HEX=$(printf "%08x" $BOOT_STRAP_ADDR)
+BOOT_STRAP_DST_ADDR_HEX=$(printf "%08x" $BOOT_STRAP_DST_ADDR)
+BOOT_STRAP_SIZE_HEX=$(printf "%08x" $BOOT_STRAP_SIZE)
+
+if [ $BOOT_STRAP_SIZE_HEX == 00000000 ]; then
+ echo "ERROR: in calculating bootstrap size"
+ exit 1
+fi
+
+# Write 4 bytes from hex string, LSB first
+printf "\x"${L1_APP_DESCR_SIZE_HEX:6:2} > $L1_DESC_TEMP
+printf "\x"${L1_APP_DESCR_SIZE_HEX:4:2} >> $L1_DESC_TEMP
+printf "\x"${L1_APP_DESCR_SIZE_HEX:2:2} >> $L1_DESC_TEMP
+printf "\x"${L1_APP_DESCR_SIZE_HEX:0:2} >> $L1_DESC_TEMP
+
+printf "\x"${BOOT_STRAP_ADDR_HEX:6:2} >> $L1_DESC_TEMP
+printf "\x"${BOOT_STRAP_ADDR_HEX:4:2} >> $L1_DESC_TEMP
+printf "\x"${BOOT_STRAP_ADDR_HEX:2:2} >> $L1_DESC_TEMP
+printf "\x"${BOOT_STRAP_ADDR_HEX:0:2} >> $L1_DESC_TEMP
+
+printf "\x"${BOOT_STRAP_DST_ADDR_HEX:6:2} >> $L1_DESC_TEMP
+printf "\x"${BOOT_STRAP_DST_ADDR_HEX:4:2} >> $L1_DESC_TEMP
+printf "\x"${BOOT_STRAP_DST_ADDR_HEX:2:2} >> $L1_DESC_TEMP
+printf "\x"${BOOT_STRAP_DST_ADDR_HEX:0:2} >> $L1_DESC_TEMP
+
+printf "\x"${BOOT_STRAP_SIZE_HEX:6:2} >> $L1_DESC_TEMP
+printf "\x"${BOOT_STRAP_SIZE_HEX:4:2} >> $L1_DESC_TEMP
+printf "\x"${BOOT_STRAP_SIZE_HEX:2:2} >> $L1_DESC_TEMP
+printf "\x"${BOOT_STRAP_SIZE_HEX:0:2} >> $L1_DESC_TEMP
+
+if [ ! -f "$L1_DESC_TEMP" ]; then
+ echo "Error: $L1_DESC_TEMP does not exist." > /dev/tty
+ exit -1
+fi
+
+if [ "$SMIF_CRYPTO_CFG" == "NONE" ]; then
+ for var in 0 1 2
+ do
+ SMIF_CRYPTO_CFG_HEX=00000000
+ printf "\x"${SMIF_CRYPTO_CFG_HEX:6:2} >> $L1_DESC_TEMP
+ printf "\x"${SMIF_CRYPTO_CFG_HEX:4:2} >> $L1_DESC_TEMP
+ printf "\x"${SMIF_CRYPTO_CFG_HEX:2:2} >> $L1_DESC_TEMP
+ printf "\x"${SMIF_CRYPTO_CFG_HEX:0:2} >> $L1_DESC_TEMP
+ done
+
+ `mv $L1_DESC_TEMP $L1_DESC_FILE`
+
+ if [ ! -f "$L1_DESC_FILE" ]; then
+ echo "Error: $L1_DESC_FILE does not exist." > /dev/tty
+ exit -1
+ fi
+else
+ if [ ! -f "$L1_DESC_TEMP.bin" ]; then
+ echo "Error: $L1_DESC_TEMP.bin does not exist." > /dev/tty
+ exit -1
+ fi
+ if [ ! -f "$SMIF_CRYPTO_CFG.bin" ]; then
+ echo "Error: $SMIF_CRYPTO_CFG.bin does not exist." > /dev/tty
+ exit -1
+ fi
+
+ `cat $L1_DESC_TEMP $SMIF_CRYPTO_CFG.bin > $L1_DESC_FILE
+ rm -f $L1_DESC_TEMP`
+
+ if [ ! -f "$L1_DESC_FILE" ]; then
+ echo "Error: $L1_DESC_FILE does not exist." > /dev/tty
+ exit -1
+ fi
+ if [ -f "$L1_DESC_TEMP" ]; then
+ echo "Error: $L1_DESC_TEMP has not been removed." > /dev/tty
+ exit -1
+ fi
+fi
+
+if [ ! -f "$TOC2_FILE" ]; then
+ echo "Error: $TOC2_FILE does not exist." > /dev/tty
+ exit -1
+fi
+if [ ! -f "$L1_DESC_FILE" ]; then
+ echo "Error: $L1_DESC_FILE does not exist." > /dev/tty
+ exit -1
+fi
+
+# 4 bytes of padding (encrypted data should be aligned to 0x10 boundary)
+echo -en "\0\0\0\0" >> $L1_DESC_FILE
+
+if [ "$LCS" == "NORMAL_NO_SECURE" ]; then
+
+ number=0
+
+ L1_USER_APP_HEADER_HEX=00000000
+ # create 32 byte null header for bootstrap
+ printf "\x"${L1_USER_APP_HEADER_HEX:6:2} > $L1_USER_APP_HEADER_FILE
+ printf "\x"${L1_USER_APP_HEADER_HEX:4:2} >> $L1_USER_APP_HEADER_FILE
+ printf "\x"${L1_USER_APP_HEADER_HEX:2:2} >> $L1_USER_APP_HEADER_FILE
+ printf "\x"${L1_USER_APP_HEADER_HEX:0:2} >> $L1_USER_APP_HEADER_FILE
+
+ if [ ! -f "$L1_USER_APP_HEADER_FILE" ]; then
+ echo "Error: $L1_USER_APP_HEADER_FILE does not exist." > /dev/tty
+ exit -1
+ fi
+
+ while [ $number -lt 7 ]
+ do
+ printf "\x"${L1_USER_APP_HEADER_HEX:6:2} >> $L1_USER_APP_HEADER_FILE
+ printf "\x"${L1_USER_APP_HEADER_HEX:4:2} >> $L1_USER_APP_HEADER_FILE
+ printf "\x"${L1_USER_APP_HEADER_HEX:2:2} >> $L1_USER_APP_HEADER_FILE
+ printf "\x"${L1_USER_APP_HEADER_HEX:0:2} >> $L1_USER_APP_HEADER_FILE
+
+ number=`expr $number + 1`
+ done
+
+ if [ ! -f "$L1_USER_APP_HEADER_FILE" ]; then
+ echo "Error: $L1_USER_APP_HEADER_FILE does not exist." > /dev/tty
+ exit -1
+ fi
+ if [ ! -f "$L1_USER_APP_BIN" ]; then
+ echo "Error: $L1_USER_APP_BIN does not exist." > /dev/tty
+ exit -1
+ fi
+
+ # Combining all images (toc2+l1_app_desc+l1_user_app_header+l1_user_app) to Final binary file
+ `cat $TOC2_FILE $L1_DESC_FILE $L1_USER_APP_HEADER_FILE $L1_USER_APP_BIN > $FINAL_BIN_FILE`
+elif [ "$LCS" == "SECURE" ]; then
+ if [ ! -f "$L1_USER_APP_BIN" ]; then
+ echo "Error: $L1_USER_APP_BIN does not exist." > /dev/tty
+ exit -1
+ fi
+
+ # Sign l1 user app L1_USER_APP_BIN_SIGN
+ cysecuretools -q -t cyw20829 -p $POLICY_PATH sign-image --image-format bootrom_next_app -i $L1_USER_APP_BIN -k 0 -o $L1_USER_APP_BIN_SIGN --slot-size $SLOT_SIZE --app-addr 0x08000030 $ENC_OPTION
+
+ if [ ! -f "$L1_USER_APP_BIN_SIGN" ]; then
+ echo "Error: $L1_USER_APP_BIN_SIGN has not been created." > /dev/tty
+ exit -1
+ fi
+
+ # Combining all images (toc2+l1_app_desc+l1_user_app) to Final binary file of MCUBootApp
+ if [ -z $ENC_OPTION ]; then
+ cat $TOC2_FILE $L1_DESC_FILE $L1_USER_APP_BIN_SIGN > $FINAL_BIN_FILE
+ else
+ # Patching L1 app descriptor with AES-CTR Nonce
+ dd seek=16 bs=1 count=12 conv=notrunc if=$AES_CTR_NONCE_FILE of=$L1_DESC_FILE >& /dev/null && \
+ cat $TOC2_FILE $L1_DESC_FILE ${ENCRYPTED_MCUBOOT_BIN_FILE} > $FINAL_BIN_FILE
+ fi
+else
+ echo "ERROR: Invalid LCS ($LCS) value"
+ exit 1
+fi
+
+if [ ! -f "$FINAL_BIN_FILE" ]; then
+ echo "Error: $FINAL_BIN_FILE does not exist." > /dev/tty
+ exit -1
+fi
diff --git a/boot/cypress/scripts/bin2c.py b/boot/cypress/scripts/bin2c.py
new file mode 100644
index 0000000..04bc67a
--- /dev/null
+++ b/boot/cypress/scripts/bin2c.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import argparse
+import binascii
+
+number_of_columns = 16
+
+copyright = """/***************************************************************************//**
+* \\file {}
+*
+* \\brief
+* Cortex-M0+ prebuilt application image.
+*
+********************************************************************************
+* \\copyright
+* Copyright (c) 2018-2019 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: LicenseRef-PBL
+*
+* Licensed under the Permissive Binary License
+*******************************************************************************/
+
+"""
+
+header = """
+#if defined(__APPLE__) && defined(__clang__)
+__attribute__ ((__section__("__CY_M0P_IMAGE,__cy_m0p_image"), used))
+#elif defined(__GNUC__) || defined(__ARMCC_VERSION)
+__attribute__ ((__section__(".cy_m0p_image"), used))
+#elif defined(__ICCARM__)
+#pragma location=".cy_m0p_image"
+#else
+#error "An unsupported toolchain"
+#endif
+const uint8_t cy_m0p_image[] = {
+"""
+
+c_list = []
+
+
+# Get component name from the command line
+parser = argparse.ArgumentParser()
+parser.add_argument("bin_path", help="Specify path the input binary file to be converted to a C array.")
+parser.add_argument("c_path", help="Specify path the output C file with the C array.")
+parser.add_argument("c_macro", help="Specify the C preprocessor macro to wrap the variable.")
+args = parser.parse_args()
+bin_path = args.bin_path
+c_path = args.c_path
+c_macro = args.c_macro
+
+c_file=os.path.basename(c_path)
+
+f = open(bin_path, "rb")
+data = list(f.read())
+
+with open(c_path, "w") as c_fd:
+
+ # Clear content of the file
+ c_fd.seek(0)
+ c_fd.truncate()
+
+ # Write copyright
+ c_fd.write(copyright.format(c_file))
+
+ # Include headers
+ c_fd.write("#include <stdint.h>\n")
+ c_fd.write("#include \"cy_device_headers.h\"\n")
+ c_fd.write("\n")
+
+ # Open conditional block
+ if c_macro:
+ c_fd.write("#if defined(" + c_macro + ")\n")
+
+ # Write template
+ c_fd.write(header)
+
+ # Generate list of the data bytes
+ for n in data:
+ c_list.append(format(n, '#04x'))
+
+ for i in range(int(len(c_list) / number_of_columns) + 1):
+ line_list = c_list[i * number_of_columns: (i + 1) * number_of_columns]
+ c_fd.write(" ")
+ for item in line_list:
+ c_fd.write(" %su," % item)
+ c_fd.write("\n")
+
+ c_fd.write("};\n")
+
+ # Close conditional block
+ if c_macro:
+ c_fd.write("#endif /* defined(" + c_macro + ") */")
+ c_fd.write("\n")
+f.close()
diff --git a/boot/cypress/scripts/cppcheck.sh b/boot/cypress/scripts/cppcheck.sh
new file mode 100644
index 0000000..862b926
--- /dev/null
+++ b/boot/cypress/scripts/cppcheck.sh
@@ -0,0 +1,145 @@
+#!/bin/bash
+#
+# this must be the first non-commented line in this script. It ensures
+# bash doesn't choke on \r on Windows
+(set -o igncr) 2>/dev/null && set -o igncr; # this comment is needed
+
+#
+# This script does static code analysis using Cppcheck tool
+# Copyright (c) 2019 Cypress Semiconductor.
+#
+
+# It performs Cppcheck code analysis with following inputs
+# 1. CypressBootloader/sources - Code analysis is done on all the sources of CypressBootloader.
+# 2. Additional source files to be analyzed are grabbed from config file that is provided as a first argument to the script.
+# 3. Files to be ignored are grabbed from config file that is provided as a first argument to the script.
+# 4. To ignore a file its name need to be added to the config file with word "ignore" as perfix
+# 5. To add any additional files, apart the files from CypressBootloader/sources, those names need
+# to be added in a config file.
+# Example
+# A). add below entries in cpp_check.dat file
+# ignore cy_bootloader_hw.c
+# file1.c
+# file2.c
+# ignore cy_bootloader_services.c
+# B). invoke cpp_check shell script
+# cpp_check.sh cpp_check.dat
+#
+# Above example performs Cppcheck analysis on CypressBootloader/sources, ignore cy_bootloader_hw.c, file1.c, file2.c and ignores cy_bootloader_services.c
+
+
+app_name="$1"
+platform="$2"
+app_defines="$3"
+app_includes="$4"
+CPP_CHECK_FILES="$5"
+scope="$6"
+buildcfg="$7"
+
+if [[ ${scope} != "" ]]; then
+ SCOPE="--enable=${scope}"
+else
+ SCOPE=""
+fi
+
+#Retrieve list of files need to be ignored
+while IFS= read -r line
+do
+ CPP_CHECK_IGNORE_FILES="$CPP_CHECK_IGNORE_FILES -i $line"
+done < "${app_name}/cppcheck/ignore_files.list"
+
+#Retrieve list of cppcheck directives
+while IFS= read -r line
+do
+ CPP_CHECK_SUPPRESS="$CPP_CHECK_SUPPRESS --suppress=$line"
+done < "${app_name}/cppcheck/suppress_types.list"
+
+echo "-------------------------------------------"
+echo "Suppress options:" "$CPP_CHECK_SUPPRESS"
+echo "-------------------------------------------"
+echo "Additional files:" "$CPP_CHECK_FILES"
+echo "-------------------------------------------"
+echo "Ignoring files:" "$CPP_CHECK_IGNORE_FILES"
+echo "-------------------------------------------"
+echo "CppCheck scope of messages defined with option " ${SCOPE}
+echo "-------------------------------------------"
+echo "Run CppCheck for platform" ${platform}
+echo "-------------------------------------------"
+echo "Defines passed to CppCheck:"
+echo ${app_defines}
+echo "-------------------------------------------"
+echo "Include dirs passed to CppCheck:"
+echo ${app_includes}
+echo "-------------------------------------------"
+
+mkdir -p ${app_name}/cppcheck/results/${platform}/${buildcfg}/cppcheck_report_html
+
+dos2unix ${app_name}/cppcheck/suppress_messages.list
+
+#Generate xml file
+cppcheck ${SCOPE} ${CPP_CHECK_SUPPRESS} -D__GNUC__ -D${platform} ${app_defines} ${app_includes} ${CPP_CHECK_FILES} ${CPP_CHECK_IGNORE_FILES} \
+ --xml 2> ${app_name}/cppcheck/results/${platform}/${buildcfg}/cppcheck_report_${scope}.xml
+
+#Generate html file
+python scripts/cppcheck-htmlreport.py --file=${app_name}/cppcheck/results/${platform}/${buildcfg}/cppcheck_report_${scope}.xml --report-dir=${app_name}/cppcheck/results/${platform}/${buildcfg}/cppcheck_report_html --title=${app_name}
+
+cppcheck ${SCOPE} ${CPP_CHECK_SUPPRESS} -D__GNUC__ -D${platform} ${app_defines} ${app_includes} ${CPP_CHECK_FILES} ${CPP_CHECK_IGNORE_FILES} \
+ --template="{severity}\n{id}\n{message}\n{file}\n{line}:{column}\n{code}\n" 2> ${app_name}/cppcheck/results/${platform}/${buildcfg}/cppcheck_report_${scope}.full
+
+#Generate csv file
+echo "severity@id@message@file@line" > ${app_name}/cppcheck/results/${platform}/${buildcfg}/cppcheck_report_${scope}.csv
+while IFS= read -r line
+do
+ read -r line2
+ read -r line3
+ read -r line4
+ read -r line5
+ line4=$(echo $line4 | sed 's/.*\\cy_mcuboot\\//' | tr '\\' '/')
+ if grep -xq "${line}@${line2}@${line3}@${line4}@${line5}" ${app_name}/cppcheck/suppress_messages.list
+ then
+ :;#suppress current warning
+ else
+ echo ${line}@${line2}@${line3}@${line4}@${line5}
+ fi
+ read -r line
+ read -r line
+ read -r line
+done \
+< ${app_name}/cppcheck/results/${platform}/${buildcfg}/cppcheck_report_${scope}.full \
+>>${app_name}/cppcheck/results/${platform}/${buildcfg}/cppcheck_report_${scope}.csv
+
+#Generate log file
+while IFS= read -r line
+do
+ read -r line2
+ read -r line3
+ read -r line4
+ read -r line5
+ line4=$(echo $line4 | sed 's/.*\\cy_mcuboot\\//' | tr '\\' '/')
+ if grep -xq "${line}@${line2}@${line3}@${line4}@${line5}" ${app_name}/cppcheck/suppress_messages.list
+ then
+ read -r line
+ read -r line
+ read -r line
+ else
+ echo ${line} : ${line2}
+ echo ${line3}
+ echo "${line4} (${line5})"
+ read -r line
+ echo ${line}
+ read -r line
+ echo ${line}
+ read -r line
+ echo "-------------------------------------------"
+ fi
+done \
+< ${app_name}/cppcheck/results/${platform}/${buildcfg}/cppcheck_report_${scope}.full \
+> ${app_name}/cppcheck/results/${platform}/${buildcfg}/cppcheck_report_${scope}.log
+
+rm ${app_name}/cppcheck/results/${platform}/${buildcfg}/cppcheck_report_${scope}.full
+cat ${app_name}/cppcheck/results/${platform}/${buildcfg}/cppcheck_report_${scope}.log
+
+RC=$(( $(wc -l ${app_name}/cppcheck/results/${platform}/${buildcfg}/cppcheck_report_${scope}.csv | cut -d' ' -f1) -1 ))
+echo "${app_name} CPPCHECK FOR ${platform} KIT FOUND $RC ERRORS"
+
+exit $RC
\ No newline at end of file
diff --git a/boot/cypress/scripts/find_cysectools.py b/boot/cypress/scripts/find_cysectools.py
new file mode 100644
index 0000000..7bea0fc
--- /dev/null
+++ b/boot/cypress/scripts/find_cysectools.py
@@ -0,0 +1,58 @@
+"""
+Copyright (c) 2019 Cypress Semiconductor Corporation
+
+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.
+"""
+
+import subprocess
+import sys
+
+package = 'cysecuretools'
+
+def find_cysectools(package_name):
+
+ """
+ Check if package exist in system and return its location if it does
+ """
+
+ pip_show = subprocess.Popen([sys.executable, '-m', 'pip', 'show', package],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ stdout = pip_show.communicate()[0]
+ rc = pip_show.wait()
+
+ if (rc != 0):
+ print("No package with name " + package + " found")
+ exit(1)
+ else:
+ pip_show_info = stdout.decode("utf-8").splitlines()
+
+ for line in pip_show_info:
+ if 'Location:' in line:
+ location = line.replace('Location: ', '')
+
+ if sys.platform == 'win32':
+ return location.replace('\\','/')
+ else:
+ return location
+
+def main():
+ """
+ Call function and print output
+ """
+ cysecuretools_path = find_cysectools(package)
+
+ print(cysecuretools_path)
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/boot/cypress/scripts/flashmap.py b/boot/cypress/scripts/flashmap.py
new file mode 100644
index 0000000..339e4c5
--- /dev/null
+++ b/boot/cypress/scripts/flashmap.py
@@ -0,0 +1,710 @@
+"""MCUBoot Flash Map Converter (JSON to .h)
+Copyright (c) 2022 Infineon Technologies AG
+"""
+
+import sys
+import getopt
+import json
+
+# Supported Platforms
+platDict = {
+ 'PSOC_062_2M': {
+ 'flashAddr': 0x10000000,
+ 'flashSize': 0x200000, # 2 MBytes
+ 'eraseSize': 0x200, # 512 bytes
+ 'smifAddr': 0x18000000,
+ 'smifSize': 0x8000000 # i.e., window size
+ },
+ 'PSOC_062_1M': {
+ 'flashAddr': 0x10000000,
+ 'flashSize': 0x100000, # 1 MByte
+ 'eraseSize': 0x200, # 512 bytes
+ 'smifAddr': 0x18000000,
+ 'smifSize': 0x8000000 # i.e., window size
+ },
+ 'PSOC_062_512K': {
+ 'flashAddr': 0x10000000,
+ 'flashSize': 0x80000, # 512 KBytes
+ 'eraseSize': 0x200, # 512 bytes
+ 'smifAddr': 0x18000000,
+ 'smifSize': 0x8000000 # i.e., window size
+ },
+ 'CYW20829': {
+ 'flashSize': 0, # n/a
+ 'smifAddr': 0x60000000,
+ 'smifSize': 0x8000000 # i.e., window size
+ }
+}
+
+# Supported SPI Flash ICs
+flashDict = {
+ # Fudan
+ 'FM25Q04': {
+ 'flashSize': 0x80000, # 4 Mbits
+ 'eraseSize': 0x1000, # 128 uniform sectors with 4K-byte each
+ },
+ 'FM25W04': {
+ 'flashSize': 0x80000, # 4 Mbits
+ 'eraseSize': 0x1000, # 128 uniform sectors with 4K-byte each
+ },
+ 'FM25Q08': {
+ 'flashSize': 0x100000, # 8 Mbits
+ 'eraseSize': 0x1000, # 256 uniform sectors with 4K-byte each
+ },
+ 'FM25W08': {
+ 'flashSize': 0x100000, # 8 Mbits
+ 'eraseSize': 0x1000, # 256 uniform sectors with 4K-byte each
+ },
+ # Puya
+ 'P25Q05H': {
+ 'flashSize': 0x10000, # 512 Kbits
+ 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase
+ },
+ 'P25Q10H': {
+ 'flashSize': 0x20000, # 1 Mbit
+ 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase
+ },
+ 'P25Q20H': {
+ 'flashSize': 0x40000, # 2 Mbits
+ 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase
+ },
+ 'P25Q40H': {
+ 'flashSize': 0x80000, # 4 Mbits
+ 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase
+ },
+ # Infineon
+ 'S25HS256T': {
+ 'flashSize': 0x2000000, # 256 Mbits
+ 'eraseSize': 0x40000, # Uniform Sector Architecture
+ },
+ 'S25HS512T': {
+ 'flashSize': 0x4000000, # 512 Mbits
+ 'eraseSize': 0x40000, # Uniform Sector Architecture
+ },
+ 'S25HS01GT': {
+ 'flashSize': 0x8000000, # 1 Gbit
+ 'eraseSize': 0x40000, # Uniform Sector Architecture
+ }
+}
+
+
+def is_overlap(fa1off, fa1size, fa2off, fa2size, align):
+ """Check if two flash areas on the same device overlap"""
+ mask = align - 1
+ assert align > 0 and (align & mask) == 0 # ensure align is a power of 2
+ fa1end = (fa1off + fa1size + mask) & ~mask
+ fa2end = (fa2off + fa2size + mask) & ~mask
+ fa1off = fa1off & ~mask
+ fa2off = fa2off & ~mask
+ return fa1off < fa2end and fa2off < fa1end
+
+
+def is_same_mem(fa1addr, fa2addr):
+ """Check if two addresses belong to the same memory"""
+ if fa1addr is None or fa2addr is None:
+ return False
+ mask = 0xFF000000
+ return (fa1addr & mask) == (fa2addr & mask)
+
+
+class CmdLineParams:
+ """Command line parameters"""
+
+ def __init__(self):
+ self.plat_id = ''
+ self.in_file = ''
+ self.out_file = ''
+ self.img_id = None
+
+ usage = 'USAGE:\n' + sys.argv[0] + \
+ ''' -p <platform> -i <flash_map.json> -o <flash_map.h> -d <img_id>
+
+OPTIONS:
+-h --help Display the usage information
+-p --platform= Target (e.g., PSOC_062_512K)
+-i --ifile= JSON flash map file
+-o --ofile= C header file to be generated
+-d --img_id ID of application to build'''
+
+ try:
+ opts, unused = getopt.getopt(
+ sys.argv[1:], 'hi:o:p:d:',
+ ['help', 'platform=', 'ifile=', 'ofile=', 'img_id='])
+ if len(unused) > 0:
+ print(usage, file=sys.stderr)
+ sys.exit(1)
+ except getopt.GetoptError:
+ print(usage, file=sys.stderr)
+ sys.exit(1)
+
+ for opt, arg in opts:
+ if opt in ('-h', '--help'):
+ print(usage, file=sys.stderr)
+ sys.exit()
+ elif opt in ('-p', '--platform'):
+ self.plat_id = arg
+ elif opt in ('-i', '--ifile'):
+ self.in_file = arg
+ elif opt in ('-o', '--ofile'):
+ self.out_file = arg
+ elif opt in ('-d', '--img_id'):
+ self.img_id = arg
+
+ if len(self.in_file) == 0 or len(self.out_file) == 0:
+ print(usage, file=sys.stderr)
+ sys.exit(1)
+
+
+class AreaList:
+ """List of flash areas"""
+
+ def __init__(self, plat, flash, use_overwrite):
+ self.plat = plat
+ self.flash = flash
+ self.use_overwrite = use_overwrite
+ self.areas = []
+ self.peers = {}
+ self.trailers = {}
+ self.internal_flash = False
+ self.external_flash = False
+ self.external_flash_xip = False
+
+ def get_min_erase_size(self):
+ """Calculate minimum erase block size for int./ext. Flash """
+ return self.plat['eraseSize'] if self.plat['flashSize'] > 0 \
+ else self.flash['eraseSize']
+
+ def get_img_trailer_size(self):
+ """Calculate image trailer size"""
+ return self.get_min_erase_size()
+
+ def process_int_area(self, title, fa_addr, fa_size,
+ img_trailer_size, shared_slot):
+ """Process internal flash area"""
+ fa_device_id = 'FLASH_DEVICE_INTERNAL_FLASH'
+ fa_off = fa_addr - self.plat['flashAddr']
+ if img_trailer_size is not None:
+ if self.use_overwrite:
+ if shared_slot:
+ print('Shared slot', title,
+ 'is not supported in OVERWRITE mode',
+ file=sys.stderr)
+ sys.exit(7)
+ else:
+ # Check trailer alignment (start at the sector boundary)
+ align = (fa_off + fa_size - img_trailer_size) % \
+ self.plat['eraseSize']
+ if align != 0:
+ fa_addr += self.plat['eraseSize'] - align
+ if fa_addr + fa_size <= \
+ self.plat['flashAddr'] + self.plat['flashSize']:
+ print('Misaligned', title,
+ '- suggested address', hex(fa_addr),
+ file=sys.stderr)
+ else:
+ print('Misaligned', title, file=sys.stderr)
+ sys.exit(7)
+ else:
+ # Check alignment (flash area should start at the sector boundary)
+ if fa_off % self.plat['eraseSize'] != 0:
+ print('Misaligned', title, file=sys.stderr)
+ sys.exit(7)
+ slot_sectors = int((fa_off % self.plat['eraseSize'] +
+ fa_size + self.plat['eraseSize'] - 1) //
+ self.plat['eraseSize'])
+ return fa_device_id, fa_off, slot_sectors
+
+ def process_ext_area(self, title, fa_addr, fa_size,
+ img_trailer_size, shared_slot):
+ """Process external flash area"""
+ if self.flash is None:
+ print('Unspecified SPI Flash IC',
+ file=sys.stderr)
+ sys.exit(3)
+ if fa_addr + fa_size <= \
+ self.plat['smifAddr'] + self.flash['flashSize']:
+ flash_idx = 'CY_BOOT_EXTERNAL_DEVICE_INDEX'
+ fa_device_id = f'FLASH_DEVICE_EXTERNAL_FLASH({flash_idx})'
+ fa_off = fa_addr - self.plat['smifAddr']
+ else:
+ print('Misfitting', title, file=sys.stderr)
+ sys.exit(7)
+ if img_trailer_size is not None:
+ if self.use_overwrite:
+ if shared_slot:
+ print('Shared slot', title,
+ 'is not supported in OVERWRITE mode',
+ file=sys.stderr)
+ sys.exit(7)
+ else:
+ # Check trailer alignment (start at the sector boundary)
+ align = (fa_off + fa_size - img_trailer_size) % \
+ self.flash['eraseSize']
+ if align != 0:
+ peer_addr = self.peers.get(fa_addr)
+ if shared_slot:
+ # Special case when using both int. and ext. memory
+ if self.plat['flashSize'] > 0 and \
+ align % self.plat['eraseSize'] == 0:
+ print('Note:', title, 'requires', align,
+ 'padding bytes before trailer',
+ file=sys.stderr)
+ else:
+ print('Misaligned', title, file=sys.stderr)
+ sys.exit(7)
+ elif is_same_mem(fa_addr, peer_addr) and \
+ fa_addr % self.flash['eraseSize'] == \
+ peer_addr % self.flash['eraseSize']:
+ pass # postpone checking
+ else:
+ fa_addr += self.flash['eraseSize'] - align
+ if fa_addr + fa_size <= \
+ self.plat['smifAddr'] + self.flash['flashSize']:
+ print('Misaligned', title,
+ '- suggested address', hex(fa_addr),
+ file=sys.stderr)
+ else:
+ print('Misaligned', title, file=sys.stderr)
+ sys.exit(7)
+ else:
+ # Check alignment (flash area should start at the sector boundary)
+ if fa_off % self.flash['eraseSize'] != 0:
+ print('Misaligned', title, file=sys.stderr)
+ sys.exit(7)
+ slot_sectors = int((fa_off % self.flash['eraseSize'] +
+ fa_size + self.flash['eraseSize'] - 1) //
+ self.flash['eraseSize'])
+ self.external_flash = True
+ if self.flash['XIP']:
+ self.external_flash_xip = True
+ return fa_device_id, fa_off, slot_sectors
+
+ def chk_area(self, fa_addr, fa_size, peer_addr=None):
+ """Check area location (internal/external flash)"""
+ if peer_addr is not None:
+ self.peers[peer_addr] = fa_addr
+ fa_limit = fa_addr + fa_size
+ if self.plat['flashSize'] and \
+ fa_addr >= self.plat['flashAddr'] and \
+ fa_limit <= self.plat['flashAddr'] + self.plat['flashSize']:
+ # Internal flash
+ self.internal_flash = True
+
+ def add_area(self, title,
+ fa_id, fa_addr, fa_size,
+ img_trailer_size=None, shared_slot=False):
+ """Add flash area to AreaList.
+ Internal/external flash is detected by address.
+ Returns number of sectors in a slot"""
+ if fa_size == 0:
+ print('Empty', title, file=sys.stderr)
+ sys.exit(7)
+
+ fa_limit = fa_addr + fa_size
+ if self.plat['flashSize'] and \
+ fa_addr >= self.plat['flashAddr'] and \
+ fa_limit <= self.plat['flashAddr'] + self.plat['flashSize']:
+ # Internal flash
+ fa_device_id, fa_off, slot_sectors = self.process_int_area(
+ title, fa_addr, fa_size, img_trailer_size, shared_slot)
+ align = self.plat['eraseSize']
+ elif self.plat['smifSize'] and \
+ fa_addr >= self.plat['smifAddr'] and \
+ fa_limit <= self.plat['smifAddr'] + self.plat['smifSize']:
+ # External flash
+ fa_device_id, fa_off, slot_sectors = self.process_ext_area(
+ title, fa_addr, fa_size, img_trailer_size, shared_slot)
+ align = self.flash['eraseSize']
+ else:
+ print('Invalid', title, file=sys.stderr)
+ sys.exit(7)
+
+ if shared_slot:
+ assert img_trailer_size is not None
+ tr_addr = fa_addr + fa_size - img_trailer_size
+ tr_name = self.trailers.get(tr_addr)
+ if tr_name is not None:
+ print('Same trailer address for', title, 'and', tr_name,
+ file=sys.stderr)
+ sys.exit(7)
+ self.trailers[tr_addr] = title
+
+ # Ensure no flash areas on this device will overlap, except the
+ # shared slot
+ for area in self.areas:
+ if fa_device_id == area['fa_device_id']:
+ over = is_overlap(fa_off, fa_size,
+ area['fa_off'], area['fa_size'],
+ align)
+ if shared_slot and area['shared_slot']:
+ if not over: # images in shared slot should overlap
+ print(title, 'is not shared with', area['title'],
+ file=sys.stderr)
+ sys.exit(7)
+ elif over:
+ print(title, 'overlaps with', area['title'],
+ file=sys.stderr)
+ sys.exit(7)
+
+ self.areas.append({'title': title,
+ 'shared_slot': shared_slot,
+ 'fa_id': fa_id,
+ 'fa_device_id': fa_device_id,
+ 'fa_off': fa_off,
+ 'fa_size': fa_size})
+ return slot_sectors
+
+ def generate_c_source(self, params):
+ """Generate C source"""
+ c_array = 'flash_areas'
+
+ try:
+ with open(params.out_file, "w", encoding='UTF-8') as out_f:
+ out_f.write('/* AUTO-GENERATED FILE, DO NOT EDIT.'
+ ' ALL CHANGES WILL BE LOST! */\n')
+ out_f.write(f'/* Platform: {params.plat_id} */\n')
+ out_f.write(f'\nstatic struct flash_area {c_array}[] = {{\n')
+ comma = len(self.areas)
+ area_count = 0
+ for area in self.areas:
+ comma -= 1
+ if area['fa_id'] is not None:
+ sss = ' /* Shared secondary slot */' \
+ if area['shared_slot'] else ''
+ out_f.writelines('\n'.join([
+ ' {' + sss,
+ f" .fa_id = {area['fa_id']},",
+ f" .fa_device_id = {area['fa_device_id']},",
+ f" .fa_off = {hex(area['fa_off'])}U,",
+ f" .fa_size = {hex(area['fa_size'])}U",
+ ' },' if comma else ' }', '']))
+ area_count += 1
+ out_f.write('};\n\n'
+ 'struct flash_area *boot_area_descs[] = {\n')
+ for area_index in range(area_count):
+ out_f.write(f' &{c_array}[{area_index}U],\n')
+ out_f.write(' NULL\n};\n')
+ except (FileNotFoundError, OSError):
+ print('Cannot create', params.out_file, file=sys.stderr)
+ sys.exit(4)
+
+
+def cvt_dec_or_hex(val, desc):
+ """Convert (hexa)decimal string to number"""
+ try:
+ return int(val, 0)
+ except ValueError:
+ print('Invalid value', val, 'for', desc, file=sys.stderr)
+ sys.exit(6)
+
+
+def get_val(obj, attr):
+ """Get JSON 'value'"""
+ obj = obj[attr]
+ try:
+ return cvt_dec_or_hex(obj['value'], obj['description'])
+ except KeyError as key:
+ print('Malformed JSON:', key,
+ 'is missing in', "'" + attr + "'",
+ file=sys.stderr)
+ sys.exit(5)
+
+
+def get_bool(obj, attr, def_val=False):
+ """Get JSON boolean value (returns def_val if it missing)"""
+ ret_val = def_val
+ obj = obj.get(attr)
+ if obj is not None:
+ try:
+ val = str(obj['value']).lower()
+ desc = obj['description']
+ if val == 'true':
+ ret_val = True
+ elif val == 'false':
+ ret_val = False
+ else:
+ print('Invalid value', val, 'for', desc, file=sys.stderr)
+ sys.exit(6)
+ except KeyError as key:
+ print('Malformed JSON:', key,
+ 'is missing in', "'" + attr + "'",
+ file=sys.stderr)
+ sys.exit(5)
+ return ret_val
+
+
+class AddrSize:
+ """Bootloader area"""
+
+ def __init__(self, bootloader, addr_name, size_name):
+ self.fa_addr = get_val(bootloader, addr_name)
+ self.fa_size = get_val(bootloader, size_name)
+
+
+def calc_status_size(boot_swap_status_row_sz, max_img_sectors,
+ img_number, scratch_flag=True):
+ """Estimate status size, see swap_status.h"""
+ boot_swap_status_cnt_sz = 4
+ boot_swap_status_crc_sz = 4
+ boot_swap_status_mgcrec_sz = 4
+ boot_swap_status_trailer_size = 64
+ boot_swap_status_payld_sz = \
+ boot_swap_status_row_sz - boot_swap_status_mgcrec_sz - \
+ boot_swap_status_cnt_sz - boot_swap_status_crc_sz
+ boot_swap_status_sect_rows_num = \
+ int((max_img_sectors - 1) //
+ boot_swap_status_payld_sz) + 1
+ boot_swap_status_trail_rows_num = \
+ int((boot_swap_status_trailer_size - 1) //
+ boot_swap_status_payld_sz) + 1
+ boot_swap_status_d_size = \
+ boot_swap_status_row_sz * \
+ (boot_swap_status_sect_rows_num + boot_swap_status_trail_rows_num)
+ boot_swap_status_mult = 2
+ boot_swap_status_size = boot_swap_status_mult * boot_swap_status_d_size
+ status_zone_cnt = 2 * img_number
+ if scratch_flag:
+ status_zone_cnt += 1
+ return boot_swap_status_size * status_zone_cnt
+
+
+def process_json(in_file):
+ """Process JSON"""
+ try:
+ with open(in_file, encoding='UTF-8') as in_f:
+ try:
+ flash_map = json.load(in_f)
+ except ValueError:
+ print('Cannot parse', in_file, file=sys.stderr)
+ sys.exit(4)
+ except (FileNotFoundError, OSError):
+ print('Cannot open', in_file, file=sys.stderr)
+ sys.exit(4)
+ flash = flash_map.get('external_flash')
+ if flash is not None:
+ flash = flash[0]
+ model = flash.get('model')
+ mode = flash.get('mode')
+ if model is not None:
+ try:
+ flash = flashDict[model]
+ except KeyError:
+ print('Supported SPI Flash ICs are:',
+ ', '.join(flashDict.keys()),
+ file=sys.stderr)
+ sys.exit(3)
+ else:
+ try:
+ flash = {'flashSize': cvt_dec_or_hex(flash['flash-size'],
+ 'flash-size'),
+ 'eraseSize': cvt_dec_or_hex(flash['erase-size'],
+ 'erase-size')}
+ except KeyError as key:
+ print('Malformed JSON:', key,
+ "is missing in 'external_flash'",
+ file=sys.stderr)
+ sys.exit(3)
+ flash.update({'XIP': str(mode).upper() == 'XIP'})
+ return flash_map['boot_and_upgrade'], flash
+
+
+def process_images(area_list, boot_and_upgrade):
+ """Process images"""
+ app_count = 0
+ slot_sectors_max = 0
+ all_shared = get_bool(boot_and_upgrade['bootloader'], 'shared_slot')
+ any_shared = all_shared
+
+ apps_flash_map = [None, ]
+
+ for stage in range(2):
+ for app_index in range(1, 5):
+
+ app_flash_map = {}
+
+ try:
+ app_ident = f'application_{app_index}'
+ application = boot_and_upgrade[app_ident]
+ try:
+ primary_addr = get_val(application, 'address')
+ primary_size = get_val(application, 'size')
+ secondary_addr = get_val(application, 'upgrade_address')
+ secondary_size = get_val(application, 'upgrade_size')
+ except KeyError as key:
+ print('Malformed JSON:', key, 'is missing',
+ file=sys.stderr)
+ sys.exit(5)
+ if stage == 0:
+ if primary_size != secondary_size:
+ print('Primary and secondary slot sizes'
+ ' are different for', app_ident,
+ file=sys.stderr)
+ sys.exit(6)
+ area_list.chk_area(primary_addr, primary_size)
+ area_list.chk_area(secondary_addr, secondary_size,
+ primary_addr)
+ else:
+ slot_sectors_max = max(
+ slot_sectors_max,
+ area_list.add_area(
+ f'{app_ident} (primary slot)',
+ f'FLASH_AREA_IMG_{app_index}_PRIMARY',
+ primary_addr, primary_size,
+ area_list.get_img_trailer_size()))
+ shared_slot = get_bool(application, 'shared_slot', all_shared)
+ any_shared = any_shared or shared_slot
+ slot_sectors_max = max(
+ slot_sectors_max,
+ area_list.add_area(
+ f'{app_ident} (secondary slot)',
+ f'FLASH_AREA_IMG_{app_index}_SECONDARY',
+ secondary_addr, secondary_size,
+ area_list.get_img_trailer_size(),
+ shared_slot))
+
+ app_slot_prim = {"address": hex(primary_addr), "size": hex(primary_size)}
+ app_slot_sec = {"address": hex(secondary_addr), "size": hex(secondary_size)}
+
+ app_flash_map.update({"primary": app_slot_prim, "secondary": app_slot_sec})
+ apps_flash_map.append(app_flash_map)
+
+ app_count = app_index
+
+ except KeyError:
+ break
+ if app_count == 0:
+ print('Malformed JSON: no application(s) found',
+ file=sys.stderr)
+ sys.exit(5)
+
+ return app_count, slot_sectors_max, apps_flash_map, any_shared
+
+
+def main():
+ """Flash map converter"""
+ params = CmdLineParams()
+
+ try:
+ plat = platDict[params.plat_id]
+ except KeyError:
+ print('Supported platforms are:', ', '.join(platDict.keys()),
+ file=sys.stderr)
+ sys.exit(2)
+
+ try:
+ boot_and_upgrade, flash = process_json(params.in_file)
+ bootloader = boot_and_upgrade['bootloader']
+ boot = AddrSize(bootloader, 'address', 'size')
+ except KeyError as key:
+ print('Malformed JSON:', key, 'is missing',
+ file=sys.stderr)
+ sys.exit(5)
+
+ try:
+ scratch = AddrSize(bootloader, 'scratch_address', 'scratch_size')
+ except KeyError:
+ scratch = None
+
+ try:
+ swap_status = AddrSize(bootloader, 'status_address', 'status_size')
+ except KeyError:
+ swap_status = None
+
+ # Create flash areas
+ area_list = AreaList(plat, flash, scratch is None and swap_status is None)
+ area_list.add_area('bootloader', 'FLASH_AREA_BOOTLOADER',
+ boot.fa_addr, boot.fa_size)
+
+ # Service RAM app (optional)
+ service_app = boot_and_upgrade.get('service_app')
+ app_binary = None
+ input_params = None
+ app_desc = None
+ if service_app is not None:
+ if plat['flashSize'] > 0:
+ print('service_app is unsupported on this platform',
+ file=sys.stderr)
+ sys.exit(7)
+ try:
+ app_binary = AddrSize(service_app, 'address', 'size')
+ input_params = AddrSize(service_app, 'params_address', 'params_size')
+ app_desc = AddrSize(service_app, 'desc_address', 'desc_size')
+ if input_params.fa_addr != app_binary.fa_addr + app_binary.fa_size or \
+ app_desc.fa_addr != input_params.fa_addr + input_params.fa_size or \
+ app_desc.fa_size != 0x20:
+ print('Malformed service_app definition', file=sys.stderr)
+ sys.exit(7)
+ area_list.add_area('service_app', None, app_binary.fa_addr,
+ app_binary.fa_size + input_params.fa_size + app_desc.fa_size)
+ except KeyError as key:
+ print('Malformed JSON:', key, 'is missing',
+ file=sys.stderr)
+ sys.exit(5)
+
+ # Fill flash areas
+ app_count, slot_sectors_max, apps_flash_map, shared_slot = \
+ process_images(area_list, boot_and_upgrade)
+
+ slot_sectors_max = max(slot_sectors_max, 32)
+
+ if swap_status is not None:
+ status_size_min = calc_status_size(area_list.get_min_erase_size(),
+ slot_sectors_max,
+ app_count,
+ scratch is not None)
+
+ if swap_status.fa_size < status_size_min:
+ print('Insufficient swap status area - suggested size',
+ hex(status_size_min),
+ file=sys.stderr)
+ sys.exit(7)
+ area_list.add_area('swap status partition',
+ 'FLASH_AREA_IMAGE_SWAP_STATUS',
+ swap_status.fa_addr, swap_status.fa_size)
+
+ if scratch is not None:
+ area_list.add_area('scratch area',
+ 'FLASH_AREA_IMAGE_SCRATCH',
+ scratch.fa_addr, scratch.fa_size)
+
+ # Image id parameter is not used for MCUBootApp
+ if params.img_id is None:
+ area_list.generate_c_source(params)
+
+ # Report necessary values back to make
+ print('# AUTO-GENERATED FILE, DO NOT EDIT. ALL CHANGES WILL BE LOST!')
+
+ if params.img_id is not None:
+ primary_img_start = (apps_flash_map[int(params.img_id)].get("primary")).get("address")
+ secondary_img_start = (apps_flash_map[int(params.img_id)].get("secondary")).get("address")
+ bootloader_size = (bootloader.get("size")).get("value")
+ slot_size = (apps_flash_map[int(params.img_id)].get("primary")).get("size")
+
+ print('PRIMARY_IMG_START := ' + primary_img_start)
+ print('SECONDARY_IMG_START := ' + secondary_img_start)
+ print('SLOT_SIZE := ' + slot_size)
+ print('BOOTLOADER_SIZE := ' + bootloader_size)
+ else:
+ print('MCUBOOT_IMAGE_NUMBER :=', app_count)
+ print('MAX_IMG_SECTORS :=', slot_sectors_max)
+
+ if area_list.use_overwrite:
+ print('USE_OVERWRITE := 1')
+ if area_list.external_flash:
+ print('USE_EXTERNAL_FLASH := 1')
+ if area_list.external_flash_xip:
+ print('USE_XIP := 1')
+ if shared_slot:
+ print('USE_SHARED_SLOT := 1')
+ if service_app is not None:
+ print('PLATFORM_SERVICE_APP_OFFSET :=',
+ hex(app_binary.fa_addr - plat['smifAddr']))
+ print('PLATFORM_SERVICE_APP_INPUT_PARAMS_OFFSET :=',
+ hex(input_params.fa_addr - plat['smifAddr']))
+ print('PLATFORM_SERVICE_APP_DESC_OFFSET :=',
+ hex(app_desc.fa_addr - plat['smifAddr']))
+ print('USE_HW_ROLLBACK_PROT := 1')
+
+
+if __name__ == '__main__':
+ main()
diff --git a/boot/cypress/scripts/verbose_make.py b/boot/cypress/scripts/verbose_make.py
new file mode 100644
index 0000000..c9cc037
--- /dev/null
+++ b/boot/cypress/scripts/verbose_make.py
@@ -0,0 +1,49 @@
+"""VERBOSE Makefile Generator
+Copyright (c) 2022 Infineon Technologies AG
+"""
+
+import os
+import re
+import sys
+
+
+def main():
+ """VERBOSE Makefile Generator"""
+ if len(sys.argv) != 2:
+ print(f'Usage: {sys.argv[0]} <makefile>\n', file=sys.stderr)
+ sys.exit(1)
+
+ with open(sys.argv[1], 'r', encoding='UTF-8') as mk_file:
+ mk_vars = {}
+
+ for line in mk_file:
+ line = line.strip()
+
+ if re.search(r'\s*#', line): # skip comments
+ continue
+
+ match = re.search(r'^\t*([A-Za-z_]\w+)\s*[+:?]=', line)
+ if match: # set variable
+ var = match.group(1)
+ mk_vars[var] = 1 | mk_vars.get(var, 0)
+
+ match = re.findall(r'\$\(([A-Za-z_]\w+)\)', line)
+ for var in match: # get variable(s)
+ mk_vars[var] = 2 | mk_vars.get(var, 0)
+
+ if mk_vars.get('VERBOSE'):
+ del mk_vars['VERBOSE']
+
+ print('''\
+###############################################################################
+# Print debug information about all settings used and/or set in this file
+ifeq ($(VERBOSE), 1)''')
+ print(f'$(info #### {os.path.basename(sys.argv[1])} ####)')
+ dirs = (None, '-->', '<--', '<->')
+ for var in sorted(mk_vars.keys()):
+ print(f'$(info {var} {dirs[mk_vars[var]]} $({var}))')
+ print('endif')
+
+
+if __name__ == '__main__':
+ main()
diff --git a/boot/cypress/toolchains.mk b/boot/cypress/toolchains.mk
index 970f325..2e20404 100644
--- a/boot/cypress/toolchains.mk
+++ b/boot/cypress/toolchains.mk
@@ -23,7 +23,7 @@
# limitations under the License.
################################################################################
-include common_libs.mk
+include host.mk
# Compilers
GCC_ARM := 1
@@ -31,27 +31,16 @@
ARM := 3
OTHER := 4
-ifeq ($(MAKEINFO), 1)
+ifeq ($(VERBOSE), 1)
$(info $(COMPILER))
endif
-# Detect host OS to make resolving compiler pathes easier
-UNAME_S := $(shell uname -s)
-ifeq ($(UNAME_S), Darwin)
- HOST_OS = osx
-else
- ifeq ($(UNAME_S), Linux)
- HOST_OS = linux
- else
- HOST_OS = win
- endif
-endif
# Path to the compiler installation
# NOTE: Absolute pathes for now for the sake of development
ifeq ($(HOST_OS), win)
ifeq ($(COMPILER), GCC_ARM)
- TOOLCHAIN_PATH ?= c:/Users/$(USERNAME)/ModusToolbox/tools_2.2/gcc
- MY_TOOLCHAIN_PATH:=$(subst \,/,$(TOOLCHAIN_PATH))
+ TOOLCHAIN_PATH ?= c:/Users/$(USERNAME)/ModusToolbox/tools_2.3/gcc
+ MY_TOOLCHAIN_PATH := $(call get_os_path, $(TOOLCHAIN_PATH))
TOOLCHAIN_PATH := $(MY_TOOLCHAIN_PATH)
GCC_PATH := $(TOOLCHAIN_PATH)
# executables
@@ -82,23 +71,31 @@
# Set flags for toolchain executables
ifeq ($(COMPILER), GCC_ARM)
# set build-in compiler flags
- CFLAGS_COMMON := -mcpu=cortex-$(CORE_SIFFX) -mthumb -mfloat-abi=soft -fno-stack-protector -ffunction-sections -fdata-sections -ffat-lto-objects -fstrict-aliasing -g -Wall -Wextra
- # preset default level of optimization - can be changed in application.mk
+ CFLAGS_COMMON := -mthumb -ffunction-sections -fdata-sections -g -Wall -Wextra
ifeq ($(BUILDCFG), Debug)
- CFLAGS_OPTIMIZATION ?= -Og -g3
+ CFLAGS_SPECIAL ?= -Og -g3
+ CFLAGS_COMMON += $(CFLAGS_SPECIAL)
else ifeq ($(BUILDCFG), Release)
- CFLAGS_OPTIMIZATION ?= -Os -g
+ CFLAGS_COMMON += -Os -g -DNDEBUG
else
$(error BUILDCFG : '$(BUILDCFG)' is not supported)
endif
- # add defines and includes
- CFLAGS := $(CFLAGS_COMMON) $(INCLUDES)
+
+ # ifeq ($(CORE), CM33)
+ # CFLAGS_PLATFORM := -c -mcpu=cortex-m33+nodsp --specs=nano.specs
+ # else
+ # CFLAGS_PLATFORM := -mcpu=cortex-$(CORE_SUFFIX) -mfloat-abi=soft -fno-stack-protector -fstrict-aliasing
+ # endif
+
+ # $CFLAGS_PLATFORM is defined in plaform specific mk file
+ CFLAGS := $(CFLAGS_COMMON) $(CFLAGS_PLATFORM) $(INCLUDES)
+
CC_DEPEND = -MD -MP -MF
- LDFLAGS_COMMON := -mcpu=cortex-$(CORE_SIFFX) -mthumb -specs=nano.specs -ffunction-sections -fdata-sections -Wl,--gc-sections -L "$(GCC_PATH)/lib/gcc/arm-none-eabi/7.2.1/thumb/v6-m" -ffat-lto-objects -g --enable-objc-gc
+ LDFLAGS_COMMON := -mcpu=cortex-$(CORE_SUFFIX) -mthumb -specs=nano.specs -ffunction-sections -fdata-sections -Wl,--gc-sections -ffat-lto-objects -g --enable-objc-gc
ifeq ($(BUILDCFG), Debug)
- # preset default level of optimization - can be changed in application.mk
- LDFLAGS_OPTIMIZATION ?= -Og
+ LDFLAGS_SPECIAL ?= -Og
+ LDFLAGS_COMMON += $(LDFLAGS_SPECIAL)
else ifeq ($(BUILDCFG), Release)
LDFLAGS_OPTIMIZATION ?= -Os
else
@@ -107,3 +104,36 @@
LDFLAGS_NANO := -L "$(GCC_PATH)/arm-none-eabi/lib/thumb/v6-m"
LDFLAGS := $(LDFLAGS_COMMON) $(LDFLAGS_NANO)
endif
+
+###############################################################################
+# Print debug information about all settings used and/or set in this file
+ifeq ($(VERBOSE), 1)
+$(info #### toolchains.mk ####)
+$(info ARM --> $(ARM))
+$(info BUILDCFG <-- $(BUILDCFG))
+$(info CC <-> $(CC))
+$(info CFLAGS --> $(CFLAGS))
+$(info CFLAGS_COMMON <-> $(CFLAGS_COMMON))
+$(info CFLAGS_PLATFORM <-- $(CFLAGS_PLATFORM))
+$(info CFLAGS_SPECIAL <-> $(CFLAGS_SPECIAL))
+$(info COMPILER <-- $(COMPILER))
+$(info CORE_SUFFIX <-- $(CORE_SUFFIX))
+$(info GCC_ARM --> $(GCC_ARM))
+$(info GCC_PATH <-> $(GCC_PATH))
+$(info HOST_OS <-- $(HOST_OS))
+$(info IAR --> $(IAR))
+$(info INCLUDES <-- $(INCLUDES))
+$(info LD --> $(LD))
+$(info LDFLAGS --> $(LDFLAGS))
+$(info LDFLAGS_COMMON <-> $(LDFLAGS_COMMON))
+$(info LDFLAGS_NANO <-> $(LDFLAGS_NANO))
+$(info LDFLAGS_OPTIMIZATION --> $(LDFLAGS_OPTIMIZATION))
+$(info LDFLAGS_SPECIAL <-> $(LDFLAGS_SPECIAL))
+$(info MY_TOOLCHAIN_PATH <-> $(MY_TOOLCHAIN_PATH))
+$(info OBJCOPY --> $(OBJCOPY))
+$(info OBJDUMP --> $(OBJDUMP))
+$(info OTHER --> $(OTHER))
+$(info PDL_ELFTOOL --> $(PDL_ELFTOOL))
+$(info TOOLCHAIN_PATH <-> $(TOOLCHAIN_PATH))
+$(info USERNAME <-- $(USERNAME))
+endif
diff --git a/boot/mbed/app_enc_keys.c b/boot/mbed/app_enc_keys.c
index cf4bd40..9bed4d8 100644
--- a/boot/mbed/app_enc_keys.c
+++ b/boot/mbed/app_enc_keys.c
@@ -30,8 +30,6 @@
#define HAVE_KEYS
extern const unsigned char ed25519_pub_key[];
extern unsigned int ed25519_pub_key_len;
-#else
-#error "No public key available for given signing algorithm."
#endif
/*
diff --git a/boot/mbed/include/flash_map_backend/flash_map_backend.h b/boot/mbed/include/flash_map_backend/flash_map_backend.h
index 8057baf..f2bad16 100644
--- a/boot/mbed/include/flash_map_backend/flash_map_backend.h
+++ b/boot/mbed/include/flash_map_backend/flash_map_backend.h
@@ -75,6 +75,26 @@
uint32_t fa_size;
};
+static inline uint8_t flash_area_get_id(const struct flash_area *fa)
+{
+ return fa->fa_id;
+}
+
+static inline uint8_t flash_area_get_device_id(const struct flash_area *fa)
+{
+ return fa->fa_device_id;
+}
+
+static inline uint32_t flash_area_get_off(const struct flash_area *fa)
+{
+ return fa->fa_off;
+}
+
+static inline uint32_t flash_area_get_size(const struct flash_area *fa)
+{
+ return fa->fa_size;
+}
+
/**
* @brief Structure describing a sector within a flash area.
*
@@ -94,6 +114,16 @@
uint32_t fs_size;
};
+static inline uint32_t flash_sector_get_off(const struct flash_sector *fs)
+{
+ return fs->fs_off;
+}
+
+static inline uint32_t flash_sector_get_size(const struct flash_sector *fs)
+{
+ return fs->fs_size;
+}
+
/*
* Start using flash area.
*/
diff --git a/boot/mbed/include/mcuboot_config/mcuboot_config.h b/boot/mbed/include/mcuboot_config/mcuboot_config.h
index 29dbf75..b57e8d6 100644
--- a/boot/mbed/include/mcuboot_config/mcuboot_config.h
+++ b/boot/mbed/include/mcuboot_config/mcuboot_config.h
@@ -18,6 +18,7 @@
#define SIGNATURE_TYPE_RSA 0
#define SIGNATURE_TYPE_EC256 1
#define SIGNATURE_TYPE_ED25519 2
+#define SIGNATURE_TYPE_NONE 3
/*
* Signature algorithm
@@ -59,6 +60,12 @@
#define MCUBOOT_IMAGE_NUMBER 1
/*
+ * Currently there is no configuration option, for this platform,
+ * that enables the system specific mcumgr commands in mcuboot
+ */
+#define MCUBOOT_PERUSER_MGMT_GROUP_ENABLED 0
+
+/*
* Encrypted Images
*/
#if defined(MCUBOOT_ENCRYPT_RSA) || defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519)
@@ -78,5 +85,11 @@
do { \
} while (0)
+/*
+ * No direct idle call implemented
+ */
+#define MCUBOOT_CPU_IDLE() \
+ do { \
+ } while (0)
#endif /* __MCUBOOT_CONFIG_H__ */
diff --git a/boot/mbed/include/utils/DataShare.cpp b/boot/mbed/include/utils/DataShare.cpp
new file mode 100644
index 0000000..a7d012b
--- /dev/null
+++ b/boot/mbed/include/utils/DataShare.cpp
@@ -0,0 +1,97 @@
+/**
+ *
+ * Built with ARM Mbed-OS
+ *
+ * Copyright (c) 2019-2021 Embedded Planet, Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ */
+
+#if MCUBOOT_DATA_SHARING && !MCUBOOT_BOOTLOADER_BUILD
+
+#include "DataShare.h"
+#include "boot_status.h"
+
+#include <cstring>
+
+#define PTR_TO_UINT8(x) ((volatile uint8_t *) x)
+#define PTR_TO_UINT16(x) ((volatile uint16_t *) x)
+#define PTR_TO_UINT32(x) ((volatile uint32_t *) x)
+
+#define SHARED_DATA_ENTRY_BASE MCUBOOT_SHARED_DATA_BASE+SHARED_DATA_HEADER_SIZE
+
+DataShare::DataShare(uint8_t *shared_base) : _shared_base(shared_base) {
+ volatile uint16_t *ptr = PTR_TO_UINT16(MCUBOOT_SHARED_DATA_BASE);
+
+ /* Validate magic word */
+ if(*ptr++ == SHARED_DATA_TLV_INFO_MAGIC) {
+ _is_valid = true;
+ }
+
+ _total_size = *ptr;
+
+}
+
+bool DataShare::is_valid() {
+ return _is_valid;
+}
+
+uint16_t DataShare::get_total_size() {
+ if(!is_valid()) {
+ return 0;
+ }
+
+ return _total_size;
+}
+
+int DataShare::get_next(uint16_t *type, mbed::Span<uint8_t> buf, uint16_t *actual_size) {
+
+ if(!is_valid()) {
+ return DATA_SHARE_ERROR_CORRUPT;
+ }
+
+ if(_current_offset >= (_total_size - SHARED_DATA_HEADER_SIZE)) {
+ return DATA_SHARE_ERROR_EOF;
+ }
+
+ uint16_t working_offset = _current_offset;
+
+ /* Get the type and the length */
+ *type = *PTR_TO_UINT16((SHARED_DATA_ENTRY_BASE + working_offset));
+ working_offset += sizeof(uint16_t);
+ *actual_size = *PTR_TO_UINT16((SHARED_DATA_ENTRY_BASE + working_offset));
+ working_offset += sizeof(uint16_t);
+
+ /* Check if the output buffer is large enough */
+ if((size_t)buf.size() < *actual_size) {
+ return DATA_SHARE_ERROR_OUT_OF_MEM;
+ }
+
+ /* Copy data of TLV entry */
+ memcpy(buf.data(), (const uint8_t*)PTR_TO_UINT8((SHARED_DATA_ENTRY_BASE + working_offset)), *actual_size);
+
+ working_offset += *actual_size;
+
+ /* Update state */
+ _current_offset = working_offset;
+
+ return DATA_SHARE_OK;
+
+}
+
+void DataShare::rewind() {
+ _current_offset = 0;
+}
+
+#endif /* MCUBOOT_DATA_SHARING && !MCUBOOT_BOOTLOADER_BUILD */
diff --git a/boot/mbed/include/utils/DataShare.h b/boot/mbed/include/utils/DataShare.h
new file mode 100644
index 0000000..fbb7e8e
--- /dev/null
+++ b/boot/mbed/include/utils/DataShare.h
@@ -0,0 +1,92 @@
+/**
+ *
+ * Built with ARM Mbed-OS
+ *
+ * Copyright (c) 2019-2021 Embedded Planet, Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ */
+
+
+#ifndef DATASHARE_H_
+#define DATASHARE_H_
+
+/**
+ * This is an utility intended to be used by the booted application rather
+ * than by the bootloader
+ */
+#if MCUBOOT_DATA_SHARING && !MCUBOOT_BOOTLOADER_BUILD
+
+#include <stdint.h>
+#include "platform/Span.h"
+
+/* Error codes */
+#define DATA_SHARE_OK 0
+#define DATA_SHARE_ERROR_EOF 1 /* No more TLV entries available */
+#define DATA_SHARE_ERROR_OUT_OF_MEM 2 /* The output buffer was not large enough to hold the contents of the TLV entry */
+#define DATA_SHARE_ERROR_CORRUPT 3 /* Data corruption has been detected */
+
+/**
+ * Class enabling iterator-style access to the TLV-encoded data shared
+ * by an mcuboot-based bootloader.
+ */
+class DataShare
+{
+public:
+
+ /**
+ * Initializes a DataShare iterator at the given base address
+ * @note the configured MCUBOOT_SHARED_DATA_BASE address is used by default
+ */
+ DataShare(uint8_t * shared_base = ((uint8_t *) MCUBOOT_SHARED_DATA_BASE));
+
+ /**
+ * Validates the magic number of the shared data section
+ * @return true if magic number is found, false otherwise
+ */
+ bool is_valid();
+
+ /**
+ * Gets the total size of the shared data region
+ * @return 0 if shared data region is not valid, otherwise the size of the shared data region
+ */
+ uint16_t get_total_size();
+
+ /**
+ * Attempts to get the next TLV entry in the shared data memory
+ * @param[put] type Type code of the data entry
+ * @param[out] out Output buffer span
+ * @param[out] actual_size Size of entry copied to output buffer in bytes
+ * @return err Zero if output buffer contents is valid (successful), non-zero on failure
+ */
+ int get_next(uint16_t *type, mbed::Span<uint8_t> buf, uint16_t *actual_size);
+
+ /**
+ * Resets the iterator-like pointer to the first TLV element in the shared
+ * data region
+ */
+ void rewind();
+
+protected:
+
+ uint8_t *_shared_base;
+ bool _is_valid = false;
+ uint16_t _total_size = 0;
+ uint16_t _current_offset = 0;
+
+};
+
+#endif /* MCUBOOT_DATA_SHARING && !MCUBOOT_BOOTLOADER_BUILD */
+
+#endif /* DATASHARE_H_ */
diff --git a/boot/mbed/mbed_lib.json b/boot/mbed/mbed_lib.json
index ef16f0c..ae8e288 100644
--- a/boot/mbed/mbed_lib.json
+++ b/boot/mbed/mbed_lib.json
@@ -25,12 +25,6 @@
"help": "Size of the scratch area, in bytes. If needed, please set on a per-target basis.",
"macro_name": "MCUBOOT_SCRATCH_SIZE"
},
- "header-size": {
- "help": "Header size, in bytes, prepended to the bootable application image. Should be one or multiple times the sector size.",
- "macro_name": "MCUBOOT_HEADER_SIZE",
- "required": true,
- "value": 4096
- },
"validate-primary-slot": {
"help": "Always check the signature of the image in the primary slot before booting, even if no upgrade was performed. This is recommended if the boot time penalty is acceptable.",
"macro_name": "MCUBOOT_VALIDATE_PRIMARY_SLOT",
@@ -41,7 +35,7 @@
"help": "The algorithm used for digital signing.",
"macro_name": "MCUBOOT_SIGNATURE_ALGORITHM",
"required": true,
- "accepted_values": ["SIGNATURE_TYPE_RSA", "SIGNATURE_TYPE_EC256", "SIGNATURE_TYPE_ED25519"],
+ "accepted_values": ["SIGNATURE_TYPE_RSA", "SIGNATURE_TYPE_EC256", "SIGNATURE_TYPE_ED25519", "SIGNATURE_TYPE_NONE"],
"value": "SIGNATURE_TYPE_RSA"
},
"rsa-signature-length": {
@@ -161,6 +155,16 @@
"macro_name": "MCUBOOT_DATA_SHARING",
"value": null
},
+ "share-data-base-address": {
+ "help": "Start of reserved RAM region for data shared between bootloader and application",
+ "macro_name": "MCUBOOT_SHARED_DATA_BASE",
+ "value": null
+ },
+ "share-data-size": {
+ "help": "Size of reserved RAM region for data shared between bootloader and application",
+ "macro_name": "MCUBOOT_SHARED_DATA_SIZE",
+ "value": null
+ },
"direct-xip": {
"help": "Enable ability to boot update candidates in-place.",
"macro_name": "MCUBOOT_DIRECT_XIP",
diff --git a/boot/mynewt/flash_map_backend/include/flash_map_backend/flash_map_backend.h b/boot/mynewt/flash_map_backend/include/flash_map_backend/flash_map_backend.h
index ff628e1..14e4dda 100644
--- a/boot/mynewt/flash_map_backend/include/flash_map_backend/flash_map_backend.h
+++ b/boot/mynewt/flash_map_backend/include/flash_map_backend/flash_map_backend.h
@@ -8,6 +8,7 @@
#define __FLASH_MAP_BACKEND_H__
#include <sysflash/sysflash.h>
+#include <flash_map/flash_map.h>
#include <mcuboot_config/mcuboot_config.h>
#if (MCUBOOT_IMAGE_NUMBER == 1)
@@ -39,4 +40,24 @@
int flash_area_id_from_multi_image_slot(int image_index, int slot);
int flash_area_id_to_multi_image_slot(int image_index, int area_id);
+static inline uint8_t flash_area_get_id(const struct flash_area *fa)
+{
+ return fa->fa_id;
+}
+
+static inline uint8_t flash_area_get_device_id(const struct flash_area *fa)
+{
+ return fa->fa_device_id;
+}
+
+static inline uint32_t flash_area_get_off(const struct flash_area *fa)
+{
+ return fa->fa_off;
+}
+
+static inline uint32_t flash_area_get_size(const struct flash_area *fa)
+{
+ return fa->fa_size;
+}
+
#endif /* __FLASH_MAP_BACKEND_H__ */
diff --git a/boot/mynewt/mcuboot_config/include/mcuboot_config/mcuboot_config.h b/boot/mynewt/mcuboot_config/include/mcuboot_config/mcuboot_config.h
index 696f2e7..2f8f767 100644
--- a/boot/mynewt/mcuboot_config/include/mcuboot_config/mcuboot_config.h
+++ b/boot/mynewt/mcuboot_config/include/mcuboot_config/mcuboot_config.h
@@ -89,6 +89,12 @@
#define MCUBOOT_BOOTSTRAP 1
#endif
+/*
+ * Currently there is no configuration option, for this platform,
+ * that enables the system specific mcumgr commands in mcuboot
+ */
+#define MCUBOOT_PERUSER_MGMT_GROUP_ENABLED 0
+
#define MCUBOOT_MAX_IMG_SECTORS MYNEWT_VAL(BOOTUTIL_MAX_IMG_SECTORS)
#if MYNEWT_VAL(BOOTUTIL_FEED_WATCHDOG) && MYNEWT_VAL(WATCHDOG_INTERVAL)
@@ -101,4 +107,11 @@
#define MCUBOOT_WATCHDOG_FEED() do {} while (0)
#endif
+/*
+ * No direct idle call implemented
+ */
+#define MCUBOOT_CPU_IDLE() \
+ do { \
+ } while (0)
+
#endif /* __MCUBOOT_CONFIG_H__ */
diff --git a/boot/nuttx/include/flash_map_backend/flash_map_backend.h b/boot/nuttx/include/flash_map_backend/flash_map_backend.h
new file mode 100644
index 0000000..7d17a8b
--- /dev/null
+++ b/boot/nuttx/include/flash_map_backend/flash_map_backend.h
@@ -0,0 +1,422 @@
+/****************************************************************************
+ * boot/nuttx/include/flash_map_backend/flash_map_backend.h
+ *
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __BOOT_NUTTX_INCLUDE_FLASH_MAP_BACKEND_FLASH_MAP_BACKEND_H
+#define __BOOT_NUTTX_INCLUDE_FLASH_MAP_BACKEND_FLASH_MAP_BACKEND_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <inttypes.h>
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* Structure describing a flash area. */
+
+struct flash_area
+{
+ /* MCUboot-API fields */
+
+ uint8_t fa_id; /* The slot/scratch ID */
+ uint8_t fa_device_id; /* The device ID (usually there's only one) */
+ uint16_t pad16; /* Padding */
+ uint32_t fa_off; /* The flash offset from the beginning */
+ uint32_t fa_size; /* The size of this sector */
+
+ /* NuttX implementation-specific fields */
+
+ const char *fa_mtd_path; /* Path for the MTD partition */
+};
+
+/* Structure describing a sector within a flash area. */
+
+struct flash_sector
+{
+ /* Offset of this sector, from the start of its flash area (not device). */
+
+ uint32_t fs_off;
+
+ /* Size of this sector, in bytes. */
+
+ uint32_t fs_size;
+};
+
+/****************************************************************************
+ * Inline Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: flash_area_get_id
+ *
+ * Description:
+ * Obtain the ID of a given flash area.
+ *
+ * Input Parameters:
+ * fa - Flash area.
+ *
+ * Returned Value:
+ * The ID of the requested flash area.
+ *
+ ****************************************************************************/
+
+static inline uint8_t flash_area_get_id(const struct flash_area *fa)
+{
+ return fa->fa_id;
+}
+
+/****************************************************************************
+ * Name: flash_area_get_device_id
+ *
+ * Description:
+ * Obtain the ID of the device in which a given flash area resides on.
+ *
+ * Input Parameters:
+ * fa - Flash area.
+ *
+ * Returned Value:
+ * The device ID of the requested flash area.
+ *
+ ****************************************************************************/
+
+static inline uint8_t flash_area_get_device_id(const struct flash_area *fa)
+{
+ return fa->fa_device_id;
+}
+
+/****************************************************************************
+ * Name: flash_area_get_off
+ *
+ * Description:
+ * Obtain the offset, from the beginning of a device, where a given flash
+ * area starts at.
+ *
+ * Input Parameters:
+ * fa - Flash area.
+ *
+ * Returned Value:
+ * The offset value of the requested flash area.
+ *
+ ****************************************************************************/
+
+static inline uint32_t flash_area_get_off(const struct flash_area *fa)
+{
+ return fa->fa_off;
+}
+
+/****************************************************************************
+ * Name: flash_area_get_size
+ *
+ * Description:
+ * Obtain the size, from the offset, of a given flash area.
+ *
+ * Input Parameters:
+ * fa - Flash area.
+ *
+ * Returned Value:
+ * The size value of the requested flash area.
+ *
+ ****************************************************************************/
+
+static inline uint32_t flash_area_get_size(const struct flash_area *fa)
+{
+ return fa->fa_size;
+}
+
+/****************************************************************************
+ * Name: flash_sector_get_off
+ *
+ * Description:
+ * Obtain the offset, from the beginning of its flash area, where a given
+ * flash sector starts at.
+ *
+ * Input Parameters:
+ * fs - Flash sector.
+ *
+ * Returned Value:
+ * The offset value of the requested flash sector.
+ *
+ ****************************************************************************/
+
+static inline uint32_t flash_sector_get_off(const struct flash_sector *fs)
+{
+ return fs->fs_off;
+}
+
+/****************************************************************************
+ * Name: flash_sector_get_size
+ *
+ * Description:
+ * Obtain the size, from the offset, of a given flash sector.
+ *
+ * Input Parameters:
+ * fs - Flash sector.
+ *
+ * Returned Value:
+ * The size in bytes of the requested flash sector.
+ *
+ ****************************************************************************/
+
+static inline uint32_t flash_sector_get_size(const struct flash_sector *fs)
+{
+ return fs->fs_size;
+}
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: flash_area_open
+ *
+ * Description:
+ * Retrieve flash area from the flash map for a given partition.
+ *
+ * Input Parameters:
+ * fa_id - ID of the flash partition.
+ *
+ * Output Parameters:
+ * fa - Pointer which will contain the reference to flash_area.
+ * If ID is unknown, it will be NULL on output.
+ *
+ * Returned Value:
+ * Zero on success, or negative value in case of error.
+ *
+ ****************************************************************************/
+
+int flash_area_open(uint8_t id, const struct flash_area **fa);
+
+/****************************************************************************
+ * Name: flash_area_close
+ *
+ * Description:
+ * Close a given flash area.
+ *
+ * Input Parameters:
+ * fa - Flash area to be closed.
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+void flash_area_close(const struct flash_area *fa);
+
+/****************************************************************************
+ * Name: flash_area_read
+ *
+ * Description:
+ * Read data from flash area.
+ * Area readout boundaries are asserted before read request. API has the
+ * same limitation regarding read-block alignment and size as the
+ * underlying flash driver.
+ *
+ * Input Parameters:
+ * fa - Flash area to be read.
+ * off - Offset relative from beginning of flash area to be read.
+ * len - Number of bytes to read.
+ *
+ * Output Parameters:
+ * dst - Buffer to store read data.
+ *
+ * Returned Value:
+ * Zero on success, or negative value in case of error.
+ *
+ ****************************************************************************/
+
+int flash_area_read(const struct flash_area *fa, uint32_t off,
+ void *dst, uint32_t len);
+
+/****************************************************************************
+ * Name: flash_area_write
+ *
+ * Description:
+ * Write data to flash area.
+ * Area write boundaries are asserted before write request. API has the
+ * same limitation regarding write-block alignment and size as the
+ * underlying flash driver.
+ *
+ * Input Parameters:
+ * fa - Flash area to be written.
+ * off - Offset relative from beginning of flash area to be written.
+ * src - Buffer with data to be written.
+ * len - Number of bytes to write.
+ *
+ * Returned Value:
+ * Zero on success, or negative value in case of error.
+ *
+ ****************************************************************************/
+
+int flash_area_write(const struct flash_area *fa, uint32_t off,
+ const void *src, uint32_t len);
+
+/****************************************************************************
+ * Name: flash_area_erase
+ *
+ * Description:
+ * Erase a given flash area range.
+ * Area boundaries are asserted before erase request. API has the same
+ * limitation regarding erase-block alignment and size as the underlying
+ * flash driver.
+ *
+ * Input Parameters:
+ * fa - Flash area to be erased.
+ * off - Offset relative from beginning of flash area to be erased.
+ * len - Number of bytes to be erase.
+ *
+ * Returned Value:
+ * Zero on success, or negative value in case of error.
+ *
+ ****************************************************************************/
+
+int flash_area_erase(const struct flash_area *fa, uint32_t off,
+ uint32_t len);
+
+/****************************************************************************
+ * Name: flash_area_align
+ *
+ * Description:
+ * Get write block size of the flash area.
+ * Write block size might be treated as read block size, although most
+ * drivers support unaligned readout.
+ *
+ * Input Parameters:
+ * fa - Flash area.
+ *
+ * Returned Value:
+ * Alignment restriction for flash writes in the given flash area.
+ *
+ ****************************************************************************/
+
+uint8_t flash_area_align(const struct flash_area *fa);
+
+/****************************************************************************
+ * Name: flash_area_erased_val
+ *
+ * Description:
+ * Get the value expected to be read when accessing any erased flash byte.
+ * This API is compatible with the MCUboot's porting layer.
+ *
+ * Input Parameters:
+ * fa - Flash area.
+ *
+ * Returned Value:
+ * Byte value of erased memory.
+ *
+ ****************************************************************************/
+
+uint8_t flash_area_erased_val(const struct flash_area *fa);
+
+/****************************************************************************
+ * Name: flash_area_get_sectors
+ *
+ * Description:
+ * Retrieve info about sectors within the area.
+ *
+ * Input Parameters:
+ * fa_id - ID of the flash area whose info will be retrieved.
+ * count - On input, represents the capacity of the sectors buffer.
+ *
+ * Output Parameters:
+ * count - On output, it shall contain the number of retrieved sectors.
+ * sectors - Buffer for sectors data.
+ *
+ * Returned Value:
+ * Zero on success, or negative value in case of error.
+ *
+ ****************************************************************************/
+
+int flash_area_get_sectors(int fa_id, uint32_t *count,
+ struct flash_sector *sectors);
+
+/****************************************************************************
+ * Name: flash_area_id_from_multi_image_slot
+ *
+ * Description:
+ * Return the flash area ID for a given slot and a given image index
+ * (in case of a multi-image setup).
+ *
+ * Input Parameters:
+ * image_index - Index of the image.
+ * slot - Image slot, which may be 0 (primary) or 1 (secondary).
+ *
+ * Returned Value:
+ * Flash area ID (0 or 1), or negative value in case the requested slot
+ * is invalid.
+ *
+ ****************************************************************************/
+
+int flash_area_id_from_multi_image_slot(int image_index, int slot);
+
+/****************************************************************************
+ * Name: flash_area_id_from_image_slot
+ *
+ * Description:
+ * Return the flash area ID for a given slot.
+ *
+ * Input Parameters:
+ * slot - Image slot, which may be 0 (primary) or 1 (secondary).
+ *
+ * Returned Value:
+ * Flash area ID (0 or 1), or negative value in case the requested slot
+ * is invalid.
+ *
+ ****************************************************************************/
+
+int flash_area_id_from_image_slot(int slot);
+
+/****************************************************************************
+ * Name: flash_area_id_to_multi_image_slot
+ *
+ * Description:
+ * Convert the specified flash area ID and image index (in case of a
+ * multi-image setup) to an image slot index.
+ *
+ * Input Parameters:
+ * image_index - Index of the image.
+ * fa_id - Image slot, which may be 0 (primary) or 1 (secondary).
+ *
+ * Returned Value:
+ * Image slot index (0 or 1), or negative value in case ID doesn't
+ * correspond to an image slot.
+ *
+ ****************************************************************************/
+
+int flash_area_id_to_multi_image_slot(int image_index, int fa_id);
+
+/****************************************************************************
+ * Name: flash_area_id_from_image_offset
+ *
+ * Description:
+ * Return the flash area ID for a given image offset.
+ *
+ * Input Parameters:
+ * offset - Image offset.
+ *
+ * Returned Value:
+ * Flash area ID (0 or 1), or negative value in case the requested slot
+ * is invalid.
+ *
+ ****************************************************************************/
+
+int flash_area_id_from_image_offset(uint32_t offset);
+
+#endif /* __BOOT_NUTTX_INCLUDE_FLASH_MAP_BACKEND_FLASH_MAP_BACKEND_H */
diff --git a/boot/nuttx/include/mcuboot_config/mcuboot_config.h b/boot/nuttx/include/mcuboot_config/mcuboot_config.h
new file mode 100644
index 0000000..ae945f6
--- /dev/null
+++ b/boot/nuttx/include/mcuboot_config/mcuboot_config.h
@@ -0,0 +1,181 @@
+/****************************************************************************
+ * boot/nuttx/include/mcuboot_config/mcuboot_config.h
+ *
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __BOOT_NUTTX_INCLUDE_MCUBOOT_CONFIG_MCUBOOT_CONFIG_H
+#define __BOOT_NUTTX_INCLUDE_MCUBOOT_CONFIG_MCUBOOT_CONFIG_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifdef CONFIG_MCUBOOT_WATCHDOG
+#include "watchdog/watchdog.h"
+#endif
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Signature types
+ *
+ * You must choose exactly one signature type.
+ */
+
+/* Uncomment for RSA signature support */
+
+/* #define MCUBOOT_SIGN_RSA */
+
+/* Uncomment for ECDSA signatures using curve P-256. */
+
+/* #define MCUBOOT_SIGN_EC256 */
+
+/* Upgrade mode
+ *
+ * The default is to support A/B image swapping with rollback. Other modes
+ * with simpler code path, which only supports overwriting the existing image
+ * with the update image or running the newest image directly from its flash
+ * partition, are also available.
+ *
+ * You can enable only one mode at a time from the list below to override
+ * the default upgrade mode.
+ */
+
+/* Uncomment to enable the overwrite-only code path. */
+
+/* #define MCUBOOT_OVERWRITE_ONLY */
+
+#ifdef MCUBOOT_OVERWRITE_ONLY
+
+/* Uncomment to only erase and overwrite those primary slot sectors needed
+ * to install the new image, rather than the entire image slot.
+ */
+
+/* #define MCUBOOT_OVERWRITE_ONLY_FAST */
+
+#endif
+
+/* Uncomment to enable the direct-xip code path. */
+
+/* #define MCUBOOT_DIRECT_XIP */
+
+/* Uncomment to enable the ram-load code path. */
+
+/* #define MCUBOOT_RAM_LOAD */
+
+/* Cryptographic settings
+ *
+ * You must choose between mbedTLS and Tinycrypt as source of
+ * cryptographic primitives. Other cryptographic settings are also
+ * available.
+ */
+
+#ifdef CONFIG_MCUBOOT_USE_MBED_TLS
+#define MCUBOOT_USE_MBED_TLS
+#endif
+
+#ifdef CONFIG_MCUBOOT_USE_TINYCRYPT
+#define MCUBOOT_USE_TINYCRYPT
+#endif
+
+/* Always check the signature of the image in the primary slot before
+ * booting, even if no upgrade was performed. This is recommended if the boot
+ * time penalty is acceptable.
+ */
+
+#define MCUBOOT_VALIDATE_PRIMARY_SLOT
+
+/* Flash abstraction */
+
+/* Uncomment if your flash map API supports flash_area_get_sectors().
+ * See the flash APIs for more details.
+ */
+
+#define MCUBOOT_USE_FLASH_AREA_GET_SECTORS
+
+/* Default maximum number of flash sectors per image slot; change
+ * as desirable.
+ */
+
+#define MCUBOOT_MAX_IMG_SECTORS 512
+
+/* Default number of separately updateable images; change in case of
+ * multiple images.
+ */
+
+#define MCUBOOT_IMAGE_NUMBER 1
+
+/* Logging */
+
+/* If logging is enabled the following functions must be defined by the
+ * platform:
+ *
+ * MCUBOOT_LOG_MODULE_REGISTER(domain)
+ * Register a new log module and add the current C file to it.
+ *
+ * MCUBOOT_LOG_MODULE_DECLARE(domain)
+ * Add the current C file to an existing log module.
+ *
+ * MCUBOOT_LOG_ERR(...)
+ * MCUBOOT_LOG_WRN(...)
+ * MCUBOOT_LOG_INF(...)
+ * MCUBOOT_LOG_DBG(...)
+ *
+ * The function priority is:
+ *
+ * MCUBOOT_LOG_ERR > MCUBOOT_LOG_WRN > MCUBOOT_LOG_INF > MCUBOOT_LOG_DBG
+ */
+
+#ifdef CONFIG_MCUBOOT_ENABLE_LOGGING
+# define MCUBOOT_HAVE_LOGGING
+#endif
+
+/* Assertions */
+
+/* Uncomment if your platform has its own mcuboot_config/mcuboot_assert.h.
+ * If so, it must provide an ASSERT macro for use by bootutil. Otherwise,
+ * "assert" is used.
+ */
+
+/* #define MCUBOOT_HAVE_ASSERT_H 1 */
+
+/* Watchdog feeding */
+
+/* This macro might be implemented if the OS / HW watchdog is enabled while
+ * doing a swap upgrade and the time it takes for a swapping is long enough
+ * to cause an unwanted reset. If implementing this, the OS main.c must also
+ * enable the watchdog (if required)!
+ */
+
+#ifdef CONFIG_MCUBOOT_WATCHDOG
+# define MCUBOOT_WATCHDOG_FEED() do \
+ { \
+ mcuboot_watchdog_feed(); \
+ } \
+ while (0)
+
+#else
+# define MCUBOOT_WATCHDOG_FEED() do \
+ { \
+ } \
+ while (0)
+#endif
+
+#endif /* __BOOT_NUTTX_INCLUDE_MCUBOOT_CONFIG_MCUBOOT_CONFIG_H */
diff --git a/boot/nuttx/include/mcuboot_config/mcuboot_logging.h b/boot/nuttx/include/mcuboot_config/mcuboot_logging.h
new file mode 100644
index 0000000..6853fff
--- /dev/null
+++ b/boot/nuttx/include/mcuboot_config/mcuboot_logging.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+ * boot/nuttx/include/mcuboot_config/mcuboot_logging.h
+ *
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __BOOT_NUTTX_INCLUDE_MCUBOOT_CONFIG_MCUBOOT_LOGGING_H
+#define __BOOT_NUTTX_INCLUDE_MCUBOOT_CONFIG_MCUBOOT_LOGGING_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <syslog.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MCUBOOT_LOG_ERR(format, ...) \
+ syslog(LOG_ERR, "%s: " format "\n", __FUNCTION__, ##__VA_ARGS__)
+
+#define MCUBOOT_LOG_WRN(format, ...) \
+ syslog(LOG_WARNING, "%s: " format "\n", __FUNCTION__, ##__VA_ARGS__)
+
+#define MCUBOOT_LOG_INF(format, ...) \
+ syslog(LOG_INFO, "%s: " format "\n", __FUNCTION__, ##__VA_ARGS__)
+
+#define MCUBOOT_LOG_DBG(format, ...) \
+ syslog(LOG_DEBUG, "%s: " format "\n", __FUNCTION__, ##__VA_ARGS__)
+
+#endif /* __BOOT_NUTTX_INCLUDE_MCUBOOT_CONFIG_MCUBOOT_LOGGING_H */
diff --git a/boot/nuttx/include/os/os_malloc.h b/boot/nuttx/include/os/os_malloc.h
new file mode 100644
index 0000000..1fbefad
--- /dev/null
+++ b/boot/nuttx/include/os/os_malloc.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ * boot/nuttx/include/os/os_malloc.h
+ *
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __BOOT_NUTTX_INCLUDE_OS_OS_MALLOC_H
+#define __BOOT_NUTTX_INCLUDE_OS_OS_MALLOC_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdlib.h>
+
+#endif /* __BOOT_NUTTX_INCLUDE_OS_OS_MALLOC_H */
diff --git a/boot/nuttx/include/sysflash/sysflash.h b/boot/nuttx/include/sysflash/sysflash.h
new file mode 100644
index 0000000..304ca0c
--- /dev/null
+++ b/boot/nuttx/include/sysflash/sysflash.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+ * boot/nuttx/include/sysflash/sysflash.h
+ *
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __BOOT_NUTTX_INCLUDE_SYSFLASH_SYSFLASH_H
+#define __BOOT_NUTTX_INCLUDE_SYSFLASH_SYSFLASH_H
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define PRIMARY_ID 0
+#define SECONDARY_ID 1
+#define SCRATCH_ID 2
+
+#define FLASH_AREA_IMAGE_PRIMARY(x) (((x) == 0) ? \
+ PRIMARY_ID : \
+ PRIMARY_ID)
+#define FLASH_AREA_IMAGE_SECONDARY(x) (((x) == 0) ? \
+ SECONDARY_ID : \
+ SECONDARY_ID)
+#define FLASH_AREA_IMAGE_SCRATCH SCRATCH_ID
+
+#endif /* __BOOT_NUTTX_INCLUDE_SYSFLASH_SYSFLASH_H */
diff --git a/boot/nuttx/include/watchdog/watchdog.h b/boot/nuttx/include/watchdog/watchdog.h
new file mode 100644
index 0000000..01cf31d
--- /dev/null
+++ b/boot/nuttx/include/watchdog/watchdog.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+ * boot/nuttx/include/watchdog/watchdog.h
+ *
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __BOOT_NUTTX_INCLUDE_WATCHDOG_WATCHDOG_H
+#define __BOOT_NUTTX_INCLUDE_WATCHDOG_WATCHDOG_H
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mcuboot_watchdog_feed
+ *
+ * Description:
+ * Reset the watchdog timer to the current timeout value, preventing any
+ * imminent watchdog timeouts.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+void mcuboot_watchdog_feed(void);
+
+#endif /* __BOOT_NUTTX_INCLUDE_WATCHDOG_WATCHDOG_H */
diff --git a/boot/nuttx/main.c b/boot/nuttx/main.c
new file mode 100644
index 0000000..728df13
--- /dev/null
+++ b/boot/nuttx/main.c
@@ -0,0 +1,95 @@
+/****************************************************************************
+ * boot/nuttx/main.c
+ *
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+
+#include <sys/boardctl.h>
+
+#include <bootutil/bootutil.h>
+#include <bootutil/image.h>
+
+#include "flash_map_backend/flash_map_backend.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * do_boot
+ ****************************************************************************/
+
+static void do_boot(struct boot_rsp *rsp)
+{
+ const struct flash_area *flash_area;
+ struct boardioc_boot_info_s info;
+ int area_id;
+ int ret;
+
+ area_id = flash_area_id_from_image_offset(rsp->br_image_off);
+
+ ret = flash_area_open(area_id, &flash_area);
+ assert(ret == OK);
+
+ printf("Booting from %s...\n", flash_area->fa_mtd_path);
+
+ info.path = flash_area->fa_mtd_path;
+ info.header_size = rsp->br_hdr->ih_hdr_size;
+
+ flash_area_close(flash_area);
+
+ if (boardctl(BOARDIOC_BOOT_IMAGE, (uintptr_t)&info) != OK)
+ {
+ fprintf(stderr, "Failed to load application image!\n");
+ FIH_PANIC;
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * main
+ ****************************************************************************/
+
+int main(int argc, FAR char *argv[])
+{
+ struct boot_rsp rsp;
+ fih_int fih_rc = FIH_FAILURE;
+
+ printf("*** Booting MCUboot build %s ***\n", CONFIG_MCUBOOT_VERSION);
+
+ FIH_CALL(boot_go, fih_rc, &rsp);
+
+ if (fih_not_eq(fih_rc, FIH_SUCCESS))
+ {
+ fprintf(stderr, "Unable to find bootable image\n");
+ FIH_PANIC;
+ }
+
+ do_boot(&rsp);
+
+ while (1);
+}
diff --git a/boot/nuttx/src/flash_map_backend/flash_map_backend.c b/boot/nuttx/src/flash_map_backend/flash_map_backend.c
new file mode 100644
index 0000000..3aa53fb
--- /dev/null
+++ b/boot/nuttx/src/flash_map_backend/flash_map_backend.c
@@ -0,0 +1,805 @@
+/****************************************************************************
+ * boot/nuttx/src/flash_map_backend/flash_map_backend.c
+ *
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <nuttx/fs/fs.h>
+#include <nuttx/mtd/mtd.h>
+
+#include <bootutil/bootutil_log.h>
+
+#include "flash_map_backend/flash_map_backend.h"
+#include "os/os_malloc.h"
+#include "sysflash/sysflash.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0]))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct flash_device_s
+{
+ /* Reference to the flash area configuration parameters */
+
+ struct flash_area *fa_cfg;
+
+ /* Geometry characteristics of the underlying MTD device */
+
+ struct mtd_geometry_s mtdgeo;
+
+ /* Partition information */
+
+ struct partition_info_s partinfo;
+
+ int fd; /* File descriptor for an open flash area */
+ int32_t refs; /* Reference counter */
+ uint8_t erase_state; /* Byte value of the flash erased state */
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct flash_area g_primary_img0 =
+{
+ .fa_id = FLASH_AREA_IMAGE_PRIMARY(0),
+ .fa_device_id = 0,
+ .fa_off = 0,
+ .fa_size = 0,
+ .fa_mtd_path = CONFIG_MCUBOOT_PRIMARY_SLOT_PATH
+};
+
+static struct flash_device_s g_primary_priv =
+{
+ .fa_cfg = &g_primary_img0,
+ .mtdgeo =
+ {
+ 0
+ },
+ .partinfo =
+ {
+ 0
+ },
+ .fd = -1,
+ .refs = 0,
+ .erase_state = CONFIG_MCUBOOT_DEFAULT_FLASH_ERASE_STATE
+};
+
+static struct flash_area g_secondary_img0 =
+{
+ .fa_id = FLASH_AREA_IMAGE_SECONDARY(0),
+ .fa_device_id = 0,
+ .fa_off = 0,
+ .fa_size = 0,
+ .fa_mtd_path = CONFIG_MCUBOOT_SECONDARY_SLOT_PATH
+};
+
+static struct flash_device_s g_secondary_priv =
+{
+ .fa_cfg = &g_secondary_img0,
+ .mtdgeo =
+ {
+ 0
+ },
+ .partinfo =
+ {
+ 0
+ },
+ .fd = -1,
+ .refs = 0,
+ .erase_state = CONFIG_MCUBOOT_DEFAULT_FLASH_ERASE_STATE
+};
+
+static struct flash_area g_scratch_img0 =
+{
+ .fa_id = FLASH_AREA_IMAGE_SCRATCH,
+ .fa_device_id = 0,
+ .fa_off = 0,
+ .fa_size = 0,
+ .fa_mtd_path = CONFIG_MCUBOOT_SCRATCH_PATH
+};
+
+static struct flash_device_s g_scratch_priv =
+{
+ .fa_cfg = &g_scratch_img0,
+ .mtdgeo =
+ {
+ 0
+ },
+ .partinfo =
+ {
+ 0
+ },
+ .fd = -1,
+ .refs = 0,
+ .erase_state = CONFIG_MCUBOOT_DEFAULT_FLASH_ERASE_STATE
+};
+
+static struct flash_device_s *g_flash_devices[] =
+{
+ &g_primary_priv,
+ &g_secondary_priv,
+ &g_scratch_priv,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lookup_flash_device_by_id
+ *
+ * Description:
+ * Retrieve flash device from a given flash area ID.
+ *
+ * Input Parameters:
+ * fa_id - ID of the flash area.
+ *
+ * Returned Value:
+ * Reference to the found flash device, or NULL in case it does not exist.
+ *
+ ****************************************************************************/
+
+static struct flash_device_s *lookup_flash_device_by_id(uint8_t fa_id)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAYSIZE(g_flash_devices); i++)
+ {
+ struct flash_device_s *dev = g_flash_devices[i];
+
+ if (fa_id == dev->fa_cfg->fa_id)
+ {
+ return dev;
+ }
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: lookup_flash_device_by_offset
+ *
+ * Description:
+ * Retrieve flash device from a given flash area offset.
+ *
+ * Input Parameters:
+ * offset - Offset of the flash area.
+ *
+ * Returned Value:
+ * Reference to the found flash device, or NULL in case it does not exist.
+ *
+ ****************************************************************************/
+
+static struct flash_device_s *lookup_flash_device_by_offset(uint32_t offset)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAYSIZE(g_flash_devices); i++)
+ {
+ struct flash_device_s *dev = g_flash_devices[i];
+
+ if (offset == dev->fa_cfg->fa_off)
+ {
+ return dev;
+ }
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: flash_area_open
+ *
+ * Description:
+ * Retrieve flash area from the flash map for a given ID.
+ *
+ * Input Parameters:
+ * fa_id - ID of the flash area.
+ *
+ * Output Parameters:
+ * fa - Pointer which will contain the reference to flash_area.
+ * If ID is unknown, it will be NULL on output.
+ *
+ * Returned Value:
+ * Zero on success, or negative value in case of error.
+ *
+ ****************************************************************************/
+
+int flash_area_open(uint8_t id, const struct flash_area **fa)
+{
+ struct flash_device_s *dev;
+ int fd;
+ int ret;
+
+ BOOT_LOG_INF("ID:%" PRIu8, id);
+
+ dev = lookup_flash_device_by_id(id);
+ if (dev == NULL)
+ {
+ BOOT_LOG_ERR("Undefined flash area: %d", id);
+
+ return ERROR;
+ }
+
+ *fa = dev->fa_cfg;
+
+ if (dev->refs++ > 0)
+ {
+ BOOT_LOG_INF("Flash area ID %d already open, count: %d (+)",
+ id, dev->refs);
+
+ return OK;
+ }
+
+ fd = open(dev->fa_cfg->fa_mtd_path, O_RDWR);
+ if (fd < 0)
+ {
+ int errcode = errno;
+
+ BOOT_LOG_ERR("Error opening MTD device: %d", errcode);
+
+ goto errout;
+ }
+
+ ret = ioctl(fd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&dev->mtdgeo));
+ if (ret < 0)
+ {
+ int errcode = errno;
+
+ BOOT_LOG_ERR("Error retrieving MTD device geometry: %d", errcode);
+
+ goto errout_with_fd;
+ }
+
+ ret = ioctl(fd, BIOC_PARTINFO, (unsigned long)((uintptr_t)&dev->partinfo));
+ if (ret < 0)
+ {
+ int errcode = errno;
+
+ BOOT_LOG_ERR("Error retrieving MTD partition info: %d", errcode);
+
+ goto errout_with_fd;
+ }
+
+ ret = ioctl(fd, MTDIOC_ERASESTATE,
+ (unsigned long)((uintptr_t)&dev->erase_state));
+ if (ret < 0)
+ {
+ int errcode = errno;
+
+ BOOT_LOG_ERR("Error retrieving MTD device erase state: %d", errcode);
+
+ goto errout_with_fd;
+ }
+
+ dev->fa_cfg->fa_off = dev->partinfo.startsector * dev->partinfo.sectorsize;
+ dev->fa_cfg->fa_size = dev->partinfo.numsectors * dev->partinfo.sectorsize;
+
+ BOOT_LOG_INF("Flash area offset: 0x%" PRIx32, dev->fa_cfg->fa_off);
+ BOOT_LOG_INF("Flash area size: %" PRIu32, dev->fa_cfg->fa_size);
+ BOOT_LOG_INF("MTD erase state: 0x%" PRIx8, dev->erase_state);
+
+ dev->fd = fd;
+
+ BOOT_LOG_INF("Flash area %d open, count: %d (+)", id, dev->refs);
+
+ return OK;
+
+errout_with_fd:
+ close(fd);
+
+errout:
+ --dev->refs;
+
+ return ERROR;
+}
+
+/****************************************************************************
+ * Name: flash_area_close
+ *
+ * Description:
+ * Close a given flash area.
+ *
+ * Input Parameters:
+ * fa - Flash area to be closed.
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+void flash_area_close(const struct flash_area *fa)
+{
+ BOOT_LOG_INF("ID:%" PRIu8, fa->fa_id);
+
+ struct flash_device_s *dev = lookup_flash_device_by_id(fa->fa_id);
+
+ DEBUGASSERT(dev != NULL);
+
+ if (dev->refs == 0)
+ {
+ /* No need to close an unopened flash area, avoid an overflow of the
+ * counter.
+ */
+
+ return;
+ }
+
+ BOOT_LOG_INF("Close request for flash area %" PRIu8 ", count: %d (-)",
+ fa->fa_id, dev->refs);
+
+ if (--dev->refs == 0)
+ {
+ close(dev->fd);
+ dev->fd = -1;
+
+ BOOT_LOG_INF("Flash area %" PRIu8 " closed", fa->fa_id);
+ }
+}
+
+/****************************************************************************
+ * Name: flash_area_read
+ *
+ * Description:
+ * Read data from flash area.
+ * Area readout boundaries are asserted before read request. API has the
+ * same limitation regarding read-block alignment and size as the
+ * underlying flash driver.
+ *
+ * Input Parameters:
+ * fa - Flash area to be read.
+ * off - Offset relative from beginning of flash area to be read.
+ * len - Number of bytes to read.
+ *
+ * Output Parameters:
+ * dst - Buffer to store read data.
+ *
+ * Returned Value:
+ * Zero on success, or negative value in case of error.
+ *
+ ****************************************************************************/
+
+int flash_area_read(const struct flash_area *fa, uint32_t off,
+ void *dst, uint32_t len)
+{
+ struct flash_device_s *dev;
+ off_t seekpos;
+ ssize_t nbytes;
+
+ BOOT_LOG_INF("ID:%" PRIu8 " offset:%" PRIu32 " length:%" PRIu32,
+ fa->fa_id, off, len);
+
+ dev = lookup_flash_device_by_id(fa->fa_id);
+
+ DEBUGASSERT(dev != NULL);
+
+ if (off + len > fa->fa_size)
+ {
+ BOOT_LOG_ERR("Attempt to read out of flash area bounds");
+
+ return ERROR;
+ }
+
+ /* Reposition the file offset from the beginning of the flash area */
+
+ seekpos = lseek(dev->fd, (off_t)off, SEEK_SET);
+ if (seekpos != off)
+ {
+ int errcode = errno;
+
+ BOOT_LOG_ERR("Seek to offset %" PRIu32 " failed: %d", off, errcode);
+
+ return ERROR;
+ }
+
+ /* Read the flash block into memory */
+
+ nbytes = read(dev->fd, dst, len);
+ if (nbytes < 0)
+ {
+ int errcode = errno;
+
+ BOOT_LOG_ERR("Read from %s failed: %d", fa->fa_mtd_path, errcode);
+
+ return ERROR;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: flash_area_write
+ *
+ * Description:
+ * Write data to flash area.
+ * Area write boundaries are asserted before write request. API has the
+ * same limitation regarding write-block alignment and size as the
+ * underlying flash driver.
+ *
+ * Input Parameters:
+ * fa - Flash area to be written.
+ * off - Offset relative from beginning of flash area to be written.
+ * src - Buffer with data to be written.
+ * len - Number of bytes to write.
+ *
+ * Returned Value:
+ * Zero on success, or negative value in case of error.
+ *
+ ****************************************************************************/
+
+int flash_area_write(const struct flash_area *fa, uint32_t off,
+ const void *src, uint32_t len)
+{
+ struct flash_device_s *dev;
+ off_t seekpos;
+ ssize_t nbytes;
+
+ BOOT_LOG_INF("ID:%" PRIu8 " offset:%" PRIu32 " length:%" PRIu32,
+ fa->fa_id, off, len);
+
+ dev = lookup_flash_device_by_id(fa->fa_id);
+
+ DEBUGASSERT(dev != NULL);
+
+ if (off + len > fa->fa_size)
+ {
+ BOOT_LOG_ERR("Attempt to write out of flash area bounds");
+
+ return ERROR;
+ }
+
+ /* Reposition the file offset from the beginning of the flash area */
+
+ seekpos = lseek(dev->fd, (off_t)off, SEEK_SET);
+ if (seekpos != off)
+ {
+ int errcode = errno;
+
+ BOOT_LOG_ERR("Seek to offset %" PRIu32 " failed: %d", off, errcode);
+
+ return ERROR;
+ }
+
+ /* Write the buffer to the flash block */
+
+ nbytes = write(dev->fd, src, len);
+ if (nbytes < 0)
+ {
+ int errcode = errno;
+
+ BOOT_LOG_ERR("Write to %s failed: %d", fa->fa_mtd_path, errcode);
+
+ return ERROR;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: flash_area_erase
+ *
+ * Description:
+ * Erase a given flash area range.
+ * Area boundaries are asserted before erase request. API has the same
+ * limitation regarding erase-block alignment and size as the underlying
+ * flash driver.
+ *
+ * Input Parameters:
+ * fa - Flash area to be erased.
+ * off - Offset relative from beginning of flash area to be erased.
+ * len - Number of bytes to be erase.
+ *
+ * Returned Value:
+ * Zero on success, or negative value in case of error.
+ *
+ ****************************************************************************/
+
+int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len)
+{
+ int ret;
+ void *buffer;
+ size_t i;
+ struct flash_device_s *dev = lookup_flash_device_by_id(fa->fa_id);
+ const size_t sector_size = dev->mtdgeo.erasesize;
+ const uint8_t erase_val = dev->erase_state;
+
+ BOOT_LOG_INF("ID:%" PRIu8 " offset:%" PRIu32 " length:%" PRIu32,
+ fa->fa_id, off, len);
+
+ buffer = malloc(sector_size);
+ if (buffer == NULL)
+ {
+ BOOT_LOG_ERR("Failed to allocate erase buffer");
+
+ return ERROR;
+ }
+
+ memset(buffer, erase_val, sizeof(buffer));
+
+ i = 0;
+
+ do
+ {
+ BOOT_LOG_DBG("Erasing %zu bytes at offset %" PRIu32,
+ sector_size, off + i);
+
+ ret = flash_area_write(fa, off + i, buffer, sector_size);
+ i += sector_size;
+ }
+ while (ret == OK && i < (len - sector_size));
+
+ if (ret == OK)
+ {
+ BOOT_LOG_DBG("Erasing %zu bytes at offset %" PRIu32,
+ len - i, off + i);
+
+ ret = flash_area_write(fa, off + i, buffer, len - i);
+ }
+
+ free(buffer);
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: flash_area_align
+ *
+ * Description:
+ * Get write block size of the flash area.
+ * Write block size might be treated as read block size, although most
+ * drivers support unaligned readout.
+ *
+ * Input Parameters:
+ * fa - Flash area.
+ *
+ * Returned Value:
+ * Alignment restriction for flash writes in the given flash area.
+ *
+ ****************************************************************************/
+
+uint8_t flash_area_align(const struct flash_area *fa)
+{
+ /* MTD access alignment is handled by the character and block device
+ * drivers.
+ */
+
+ const uint8_t minimum_write_length = 1;
+
+ BOOT_LOG_INF("ID:%" PRIu8 " align:%" PRIu8,
+ fa->fa_id, minimum_write_length);
+
+ return minimum_write_length;
+}
+
+/****************************************************************************
+ * Name: flash_area_erased_val
+ *
+ * Description:
+ * Get the value expected to be read when accessing any erased flash byte.
+ * This API is compatible with the MCUboot's porting layer.
+ *
+ * Input Parameters:
+ * fa - Flash area.
+ *
+ * Returned Value:
+ * Byte value of erased memory.
+ *
+ ****************************************************************************/
+
+uint8_t flash_area_erased_val(const struct flash_area *fa)
+{
+ struct flash_device_s *dev;
+ uint8_t erased_val;
+
+ dev = lookup_flash_device_by_id(fa->fa_id);
+
+ DEBUGASSERT(dev != NULL);
+
+ erased_val = dev->erase_state;
+
+ BOOT_LOG_INF("ID:%" PRIu8 " erased_val:0x%" PRIx8, fa->fa_id, erased_val);
+
+ return erased_val;
+}
+
+/****************************************************************************
+ * Name: flash_area_get_sectors
+ *
+ * Description:
+ * Retrieve info about sectors within the area.
+ *
+ * Input Parameters:
+ * fa_id - ID of the flash area whose info will be retrieved.
+ * count - On input, represents the capacity of the sectors buffer.
+ *
+ * Output Parameters:
+ * count - On output, it shall contain the number of retrieved sectors.
+ * sectors - Buffer for sectors data.
+ *
+ * Returned Value:
+ * Zero on success, or negative value in case of error.
+ *
+ ****************************************************************************/
+
+int flash_area_get_sectors(int fa_id, uint32_t *count,
+ struct flash_sector *sectors)
+{
+ size_t off;
+ uint32_t total_count = 0;
+ struct flash_device_s *dev = lookup_flash_device_by_id(fa_id);
+ const size_t sector_size = dev->mtdgeo.erasesize;
+ const struct flash_area *fa = fa = dev->fa_cfg;
+
+ for (off = 0; off < fa->fa_size; off += sector_size)
+ {
+ /* Note: Offset here is relative to flash area, not device */
+
+ sectors[total_count].fs_off = off;
+ sectors[total_count].fs_size = sector_size;
+ total_count++;
+ }
+
+ *count = total_count;
+
+ DEBUGASSERT(total_count == dev->mtdgeo.neraseblocks);
+
+ BOOT_LOG_INF("ID:%d count:%" PRIu32, fa_id, *count);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: flash_area_id_from_multi_image_slot
+ *
+ * Description:
+ * Return the flash area ID for a given slot and a given image index
+ * (in case of a multi-image setup).
+ *
+ * Input Parameters:
+ * image_index - Index of the image.
+ * slot - Image slot, which may be 0 (primary) or 1 (secondary).
+ *
+ * Returned Value:
+ * Flash area ID (0 or 1), or negative value in case the requested slot
+ * is invalid.
+ *
+ ****************************************************************************/
+
+int flash_area_id_from_multi_image_slot(int image_index, int slot)
+{
+ BOOT_LOG_INF("image_index:%d slot:%d", image_index, slot);
+
+ switch (slot)
+ {
+ case 0:
+ return FLASH_AREA_IMAGE_PRIMARY(image_index);
+ case 1:
+ return FLASH_AREA_IMAGE_SECONDARY(image_index);
+ }
+
+ BOOT_LOG_ERR("Unexpected Request: image_index:%d, slot:%d",
+ image_index, slot);
+
+ return ERROR; /* flash_area_open will fail on that */
+}
+
+/****************************************************************************
+ * Name: flash_area_id_from_image_slot
+ *
+ * Description:
+ * Return the flash area ID for a given slot.
+ *
+ * Input Parameters:
+ * slot - Image slot, which may be 0 (primary) or 1 (secondary).
+ *
+ * Returned Value:
+ * Flash area ID (0 or 1), or negative value in case the requested slot
+ * is invalid.
+ *
+ ****************************************************************************/
+
+int flash_area_id_from_image_slot(int slot)
+{
+ BOOT_LOG_INF("slot:%d", slot);
+
+ return flash_area_id_from_multi_image_slot(0, slot);
+}
+
+/****************************************************************************
+ * Name: flash_area_id_to_multi_image_slot
+ *
+ * Description:
+ * Convert the specified flash area ID and image index (in case of a
+ * multi-image setup) to an image slot index.
+ *
+ * Input Parameters:
+ * image_index - Index of the image.
+ * fa_id - Image slot, which may be 0 (primary) or 1 (secondary).
+ *
+ * Returned Value:
+ * Image slot index (0 or 1), or negative value in case ID doesn't
+ * correspond to an image slot.
+ *
+ ****************************************************************************/
+
+int flash_area_id_to_multi_image_slot(int image_index, int fa_id)
+{
+ BOOT_LOG_INF("image_index:%d fa_id:%d", image_index, fa_id);
+
+ if (fa_id == FLASH_AREA_IMAGE_PRIMARY(image_index))
+ {
+ return 0;
+ }
+
+ if (fa_id == FLASH_AREA_IMAGE_SECONDARY(image_index))
+ {
+ return 1;
+ }
+
+ BOOT_LOG_ERR("Unexpected Request: image_index:%d, fa_id:%d",
+ image_index, fa_id);
+
+ return ERROR; /* flash_area_open will fail on that */
+}
+
+/****************************************************************************
+ * Name: flash_area_id_from_image_offset
+ *
+ * Description:
+ * Return the flash area ID for a given image offset.
+ *
+ * Input Parameters:
+ * offset - Image offset.
+ *
+ * Returned Value:
+ * Flash area ID (0 or 1), or negative value in case the requested slot
+ * is invalid.
+ *
+ ****************************************************************************/
+
+int flash_area_id_from_image_offset(uint32_t offset)
+{
+ struct flash_device_s *dev = lookup_flash_device_by_offset(offset);
+
+ BOOT_LOG_INF("offset:%" PRIu32, offset);
+
+ return dev->fa_cfg->fa_id;
+}
diff --git a/boot/nuttx/src/watchdog/watchdog.c b/boot/nuttx/src/watchdog/watchdog.c
new file mode 100644
index 0000000..12f2aee
--- /dev/null
+++ b/boot/nuttx/src/watchdog/watchdog.c
@@ -0,0 +1,76 @@
+/****************************************************************************
+ * boot/nuttx/src/watchdog/watchdog.c
+ *
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "watchdog/watchdog.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+#include <nuttx/timers/watchdog.h>
+
+#include <bootutil/bootutil_log.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mcuboot_watchdog_feed
+ *
+ * Description:
+ * Reset the watchdog timer to the current timeout value, preventing any
+ * imminent watchdog timeouts.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+void mcuboot_watchdog_feed(void)
+{
+ int fd;
+ int ret;
+
+ fd = open(CONFIG_MCUBOOT_WATCHDOG_DEVPATH, O_RDONLY);
+ if (fd < 0)
+ {
+ BOOT_LOG_ERR("Failed to open %s", CONFIG_MCUBOOT_WATCHDOG_DEVPATH);
+
+ return;
+ }
+
+ ret = ioctl(fd, WDIOC_KEEPALIVE, 0);
+ if (ret < 0)
+ {
+ int errcode = errno;
+
+ BOOT_LOG_ERR("Failed to ping watchdog device: %d", errcode);
+ }
+
+ close(fd);
+}
diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt
index 49b0fa0..b9bf517 100644
--- a/boot/zephyr/CMakeLists.txt
+++ b/boot/zephyr/CMakeLists.txt
@@ -94,6 +94,12 @@
keys.c
)
+if(DEFINED CONFIG_ENABLE_MGMT_PERUSER)
+ zephyr_library_sources(
+ boot_serial_extensions.c
+ )
+endif()
+
if(NOT DEFINED CONFIG_FLASH_PAGE_LAYOUT)
zephyr_library_sources(
flash_map_legacy.c
@@ -239,6 +245,8 @@
zephyr_sources(${BOOT_DIR}/boot_serial/src/boot_serial.c)
zephyr_sources(${BOOT_DIR}/boot_serial/src/serial_recovery_cbor.c)
zephyr_sources(${BOOT_DIR}/boot_serial/src/cbor_decode.c)
+ zephyr_sources(${BOOT_DIR}/boot_serial/src/cbor_encode.c)
+ zephyr_sources(${BOOT_DIR}/boot_serial/src/cbor_common.c)
zephyr_include_directories(${BOOT_DIR}/bootutil/include)
zephyr_include_directories(${BOOT_DIR}/boot_serial/include)
@@ -250,20 +258,20 @@
)
endif()
-# CONF_FILE points to the KConfig configuration files of the bootloader.
-foreach (filepath ${CONF_FILE})
- file(READ ${filepath} temp_text)
- string(FIND "${temp_text}" ${CONFIG_BOOT_SIGNATURE_KEY_FILE} match)
- if (${match} GREATER_EQUAL 0)
- if (NOT DEFINED CONF_DIR)
- get_filename_component(CONF_DIR ${filepath} DIRECTORY)
- else()
- message(FATAL_ERROR "Signature key file defined in multiple conf files")
- endif()
- endif()
-endforeach()
-
if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "")
+ # CONF_FILE points to the KConfig configuration files of the bootloader.
+ foreach (filepath ${CONF_FILE})
+ file(READ ${filepath} temp_text)
+ string(FIND "${temp_text}" ${CONFIG_BOOT_SIGNATURE_KEY_FILE} match)
+ if (${match} GREATER_EQUAL 0)
+ if (NOT DEFINED CONF_DIR)
+ get_filename_component(CONF_DIR ${filepath} DIRECTORY)
+ else()
+ message(FATAL_ERROR "Signature key file defined in multiple conf files")
+ endif()
+ endif()
+ endforeach()
+
if(IS_ABSOLUTE ${CONFIG_BOOT_SIGNATURE_KEY_FILE})
set(KEY_FILE ${CONFIG_BOOT_SIGNATURE_KEY_FILE})
elseif((DEFINED CONF_DIR) AND
diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig
index 2e7ac39..5d71cd2 100644
--- a/boot/zephyr/Kconfig
+++ b/boot/zephyr/Kconfig
@@ -30,7 +30,6 @@
# When building for ECDSA, we use our own copy of mbedTLS, so the
# Zephyr one must not be enabled or the MBEDTLS_CONFIG_FILE macros
# will collide.
- depends on ! MBEDTLS
help
Use TinyCrypt for crypto primitives.
@@ -41,7 +40,6 @@
# When building for ECDSA, we use our own copy of mbedTLS, so the
# Zephyr one must not be enabled or the MBEDTLS_CONFIG_FILE macros
# will collide.
- depends on ! MBEDTLS
help
Use cc310 for crypto primitives.
@@ -298,15 +296,6 @@
memory usage; larger values allow it to support larger images.
If unsure, leave at the default value.
-config BOOT_ERASE_PROGRESSIVELY
- bool "Erase flash progressively when receiving new firmware"
- default y if SOC_FAMILY_NRF
- help
- If enabled, flash is erased as necessary when receiving new firmware,
- instead of erasing the whole image slot at once. This is necessary
- on some hardware that has long erase times, to prevent long wait
- times at the beginning of the DFU process.
-
config MEASURED_BOOT
bool "Store the boot state/measurements in shared memory"
default n
@@ -364,7 +353,7 @@
config BOOT_USB_DFU_WAIT
bool "Wait for a prescribed duration to see if USB DFU is invoked"
- select USB
+ select USB_DEVICE_STACK
select USB_DFU_CLASS
select IMG_MANAGER
help
@@ -374,7 +363,7 @@
config BOOT_USB_DFU_GPIO
bool "Use GPIO to detect whether to trigger DFU mode"
- select USB
+ select USB_DEVICE_STACK
select USB_DFU_CLASS
select IMG_MANAGER
help
@@ -403,7 +392,8 @@
default 6 if BOARD_NRF9160DK_NRF9160
default 11 if BOARD_NRF52840DK_NRF52840
default 13 if BOARD_NRF52DK_NRF52832
- default 23 if BOARD_NRF5340_DK_NRF5340_CPUAPP || BOARD_NRF5340_DK_NRF5340_CPUAPPNS
+ default 23 if BOARD_NRF5340_DK_NRF5340_CPUAPP || BOARD_NRF5340_DK_NRF5340_CPUAPP_NS
+ default 43 if BOARD_BL5340_DVK_CPUAPP || BOARD_BL5340_DVK_CPUAPP_NS
help
Pin on the DFU detect port that triggers DFU mode.
@@ -468,7 +458,6 @@
select SERIAL
select UART_INTERRUPT_DRIVEN
select BASE64
- select TINYCBOR
help
If y, enables a serial-port based update mode. This allows
MCUboot itself to load update images into flash over a UART.
@@ -487,12 +476,25 @@
config BOOT_SERIAL_CDC_ACM
bool "CDC ACM"
- select USB
select USB_DEVICE_STACK
- select USB_CDC_ACM
endchoice
+config MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD
+ bool "Allow to select image number for DFU"
+ help
+ With the option enabled, the mcuboot serial recovery will
+ respect the "image" field in mcumgr image update frame
+ header.
+ The mapping of image number to partition is as follows:
+ 0 -> default behaviour, same as 1;
+ 1 -> image-0 (primary slot of the first image);
+ 2 -> image-1 (secondary slot of the first image);
+ 3 -> image-2;
+ 4 -> image-3.
+ Note that 0 is default upload target when no explicit
+ selection is done.
+
config MCUBOOT_INDICATION_LED
bool "Turns on LED indication when device is in DFU"
default n
@@ -518,9 +520,9 @@
int "Pin to trigger serial recovery mode"
default 6 if BOARD_NRF9160DK_NRF9160
default 11 if BOARD_NRF52840DK_NRF52840
- default 13 if BOARD_NRF52DK_NRF52832
- default 23 if BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS || \
- BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPPNS
+ default 13 if BOARD_NRF52DK_NRF52832 || BOARD_NRF52833DK_NRF52833
+ default 23 if BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPP_NS || \
+ BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP_NS
help
Pin on the serial detect port that triggers serial recovery mode.
@@ -540,18 +542,40 @@
Useful for powering on when using the same button as
the one used to place the device in bootloader mode.
-# Workaround for not being able to have commas in macro arguments
-DT_CHOSEN_Z_CONSOLE := zephyr,console
-
-config RECOVERY_UART_DEV_NAME
- string "UART Device Name for Recovery UART"
- default "$(dt_chosen_label,$(DT_CHOSEN_Z_CONSOLE))" if HAS_DTS
- default "UART_0"
- depends on BOOT_SERIAL_UART
+config BOOT_ERASE_PROGRESSIVELY
+ bool "Erase flash progressively when receiving new firmware"
+ default y if SOC_FAMILY_NRF
help
- This option specifies the name of UART device to be used for
- serial recovery.
+ If enabled, flash is erased as necessary when receiving new firmware,
+ instead of erasing the whole image slot at once. This is necessary
+ on some hardware that has long erase times, to prevent long wait
+ times at the beginning of the DFU process.
+menuconfig ENABLE_MGMT_PERUSER
+ bool "Enable system specific mcumgr commands"
+ help
+ The option enables processing of system specific mcumgr commands;
+ system specific commands are within group MGMT_GROUP_ID_PERUSER (64)
+ and above, as defined within mcumgr library.
+ These are system specific command and system specific implementation
+ function is required to process these commands.
+
+if ENABLE_MGMT_PERUSER
+config BOOT_MGMT_CUSTOM_STORAGE_ERASE
+ bool "Enable storage erase command"
+ help
+ The option enables mcumgr command that allows to erase storage
+ partition.
+ Note that the storage partition needs to be defined, in DTS, otherwise
+ enabling the option will cause a compilation to fail.
+
+config BOOT_MGMT_CUSTOM_IMG_LIST
+ bool "Enable custom image list command"
+ help
+ The option enables command which returns versions and installation
+ statuses (custom property) for all images.
+
+endif # ENABLE_MGMT_PERUSER
endif # MCUBOOT_SERIAL
config BOOT_INTR_VEC_RELOC
@@ -604,6 +628,24 @@
Enables implementation of MCUBOOT_WATCHDOG_FEED() macro which is
used to feed watchdog while doing time consuming operations.
+config BOOT_IMAGE_ACCESS_HOOKS
+ bool "Enable hooks for overriding MCUboot's native routines"
+ help
+ Allow to provide procedures for override or extend native
+ MCUboot's routines required for access the image data and the image
+ update.
+
+config BOOT_IMAGE_ACCESS_HOOKS_FILE
+ string "Hooks implementation file path"
+ depends on BOOT_IMAGE_ACCESS_HOOKS
+ help
+ Path to the file which implements hooks.
+ You can use either absolute or relative path.
+ In case relative path is used, the build system assumes that it starts
+ from the directory where the MCUBoot KConfig configuration file is
+ located. If the key file is not there, the build system uses relative
+ path that starts from the zephyr port cmake directory (boot/zephyr/).
+
endmenu
config MCUBOOT_DEVICE_SETTINGS
@@ -638,10 +680,6 @@
default n if SOC_FAMILY_NRF
default y
-config LOG_IMMEDIATE
- default n if MULTITHREADING
- default y
-
config LOG_PROCESS_THREAD
default n # mcuboot has its own log processing thread
diff --git a/boot/zephyr/boards/flash_sim_driver.conf b/boot/zephyr/boards/flash_sim_driver.conf
new file mode 100644
index 0000000..7e5e58e
--- /dev/null
+++ b/boot/zephyr/boards/flash_sim_driver.conf
@@ -0,0 +1,2 @@
+CONFIG_FLASH_SIMULATOR=y
+CONFIG_FLASH_SIMULATOR_UNALIGNED_READ=y
diff --git a/boot/zephyr/boards/mimxrt1020_evk.conf b/boot/zephyr/boards/mimxrt1020_evk.conf
new file mode 100644
index 0000000..37ed5f8
--- /dev/null
+++ b/boot/zephyr/boards/mimxrt1020_evk.conf
@@ -0,0 +1,4 @@
+# Copyright 2021 NXP
+# SPDX-License-Identifier: Apache-2.0
+
+CONFIG_BOOT_MAX_IMG_SECTORS=1024
diff --git a/boot/zephyr/boards/mimxrt1050_evk_qspi.conf b/boot/zephyr/boards/mimxrt1050_evk_qspi.conf
new file mode 100644
index 0000000..37ed5f8
--- /dev/null
+++ b/boot/zephyr/boards/mimxrt1050_evk_qspi.conf
@@ -0,0 +1,4 @@
+# Copyright 2021 NXP
+# SPDX-License-Identifier: Apache-2.0
+
+CONFIG_BOOT_MAX_IMG_SECTORS=1024
diff --git a/boot/zephyr/boards/mimxrt1060_evk.conf b/boot/zephyr/boards/mimxrt1060_evk.conf
new file mode 100644
index 0000000..37ed5f8
--- /dev/null
+++ b/boot/zephyr/boards/mimxrt1060_evk.conf
@@ -0,0 +1,4 @@
+# Copyright 2021 NXP
+# SPDX-License-Identifier: Apache-2.0
+
+CONFIG_BOOT_MAX_IMG_SECTORS=1024
diff --git a/boot/zephyr/boards/mimxrt1064_evk.conf b/boot/zephyr/boards/mimxrt1064_evk.conf
new file mode 100644
index 0000000..1c50bc9
--- /dev/null
+++ b/boot/zephyr/boards/mimxrt1064_evk.conf
@@ -0,0 +1,4 @@
+# Copyright 2021 NXP
+# SPDX-License-Identifier: Apache-2.0
+
+CONFIG_BOOT_MAX_IMG_SECTORS=512
diff --git a/boot/zephyr/boards/nrf52840_big.overlay b/boot/zephyr/boards/nrf52840_big.overlay
index 094a7a4..778a1ed 100644
--- a/boot/zephyr/boards/nrf52840_big.overlay
+++ b/boot/zephyr/boards/nrf52840_big.overlay
@@ -28,3 +28,10 @@
};
};
};
+
+&zephyr_udc0 {
+ cdc_acm_uart0 {
+ compatible = "zephyr,cdc-acm-uart";
+ label = "CDC_ACM_0";
+ };
+};
diff --git a/boot/zephyr/boards/nrf52840dk_hooks_sample_overlay.conf b/boot/zephyr/boards/nrf52840dk_hooks_sample_overlay.conf
new file mode 100644
index 0000000..5c13cd2
--- /dev/null
+++ b/boot/zephyr/boards/nrf52840dk_hooks_sample_overlay.conf
@@ -0,0 +1,7 @@
+CONFIG_UPDATEABLE_IMAGE_NUMBER=2
+
+CONFIG_FLASH_SIMULATOR=y
+CONFIG_FLASH_SIMULATOR_UNALIGNED_READ=y
+
+CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y
+CONFIG_BOOT_IMAGE_ACCESS_HOOKS_FILE="hooks_sample.c"
diff --git a/boot/zephyr/boards/nrf52840dk_ram.overlay b/boot/zephyr/boards/nrf52840dk_ram.overlay
new file mode 100644
index 0000000..a1f9f38
--- /dev/null
+++ b/boot/zephyr/boards/nrf52840dk_ram.overlay
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2021 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/delete-node/ &slot1_partition;
+/delete-node/ &slot0_partition;
+/delete-node/ &boot_partition;
+
+&flash0 {
+ partitions {
+ boot_partition: partition@0 {
+ label = "mcuboot";
+ reg = <0x000000000 0x00010000>;
+ };
+ slot0_partition: partition@10000 {
+ label = "image-0";
+ reg = <0x000010000 0x00000A000>;
+ };
+ };
+};
+
+/ {
+ soc {
+ flash_controller2: flash-controller@2 {
+ compatible = "zephyr,sim-flash";
+ reg = <0x00000000 DT_SIZE_K(40)>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ erase-value = <0xff>;
+
+ label = "flash_ctrl";
+
+ flash_sim0: flash_sim@0 {
+ status = "okay";
+ compatible = "soc-nv-flash";
+ label = "simulated_flash";
+ erase-block-size = <4096>;
+ write-block-size = <1>;
+ reg = <0x00000000 DT_SIZE_K(40)>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ slot1_partition: partition@0 {
+ label = "image-1";
+ reg = <0x00000000 0x00000A000>;
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/boot/zephyr/boards/nrf52840dk_ram_multi.overlay b/boot/zephyr/boards/nrf52840dk_ram_multi.overlay
new file mode 100644
index 0000000..7befec9
--- /dev/null
+++ b/boot/zephyr/boards/nrf52840dk_ram_multi.overlay
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2021 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/delete-node/ &slot1_partition;
+/delete-node/ &slot0_partition;
+/delete-node/ &boot_partition;
+
+&flash0 {
+ partitions {
+ boot_partition: partition@0 {
+ label = "mcuboot";
+ reg = <0x000000000 0x00010000>;
+ };
+ slot0_partition: partition@10000 {
+ label = "image-0";
+ reg = <0x000010000 0x00000A000>;
+ };
+ slot1_partition: partition@1A000 {
+ label = "image-1";
+ reg = <0x00001A000 0x00000A000>;
+ };
+ slot3_partition: partition@24000 {
+ label = "image-3";
+ reg = <0x000024000 0x00000A000>;
+ };
+ };
+};
+
+/ {
+ soc {
+ flash_controller2: flash-controller@2 {
+ compatible = "zephyr,sim-flash";
+ reg = <0x00000000 DT_SIZE_K(40)>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ erase-value = <0xff>;
+
+ label = "flash_ctrl";
+
+ flash_sim0: flash_sim@0 {
+ status = "okay";
+ compatible = "soc-nv-flash";
+ label = "simulated_flash";
+ erase-block-size = <4096>;
+ write-block-size = <1>;
+ reg = <0x00000000 DT_SIZE_K(40)>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ slot2_partition: partition@0 {
+ label = "image-2";
+ reg = <0x00000000 0x00000A000>;
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/boot/zephyr/boards/nrf52840dongle_nrf52840.conf b/boot/zephyr/boards/nrf52840dongle_nrf52840.conf
index ba333d9..f4fbb39 100644
--- a/boot/zephyr/boards/nrf52840dongle_nrf52840.conf
+++ b/boot/zephyr/boards/nrf52840dongle_nrf52840.conf
@@ -24,9 +24,7 @@
CONFIG_MULTITHREADING=y
# USB
-CONFIG_USB=y
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_PRODUCT="MCUBOOT"
-CONFIG_USB_CDC_ACM=y
CONFIG_USB_COMPOSITE_DEVICE=n
CONFIG_USB_MASS_STORAGE=n
diff --git a/boot/zephyr/boards/nrf52_minimal_footprint.conf b/boot/zephyr/boards/nrf52_minimal_footprint.conf
index afe8c9b..81c0845 100644
--- a/boot/zephyr/boards/nrf52_minimal_footprint.conf
+++ b/boot/zephyr/boards/nrf52_minimal_footprint.conf
@@ -44,7 +44,7 @@
CONFIG_SERIAL=n
# Power management
-CONFIG_SYS_POWER_MANAGEMENT=n
+CONFIG_PM=n
# Interrupts
CONFIG_DYNAMIC_INTERRUPTS=n
diff --git a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf
new file mode 100644
index 0000000..754bf7b
--- /dev/null
+++ b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf
@@ -0,0 +1,81 @@
+CONFIG_SIZE_OPTIMIZATIONS=y
+
+CONFIG_SYSTEM_CLOCK_DISABLE=y
+CONFIG_SYSTEM_CLOCK_NO_WAIT=y
+CONFIG_PM=n
+
+CONFIG_MAIN_STACK_SIZE=10240
+CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h"
+
+CONFIG_BOOT_MAX_IMG_SECTORS=2048
+CONFIG_BOOT_SIGNATURE_TYPE_RSA=y
+
+# Flash
+CONFIG_FLASH=y
+CONFIG_BOOT_ERASE_PROGRESSIVELY=y
+CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS=y
+CONFIG_FPROTECT=y
+
+# Serial
+CONFIG_SERIAL=y
+CONFIG_UART_LINE_CTRL=y
+
+# MCUBoot serial
+CONFIG_GPIO=y
+CONFIG_MCUBOOT_SERIAL=y
+CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y
+CONFIG_BOOT_SERIAL_CDC_ACM=y
+CONFIG_BOOT_SERIAL_DETECT_PORT="GPIO_1"
+CONFIG_BOOT_SERIAL_DETECT_PIN=13
+
+# Required by QSPI
+CONFIG_NORDIC_QSPI_NOR=y
+CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
+CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16
+
+CONFIG_PM_EXTERNAL_FLASH_SUPPORT_LEGACY=y
+CONFIG_PM_EXTERNAL_FLASH=y
+CONFIG_PM_EXTERNAL_FLASH_DEV_NAME="MX25R64"
+CONFIG_PM_EXTERNAL_FLASH_BASE=0x0
+CONFIG_PM_EXTERNAL_FLASH_SIZE=0x800000
+
+# Required by USB and QSPI
+CONFIG_MULTITHREADING=y
+
+# USB
+CONFIG_USB=y
+CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor ASA"
+CONFIG_USB_DEVICE_PRODUCT="Bootloader Thingy:53"
+CONFIG_USB_DEVICE_VID=0x1915
+CONFIG_USB_DEVICE_PID=0x5300
+CONFIG_USB_CDC_ACM=y
+
+# Decrease memory footprint
+CONFIG_CBPRINTF_NANO=y
+CONFIG_TIMESLICING=n
+CONFIG_BOOT_BANNER=n
+CONFIG_CONSOLE=n
+CONFIG_CONSOLE_HANDLER=n
+CONFIG_UART_CONSOLE=n
+CONFIG_USE_SEGGER_RTT=n
+CONFIG_LOG=n
+CONFIG_ERRNO=n
+CONFIG_PRINTK=n
+CONFIG_RESET_ON_FATAL_ERROR=n
+CONFIG_SPI=n
+CONFIG_I2C=n
+CONFIG_UART_NRFX=n
+
+# The following configurations are required to support simultaneous multi image update
+CONFIG_PCD_APP=y
+CONFIG_UPDATEABLE_IMAGE_NUMBER=2
+CONFIG_BOOT_UPGRADE_ONLY=y
+# The network core cannot access external flash directly. The flash simulator must be used to
+# provide a memory region that is used to forward the new firmware to the network core.
+CONFIG_FLASH_SIMULATOR=y
+CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y
+CONFIG_FLASH_SIMULATOR_STATS=n
+
+# Enable custom command to erase settings partition.
+CONFIG_ENABLE_MGMT_PERUSER=y
+CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y
diff --git a/boot/zephyr/boot_serial_extensions.c b/boot/zephyr/boot_serial_extensions.c
new file mode 100644
index 0000000..49bb4ea
--- /dev/null
+++ b/boot/zephyr/boot_serial_extensions.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2021 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <zephyr.h>
+#include <drivers/flash.h>
+#include <mgmt/mcumgr/zephyr_groups.h>
+
+#include <flash_map_backend/flash_map_backend.h>
+#include <sysflash/sysflash.h>
+
+#include "bootutil/bootutil_log.h"
+#include "../boot_serial/src/boot_serial_priv.h"
+#include "../boot_serial/src/cbor_encode.h"
+
+#include "bootutil/image.h"
+#include "bootutil/bootutil_public.h"
+#include "bootutil/boot_hooks.h"
+
+MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
+
+#ifdef CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE
+static int bs_custom_storage_erase(cbor_state_t *cs)
+{
+ int rc;
+
+ const struct flash_area *fa;
+
+ rc = flash_area_open(FLASH_AREA_ID(storage), &fa);
+
+ if (rc < 0) {
+ LOG_ERR("failed to open flash area");
+ } else {
+ rc = flash_area_erase(fa, 0, FLASH_AREA_SIZE(storage));
+ if (rc < 0) {
+ LOG_ERR("failed to erase flash area");
+ }
+ flash_area_close(fa);
+ }
+ if (rc == 0) {
+ rc = MGMT_ERR_OK;
+ } else {
+ rc = MGMT_ERR_EUNKNOWN;
+ }
+
+ map_start_encode(cs, 10);
+ tstrx_put(cs, "rc");
+ uintx32_put(cs, rc);
+ map_end_encode(cs, 10);
+
+ return rc;
+}
+#endif
+
+#ifdef MCUBOOT_MGMT_CUSTOM_IMG_LIST
+static int custom_img_status(int image_index, uint32_t slot,char *buffer,
+ ssize_t len)
+{
+ uint32_t area_id;
+ struct flash_area const *fap;
+ struct image_header hdr;
+ int rc;
+ int img_install_stat;
+
+ rc = BOOT_HOOK_CALL(boot_img_install_stat_hook, BOOT_HOOK_REGULAR,
+ image_index, slot, &img_install_stat);
+ if (rc == BOOT_HOOK_REGULAR)
+ {
+ img_install_stat = 0;
+ }
+
+ rc = BOOT_HOOK_CALL(boot_read_image_header_hook, BOOT_HOOK_REGULAR,
+ image_index, slot, &hdr);
+ if (rc == BOOT_HOOK_REGULAR)
+ {
+ area_id = flash_area_id_from_multi_image_slot(image_index, slot);
+
+ rc = flash_area_open(area_id, &fap);
+ if (rc) {
+ return rc;
+ }
+
+ rc = flash_area_read(fap, 0, &hdr, sizeof(hdr));
+
+ flash_area_close(fap);
+ }
+
+ if (rc == 0) {
+ if (hdr.ih_magic == IMAGE_MAGIC) {
+ snprintf(buffer, len, "ver=%d.%d.%d.%d,install_stat=%d",
+ hdr.ih_ver.iv_major,
+ hdr.ih_ver.iv_minor,
+ hdr.ih_ver.iv_revision,
+ hdr.ih_ver.iv_build_num,
+ img_install_stat);
+ } else {
+ rc = 1;
+ }
+ }
+
+ return rc;
+}
+
+static int bs_custom_img_list(cbor_state_t *cs)
+{
+ int rc = 0;
+ char tmpbuf[64]; /* Buffer should fit version and flags */
+
+ map_start_encode(cs, 10);
+
+ for (int img = 0; img < MCUBOOT_IMAGE_NUMBER; img++) {
+ for (int slot = 0; slot < 2; slot++) {
+ rc = custom_img_status(img, slot, tmpbuf, sizeof(tmpbuf));
+
+ intx32_put(cs, img * 2 + slot + 1);
+ if (rc == 0) {
+ tstrx_put_term(cs, tmpbuf);
+ } else {
+ tstrx_put_term(cs, "");
+ }
+ }
+ }
+
+ tstrx_put(cs, "rc");
+ uintx32_put(cs, MGMT_ERR_OK);
+ map_end_encode(cs, 10);
+
+ return rc;
+}
+
+#ifndef ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST
+ #define ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST 1
+#endif
+#endif /*MCUBOOT_MGMT_CUSTOM_IMG_LIST*/
+
+int bs_peruser_system_specific(const struct nmgr_hdr *hdr, const char *buffer,
+ int len, cbor_state_t *cs)
+{
+ int mgmt_rc = MGMT_ERR_ENOTSUP;
+
+ if (hdr->nh_group == ZEPHYR_MGMT_GRP_BASE) {
+ if (hdr->nh_op == NMGR_OP_WRITE) {
+#ifdef CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE
+ if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_ERASE_STORAGE) {
+ mgmt_rc = bs_custom_storage_erase(cs);
+ }
+#endif
+ } else if (hdr->nh_op == NMGR_OP_READ) {
+#ifdef MCUBOOT_MGMT_CUSTOM_IMG_LIST
+ if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST) {
+ mgmt_rc = bs_custom_img_list(cs);
+ }
+#endif
+ }
+ }
+
+ if (mgmt_rc == MGMT_ERR_ENOTSUP) {
+ map_start_encode(cs, 10);
+ tstrx_put(cs, "rc");
+ uintx32_put(cs, mgmt_rc);
+ map_end_encode(cs, 10);
+ }
+
+ return MGMT_ERR_OK;
+}
diff --git a/boot/zephyr/flash_map_extended.c b/boot/zephyr/flash_map_extended.c
index 7b6ae63..a52d58f 100644
--- a/boot/zephyr/flash_map_extended.c
+++ b/boot/zephyr/flash_map_extended.c
@@ -15,7 +15,7 @@
#include "bootutil/bootutil_log.h"
-MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
+BOOT_LOG_MODULE_DECLARE(mcuboot);
#if (!defined(CONFIG_XTENSA) && defined(DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL))
#define FLASH_DEVICE_ID SOC_FLASH_0_ID
@@ -59,9 +59,9 @@
case 0: return FLASH_AREA_IMAGE_PRIMARY(image_index);
#if !defined(CONFIG_SINGLE_APPLICATION_SLOT)
case 1: return FLASH_AREA_IMAGE_SECONDARY(image_index);
-#if !defined(CONFIG_BOOT_SWAP_USING_MOVE)
- case 2: return FLASH_AREA_IMAGE_SCRATCH;
#endif
+#if defined(CONFIG_BOOT_SWAP_USING_SCRATCH)
+ case 2: return FLASH_AREA_IMAGE_SCRATCH;
#endif
}
@@ -93,6 +93,30 @@
return flash_area_id_to_multi_image_slot(0, area_id);
}
+#if defined(CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD)
+int flash_area_id_from_direct_image(int image_id)
+{
+ switch (image_id) {
+ case 0:
+ case 1:
+ return FLASH_AREA_ID(image_0);
+#if DT_HAS_FIXED_PARTITION_LABEL(image_1)
+ case 2:
+ return FLASH_AREA_ID(image_1);
+#endif
+#if DT_HAS_FIXED_PARTITION_LABEL(image_2)
+ case 3:
+ return FLASH_AREA_ID(image_2);
+#endif
+#if DT_HAS_FIXED_PARTITION_LABEL(image_3)
+ case 4:
+ return FLASH_AREA_ID(image_3);
+#endif
+ }
+ return -EINVAL;
+}
+#endif
+
int flash_area_sector_from_off(off_t off, struct flash_sector *sector)
{
int rc;
@@ -109,6 +133,12 @@
return rc;
}
+uint8_t flash_area_get_device_id(const struct flash_area *fa)
+{
+ (void)fa;
+ return FLASH_DEVICE_ID;
+}
+
#define ERASED_VAL 0xff
__weak uint8_t flash_area_erased_val(const struct flash_area *fap)
{
diff --git a/boot/zephyr/flash_map_legacy.c b/boot/zephyr/flash_map_legacy.c
index b217947..6a8e7ae 100644
--- a/boot/zephyr/flash_map_legacy.c
+++ b/boot/zephyr/flash_map_legacy.c
@@ -49,7 +49,7 @@
#define FLASH_AREA_IMAGE_SECTOR_SIZE FLASH_AREA_IMAGE_SCRATCH_SIZE
#endif
-MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
+BOOT_LOG_MODULE_DECLARE(mcuboot);
/*
* Lookup the sector map for a given flash area. This should fill in
diff --git a/boot/zephyr/hooks_sample.c b/boot/zephyr/hooks_sample.c
new file mode 100644
index 0000000..a4dbfb5
--- /dev/null
+++ b/boot/zephyr/hooks_sample.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2021 Nordic Semiconductor ASA
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <zephyr.h>
+#include "bootutil/image.h"
+#include "bootutil/bootutil.h"
+#include "bootutil/fault_injection_hardening.h"
+#include "flash_map_backend/flash_map_backend.h"
+
+/* @retval 0: header was read/populated
+ * FIH_FAILURE: image is invalid,
+ * BOOT_HOOK_REGULAR if hook not implemented for the image-slot,
+ * othervise an error-code value.
+ */
+int boot_read_image_header_hook(int img_index, int slot,
+ struct image_header *img_hed)
+{
+ if (img_index == 1 && slot == 0) {
+ img_hed->ih_magic = IMAGE_MAGIC;
+ return 0;
+ }
+
+ return BOOT_HOOK_REGULAR;
+}
+
+/* @retval FIH_SUCCESS: image is valid,
+ * FIH_FAILURE: image is invalid,
+ * fih encoded BOOT_HOOK_REGULAR if hook not implemented for
+ * the image-slot.
+ */
+fih_int boot_image_check_hook(int img_index, int slot)
+{
+ if (img_index == 1 && slot == 0) {
+ FIH_RET(FIH_SUCCESS);
+ }
+
+ FIH_RET(fih_int_encode(BOOT_HOOK_REGULAR));
+}
+
+int boot_perform_update_hook(int img_index, struct image_header *img_head,
+ const struct flash_area *area)
+{
+ if (img_index == 1) {
+ return 0;
+ }
+
+ return BOOT_HOOK_REGULAR;
+}
+
+int boot_read_swap_state_primary_slot_hook(int image_index,
+ struct boot_swap_state *state)
+{
+ if (image_index == 1) {
+ state->magic = BOOT_MAGIC_UNSET;
+ state->swap_type = BOOT_SWAP_TYPE_NONE;
+ state->image_num = image_index ; // ?
+ state->copy_done = BOOT_FLAG_UNSET;
+ state->image_ok = BOOT_FLAG_UNSET;
+
+ return 0;
+ }
+
+ return BOOT_HOOK_REGULAR;
+}
+
+int boot_copy_region_post_hook(int img_index, const struct flash_area *area,
+ size_t size)
+{
+ return 0;
+}
+
+int boot_serial_uploaded_hook(int img_index, const struct flash_area *area,
+ size_t size)
+{
+ return 0;
+}
+
+int boot_img_install_stat_hook(int image_index, int slot, int *img_install_stat)
+{
+ return BOOT_HOOK_REGULAR;
+}
diff --git a/boot/zephyr/include/config-ecdsa.h b/boot/zephyr/include/config-ec.h
similarity index 93%
rename from boot/zephyr/include/config-ecdsa.h
rename to boot/zephyr/include/config-ec.h
index 6ae1ada..3b11295 100644
--- a/boot/zephyr/include/config-ecdsa.h
+++ b/boot/zephyr/include/config-ec.h
@@ -1,7 +1,7 @@
/*
* Minimal configuration for using TLS in the bootloader
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright (C) 2006-2021, ARM Limited, All Rights Reserved
* Copyright (C) 2016, Linaro Ltd
* SPDX-License-Identifier: Apache-2.0
*
@@ -53,6 +53,7 @@
#endif
#define MBEDTLS_ECDSA_C
+#define MBEDTLS_ECDH_C
/* mbed TLS modules */
#define MBEDTLS_ASN1_PARSE_C
@@ -64,6 +65,7 @@
#define MBEDTLS_MD_C
#define MBEDTLS_OID_C
#define MBEDTLS_SHA256_C
+#define MBEDTLS_SHA224_C
#define MBEDTLS_AES_C
/* Bring in support for x509. */
@@ -77,7 +79,7 @@
#define MBEDTLS_MPI_MAX_SIZE 32
-#define MBEDTLS_SSL_MAX_CONTENT_LEN 1024
+#define MBEDTLS_SSL_MAX_CONTENT_LEN 1024
/* Save ROM and a few bytes of RAM by specifying our own ciphersuite list */
#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
diff --git a/boot/zephyr/include/config-ed25519.h b/boot/zephyr/include/config-ed25519.h
index 3efb7bd..7e43708 100644
--- a/boot/zephyr/include/config-ed25519.h
+++ b/boot/zephyr/include/config-ed25519.h
@@ -1,7 +1,7 @@
/*
* Configuration of mbedTLS containing only the ASN.1 parser.
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright (C) 2006-2021, ARM Limited, All Rights Reserved
* Copyright (C) 2016, Linaro Ltd
* SPDX-License-Identifier: Apache-2.0
*
@@ -60,6 +60,7 @@
#define MBEDTLS_MD_C
#define MBEDTLS_OID_C
#define MBEDTLS_SHA256_C
+#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA512_C
#define MBEDTLS_AES_C
diff --git a/boot/zephyr/include/config-kw.h b/boot/zephyr/include/config-kw.h
index 0ed94d1..168e56e 100644
--- a/boot/zephyr/include/config-kw.h
+++ b/boot/zephyr/include/config-kw.h
@@ -1,7 +1,7 @@
/*
* Minimal configuration for using TLS in the bootloader
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright (C) 2006-2021, ARM Limited, All Rights Reserved
* Copyright (C) 2016, Linaro Ltd
* SPDX-License-Identifier: Apache-2.0
*
@@ -57,6 +57,7 @@
#define MBEDTLS_CIPHER_MODE_CTR
#define MBEDTLS_SHA256_C
+#define MBEDTLS_SHA224_C
#define MBEDTLS_AES_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_NIST_KW_C
diff --git a/boot/zephyr/include/config-rsa-kw.h b/boot/zephyr/include/config-rsa-kw.h
index 99c9957..bc3da7d 100644
--- a/boot/zephyr/include/config-rsa-kw.h
+++ b/boot/zephyr/include/config-rsa-kw.h
@@ -1,7 +1,7 @@
/*
* Minimal configuration for using TLS in the bootloader
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright (C) 2006-2021, ARM Limited, All Rights Reserved
* Copyright (C) 2016, Linaro Ltd
* SPDX-License-Identifier: Apache-2.0
*
@@ -63,6 +63,7 @@
#define MBEDTLS_MD_C
#define MBEDTLS_OID_C
#define MBEDTLS_SHA256_C
+#define MBEDTLS_SHA224_C
#define MBEDTLS_AES_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_NIST_KW_C
diff --git a/boot/zephyr/include/config-rsa.h b/boot/zephyr/include/config-rsa.h
index 265b290..0552420 100644
--- a/boot/zephyr/include/config-rsa.h
+++ b/boot/zephyr/include/config-rsa.h
@@ -1,7 +1,7 @@
/*
* Minimal configuration for using TLS in the bootloader
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright (C) 2006-2021, ARM Limited, All Rights Reserved
* Copyright (C) 2016, Linaro Ltd
* SPDX-License-Identifier: Apache-2.0
*
@@ -64,6 +64,7 @@
#define MBEDTLS_MD_C
#define MBEDTLS_OID_C
#define MBEDTLS_SHA256_C
+#define MBEDTLS_SHA224_C
#define MBEDTLS_AES_C
/* Save RAM by adjusting to our exact needs */
diff --git a/boot/zephyr/include/flash_map_backend/flash_map_backend.h b/boot/zephyr/include/flash_map_backend/flash_map_backend.h
index 958cdcb..ae95217 100644
--- a/boot/zephyr/include/flash_map_backend/flash_map_backend.h
+++ b/boot/zephyr/include/flash_map_backend/flash_map_backend.h
@@ -76,19 +76,38 @@
*/
int flash_area_sector_from_off(off_t off, struct flash_sector *sector);
+static inline uint32_t flash_area_get_off(const struct flash_area *fa)
+{
+ return (uint32_t)fa->fa_off;
+}
+
+static inline uint32_t flash_area_get_size(const struct flash_area *fa)
+{
+ return (uint32_t)fa->fa_size;
+}
+
+static inline uint8_t flash_area_get_id(const struct flash_area *fa)
+{
+ return fa->fa_id;
+}
+
+uint8_t flash_area_get_device_id(const struct flash_area *fa);
+
/*
* Returns the value expected to be read when accessing any erased
* flash byte.
*/
uint8_t flash_area_erased_val(const struct flash_area *fap);
-/*
- * Reads len bytes from off, and checks if the read data is erased.
- *
- * Returns 1 if erased, 0 if non-erased, and -1 on failure.
- */
-int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off,
- void *dst, uint32_t len);
+static inline uint32_t flash_sector_get_off(const struct flash_sector *fs)
+{
+ return fs->fs_off;
+}
+
+static inline uint32_t flash_sector_get_size(const struct flash_sector *fs)
+{
+ return fs->fs_size;
+}
#ifdef __cplusplus
}
diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h
index 8f2b157..7061fc1 100644
--- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h
+++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h
@@ -34,6 +34,14 @@
#define MCUBOOT_SIGN_ED25519
#endif
+#if defined(CONFIG_BOOT_USE_TINYCRYPT)
+# if defined(CONFIG_MBEDTLS) || defined(CONFIG_BOOT_USE_CC310)
+# error "One crypto library implementation allowed at a time."
+# endif
+#elif defined(CONFIG_MBEDTLS) && defined(CONFIG_BOOT_USE_CC310)
+# error "One crypto library implementation allowed at a time."
+#endif
+
#ifdef CONFIG_BOOT_USE_MBEDTLS
#define MCUBOOT_USE_MBED_TLS
#elif defined(CONFIG_BOOT_USE_TINYCRYPT)
@@ -60,6 +68,7 @@
#ifdef CONFIG_SINGLE_APPLICATION_SLOT
#define MCUBOOT_SINGLE_APPLICATION_SLOT 1
+#define MCUBOOT_IMAGE_NUMBER 1
#else
#ifdef CONFIG_BOOT_SWAP_USING_MOVE
@@ -145,6 +154,40 @@
#define MCUBOOT_FIH_PROFILE_HIGH
#endif
+#ifdef CONFIG_ENABLE_MGMT_PERUSER
+#define MCUBOOT_PERUSER_MGMT_GROUP_ENABLED 1
+#else
+#define MCUBOOT_PERUSER_MGMT_GROUP_ENABLED 0
+#endif
+
+#ifdef CONFIG_BOOT_MGMT_CUSTOM_IMG_LIST
+#define MCUBOOT_MGMT_CUSTOM_IMG_LIST
+#endif
+
+#ifdef CONFIG_BOOT_IMAGE_ACCESS_HOOKS
+#define MCUBOOT_IMAGE_ACCESS_HOOKS
+#endif
+
+/*
+ * The configuration option enables direct image upload with the
+ * serial recovery.
+ */
+#ifdef CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD
+#define MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD
+#endif
+
+/*
+ * The option enables code, currently in boot_serial, that attempts
+ * to erase flash progressively, as update fragments are received,
+ * instead of erasing whole image size of flash area after receiving
+ * first frame.
+ * Enabling this options prevents stalling the beginning of transfer
+ * for the time needed to erase large chunk of flash.
+ */
+#ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
+#define MCBOOT_ERASE_PROGRESSIVELY
+#endif
+
/*
* Enabling this option uses newer flash map APIs. This saves RAM and
* avoids deprecated API usage.
@@ -154,6 +197,13 @@
*/
#define MCUBOOT_USE_FLASH_AREA_GET_SECTORS
+#if (defined(CONFIG_BOOT_USB_DFU_WAIT) || \
+ defined(CONFIG_BOOT_USB_DFU_GPIO))
+# ifndef CONFIG_MULTITHREADING
+# error "USB DFU Requires MULTITHREADING"
+# endif
+#endif
+
#ifdef CONFIG_BOOT_MAX_IMG_SECTORS
#define MCUBOOT_MAX_IMG_SECTORS CONFIG_BOOT_MAX_IMG_SECTORS
@@ -205,4 +255,9 @@
#endif /* CONFIG_BOOT_WATCHDOG_FEED */
+#define MCUBOOT_CPU_IDLE() \
+ if (!IS_ENABLED(CONFIG_MULTITHREADING)) { \
+ k_cpu_idle(); \
+ }
+
#endif /* __MCUBOOT_CONFIG_H__ */
diff --git a/boot/zephyr/include/platform-bench.h b/boot/zephyr/include/platform-bench.h
index ed74612..d0cb963 100644
--- a/boot/zephyr/include/platform-bench.h
+++ b/boot/zephyr/include/platform-bench.h
@@ -23,7 +23,7 @@
#include "bootutil/bootutil_log.h"
/* TODO: Unclear if this can be here (redundantly). */
-MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
+BOOT_LOG_MODULE_DECLARE(mcuboot);
typedef uint32_t bench_state_t;
diff --git a/boot/zephyr/include/target.h b/boot/zephyr/include/target.h
index 1b0c8f5..5f60daa 100644
--- a/boot/zephyr/include/target.h
+++ b/boot/zephyr/include/target.h
@@ -38,7 +38,7 @@
!defined(FLASH_ALIGN) || \
!(FLASH_AREA_LABEL_EXISTS(image_0)) || \
!(FLASH_AREA_LABEL_EXISTS(image_1) || CONFIG_SINGLE_APPLICATION_SLOT) || \
- (!defined(CONFIG_BOOT_SWAP_USING_MOVE) && !FLASH_AREA_LABEL_EXISTS(image_scratch) && !defined(CONFIG_SINGLE_APPLICATION_SLOT))
+ (defined(CONFIG_BOOT_SWAP_USING_SCRATCH) && !FLASH_AREA_LABEL_EXISTS(image_scratch))
#error "Target support is incomplete; cannot build mcuboot."
#endif
diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c
index b375656..ab3b262 100644
--- a/boot/zephyr/main.c
+++ b/boot/zephyr/main.c
@@ -105,7 +105,7 @@
}
#endif
-MCUBOOT_LOG_MODULE_REGISTER(mcuboot);
+BOOT_LOG_MODULE_REGISTER(mcuboot);
#ifdef CONFIG_MCUBOOT_INDICATION_LED
/*
@@ -183,11 +183,10 @@
rsp->br_image_off +
rsp->br_hdr->ih_hdr_size);
- irq_lock();
#ifdef CONFIG_SYS_CLOCK_EXISTS
sys_clock_disable();
#endif
-#ifdef CONFIG_USB
+#ifdef CONFIG_USB_DEVICE_STACK
/* Disable the USB to prevent it from firing interrupts */
usb_disable();
#endif
@@ -213,6 +212,8 @@
__set_MSPLIM(0);
#endif
+#else
+ irq_lock();
#endif /* CONFIG_MCUBOOT_CLEANUP_ARM_CORE */
#ifdef CONFIG_BOOT_INTR_VEC_RELOC
@@ -390,7 +391,11 @@
if (detect_value == expected) {
if (delay > 0) {
+#ifdef CONFIG_MULTITHREADING
k_sleep(K_MSEC(50));
+#else
+ k_busy_wait(50000);
+#endif
/* Get the uptime for debounce purposes. */
int64_t timestamp = k_uptime_get();
@@ -409,7 +414,11 @@
}
/* Delay 1 ms */
+#ifdef CONFIG_MULTITHREADING
k_sleep(K_MSEC(1));
+#else
+ k_busy_wait(1000);
+#endif
}
}
}
diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf
index 7df1254..a9de580 100644
--- a/boot/zephyr/prj.conf
+++ b/boot/zephyr/prj.conf
@@ -1,7 +1,7 @@
CONFIG_CONSOLE_HANDLER=y
CONFIG_DEBUG=y
CONFIG_SYSTEM_CLOCK_DISABLE=y
-CONFIG_SYS_POWER_MANAGEMENT=n
+CONFIG_PM=n
CONFIG_MAIN_STACK_SIZE=10240
CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h"
diff --git a/boot/zephyr/sample.yaml b/boot/zephyr/sample.yaml
index a685159..6a42312 100644
--- a/boot/zephyr/sample.yaml
+++ b/boot/zephyr/sample.yaml
@@ -6,25 +6,45 @@
sample.bootloader.mcuboot:
tags: bootloader_mcuboot
platform_allow: nrf52840dk_nrf52840 frdm_k64f
+ integration_platforms:
+ - nrf52840dk_nrf52840
sample.bootloader.mcuboot.serial_recovery:
extra_args: OVERLAY_CONFIG=serial_recovery.conf
platform_allow: nrf52840dk_nrf52840
+ integration_platforms:
+ - nrf52840dk_nrf52840
tags: bootloader_mcuboot
sample.bootloader.mcuboot.usb_cdc_acm_recovery:
tags: bootloader_mcuboot
platform_allow: nrf52840dongle_nrf52840
+ extra_args: DTC_OVERLAY_FILE=./usb_cdc_acm.overlay
+ integration_platforms:
+ - nrf52840dongle_nrf52840
sample.bootloader.mcuboot.usb_cdc_acm_recovery_log:
extra_args: OVERLAY_CONFIG=./usb_cdc_acm_log_recovery.conf
DTC_OVERLAY_FILE=./boards/nrf52840_big.overlay
platform_allow: nrf52840dk_nrf52840
+ integration_platforms:
+ - nrf52840dk_nrf52840
tags: bootloader_mcuboot
sample.bootloader.mcuboot.single_slot:
extra_args: OVERLAY_CONFIG=./single_slot.conf
DTC_OVERLAY_FILE=./boards/nrf52840_single_slot.overlay
platform_allow: nrf52840dk_nrf52840
+ integration_platforms:
+ - nrf52840dk_nrf52840
tags: bootloader_mcuboot
sample.bootloader.mcuboot.qspi_nor_slot:
extra_args: DTC_OVERLAY_FILE=./boards/nrf52840dk_qspi_nor_secondary.overlay
OVERLAY_CONFIG="./boards/nrf52840dk_qspi_nor.conf;./boards/nrf52840dk_qspi_secondary_boot.conf"
platform_allow: nrf52840dk_nrf52840
+ integration_platforms:
+ - nrf52840dk_nrf52840
+ tags: bootloader_mcuboot
+ sample.bootloader.mcuboot.hooks_multi:
+ extra_args: DTC_OVERLAY_FILE=./boards/nrf52840dk_ram_multi.overlay
+ OVERLAY_CONFIG=./boards/nrf52840dk_hooks_sample_overlay.conf
+ platform_allow: nrf52840dk_nrf52840
+ integration_platforms:
+ - nrf52840dk_nrf52840
tags: bootloader_mcuboot
diff --git a/boot/zephyr/serial_adapter.c b/boot/zephyr/serial_adapter.c
index 8297522..18fab9b 100644
--- a/boot/zephyr/serial_adapter.c
+++ b/boot/zephyr/serial_adapter.c
@@ -26,7 +26,7 @@
#error Zephyr UART console must been disabled if serial_adapter module is used.
#endif
-MCUBOOT_LOG_MODULE_REGISTER(serial_adapter);
+BOOT_LOG_MODULE_REGISTER(serial_adapter);
/** @brief Console input representation
*
@@ -192,27 +192,28 @@
boot_uart_fifo_init(void)
{
#ifdef CONFIG_BOOT_SERIAL_UART
- uart_dev = device_get_binding(CONFIG_RECOVERY_UART_DEV_NAME);
+ uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
#elif CONFIG_BOOT_SERIAL_CDC_ACM
- uart_dev = device_get_binding(CONFIG_USB_CDC_ACM_DEVICE_NAME "_0");
- if (uart_dev) {
- int rc;
- rc = usb_enable(NULL);
- if (rc) {
- return (-1);
- }
- }
+ uart_dev = DEVICE_DT_GET_ONE(zephyr_cdc_acm_uart);
#endif
- uint8_t c;
- if (!uart_dev) {
+ if (!device_is_ready(uart_dev)) {
return (-1);
}
+#if CONFIG_BOOT_SERIAL_CDC_ACM
+ int rc = usb_enable(NULL);
+ if (rc) {
+ return (-1);
+ }
+#endif
+
uart_irq_callback_set(uart_dev, boot_uart_fifo_callback);
/* Drain the fifo */
if (uart_irq_rx_ready(uart_dev)) {
+ uint8_t c;
+
while (uart_fifo_read(uart_dev, &c, 1)) {
;
}
@@ -222,11 +223,5 @@
uart_irq_rx_enable(uart_dev);
- /* Enable all interrupts unconditionally. Note that this is due
- * to Zephyr issue #8393. This should be removed once the
- * issue is fixed in upstream Zephyr.
- */
- irq_unlock(0);
-
return 0;
}
diff --git a/boot/zephyr/single_loader.c b/boot/zephyr/single_loader.c
index c16a0b7..af2d398 100644
--- a/boot/zephyr/single_loader.c
+++ b/boot/zephyr/single_loader.c
@@ -13,7 +13,7 @@
#include "mcuboot_config/mcuboot_config.h"
-MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
+BOOT_LOG_MODULE_DECLARE(mcuboot);
/* Variables passed outside of unit via poiters. */
static const struct flash_area *_fa_p;
@@ -83,7 +83,7 @@
}
if (!boot_u32_safe_add(&size, hdr->ih_img_size, hdr->ih_hdr_size) ||
- size >= fa_p->fa_size) {
+ size >= flash_area_get_size(fa_p)) {
return BOOT_EBADIMAGE;
}
@@ -120,8 +120,8 @@
fih_rc = FIH_SUCCESS;
#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */
- rsp->br_flash_dev_id = _fa_p->fa_device_id;
- rsp->br_image_off = _fa_p->fa_off;
+ rsp->br_flash_dev_id = flash_area_get_device_id(_fa_p);
+ rsp->br_image_off = flash_area_get_off(_fa_p);
rsp->br_hdr = &_hdr;
out:
diff --git a/boot/zephyr/usb_cdc_acm.overlay b/boot/zephyr/usb_cdc_acm.overlay
new file mode 100644
index 0000000..09eb8cf
--- /dev/null
+++ b/boot/zephyr/usb_cdc_acm.overlay
@@ -0,0 +1,6 @@
+&zephyr_udc0 {
+ cdc_acm_uart0 {
+ compatible = "zephyr,cdc-acm-uart";
+ label = "CDC_ACM_0";
+ };
+};
diff --git a/ci/check-signed-off-by.sh b/ci/check-signed-off-by.sh
index f71e68f..c52a339 100755
--- a/ci/check-signed-off-by.sh
+++ b/ci/check-signed-off-by.sh
@@ -45,10 +45,10 @@
IFS=$'\n'
for line in ${lines}; do
stripped=$(echo $line | sed -e 's/^\s*//' | sed -e 's/\s*$//')
- if [[ ${stripped} == ${author} ]]; then
+ if [[ "${stripped}" == "${author}" ]]; then
found_author=true
fi
- if [[ ${stripped} == ${committer} ]]; then
+ if [[ "${stripped}" == "${committer}" ]]; then
found_committer=true
fi
diff --git a/ci/fih-tests_install.sh b/ci/fih-tests_install.sh
index fb6e0fb..d69308a 100755
--- a/ci/fih-tests_install.sh
+++ b/ci/fih-tests_install.sh
@@ -18,13 +18,15 @@
DOCKER_DIR=docker
-IMAGE=fih-test:0.0.1
+IMAGE=fih-test:0.0.2
CACHED_IMAGE=$DOCKER_DIR/$IMAGE
[[ -f $CACHED_IMAGE ]] && (gzip -dc $CACHED_IMAGE | docker load)
if [[ $? -ne 0 ]]; then
- docker pull mcuboot/$IMAGE
- docker save mcuboot/$IMAGE | gzip > $CACHED_IMAGE
+ docker pull mcuboot/$IMAGE
+ if [[ $GITHUB_ACTIONS != true ]]; then
+ docker save mcuboot/$IMAGE | gzip > $CACHED_IMAGE
+ fi
fi
diff --git a/ci/fih-tests_run.sh b/ci/fih-tests_run.sh
index 37d8a73..5b975d3 100755
--- a/ci/fih-tests_run.sh
+++ b/ci/fih-tests_run.sh
@@ -1,6 +1,6 @@
#!/bin/bash -x
-# Copyright (c) 2020 Arm Limited
+# Copyright (c) 2020-2021 Arm Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,9 +19,31 @@
pushd .. &&\
git clone https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git &&\
pushd trusted-firmware-m &&\
- git checkout 7ad5c5f23f4619add4aa6c88f4b25fc6fd84ec6e &&\
+ git checkout TF-Mv1.4.0 &&\
popd
+if [[ $GITHUB_ACTIONS == true ]]; then
+ if [[ -z $FIH_ENV ]]; then
+ echo "Workflow has found no \$FIH_ENV"
+ exit 1
+ fi
+
+ args=($FIH_ENV)
+ len=${#args[@]}
+ if [[ $len < 3 ]]; then
+ echo "Invalid number of \$FIH_ENV args"
+ exit 1
+ fi
+
+ BUILD_TYPE=${args[0]}
+ SKIP_SIZE=${args[1]}
+ DAMAGE_TYPE=${args[2]}
+
+ if [[ $len > 3 ]]; then
+ FIH_LEVEL=${args[3]}
+ fi
+fi
+
if test -z "$FIH_LEVEL"; then
docker run --rm -v $(pwd):/root/work/tfm:rw,z mcuboot/fih-test /bin/sh -c '/root/work/tfm/mcuboot/ci/fih_test_docker/execute_test.sh $0 $1 $2' $SKIP_SIZE $BUILD_TYPE $DAMAGE_TYPE
else
diff --git a/ci/fih_test_docker/execute_test.sh b/ci/fih_test_docker/execute_test.sh
index 9193564..3d09993 100755
--- a/ci/fih_test_docker/execute_test.sh
+++ b/ci/fih_test_docker/execute_test.sh
@@ -1,6 +1,6 @@
#!/bin/bash -x
-# Copyright (c) 2020 Arm Limited
+# Copyright (c) 2020-2021 Arm Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -37,21 +37,21 @@
mkdir -p $TFM_BUILD_DIR
cd $TFM_DIR
cmake -B $TFM_BUILD_DIR \
+ -DTFM_SPM_LOG_LEVEL=TFM_SPM_LOG_LEVEL_INFO \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DTFM_TOOLCHAIN_FILE=toolchain_GNUARM.cmake \
- -DTFM_PLATFORM=mps2/an521 \
+ -DTFM_PLATFORM=arm/mps2/an521 \
-DTEST_NS=ON \
-DTEST_S=ON \
-DTFM_PSA_API=ON \
-DMCUBOOT_PATH=$MCUBOOT_PATH \
-DMCUBOOT_LOG_LEVEL=INFO \
- -DTFM_TEST_REPO_VERSION=93ce2f59c0c4a9cba6062834496b5f45deee4010 \
$CMAKE_FIH_LEVEL \
.
cd $TFM_BUILD_DIR
make -j install
-BOOTLOADER_AXF='./install/outputs/MPS2/AN521/bl2.axf'
+BOOTLOADER_AXF='./install/outputs/ARM/MPS2/AN521/bl2.axf'
$MCUBOOT_PATH/ci/fih_test_docker/run_fi_test.sh $BOOTLOADER_AXF $SKIP_SIZE $DAMAGE_TYPE> fih_test_output.yaml
diff --git a/ci/fih_test_docker/fi_tester_gdb.sh b/ci/fih_test_docker/fi_tester_gdb.sh
index 05f0492..2a20a1d 100755
--- a/ci/fih_test_docker/fi_tester_gdb.sh
+++ b/ci/fih_test_docker/fi_tester_gdb.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright (c) 2020 Arm Limited
+# Copyright (c) 2020-2021 Arm Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -104,7 +104,7 @@
echo " test_exec_ok: True"
echo " skipped: True"
echo " boot: False"
- echo " last_line: '$LAST_LINE' "
+ echo " last_line: \"$LAST_LINE\" "
fi
else
# The target was not stopped at the desired address.
@@ -138,7 +138,7 @@
#defaults
SKIP=2
-BIN_DIR=$(pwd)/install/outputs/MPS2/AN521
+BIN_DIR=$(pwd)/install/outputs/ARM/MPS2/AN521
AXF_FILE=$BIN_DIR/bl2.axf
GDB=gdb-multiarch
BOOTLOADER=true
diff --git a/ci/imgtool_install.sh b/ci/imgtool_install.sh
index 091cfa7..66b44cf 100755
--- a/ci/imgtool_install.sh
+++ b/ci/imgtool_install.sh
@@ -13,8 +13,8 @@
# limitations under the License.
if [[ $TRAVIS == "true" ]]; then
- if [[ $TRAVIS_PULL_REQUEST != "false" || $TRAVIS_BRANCH != "master" ]]; then
- echo "Either a PR or not \"master\" branch, exiting"
+ if [[ $TRAVIS_PULL_REQUEST != "false" || $TRAVIS_BRANCH != "main" ]]; then
+ echo "Either a PR or not \"main\" branch, exiting"
exit 0
fi
fi
diff --git a/ci/imgtool_run.sh b/ci/imgtool_run.sh
index 7358706..97f0b21 100755
--- a/ci/imgtool_run.sh
+++ b/ci/imgtool_run.sh
@@ -13,8 +13,8 @@
# limitations under the License.
if [[ $TRAVIS == "true" ]]; then
- if [[ $TRAVIS_PULL_REQUEST != "false" || $TRAVIS_BRANCH != "master" ]]; then
- echo "Either a PR or not \"master\" branch, exiting"
+ if [[ $TRAVIS_PULL_REQUEST != "false" || $TRAVIS_BRANCH != "main" ]]; then
+ echo "Either a PR or not \"main\" branch, exiting"
exit 0
fi
fi
diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock
index 7e516ad..d3acbb3 100644
--- a/docs/Gemfile.lock
+++ b/docs/Gemfile.lock
@@ -7,7 +7,7 @@
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2, >= 2.2.2)
- addressable (2.7.0)
+ addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
coffee-script (2.4.1)
coffee-script-source
@@ -205,15 +205,15 @@
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
- mini_portile2 (2.5.0)
+ mini_portile2 (2.6.1)
minima (2.5.1)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.14.4)
multipart-post (2.1.1)
- nokogiri (1.11.2)
- mini_portile2 (~> 2.5.0)
+ nokogiri (1.12.5)
+ mini_portile2 (~> 2.6.1)
racc (~> 1.4)
octokit (4.20.0)
faraday (>= 0.9)
@@ -225,7 +225,7 @@
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
- rexml (3.2.4)
+ rexml (3.2.5)
rouge (3.26.0)
ruby-enum (0.9.0)
i18n
diff --git a/docs/PORTING.md b/docs/PORTING.md
index bb7e0f9..2df9b49 100644
--- a/docs/PORTING.md
+++ b/docs/PORTING.md
@@ -69,10 +69,25 @@
## Flash Map
-The bootloader requires a `flash_map` to be able to know how the flash is
-partitioned. A `flash_map` consists of `struct flash_area` entries
-specifying the partitions, where a `flash_area` defined as follows:
+The bootloader requires to be able to address flash regions where the code
+for mcuboot and images of applications are stored, in system-agnostic way.
+For that purpose the mcuboot uses ID, which is integer (uint8_t) number
+that should uniquely identify each flash region.
+Such flash regions are served by object of `const struct flash_area` type while
+layout of these objects is gathered under `flash_map`.
+The common code of mcuboot, that is non-system specific, does not directly
+access contents of that object and never modifies it, instead it calls
+`flash_area_` API to perform any actions on that object.
+This way systems are free to implement internal logic of flash map or define
+`struct flash_area` as they wish; the only restriction is that ID should be
+uniquely tied to region characterized by device, offset and size.
+Changes to common mcuboot code should not affect system specific internals
+of flash map, on the other side system specific code, within mcuboot, is
+is not restricted from directly accessing `struct flash_area` elements.
+
+
+An implementation of `struct flash_area` may take form of:
```c
struct flash_area {
uint8_t fa_id; /** The slot/scratch identification */
@@ -82,8 +97,25 @@
uint32_t fa_size; /** The size of this sector */
};
```
+The above example of structure hold all information that is currently required
+by mcuboot, although the mcuboot will not be trying to access them directly,
+instead a system is required to provide following mandatory getter functions:
-`fa_id` is can be one of the following options:
+```c
+/*< Obtains ID of the flash area characterized by `fa` */
+int flash_area_get_id(const struct flash_area *fa);
+/*< Obtains ID of a device the flash area `fa` described region resides on */
+int flash_area_get_device_id(const struct flash_area *fa)
+/*< Obtains offset, from the beginning of a device, the flash area described
+ * region starts at */
+uint32_t flash_area_get_off(const struct flash_area *fa)
+/*< Obtains size, from the offset, of the flash area `fa` characterized region */
+uint32_t flash_area_get_size(const struct flash_area *fa)
+
+```
+
+The mcuboot common code uses following defines that should be defined by system
+specific header files and are used to identify destination of flash area by ID:
```c
/* Independent from multiple image boot */
@@ -101,7 +133,11 @@
#define FLASH_AREA_IMAGE_SECONDARY 6
```
-The functions that must be defined for working with the `flash_area`s are:
+The numbers, given above, are provided as an example and depend on system
+implementation.
+
+The main, also required, set of API functions that perform operations on
+flash characterized by `struct flash_area` objects is as follows:
```c
/*< Opens the area for use. id is one of the `fa_id`s */
diff --git a/docs/design.md b/docs/design.md
old mode 100644
new mode 100755
index a50feeb..e5e94b3
--- a/docs/design.md
+++ b/docs/design.md
@@ -3,7 +3,7 @@
- Copyright (c) 2017-2020 Linaro LTD
- Copyright (c) 2017-2019 JUUL Labs
- - Copyright (c) 2019-2020 Arm Limited
+ - Copyright (c) 2019-2021 Arm Limited
- Original license:
@@ -96,6 +96,8 @@
* Image header flags.
*/
#define IMAGE_F_PIC 0x00000001 /* Not supported. */
+#define IMAGE_F_ENCRYPTED_AES128 0x00000004 /* Encrypted using AES128. */
+#define IMAGE_F_ENCRYPTED_AES256 0x00000008 /* Encrypted using AES256. */
#define IMAGE_F_NON_BOOTABLE 0x00000010 /* Split image app. */
#define IMAGE_F_RAM_LOAD 0x00000020
@@ -110,7 +112,8 @@
#define IMAGE_TLV_RSA3072_PSS 0x23 /* RSA3072 of hash output */
#define IMAGE_TLV_ED25519 0x24 /* ED25519 of hash output */
#define IMAGE_TLV_ENC_RSA2048 0x30 /* Key encrypted with RSA-OAEP-2048 */
-#define IMAGE_TLV_ENC_KW128 0x31 /* Key encrypted with AES-KW-128 */
+#define IMAGE_TLV_ENC_KW 0x31 /* Key encrypted with AES-KW-128 or
+ 256 */
#define IMAGE_TLV_ENC_EC256 0x32 /* Key encrypted with ECIES-P256 */
#define IMAGE_TLV_ENC_X25519 0x33 /* Key encrypted with ECIES-X25519 */
#define IMAGE_TLV_DEPENDENCY 0x40 /* Image depends on other image */
@@ -269,13 +272,26 @@
#define IMAGE_EXECUTABLE_RAM_SIZE <area_size_in_bytes>
```
+For multiple image load if multiple ram regions are used platform must define
+the `MULTIPLE_EXECUTABLE_RAM_REGIONS` flag instead and implement the following
+function:
+
+```c
+int boot_get_image_exec_ram_info(uint32_t image_id,
+ uint32_t *exec_ram_start,
+ uint32_t *exec_ram_size)
+```
+
When ram-load is enabled, the `--load-addr <addr>` option of the `imgtool`
script must also be used when signing the images. This option set the `RAM_LOAD`
flag in the image header which indicates that the image should be loaded to the
RAM and also set the load address in the image header.
-The ram-load mode currently supports only the single image boot and the image
-encryption feature is not supported.
+When the encryption option is enabled (`MCUBOOT_ENC_IMAGES`) along with ram-load
+the image is checked for encryption. If the image is not encrypted, RAM loading
+happens as described above. If the image is encrypted, it is copied in RAM at
+the provided address and then decrypted. Finally, the decrypted image is
+authenticated in RAM and executed.
## [Boot Swap Types](#boot-swap-types)
@@ -335,14 +351,14 @@
### [Revert mechanism in direct-xip mode](#direct-xip-revert)
The direct-xip mode also supports a "revert" mechanism which is the equivalent
-of the swap mode's "revert" swap. It can be enabled with the
-MCUBOOT_DIRECT_XIP_REVERT config option and an image trailer must also be added
-to the signed images (the "--pad" option of the `imgtool` script must be used).
-For more information on this please read the [Image Trailer](#image-trailer)
-section and the [imgtool](imgtool.md) documentation. Making the images permanent
-(marking them as confirmed in advance) is also supported just like in swap mode.
-The individual steps of the direct-xip mode's "revert" mechanism are the
-following:
+of the swap mode's "revert" swap. When the direct-xip mode is selected it can be
+enabled with the MCUBOOT_DIRECT_XIP_REVERT config option and an image trailer
+must also be added to the signed images (the "--pad" option of the `imgtool`
+script must be used). For more information on this please read the
+[Image Trailer](#image-trailer) section and the [imgtool](imgtool.md)
+documentation. Making the images permanent (marking them as confirmed in
+advance) is also supported just like in swap mode. The individual steps of the
+direct-xip mode's "revert" mechanism are the following:
1. Select the slot which holds the newest potential image.
2. Was the image previously selected to run (during a previous boot)?
@@ -426,7 +442,7 @@
either decreasing this size, to limit RAM usage, or to increase it in devices
that have massive amounts of Flash or very small sized sectors and thus require
a bigger configuration to allow for the handling of all slot's sectors.
-The factor of min-write-sz is due to the behavior of flash hardware. The factor
+The factor of min-write-size is due to the behavior of flash hardware. The factor
of 3 is explained below.
2. Encryption keys: key-encrypting keys (KEKs). These keys are needed for
@@ -689,6 +705,41 @@
+ Boot into image in the primary slot of the 0th image position\
(other image in the boot chain is started by another image).
+### [Multiple Image Boot for RAM loading and direct-xip](#multiple-image-boot-for-ram-loading-and-direct-xip)
+
+The operation of the boot loader is different when the ram-load or the
+direct-xip strategy is chosen. The flash map is very similar to the swap
+strategy but there is no need for Scratch area.
+
++ Loop 1. Until all images are loaded and all dependencies are satisfied
+ 1. Subloop 1. Iterate over all images
+ + Does any of the slots contain an image?
+ + Yes:
+ + Choose the newer image.
+ + Copy it to RAM in case of ram-load strategy.
+ + Validate the image (integrity and security check).
+ + If validation fails delete the image from flash and try the other
+ slot. (Image must be deleted from RAM too in case of ram-load
+ strategy.)
+ + No: Return with failure.
+
+ 2. Subloop 2. Iterate over all images
+ + Does the current image depend on other image(s)?
+ + Yes: Are all the image dependencies satisfied?
+ + Yes: Skip to next image.
+ + No:
+ + Delete the image from RAM in case of ram-load strategy, but
+ do not delete it from flash.
+ + Try to load the image from the other slot.
+ + Restart dependency check from the first image.
+ + No: Skip to next image.
+
++ Loop 2. Iterate over all images
+ + Increase the security counter if needed.
+ + Do the measured boot and the data sharing if needed.
+
++ Boot the loaded slot of image 0.
+
## [Image Swapping](#image-swapping)
The boot loader swaps the contents of the two image slots for two reasons:
@@ -973,8 +1024,8 @@
If you want to enable and use encrypted images, see:
[encrypted_images](encrypted_images.md).
-Note: Image encryption is not supported when the direct-xip or the ram-load
-upgrade strategy is selected.
+Note: Image encryption is not supported when the direct-xip upgrade strategy
+is selected.
### [Using Hardware Keys for Verification](#hw-key-support)
@@ -1264,6 +1315,7 @@
are issued from the MCUboot source directory):
```sh
+$ mkdir docker
$ ./ci/fih-tests_install.sh
$ FIH_LEVEL=MCUBOOT_FIH_PROFILE_MEDIUM BUILD_TYPE=RELEASE SKIP_SIZE=2 \
DAMAGE_TYPE=SIGNATURE ./ci/fih-tests_run.sh
@@ -1285,4 +1337,4 @@
the shell returns, and it is possible to investigate the results. It is also
possible to stop the test with _Ctrl+c_. The parameters to the
`execute_test.sh` are `SKIP_SIZE`, `BUILD_TYPE`, `DAMAGE_TYPE`, `FIH_LEVEL` in
- order.
\ No newline at end of file
+ order.
diff --git a/docs/encrypted_images.md b/docs/encrypted_images.md
index 74443db..838f493 100644
--- a/docs/encrypted_images.md
+++ b/docs/encrypted_images.md
@@ -59,9 +59,9 @@
that the encrypted flag is set and TLV data is OK, then it decrypts each
image block before sending the data to the hash routines.
-The image is encrypted using AES-CTR-128, with a counter that starts
-from zero (over the payload blocks) and increments by 1 for each 16-byte
-block. AES-CTR-128 was chosen for speed/simplicity and allowing for any
+The image is encrypted using AES-CTR-128 or AES-CTR-256, with a counter
+that starts from zero (over the payload blocks) and increments by 1 for each
+16-byte block. AES-CTR was chosen for speed/simplicity and allowing for any
block to be encrypted/decrypted without requiring knowledge of any other
block (allowing for simple resume operations on swap interruptions).
@@ -70,14 +70,15 @@
but randomizing a 16-byte block with a TRNG should make it highly
improbable that duplicates ever happen.
-To distribute this AES-CTR-128 key, new TLVs were defined. The key can be
-encrypted using either RSA-OAEP, AES-KW-128, ECIES-P256 or ECIES-X25519.
+To distribute this AES-CTR key, new TLVs were defined. The key can be
+encrypted using either RSA-OAEP, AES-KW (128 or 256 bits depending on the
+AES-CTR key length), ECIES-P256 or ECIES-X25519.
For RSA-OAEP a new TLV with value `0x30` is added to the image, for
-AES-KW-128 a new TLV with value `0x31` is added to the image, for
+AES-KW a new TLV with value `0x31` is added to the image, for
ECIES-P256 a new TLV with value `0x32` is added, and for ECIES-X25519 a
newt TLV with value `0x33` is added. The contents of those TLVs
-are the results of applying the given operations over the AES-CTR-128 key.
+are the results of applying the given operations over the AES-CTR key.
## [ECIES encryption](#ecies-encryption)
@@ -94,17 +95,17 @@
* Derive the new keys from the secret using HKDF (built on HMAC-SHA256). We
are not using a `salt` and using an `info` of `MCUBoot_ECIES_v1`, generating
48 bytes of key material.
-* A new random encryption key of 16 bytes is generated (for AES-128). This is
+* A new random encryption key is generated (for AES). This is
the AES key used to encrypt the images.
-* The key is encrypted with AES-128-CTR and a `nonce` of 0 using the first
- 16 bytes of key material generated previously by the HKDF.
+* The key is encrypted with AES-128-CTR or AES-256-CTR and a `nonce` of 0 using
+ the first 16 bytes of key material generated previously by the HKDF.
* The encrypted key now goes through a HMAC-SHA256 using the remaining 32
bytes of key material from the HKDF.
The final TLV is built from the 65 bytes for ECIES-P256 or 32 bytes for
ECIES-X25519, which correspond to the ephemeral public key, followed by the
-32 bytes of MAC tag and the 16 bytes of the encrypted key, resulting in a TLV
-of 113 bytes for ECIES-P256 or 80 bytes for ECIES-X25519.
+32 bytes of MAC tag and the 16 or 32 bytes of the encrypted key, resulting in
+a TLV of 113 or 129 bytes for ECIES-P256 and 80 or 96 bytes for ECIES-X25519.
The implemenation of ECIES-P256 is named ENC_EC256 in the source code and
artifacts while ECIES-X25519 is named ENC_X25519.
@@ -149,7 +150,7 @@
`imgtool getpub -k <input.pem> -l <lang>`, where lang can be one of `c` or
`rust` (defaults to `c`).
-If using AES-KW-128, follow the steps in the next section to generate the
+If using AES-KW, follow the steps in the next section to generate the
required keys.
## [Creating your keys with Unix tooling](#creating-your-keys-with-unix-tooling)
@@ -161,5 +162,6 @@
* If using ECIES-X25519, generate a private key passing the option `-t x25519`
to `imgtool keygen` command. To generate public key PEM file the following
command can be used: `openssl pkey -in <generated-private-key.pem> -pubout`
-* If using AES-KW-128 (`newt` only), the `kek` can be generated with a
- command like `dd if=/dev/urandom bs=1 count=16 | base64 > my_kek.b64`
+* If using AES-KW (`newt` only), the `kek` can be generated with a
+ command like (change count to 32 for a 256 bit key)
+ `dd if=/dev/urandom bs=1 count=16 | base64 > my_kek.b64`
diff --git a/docs/index.md b/docs/index.md
index 5f2cf09..c892c57 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -61,13 +61,13 @@
For more information in the source, here are some pointers:
-- [boot/bootutil](https://github.com/mcu-tools/mcuboot/tree/master/boot/bootutil): The core of the bootloader itself.
-- [boot/boot\_serial](https://github.com/mcu-tools/mcuboot/tree/master/boot/boot_serial): Support for serial upgrade within the bootloader itself.
-- [boot/zephyr](https://github.com/mcu-tools/mcuboot/tree/master/boot/zephyr): Port of the bootloader to Zephyr
-- [boot/mynewt](https://github.com/mcu-tools/mcuboot/tree/master/boot/mynewt): Mynewt bootloader app
-- [boot/mbed](https://github.com/mcu-tools/mcuboot/tree/master/boot/mbed): Port of the bootloader to Mbed-OS
-- [imgtool](https://github.com/mcu-tools/mcuboot/tree/master/scripts/imgtool.py): A tool to securely sign firmware images for booting by MCUboot.
-- [sim](https://github.com/mcu-tools/mcuboot/tree/master/sim): A bootloader simulator for testing and regression
+- [boot/bootutil](https://github.com/mcu-tools/mcuboot/tree/main/boot/bootutil): The core of the bootloader itself.
+- [boot/boot\_serial](https://github.com/mcu-tools/mcuboot/tree/main/boot/boot_serial): Support for serial upgrade within the bootloader itself.
+- [boot/zephyr](https://github.com/mcu-tools/mcuboot/tree/main/boot/zephyr): Port of the bootloader to Zephyr
+- [boot/mynewt](https://github.com/mcu-tools/mcuboot/tree/main/boot/mynewt): Mynewt bootloader app
+- [boot/mbed](https://github.com/mcu-tools/mcuboot/tree/main/boot/mbed): Port of the bootloader to Mbed-OS
+- [imgtool](https://github.com/mcu-tools/mcuboot/tree/main/scripts/imgtool.py): A tool to securely sign firmware images for booting by MCUboot.
+- [sim](https://github.com/mcu-tools/mcuboot/tree/main/sim): A bootloader simulator for testing and regression
## Joining
diff --git a/docs/readme-espressif.md b/docs/readme-espressif.md
new file mode 100644
index 0000000..fa72fb3
--- /dev/null
+++ b/docs/readme-espressif.md
@@ -0,0 +1,70 @@
+# Building and using MCUboot with Espressif's chips
+
+The Espressif port is build on top of ESP-IDF HAL, therefore it is required in order to build MCUboot for Espressif SoCs.
+
+Documentation about the MCUboot bootloader design, operation and features can be found in the [design document](design.md).
+
+## SoC support availability
+
+The current port is available for use in the following SoCs within the OSes:
+- ESP32
+ - Zephyr RTOS - _WIP_
+ - NuttX
+- ESP32-S2
+ - Zephyr RTOS - _WIP_
+ - NuttX - _WIP_
+
+## Installing Requirements and Dependencies
+
+1. Install additional packages required for development with MCUboot:
+
+```
+ cd ~/mcuboot # or to your directory where mcuboot is cloned
+ pip3 install --user -r scripts/requirements.txt
+```
+
+2. Update the submodules needed by the Espressif port. This may take a while.
+
+```
+git submodule update --init --recursive --checkout boot/espressif/hal/esp-idf
+```
+
+3. Next, get the mbedtls submodule required by MCUboot.
+```
+git submodule update --init --recursive ext/mbedtls
+```
+
+4. Now we need to install IDF dependencies and set environment variables. This step may take some time:
+```
+cd boot/espressif/hal/esp-idf
+./install.sh
+. ./export.sh
+cd ../..
+```
+
+## Building the bootloader itself
+
+The MCUboot Espressif port bootloader is built using the toolchain and tools provided by ESP-IDF. Additional configuration related to MCUboot features and slot partitioning may be made using the `bootloader.conf`.
+
+**Note:** Replace `<target>` with the target ESP32 family (like `esp32`, `esp32s2` and others).
+
+1. Compile and generate the ELF:
+
+```
+cmake -DCMAKE_TOOLCHAIN_FILE=tools/toolchain-<target>.cmake -DMCUBOOT_TARGET=<target> -B build -GNinja
+cmake --build build/
+```
+
+2. Convert the ELF to the final bootloader image, ready to be flashed:
+
+```
+esptool.py --chip <target> elf2image --flash_mode dio --flash_freq 40m -o build/mcuboot_<target>.bin build/mcuboot_<target>.elf
+```
+
+3. Flash MCUboot in your board:
+
+```
+esptool.py -p <PORT> -b <BAUD> --before default_reset --after hard_reset --chip <target> write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x1000 build/mcuboot_<target>.bin
+```
+
+You may adjust the port `<PORT>` (like `/dev/ttyUSB0`) and baud rate `<BAUD>` (like `2000000`) according to the connection with your board.
diff --git a/docs/readme-mbed.md b/docs/readme-mbed.md
index 189c7bf..2162678 100644
--- a/docs/readme-mbed.md
+++ b/docs/readme-mbed.md
@@ -16,7 +16,7 @@
* `"mcuboot.max-img-sectors"`: maximum number of sectors, should be at least the number of sectors in each slot
* `"target.restrict_size"`: the maximum size of the bootloader, such that it does not overlap with the primary slot
-More configurations such as signing algorithm, slot swapping, etc. can be found in [mbed_lib.json](https://github.com/mcu-tools/mcuboot/tree/master/boot/mbed/mbed_lib.json). Please note that certain features are not currently supported.
+More configurations such as signing algorithm, slot swapping, etc. can be found in [mbed_lib.json](https://github.com/mcu-tools/mcuboot/tree/main/boot/mbed/mbed_lib.json). Please note that certain features are not currently supported.
### Providing a secondary slot
diff --git a/docs/readme-nuttx.md b/docs/readme-nuttx.md
new file mode 100644
index 0000000..1c06964
--- /dev/null
+++ b/docs/readme-nuttx.md
@@ -0,0 +1,52 @@
+# MCUboot port for NuttX
+
+## Description
+
+The NuttX port of MCUboot secure boot library expects that the platform provides a Flash storage with the following partitions:
+- `CONFIG_MCUBOOT_PRIMARY_SLOT_PATH`: MTD partition for the application firmware image PRIMARY slot;
+- `CONFIG_MCUBOOT_SECONDARY_SLOT_PATH`: MTD partition for the application firmware image SECONDARY slot;
+- `CONFIG_MCUBOOT_SCRATCH_PATH`: MTD partition for the Scratch area;
+
+Also, these are optional features that may be enabled:
+
+- `CONFIG_MCUBOOT_WATCHDOG`: If `CONFIG_WATCHDOG` is enabled, MCUboot shall reset the watchdog timer indicated by `CONFIG_MCUBOOT_WATCHDOG_DEVPATH` to the current timeout value, preventing any imminent watchdog timeouts.
+
+The porting layer of MCUboot library consists of the following interfaces:
+- `<flash_map_backend/flash_map_backend.h>`, for enabling MCUboot to manage the application firmware image slots in the device storage.
+- `<mcuboot_config/mcuboot_config.h>`, for configuration of MCUboot's features.
+- `<mcuboot_config/mcuboot_logging.h>`, for providing logging capabilities.
+- `<os/os_malloc.h>`, for providing MCUboot access to the OS memory management interfaces.
+- `<sysflash/sysflash.h>`, for configuration of the system's flash area organization.
+
+The NuttX port of MCUboot is implemented at application-level and requires minimal knowledge about characteristics of the underlying storage device. This is achieved by means of the `BCH` and `FTL` subsystems, which enable MCUboot to manage MTD partitions via character device drivers using standard POSIX filesystem operations (e.g. `open()` / `close()` / `read()` / `write()`).
+
+## Creating MCUboot-compatible application firmware images
+
+One common use case for MCUboot is to integrate it to a firmware update agent, which is an important component of a secure firmware update subsystem. Through MCUboot APIs an application is able to install a newly received application firmware image and, once this application firmware image is assured to be valid, the application may confirm it as a stable image. In case that application firmware image is deemed bogus, MCUboot provides an API for invalidating that update, which will induce a rollback procedure to the most recent stable application firmware image.
+
+The `CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE` example demonstrates this workflow by downloading an application firmware image from a webserver, installing it and triggering the firmware update process for the next boot after a system reset. There is also the `CONFIG_MCUBOOT_SLOT_CONFIRM_EXAMPLE`, which is a fairly simple example that just calls an MCUboot API for confirming the executing application firmware image as stable.
+
+## Using MCUboot on NuttX as a secure boot solution
+
+NuttX port for MCUboot also enables the creation of a secure bootloader application requiring minimal platform-specific implementation. The logical implementation for the secure boot is performed at application-level by the MCUboot library. Once MCUboot validates the application firmware image, it delegates the loading and execution of the application firmware image to a platform-specific routine, which is accessed via `boardctl(BOARDIOC_BOOT_IMAGE)` call. Each platform must then provide an implementation for the `board_boot_image()` for executing the required actions in order to boot a new application firmware image (e.g. deinitialize peripherals, load the Program Counter register with the application firmware image entry point address).
+
+The MCUboot bootloader application may be enabled by selecting the `CONFIG_MCUBOOT_BOOTLOADER` option.
+
+## Assumptions
+
+### IOCTL MTD commands
+
+The implementation of `<flash_map_backend/flash_map_backend.h>` expects that the MTD driver for a given image partition handles the following `ioctl` commands:
+- `MTDIOC_GEOMETRY`, for retrieving information about the geometry of the MTD, required for the configuration of the size of each flash area.
+- `MTDIOC_ERASESTATE`, for retrieving the byte value of an erased cell of the MTD, required for the implementation of `flash_area_erased_val()` interface.
+
+### Write access alignment
+
+Through `flash_area_align()` interface MCUboot expects that the implementation provides the shortest data length that may be written via `flash_area_write()` interface. The NuttX implementation passes through the `BCH` and `FTL` layers, which appropriately handle the write alignment restrictions of the underlying MTD. So The NuttX implementation of `flash_area_align()` is able to return a fixed value of 1 byte, even if the MTD does not support byte operations.
+
+## Limitations
+
+### `<flash_map_backend/flash_map_backend.h>` functions are not multitasking-safe
+
+MCUboot's documentation imposes no restrictions regarding the usage of its public interfaces, which doesn't mean they are thread-safe.
+But, regarding NuttX implementation of the `<flash_map_backend/flash_map_backend.h>`, it is safe to state that they are **not** multitasking-safe. NuttX implementation manages the MTD partitions via character device drivers. As file-descriptors cannot be shared between different tasks, if one task calls `flash_area_open` and another task calls `flash_area_<read/write/close>` passing the same `struct flash_area` instance, it will result in failure.
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 172c934..885fe31 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -3,6 +3,44 @@
- Table of Contents
{:toc}
+## Version 1.8.0
+
+The 1.8.0 release of MCUboot contains numerous fixes, and adds support
+for the NuttX RTOS, and the Espressif ESP32 SDK.
+
+### About this release
+
+- Add support for the NuttX RTOS.
+- Add support for the Espressif ESP32 SDK.
+- `boot_serial` changed to use cddl-gen, which removes the dependency
+ on tinycbor.
+- Add various hooks to be able to change how image data is accessed.
+- Cypress supports Mbed TLS for encryption.
+- Support using Mbed TLS for ECDSA. This can be useful if Mbed TLS is
+ brought in for another reason.
+- Add simulator support for testing direct-XIP and ramload.
+- Support Mbed TLS 3.0. Updates the submodule for Mbed TLS to 3.0.
+- Enable direct-xip mode in mbed-os port.
+- extract `bootutil_public` library, a common interface for mcuboot
+ and the application.
+- Allow to boot primary image if secondary one is unreachable.
+- Add AES256 image encryption support.
+- Add Multiimage boot for direct-xip and ram-load mode.
+- Cargo files moved to top level, now `cargo test` can be run from the
+ top level directory.
+- Fault injection tests use updated TF-M.
+- Thingy:53 now supports multi-image DFU.
+- ram load and image encryption can be used together, allowing the
+ entire contents of flash to always remain encrypted.
+
+### Security fixes
+
+- [GHSA-gcxh-546h-phg4](https://github.com/mcu-tools/mcuboot/security/advisories/GHSA-gcxh-546h-phg4)
+ has been published. There is not a fix at this time, but a caution
+ to be sure to follow the instructions carefully, and make sure that
+ the development keys in the repo are never used in a production
+ system.
+
## Version 1.7.0
The 1.7.0 release of MCUBoot adds support for the Mbed-OS platform,
@@ -39,7 +77,7 @@
### Zephyr-RTOS Compatibility
-This release of MCUboot works with the Zephyr "master" at the time of the
+This release of MCUboot works with the Zephyr "main" at the time of the
release. It was tested as of has 7a3b253ce. This version of MCUboot also
works with the Zephyr v2.4.0, however it is recommended to enable
`CONFIG_MCUBOOT_CLEANUP_ARM_CORE` while using that version.
@@ -75,7 +113,7 @@
### Zephyr-RTOS Compatibility
-This release of MCUboot works the Zephyr "master" at the time of the
+This release of MCUboot works the Zephyr "main" at the time of the
release. It was tested as of has 1a89ca1238. When Zephyr v2.3.0 is
released, there will be a possible 1.6.1 or similar release of Zephyr
if needed to address any issues. There also may be branch releases of
@@ -145,7 +183,7 @@
The 1.3.1 release of MCUboot consists mostly of small bug fixes and updates.
There are no breaking changes in functionality. This release should work with
-Mynewt 1.6.0 and up, and any Zephyr `master` after sha
+Mynewt 1.6.0 and up, and any Zephyr `main` after sha
f51e3c296040f73bca0e8fe1051d5ee63ce18e0d.
### About this release
diff --git a/docs/release.md b/docs/release.md
index ff00cec..90c32b5 100644
--- a/docs/release.md
+++ b/docs/release.md
@@ -32,7 +32,7 @@
time, and allow testing to happen.
During the time between rc1 and the final release, the only changes
-that should be merged into master are those to fix bugs found in the
+that should be merged into main are those to fix bugs found in the
rc and Mynewt metadata as described in the next section.
## imgtool release
@@ -81,7 +81,7 @@
At this point, the tag can be pushed to github to make the actual
release happen:
``` bash
-git push origin HEAD:refs/heads/master
+git push origin HEAD:refs/heads/main
git push origin va.b.c-rcn
```
diff --git a/enc-aes256kw.b64 b/enc-aes256kw.b64
new file mode 100644
index 0000000..866aa6d
--- /dev/null
+++ b/enc-aes256kw.b64
@@ -0,0 +1 @@
+5FxRRtIcgjXMGhmvofKqIMiMf0Bs2yKqarXLqvixW7Q=
diff --git a/ext/cddl-gen b/ext/cddl-gen
new file mode 160000
index 0000000..9f77837
--- /dev/null
+++ b/ext/cddl-gen
@@ -0,0 +1 @@
+Subproject commit 9f77837f9950da1633d22abf6181a830521a6688
diff --git a/ext/cddl_gen b/ext/cddl_gen
deleted file mode 160000
index 9d911cf..0000000
--- a/ext/cddl_gen
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 9d911cf0c7c9f13b5a9fdd5ed6c1012df21e5576
diff --git a/ext/fiat/src/curve25519.c b/ext/fiat/src/curve25519.c
index f669570..58abb08 100644
--- a/ext/fiat/src/curve25519.c
+++ b/ext/fiat/src/curve25519.c
@@ -36,6 +36,10 @@
#if defined(MCUBOOT_USE_MBED_TLS)
#include <mbedtls/platform_util.h>
#include <mbedtls/sha512.h>
+#include <mbedtls/version.h>
+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000
+ #include <mbedtls/compat-2.x.h>
+ #endif
#else
#include <tinycrypt/constants.h>
#include <tinycrypt/utils.h>
diff --git a/ext/mbedtls b/ext/mbedtls
index 74692ae..8df2f8e 160000
--- a/ext/mbedtls
+++ b/ext/mbedtls
@@ -1 +1 @@
-Subproject commit 74692aeb8c7e2c1c0f273592d87472a6f2aabacf
+Subproject commit 8df2f8e7b9c7bb9390ac74bb7bace27edca81a2b
diff --git a/ext/mbedtls-asn1/include/common.h b/ext/mbedtls-asn1/include/common.h
new file mode 100644
index 0000000..a2c8a1e
--- /dev/null
+++ b/ext/mbedtls-asn1/include/common.h
@@ -0,0 +1,56 @@
+/**
+ * \file common.h
+ *
+ * \brief Utility macros for internal use in the library
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ */
+
+#ifndef MBEDTLS_LIBRARY_COMMON_H
+#define MBEDTLS_LIBRARY_COMMON_H
+
+#include "mbedtls/build_info.h"
+
+/** Helper to define a function as static except when building invasive tests.
+ *
+ * If a function is only used inside its own source file and should be
+ * declared `static` to allow the compiler to optimize for code size,
+ * but that function has unit tests, define it with
+ * ```
+ * MBEDTLS_STATIC_TESTABLE int mbedtls_foo(...) { ... }
+ * ```
+ * and declare it in a header in the `library/` directory with
+ * ```
+ * #if defined(MBEDTLS_TEST_HOOKS)
+ * int mbedtls_foo(...);
+ * #endif
+ * ```
+ */
+#if defined(MBEDTLS_TEST_HOOKS)
+#define MBEDTLS_STATIC_TESTABLE
+#else
+#define MBEDTLS_STATIC_TESTABLE static
+#endif
+
+/** Allow library to access its structs' private members.
+ *
+ * Although structs defined in header files are publicly available,
+ * their members are private and should not be accessed by the user.
+ */
+#define MBEDTLS_ALLOW_PRIVATE_ACCESS
+
+#endif /* MBEDTLS_LIBRARY_COMMON_H */
diff --git a/ext/mbedtls-asn1/include/mbedtls/asn1.h b/ext/mbedtls-asn1/include/mbedtls/asn1.h
index 96c1c9a..4668581 100644
--- a/ext/mbedtls-asn1/include/mbedtls/asn1.h
+++ b/ext/mbedtls-asn1/include/mbedtls/asn1.h
@@ -4,7 +4,7 @@
* \brief Generic ASN.1 parsing
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,22 +18,17 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ASN1_H
#define MBEDTLS_ASN1_H
+#include "mbedtls/private_access.h"
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
#include <stddef.h>
#if defined(MBEDTLS_BIGNUM_C)
-#include "bignum.h"
+#include "mbedtls/bignum.h"
#endif
/**
@@ -52,7 +47,7 @@
#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */
#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */
#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */
-#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */
+#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. */
#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A /**< Memory allocation failed */
#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */
@@ -75,6 +70,7 @@
#define MBEDTLS_ASN1_OCTET_STRING 0x04
#define MBEDTLS_ASN1_NULL 0x05
#define MBEDTLS_ASN1_OID 0x06
+#define MBEDTLS_ASN1_ENUMERATED 0x0A
#define MBEDTLS_ASN1_UTF8_STRING 0x0C
#define MBEDTLS_ASN1_SEQUENCE 0x10
#define MBEDTLS_ASN1_SET 0x11
@@ -89,6 +85,18 @@
#define MBEDTLS_ASN1_CONSTRUCTED 0x20
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80
+/* Slightly smaller way to check if tag is a string tag
+ * compared to canonical implementation. */
+#define MBEDTLS_ASN1_IS_STRING_TAG( tag ) \
+ ( ( tag ) < 32u && ( \
+ ( ( 1u << ( tag ) ) & ( ( 1u << MBEDTLS_ASN1_BMP_STRING ) | \
+ ( 1u << MBEDTLS_ASN1_UTF8_STRING ) | \
+ ( 1u << MBEDTLS_ASN1_T61_STRING ) | \
+ ( 1u << MBEDTLS_ASN1_IA5_STRING ) | \
+ ( 1u << MBEDTLS_ASN1_UNIVERSAL_STRING ) | \
+ ( 1u << MBEDTLS_ASN1_PRINTABLE_STRING ) | \
+ ( 1u << MBEDTLS_ASN1_BIT_STRING ) ) ) != 0 ) )
+
/*
* Bit masks for each of the components of an ASN.1 tag as specified in
* ITU X.690 (08/2015), section 8.1 "General rules for encoding",
@@ -119,6 +127,10 @@
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \
memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
+#define MBEDTLS_OID_CMP_RAW(oid_str, oid_buf, oid_buf_len) \
+ ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len) ) || \
+ memcmp( (oid_str), (oid_buf), (oid_buf_len) ) != 0 )
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -133,9 +145,9 @@
*/
typedef struct mbedtls_asn1_buf
{
- int tag; /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
- size_t len; /**< ASN1 length, in octets. */
- unsigned char *p; /**< ASN1 data, e.g. in ASCII. */
+ int MBEDTLS_PRIVATE(tag); /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
+ size_t MBEDTLS_PRIVATE(len); /**< ASN1 length, in octets. */
+ unsigned char *MBEDTLS_PRIVATE(p); /**< ASN1 data, e.g. in ASCII. */
}
mbedtls_asn1_buf;
@@ -144,9 +156,9 @@
*/
typedef struct mbedtls_asn1_bitstring
{
- size_t len; /**< ASN1 length, in octets. */
- unsigned char unused_bits; /**< Number of unused bits at the end of the string */
- unsigned char *p; /**< Raw ASN1 data for the bit string */
+ size_t MBEDTLS_PRIVATE(len); /**< ASN1 length, in octets. */
+ unsigned char MBEDTLS_PRIVATE(unused_bits); /**< Number of unused bits at the end of the string */
+ unsigned char *MBEDTLS_PRIVATE(p); /**< Raw ASN1 data for the bit string */
}
mbedtls_asn1_bitstring;
@@ -155,8 +167,8 @@
*/
typedef struct mbedtls_asn1_sequence
{
- mbedtls_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */
- struct mbedtls_asn1_sequence *next; /**< The next entry in the sequence. */
+ mbedtls_asn1_buf MBEDTLS_PRIVATE(buf); /**< Buffer containing the given ASN.1 item. */
+ struct mbedtls_asn1_sequence *MBEDTLS_PRIVATE(next); /**< The next entry in the sequence. */
}
mbedtls_asn1_sequence;
@@ -165,10 +177,10 @@
*/
typedef struct mbedtls_asn1_named_data
{
- mbedtls_asn1_buf oid; /**< The object identifier. */
- mbedtls_asn1_buf val; /**< The named value. */
- struct mbedtls_asn1_named_data *next; /**< The next entry in the sequence. */
- unsigned char next_merged; /**< Merge next item into the current one? */
+ mbedtls_asn1_buf MBEDTLS_PRIVATE(oid); /**< The object identifier. */
+ mbedtls_asn1_buf MBEDTLS_PRIVATE(val); /**< The named value. */
+ struct mbedtls_asn1_named_data *MBEDTLS_PRIVATE(next); /**< The next entry in the sequence. */
+ unsigned char MBEDTLS_PRIVATE(next_merged); /**< Merge next item into the current one? */
}
mbedtls_asn1_named_data;
@@ -176,119 +188,342 @@
* \brief Get the length of an ASN.1 element.
* Updates the pointer to immediately behind the length.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param len The variable that will receive the value
+ * \param p On entry, \c *p points to the first byte of the length,
+ * i.e. immediately after the tag.
+ * On successful completion, \c *p points to the first byte
+ * after the length, i.e. the first byte of the content.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param len On successful completion, \c *len contains the length
+ * read from the ASN.1 input.
*
- * \return 0 if successful, MBEDTLS_ERR_ASN1_OUT_OF_DATA on reaching
- * end of data, MBEDTLS_ERR_ASN1_INVALID_LENGTH if length is
- * unparseable.
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
+ * would end beyond \p end.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
*/
int mbedtls_asn1_get_len( unsigned char **p,
- const unsigned char *end,
- size_t *len );
+ const unsigned char *end,
+ size_t *len );
/**
- * \brief Get the tag and length of the tag. Check for the requested tag.
+ * \brief Get the tag and length of the element.
+ * Check for the requested tag.
* Updates the pointer to immediately behind the tag and length.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param len The variable that will receive the length
- * \param tag The expected tag
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * after the length, i.e. the first byte of the content.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param len On successful completion, \c *len contains the length
+ * read from the ASN.1 input.
+ * \param tag The expected tag.
*
- * \return 0 if successful, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if tag did
- * not match requested tag, or another specific ASN.1 error code.
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the data does not start
+ * with the requested tag.
+ * \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
+ * would end beyond \p end.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
*/
int mbedtls_asn1_get_tag( unsigned char **p,
- const unsigned char *end,
- size_t *len, int tag );
+ const unsigned char *end,
+ size_t *len, int tag );
/**
* \brief Retrieve a boolean ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param val The variable that will receive the value
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the ASN.1 element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param val On success, the parsed value (\c 0 or \c 1).
*
- * \return 0 if successful or a specific ASN.1 error code.
+ * \return 0 if successful.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 BOOLEAN.
*/
int mbedtls_asn1_get_bool( unsigned char **p,
- const unsigned char *end,
- int *val );
+ const unsigned char *end,
+ int *val );
/**
* \brief Retrieve an integer ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param val The variable that will receive the value
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the ASN.1 element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param val On success, the parsed value.
*
- * \return 0 if successful or a specific ASN.1 error code.
+ * \return 0 if successful.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 INTEGER.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
+ * not fit in an \c int.
*/
int mbedtls_asn1_get_int( unsigned char **p,
- const unsigned char *end,
- int *val );
+ const unsigned char *end,
+ int *val );
+
+/**
+ * \brief Retrieve an enumerated ASN.1 tag and its value.
+ * Updates the pointer to immediately behind the full tag.
+ *
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the ASN.1 element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param val On success, the parsed value.
+ *
+ * \return 0 if successful.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 ENUMERATED.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
+ * not fit in an \c int.
+ */
+int mbedtls_asn1_get_enum( unsigned char **p,
+ const unsigned char *end,
+ int *val );
/**
* \brief Retrieve a bitstring ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param bs The variable that will receive the value
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p is equal to \p end.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param bs On success, ::mbedtls_asn1_bitstring information about
+ * the parsed value.
*
- * \return 0 if successful or a specific ASN.1 error code.
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
+ * extra data after a valid BIT STRING.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 BIT STRING.
*/
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
- mbedtls_asn1_bitstring *bs);
+ mbedtls_asn1_bitstring *bs );
/**
* \brief Retrieve a bitstring ASN.1 tag without unused bits and its
* value.
* Updates the pointer to the beginning of the bit/octet string.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param len Length of the actual bit/octect string in bytes
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * of the content of the BIT STRING.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param len On success, \c *len is the length of the content in bytes.
*
- * \return 0 if successful or a specific ASN.1 error code.
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_DATA if the input starts with
+ * a valid BIT STRING with a nonzero number of unused bits.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 BIT STRING.
*/
-int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
- size_t *len );
+int mbedtls_asn1_get_bitstring_null( unsigned char **p,
+ const unsigned char *end,
+ size_t *len );
/**
- * \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>"
- * Updated the pointer to immediately behind the full sequence tag.
+ * \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>".
+ * Updates the pointer to immediately behind the full sequence tag.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param cur First variable in the chain to fill
- * \param tag Type of sequence
+ * This function allocates memory for the sequence elements. You can free
+ * the allocated memory with mbedtls_asn1_sequence_free().
*
- * \return 0 if successful or a specific ASN.1 error code.
+ * \note On error, this function may return a partial list in \p cur.
+ * You must set `cur->next = NULL` before calling this function!
+ * Otherwise it is impossible to distinguish a previously non-null
+ * pointer from a pointer to an object allocated by this function.
+ *
+ * \note If the sequence is empty, this function does not modify
+ * \c *cur. If the sequence is valid and non-empty, this
+ * function sets `cur->buf.tag` to \p tag. This allows
+ * callers to distinguish between an empty sequence and
+ * a one-element sequence.
+ *
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p is equal to \p end.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param cur A ::mbedtls_asn1_sequence which this function fills.
+ * When this function returns, \c *cur is the head of a linked
+ * list. Each node in this list is allocated with
+ * mbedtls_calloc() apart from \p cur itself, and should
+ * therefore be freed with mbedtls_free().
+ * The list describes the content of the sequence.
+ * The head of the list (i.e. \c *cur itself) describes the
+ * first element, `*cur->next` describes the second element, etc.
+ * For each element, `buf.tag == tag`, `buf.len` is the length
+ * of the content of the content of the element, and `buf.p`
+ * points to the first byte of the content (i.e. immediately
+ * past the length of the element).
+ * Note that list elements may be allocated even on error.
+ * \param tag Each element of the sequence must have this tag.
+ *
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
+ * extra data after a valid SEQUENCE OF \p tag.
+ * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts with
+ * an ASN.1 SEQUENCE in which an element has a tag that
+ * is different from \p tag.
+ * \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if a memory allocation failed.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 SEQUENCE.
*/
int mbedtls_asn1_get_sequence_of( unsigned char **p,
- const unsigned char *end,
- mbedtls_asn1_sequence *cur,
- int tag);
+ const unsigned char *end,
+ mbedtls_asn1_sequence *cur,
+ int tag );
+/**
+ * \brief Free a heap-allocated linked list presentation of
+ * an ASN.1 sequence, including the first element.
+ *
+ * There are two common ways to manage the memory used for the representation
+ * of a parsed ASN.1 sequence:
+ * - Allocate a head node `mbedtls_asn1_sequence *head` with mbedtls_calloc().
+ * Pass this node as the `cur` argument to mbedtls_asn1_get_sequence_of().
+ * When you have finished processing the sequence,
+ * call mbedtls_asn1_sequence_free() on `head`.
+ * - Allocate a head node `mbedtls_asn1_sequence *head` in any manner,
+ * for example on the stack. Make sure that `head->next == NULL`.
+ * Pass `head` as the `cur` argument to mbedtls_asn1_get_sequence_of().
+ * When you have finished processing the sequence,
+ * call mbedtls_asn1_sequence_free() on `head->cur`,
+ * then free `head` itself in the appropriate manner.
+ *
+ * \param seq The address of the first sequence component. This may
+ * be \c NULL, in which case this functions returns
+ * immediately.
+ */
+void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq );
+
+/**
+ * \brief Traverse an ASN.1 SEQUENCE container and
+ * call a callback for each entry.
+ *
+ * This function checks that the input is a SEQUENCE of elements that
+ * each have a "must" tag, and calls a callback function on the elements
+ * that have a "may" tag.
+ *
+ * For example, to validate that the input is a SEQUENCE of `tag1` and call
+ * `cb` on each element, use
+ * ```
+ * mbedtls_asn1_traverse_sequence_of(&p, end, 0xff, tag1, 0, 0, cb, ctx);
+ * ```
+ *
+ * To validate that the input is a SEQUENCE of ANY and call `cb` on
+ * each element, use
+ * ```
+ * mbedtls_asn1_traverse_sequence_of(&p, end, 0, 0, 0, 0, cb, ctx);
+ * ```
+ *
+ * To validate that the input is a SEQUENCE of CHOICE {NULL, OCTET STRING}
+ * and call `cb` on each element that is an OCTET STRING, use
+ * ```
+ * mbedtls_asn1_traverse_sequence_of(&p, end, 0xfe, 0x04, 0xff, 0x04, cb, ctx);
+ * ```
+ *
+ * The callback is called on the elements with a "may" tag from left to
+ * right. If the input is not a valid SEQUENCE of elements with a "must" tag,
+ * the callback is called on the elements up to the leftmost point where
+ * the input is invalid.
+ *
+ * \warning This function is still experimental and may change
+ * at any time.
+ *
+ * \param p The address of the pointer to the beginning of
+ * the ASN.1 SEQUENCE header. This is updated to
+ * point to the end of the ASN.1 SEQUENCE container
+ * on a successful invocation.
+ * \param end The end of the ASN.1 SEQUENCE container.
+ * \param tag_must_mask A mask to be applied to the ASN.1 tags found within
+ * the SEQUENCE before comparing to \p tag_must_value.
+ * \param tag_must_val The required value of each ASN.1 tag found in the
+ * SEQUENCE, after masking with \p tag_must_mask.
+ * Mismatching tags lead to an error.
+ * For example, a value of \c 0 for both \p tag_must_mask
+ * and \p tag_must_val means that every tag is allowed,
+ * while a value of \c 0xFF for \p tag_must_mask means
+ * that \p tag_must_val is the only allowed tag.
+ * \param tag_may_mask A mask to be applied to the ASN.1 tags found within
+ * the SEQUENCE before comparing to \p tag_may_value.
+ * \param tag_may_val The desired value of each ASN.1 tag found in the
+ * SEQUENCE, after masking with \p tag_may_mask.
+ * Mismatching tags will be silently ignored.
+ * For example, a value of \c 0 for \p tag_may_mask and
+ * \p tag_may_val means that any tag will be considered,
+ * while a value of \c 0xFF for \p tag_may_mask means
+ * that all tags with value different from \p tag_may_val
+ * will be ignored.
+ * \param cb The callback to trigger for each component
+ * in the ASN.1 SEQUENCE that matches \p tag_may_val.
+ * The callback function is called with the following
+ * parameters:
+ * - \p ctx.
+ * - The tag of the current element.
+ * - A pointer to the start of the current element's
+ * content inside the input.
+ * - The length of the content of the current element.
+ * If the callback returns a non-zero value,
+ * the function stops immediately,
+ * forwarding the callback's return value.
+ * \param ctx The context to be passed to the callback \p cb.
+ *
+ * \return \c 0 if successful the entire ASN.1 SEQUENCE
+ * was traversed without parsing or callback errors.
+ * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input
+ * contains extra data after a valid SEQUENCE
+ * of elements with an accepted tag.
+ * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts
+ * with an ASN.1 SEQUENCE in which an element has a tag
+ * that is not accepted.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 SEQUENCE.
+ * \return A non-zero error code forwarded from the callback
+ * \p cb in case the latter returns a non-zero value.
+ */
+int mbedtls_asn1_traverse_sequence_of(
+ unsigned char **p,
+ const unsigned char *end,
+ unsigned char tag_must_mask, unsigned char tag_must_val,
+ unsigned char tag_may_mask, unsigned char tag_may_val,
+ int (*cb)( void *ctx, int tag,
+ unsigned char* start, size_t len ),
+ void *ctx );
#if defined(MBEDTLS_BIGNUM_C)
/**
- * \brief Retrieve a MPI value from an integer ASN.1 tag.
+ * \brief Retrieve an integer ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param X The MPI that will receive the value
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the ASN.1 element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param X On success, the parsed value.
*
- * \return 0 if successful or a specific ASN.1 or MPI error code.
+ * \return 0 if successful.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 INTEGER.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
+ * not fit in an \c int.
+ * \return An MPI error code if the parsed value is too large.
*/
int mbedtls_asn1_get_mpi( unsigned char **p,
- const unsigned char *end,
- mbedtls_mpi *X );
+ const unsigned char *end,
+ mbedtls_mpi *X );
#endif /* MBEDTLS_BIGNUM_C */
/**
@@ -296,10 +531,14 @@
* Updates the pointer to immediately behind the full
* AlgorithmIdentifier.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param alg The buffer to receive the OID
- * \param params The buffer to receive the params (if any)
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the AlgorithmIdentifier element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param alg The buffer to receive the OID.
+ * \param params The buffer to receive the parameters.
+ * This is zeroized if there are no parameters.
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
@@ -313,9 +552,12 @@
* Updates the pointer to immediately behind the full
* AlgorithmIdentifier.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param alg The buffer to receive the OID
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the AlgorithmIdentifier element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param alg The buffer to receive the OID.
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
@@ -333,21 +575,25 @@
*
* \return NULL if not found, or a pointer to the existing entry.
*/
-mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
+const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( const mbedtls_asn1_named_data *list,
const char *oid, size_t len );
/**
* \brief Free a mbedtls_asn1_named_data entry
*
- * \param entry The named data entry to free
+ * \param entry The named data entry to free.
+ * This function calls mbedtls_free() on
+ * `entry->oid.p` and `entry->val.p`.
*/
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
/**
- * \brief Free all entries in a mbedtls_asn1_named_data list
- * Head will be set to NULL
+ * \brief Free all entries in a mbedtls_asn1_named_data list.
*
- * \param head Pointer to the head of the list of named data entries to free
+ * \param head Pointer to the head of the list of named data entries to free.
+ * This function calls mbedtls_asn1_free_named_data() and
+ * mbedtls_free() on each list element and
+ * sets \c *head to \c NULL.
*/
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head );
diff --git a/ext/mbedtls-asn1/include/mbedtls/bignum.h b/ext/mbedtls-asn1/include/mbedtls/bignum.h
index 40cfab4..5187d86 100644
--- a/ext/mbedtls-asn1/include/mbedtls/bignum.h
+++ b/ext/mbedtls-asn1/include/mbedtls/bignum.h
@@ -4,7 +4,7 @@
* \brief Multi-precision integer library
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,17 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_BIGNUM_H
#define MBEDTLS_BIGNUM_H
+#include "mbedtls/private_access.h"
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
#include <stddef.h>
#include <stdint.h>
@@ -46,7 +41,12 @@
#define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */
#define MBEDTLS_ERR_MPI_ALLOC_FAILED -0x0010 /**< Memory allocation failed. */
-#define MBEDTLS_MPI_CHK(f) do { if( ( ret = f ) != 0 ) goto cleanup; } while( 0 )
+#define MBEDTLS_MPI_CHK(f) \
+ do \
+ { \
+ if( ( ret = (f) ) != 0 ) \
+ goto cleanup; \
+ } while( 0 )
/*
* Maximum size MPIs are allowed to grow to in number of limbs.
@@ -58,12 +58,12 @@
* Maximum window size used for modular exponentiation. Default: 6
* Minimum value: 1. Maximum value: 6.
*
- * Result is an array of ( 2 << MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
+ * Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
* for the sliding window calculation. (So 64 by default)
*
* Reduction in size, reduces speed.
*/
-#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */
+#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */
#endif /* !MBEDTLS_MPI_WINDOW_SIZE */
#if !defined(MBEDTLS_MPI_MAX_SIZE)
@@ -124,7 +124,8 @@
defined(__ppc64__) || defined(__powerpc64__) || \
defined(__ia64__) || defined(__alpha__) || \
( defined(__sparc__) && defined(__arch64__) ) || \
- defined(__s390x__) || defined(__mips64) )
+ defined(__s390x__) || defined(__mips64) || \
+ defined(__aarch64__) )
#if !defined(MBEDTLS_HAVE_INT64)
#define MBEDTLS_HAVE_INT64
#endif /* MBEDTLS_HAVE_INT64 */
@@ -179,103 +180,122 @@
*/
typedef struct mbedtls_mpi
{
- int s; /*!< integer sign */
- size_t n; /*!< total # of limbs */
- mbedtls_mpi_uint *p; /*!< pointer to limbs */
+ int MBEDTLS_PRIVATE(s); /*!< Sign: -1 if the mpi is negative, 1 otherwise */
+ size_t MBEDTLS_PRIVATE(n); /*!< total # of limbs */
+ mbedtls_mpi_uint *MBEDTLS_PRIVATE(p); /*!< pointer to limbs */
}
mbedtls_mpi;
/**
- * \brief Initialize one MPI (make internal references valid)
- * This just makes it ready to be set or freed,
+ * \brief Initialize an MPI context.
+ *
+ * This makes the MPI ready to be set or freed,
* but does not define a value for the MPI.
*
- * \param X One MPI to initialize.
+ * \param X The MPI context to initialize. This must not be \c NULL.
*/
void mbedtls_mpi_init( mbedtls_mpi *X );
/**
- * \brief Unallocate one MPI
+ * \brief This function frees the components of an MPI context.
*
- * \param X One MPI to unallocate.
+ * \param X The MPI context to be cleared. This may be \c NULL,
+ * in which case this function is a no-op. If it is
+ * not \c NULL, it must point to an initialized MPI.
*/
void mbedtls_mpi_free( mbedtls_mpi *X );
/**
- * \brief Enlarge to the specified number of limbs
+ * \brief Enlarge an MPI to the specified number of limbs.
*
- * This function does nothing if the MPI is already large enough.
+ * \note This function does nothing if the MPI is
+ * already large enough.
*
- * \param X MPI to grow
- * \param nblimbs The target number of limbs
+ * \param X The MPI to grow. It must be initialized.
+ * \param nblimbs The target number of limbs.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs );
/**
- * \brief Resize down, keeping at least the specified number of limbs
+ * \brief This function resizes an MPI downwards, keeping at least the
+ * specified number of limbs.
*
* If \c X is smaller than \c nblimbs, it is resized up
* instead.
*
- * \param X MPI to shrink
- * \param nblimbs The minimum number of limbs to keep
+ * \param X The MPI to shrink. This must point to an initialized MPI.
+ * \param nblimbs The minimum number of limbs to keep.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
* (this can only happen when resizing up).
+ * \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs );
/**
- * \brief Copy the contents of Y into X
+ * \brief Make a copy of an MPI.
*
- * \param X Destination MPI. It is enlarged if necessary.
- * \param Y Source MPI.
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param Y The source MPI. This must point to an initialized MPI.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \note The limb-buffer in the destination MPI is enlarged
+ * if necessary to hold the value in the source MPI.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y );
/**
- * \brief Swap the contents of X and Y
+ * \brief Swap the contents of two MPIs.
*
- * \param X First MPI value
- * \param Y Second MPI value
+ * \param X The first MPI. It must be initialized.
+ * \param Y The second MPI. It must be initialized.
*/
void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y );
/**
- * \brief Safe conditional assignement X = Y if assign is 1
+ * \brief Perform a safe conditional copy of MPI which doesn't
+ * reveal whether the condition was true or not.
*
- * \param X MPI to conditionally assign to
- * \param Y Value to be assigned
- * \param assign 1: perform the assignment, 0: keep X's original value
- *
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ * \param X The MPI to conditionally assign to. This must point
+ * to an initialized MPI.
+ * \param Y The MPI to be assigned from. This must point to an
+ * initialized MPI.
+ * \param assign The condition deciding whether to perform the
+ * assignment or not. Possible values:
+ * * \c 1: Perform the assignment `X = Y`.
+ * * \c 0: Keep the original value of \p X.
*
* \note This function is equivalent to
- * if( assign ) mbedtls_mpi_copy( X, Y );
+ * `if( assign ) mbedtls_mpi_copy( X, Y );`
* except that it avoids leaking any information about whether
* the assignment was done or not (the above code may leak
* information through branch prediction and/or memory access
* patterns analysis).
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign );
/**
- * \brief Safe conditional swap X <-> Y if swap is 1
+ * \brief Perform a safe conditional swap which doesn't
+ * reveal whether the condition was true or not.
*
- * \param X First mbedtls_mpi value
- * \param Y Second mbedtls_mpi value
- * \param assign 1: perform the swap, 0: keep X and Y's original values
- *
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
+ * \param X The first MPI. This must be initialized.
+ * \param Y The second MPI. This must be initialized.
+ * \param assign The condition deciding whether to perform
+ * the swap or not. Possible values:
+ * * \c 1: Swap the values of \p X and \p Y.
+ * * \c 0: Keep the original values of \p X and \p Y.
*
* \note This function is equivalent to
* if( assign ) mbedtls_mpi_swap( X, Y );
@@ -283,415 +303,564 @@
* the assignment was done or not (the above code may leak
* information through branch prediction and/or memory access
* patterns analysis).
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return Another negative error code on other kinds of failure.
+ *
*/
int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char assign );
/**
- * \brief Set value from integer
+ * \brief Store integer value in MPI.
*
- * \param X MPI to set
- * \param z Value to use
+ * \param X The MPI to set. This must be initialized.
+ * \param z The value to use.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z );
/**
- * \brief Get a specific bit from X
+ * \brief Get a specific bit from an MPI.
*
- * \param X MPI to use
- * \param pos Zero-based index of the bit in X
+ * \param X The MPI to query. This must be initialized.
+ * \param pos Zero-based index of the bit to query.
*
- * \return Either a 0 or a 1
+ * \return \c 0 or \c 1 on success, depending on whether bit \c pos
+ * of \c X is unset or set.
+ * \return A negative error code on failure.
*/
int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos );
/**
- * \brief Set a bit of X to a specific value of 0 or 1
+ * \brief Modify a specific bit in an MPI.
*
- * \note Will grow X if necessary to set a bit to 1 in a not yet
- * existing limb. Will not grow if bit should be set to 0
+ * \note This function will grow the target MPI if necessary to set a
+ * bit to \c 1 in a not yet existing limb. It will not grow if
+ * the bit should be set to \c 0.
*
- * \param X MPI to use
- * \param pos Zero-based index of the bit in X
- * \param val The value to set the bit to (0 or 1)
+ * \param X The MPI to modify. This must be initialized.
+ * \param pos Zero-based index of the bit to modify.
+ * \param val The desired value of bit \c pos: \c 0 or \c 1.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- * MBEDTLS_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val );
/**
- * \brief Return the number of zero-bits before the least significant
- * '1' bit
+ * \brief Return the number of bits of value \c 0 before the
+ * least significant bit of value \c 1.
*
- * Note: Thus also the zero-based index of the least significant '1' bit
+ * \note This is the same as the zero-based index of
+ * the least significant bit of value \c 1.
*
- * \param X MPI to use
+ * \param X The MPI to query.
+ *
+ * \return The number of bits of value \c 0 before the least significant
+ * bit of value \c 1 in \p X.
*/
size_t mbedtls_mpi_lsb( const mbedtls_mpi *X );
/**
* \brief Return the number of bits up to and including the most
- * significant '1' bit'
+ * significant bit of value \c 1.
*
- * Note: Thus also the one-based index of the most significant '1' bit
+ * * \note This is same as the one-based index of the most
+ * significant bit of value \c 1.
*
- * \param X MPI to use
+ * \param X The MPI to query. This must point to an initialized MPI.
+ *
+ * \return The number of bits up to and including the most
+ * significant bit of value \c 1.
*/
size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X );
/**
- * \brief Return the total size in bytes
+ * \brief Return the total size of an MPI value in bytes.
*
- * \param X MPI to use
+ * \param X The MPI to use. This must point to an initialized MPI.
+ *
+ * \note The value returned by this function may be less than
+ * the number of bytes used to store \p X internally.
+ * This happens if and only if there are trailing bytes
+ * of value zero.
+ *
+ * \return The least number of bytes capable of storing
+ * the absolute value of \p X.
*/
size_t mbedtls_mpi_size( const mbedtls_mpi *X );
/**
- * \brief Import from an ASCII string
+ * \brief Import an MPI from an ASCII string.
*
- * \param X Destination MPI
- * \param radix Input numeric base
- * \param s Null-terminated string buffer
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param radix The numeric base of the input string.
+ * \param s Null-terminated string buffer.
*
- * \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code
+ * \return \c 0 if successful.
+ * \return A negative error code on failure.
*/
int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s );
/**
- * \brief Export into an ASCII string
+ * \brief Export an MPI to an ASCII string.
*
- * \param X Source MPI
- * \param radix Output numeric base
- * \param buf Buffer to write the string to
- * \param buflen Length of buf
- * \param olen Length of the string written, including final NUL byte
+ * \param X The source MPI. This must point to an initialized MPI.
+ * \param radix The numeric base of the output string.
+ * \param buf The buffer to write the string to. This must be writable
+ * buffer of length \p buflen Bytes.
+ * \param buflen The available size in Bytes of \p buf.
+ * \param olen The address at which to store the length of the string
+ * written, including the final \c NULL byte. This must
+ * not be \c NULL.
*
- * \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code.
- * *olen is always updated to reflect the amount
- * of data that has (or would have) been written.
+ * \note You can call this function with `buflen == 0` to obtain the
+ * minimum required buffer size in `*olen`.
*
- * \note Call this function with buflen = 0 to obtain the
- * minimum required buffer size in *olen.
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the target buffer \p buf
+ * is too small to hold the value of \p X in the desired base.
+ * In this case, `*olen` is nonetheless updated to contain the
+ * size of \p buf required for a successful call.
+ * \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
char *buf, size_t buflen, size_t *olen );
#if defined(MBEDTLS_FS_IO)
/**
- * \brief Read MPI from a line in an opened file
+ * \brief Read an MPI from a line in an opened file.
*
- * \param X Destination MPI
- * \param radix Input numeric base
- * \param fin Input file handle
- *
- * \return 0 if successful, MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if
- * the file read buffer is too small or a
- * MBEDTLS_ERR_MPI_XXX error code
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param radix The numeric base of the string representation used
+ * in the source line.
+ * \param fin The input file handle to use. This must not be \c NULL.
*
* \note On success, this function advances the file stream
* to the end of the current line or to EOF.
*
- * The function returns 0 on an empty line.
+ * The function returns \c 0 on an empty line.
*
* Leading whitespaces are ignored, as is a
- * '0x' prefix for radix 16.
+ * '0x' prefix for radix \c 16.
*
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the file read buffer
+ * is too small.
+ * \return Another negative error code on failure.
*/
int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin );
/**
- * \brief Write X into an opened file, or stdout if fout is NULL
+ * \brief Export an MPI into an opened file.
*
- * \param p Prefix, can be NULL
- * \param X Source MPI
- * \param radix Output numeric base
- * \param fout Output file handle (can be NULL)
+ * \param p A string prefix to emit prior to the MPI data.
+ * For example, this might be a label, or "0x" when
+ * printing in base \c 16. This may be \c NULL if no prefix
+ * is needed.
+ * \param X The source MPI. This must point to an initialized MPI.
+ * \param radix The numeric base to be used in the emitted string.
+ * \param fout The output file handle. This may be \c NULL, in which case
+ * the output is written to \c stdout.
*
- * \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code
- *
- * \note Set fout == NULL to print X on the console.
+ * \return \c 0 if successful.
+ * \return A negative error code on failure.
*/
-int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout );
+int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X,
+ int radix, FILE *fout );
#endif /* MBEDTLS_FS_IO */
/**
- * \brief Import X from unsigned binary data, big endian
+ * \brief Import an MPI from unsigned big endian binary data.
*
- * \param X Destination MPI
- * \param buf Input buffer
- * \param buflen Input buffer size
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param buf The input buffer. This must be a readable buffer of length
+ * \p buflen Bytes.
+ * \param buflen The length of the input buffer \p p in Bytes.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return Another negative error code on different kinds of failure.
*/
-int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen );
+int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf,
+ size_t buflen );
+
+/**
+ * \brief Import X from unsigned binary data, little endian
+ *
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param buf The input buffer. This must be a readable buffer of length
+ * \p buflen Bytes.
+ * \param buflen The length of the input buffer \p p in Bytes.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_read_binary_le( mbedtls_mpi *X,
+ const unsigned char *buf, size_t buflen );
/**
* \brief Export X into unsigned binary data, big endian.
* Always fills the whole buffer, which will start with zeros
* if the number is smaller.
*
- * \param X Source MPI
- * \param buf Output buffer
- * \param buflen Output buffer size
+ * \param X The source MPI. This must point to an initialized MPI.
+ * \param buf The output buffer. This must be a writable buffer of length
+ * \p buflen Bytes.
+ * \param buflen The size of the output buffer \p buf in Bytes.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't
+ * large enough to hold the value of \p X.
+ * \return Another negative error code on different kinds of failure.
*/
-int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen );
+int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf,
+ size_t buflen );
/**
- * \brief Left-shift: X <<= count
+ * \brief Export X into unsigned binary data, little endian.
+ * Always fills the whole buffer, which will end with zeros
+ * if the number is smaller.
*
- * \param X MPI to shift
- * \param count Amount to shift
+ * \param X The source MPI. This must point to an initialized MPI.
+ * \param buf The output buffer. This must be a writable buffer of length
+ * \p buflen Bytes.
+ * \param buflen The size of the output buffer \p buf in Bytes.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't
+ * large enough to hold the value of \p X.
+ * \return Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X,
+ unsigned char *buf, size_t buflen );
+
+/**
+ * \brief Perform a left-shift on an MPI: X <<= count
+ *
+ * \param X The MPI to shift. This must point to an initialized MPI.
+ * \param count The number of bits to shift by.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count );
/**
- * \brief Right-shift: X >>= count
+ * \brief Perform a right-shift on an MPI: X >>= count
*
- * \param X MPI to shift
- * \param count Amount to shift
+ * \param X The MPI to shift. This must point to an initialized MPI.
+ * \param count The number of bits to shift by.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return Another negative error code on different kinds of failure.
*/
int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count );
/**
- * \brief Compare unsigned values
+ * \brief Compare the absolute values of two MPIs.
*
- * \param X Left-hand MPI
- * \param Y Right-hand MPI
+ * \param X The left-hand MPI. This must point to an initialized MPI.
+ * \param Y The right-hand MPI. This must point to an initialized MPI.
*
- * \return 1 if |X| is greater than |Y|,
- * -1 if |X| is lesser than |Y| or
- * 0 if |X| is equal to |Y|
+ * \return \c 1 if `|X|` is greater than `|Y|`.
+ * \return \c -1 if `|X|` is lesser than `|Y|`.
+ * \return \c 0 if `|X|` is equal to `|Y|`.
*/
int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y );
/**
- * \brief Compare signed values
+ * \brief Compare two MPIs.
*
- * \param X Left-hand MPI
- * \param Y Right-hand MPI
+ * \param X The left-hand MPI. This must point to an initialized MPI.
+ * \param Y The right-hand MPI. This must point to an initialized MPI.
*
- * \return 1 if X is greater than Y,
- * -1 if X is lesser than Y or
- * 0 if X is equal to Y
+ * \return \c 1 if \p X is greater than \p Y.
+ * \return \c -1 if \p X is lesser than \p Y.
+ * \return \c 0 if \p X is equal to \p Y.
*/
int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y );
/**
- * \brief Compare signed values
+ * \brief Check if an MPI is less than the other in constant time.
*
- * \param X Left-hand MPI
- * \param z The integer value to compare to
+ * \param X The left-hand MPI. This must point to an initialized MPI
+ * with the same allocated length as Y.
+ * \param Y The right-hand MPI. This must point to an initialized MPI
+ * with the same allocated length as X.
+ * \param ret The result of the comparison:
+ * \c 1 if \p X is less than \p Y.
+ * \c 0 if \p X is greater than or equal to \p Y.
*
- * \return 1 if X is greater than z,
- * -1 if X is lesser than z or
- * 0 if X is equal to z
+ * \return 0 on success.
+ * \return MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the allocated length of
+ * the two input MPIs is not the same.
+ */
+int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
+ unsigned *ret );
+
+/**
+ * \brief Compare an MPI with an integer.
+ *
+ * \param X The left-hand MPI. This must point to an initialized MPI.
+ * \param z The integer value to compare \p X to.
+ *
+ * \return \c 1 if \p X is greater than \p z.
+ * \return \c -1 if \p X is lesser than \p z.
+ * \return \c 0 if \p X is equal to \p z.
*/
int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z );
/**
- * \brief Unsigned addition: X = |A| + |B|
+ * \brief Perform an unsigned addition of MPIs: X = |A| + |B|
*
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param A The first summand. This must point to an initialized MPI.
+ * \param B The second summand. This must point to an initialized MPI.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return Another negative error code on different kinds of failure.
*/
-int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A,
+ const mbedtls_mpi *B );
/**
- * \brief Unsigned subtraction: X = |A| - |B|
+ * \brief Perform an unsigned subtraction of MPIs: X = |A| - |B|
*
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param A The minuend. This must point to an initialized MPI.
+ * \param B The subtrahend. This must point to an initialized MPI.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_NEGATIVE_VALUE if B is greater than A
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is greater than \p A.
+ * \return Another negative error code on different kinds of failure.
+ *
*/
-int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A,
+ const mbedtls_mpi *B );
/**
- * \brief Signed addition: X = A + B
+ * \brief Perform a signed addition of MPIs: X = A + B
*
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param A The first summand. This must point to an initialized MPI.
+ * \param B The second summand. This must point to an initialized MPI.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return Another negative error code on different kinds of failure.
*/
-int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A,
+ const mbedtls_mpi *B );
/**
- * \brief Signed subtraction: X = A - B
+ * \brief Perform a signed subtraction of MPIs: X = A - B
*
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param A The minuend. This must point to an initialized MPI.
+ * \param B The subtrahend. This must point to an initialized MPI.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return Another negative error code on different kinds of failure.
*/
-int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A,
+ const mbedtls_mpi *B );
/**
- * \brief Signed addition: X = A + b
+ * \brief Perform a signed addition of an MPI and an integer: X = A + b
*
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param b The integer value to add
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param A The first summand. This must point to an initialized MPI.
+ * \param b The second summand.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return Another negative error code on different kinds of failure.
*/
-int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b );
+int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A,
+ mbedtls_mpi_sint b );
/**
- * \brief Signed subtraction: X = A - b
+ * \brief Perform a signed subtraction of an MPI and an integer:
+ * X = A - b
*
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param b The integer value to subtract
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param A The minuend. This must point to an initialized MPI.
+ * \param b The subtrahend.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return Another negative error code on different kinds of failure.
*/
-int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b );
+int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A,
+ mbedtls_mpi_sint b );
/**
- * \brief Baseline multiplication: X = A * B
+ * \brief Perform a multiplication of two MPIs: X = A * B
*
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param A The first factor. This must point to an initialized MPI.
+ * \param B The second factor. This must point to an initialized MPI.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return Another negative error code on different kinds of failure.
+ *
*/
-int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A,
+ const mbedtls_mpi *B );
/**
- * \brief Baseline multiplication: X = A * b
+ * \brief Perform a multiplication of an MPI with an unsigned integer:
+ * X = A * b
*
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param b The unsigned integer value to multiply with
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param A The first factor. This must point to an initialized MPI.
+ * \param b The second factor.
*
- * \note b is unsigned
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return Another negative error code on different kinds of failure.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
-int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b );
+int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A,
+ mbedtls_mpi_uint b );
/**
- * \brief Division by mbedtls_mpi: A = Q * B + R
+ * \brief Perform a division with remainder of two MPIs:
+ * A = Q * B + R
*
- * \param Q Destination MPI for the quotient
- * \param R Destination MPI for the rest value
- * \param A Left-hand MPI
- * \param B Right-hand MPI
+ * \param Q The destination MPI for the quotient.
+ * This may be \c NULL if the value of the
+ * quotient is not needed.
+ * \param R The destination MPI for the remainder value.
+ * This may be \c NULL if the value of the
+ * remainder is not needed.
+ * \param A The dividend. This must point to an initialized MPi.
+ * \param B The divisor. This must point to an initialized MPI.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- * MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if B == 0
- *
- * \note Either Q or R can be NULL.
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero.
+ * \return Another negative error code on different kinds of failure.
*/
-int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
+ const mbedtls_mpi *B );
/**
- * \brief Division by int: A = Q * b + R
+ * \brief Perform a division with remainder of an MPI by an integer:
+ * A = Q * b + R
*
- * \param Q Destination MPI for the quotient
- * \param R Destination MPI for the rest value
- * \param A Left-hand MPI
- * \param b Integer to divide by
+ * \param Q The destination MPI for the quotient.
+ * This may be \c NULL if the value of the
+ * quotient is not needed.
+ * \param R The destination MPI for the remainder value.
+ * This may be \c NULL if the value of the
+ * remainder is not needed.
+ * \param A The dividend. This must point to an initialized MPi.
+ * \param b The divisor.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- * MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if b == 0
- *
- * \note Either Q or R can be NULL.
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero.
+ * \return Another negative error code on different kinds of failure.
*/
-int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, mbedtls_mpi_sint b );
+int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
+ mbedtls_mpi_sint b );
/**
- * \brief Modulo: R = A mod B
+ * \brief Perform a modular reduction. R = A mod B
*
- * \param R Destination MPI for the rest value
- * \param A Left-hand MPI
- * \param B Right-hand MPI
+ * \param R The destination MPI for the residue value.
+ * This must point to an initialized MPI.
+ * \param A The MPI to compute the residue of.
+ * This must point to an initialized MPI.
+ * \param B The base of the modular reduction.
+ * This must point to an initialized MPI.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- * MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if B == 0,
- * MBEDTLS_ERR_MPI_NEGATIVE_VALUE if B < 0
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero.
+ * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is negative.
+ * \return Another negative error code on different kinds of failure.
+ *
*/
-int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A,
+ const mbedtls_mpi *B );
/**
- * \brief Modulo: r = A mod b
+ * \brief Perform a modular reduction with respect to an integer.
+ * r = A mod b
*
- * \param r Destination mbedtls_mpi_uint
- * \param A Left-hand MPI
- * \param b Integer to divide by
+ * \param r The address at which to store the residue.
+ * This must not be \c NULL.
+ * \param A The MPI to compute the residue of.
+ * This must point to an initialized MPi.
+ * \param b The integer base of the modular reduction.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- * MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if b == 0,
- * MBEDTLS_ERR_MPI_NEGATIVE_VALUE if b < 0
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero.
+ * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p b is negative.
+ * \return Another negative error code on different kinds of failure.
*/
-int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b );
+int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A,
+ mbedtls_mpi_sint b );
/**
- * \brief Sliding-window exponentiation: X = A^E mod N
+ * \brief Perform a sliding-window exponentiation: X = A^E mod N
*
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param E Exponent MPI
- * \param N Modular MPI
- * \param _RR Speed-up MPI used for recalculations
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param A The base of the exponentiation.
+ * This must point to an initialized MPI.
+ * \param E The exponent MPI. This must point to an initialized MPI.
+ * \param N The base for the modular reduction. This must point to an
+ * initialized MPI.
+ * \param _RR A helper MPI depending solely on \p N which can be used to
+ * speed-up multiple modular exponentiations for the same value
+ * of \p N. This may be \c NULL. If it is not \c NULL, it must
+ * point to an initialized MPI. If it hasn't been used after
+ * the call to mbedtls_mpi_init(), this function will compute
+ * the helper value and store it in \p _RR for reuse on
+ * subsequent calls to this function. Otherwise, the function
+ * will assume that \p _RR holds the helper value set by a
+ * previous call to mbedtls_mpi_exp_mod(), and reuse it.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- * MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is negative or even or
- * if E is negative
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or
+ * even, or if \c E is negative.
+ * \return Another negative error code on different kinds of failures.
*
- * \note _RR is used to avoid re-computing R*R mod N across
- * multiple calls, which speeds up things a bit. It can
- * be set to NULL if the extra performance is unneeded.
*/
-int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR );
+int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
+ const mbedtls_mpi *E, const mbedtls_mpi *N,
+ mbedtls_mpi *_RR );
/**
- * \brief Fill an MPI X with size bytes of random
+ * \brief Fill an MPI with a number of random bytes.
*
- * \param X Destination MPI
- * \param size Size in bytes
- * \param f_rng RNG function
- * \param p_rng RNG parameter
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param size The number of random bytes to generate.
+ * \param f_rng The RNG function to use. This must not be \c NULL.
+ * \param p_rng The RNG parameter to be passed to \p f_rng. This may be
+ * \c NULL if \p f_rng doesn't need a context argument.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return Another negative error code on failure.
*
- * \note The bytes obtained from the PRNG are interpreted
+ * \note The bytes obtained from the RNG are interpreted
* as a big-endian representation of an MPI; this can
* be relevant in applications like deterministic ECDSA.
*/
@@ -699,58 +868,76 @@
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
-/**
- * \brief Greatest common divisor: G = gcd(A, B)
+/** Generate a random number uniformly in a range.
*
- * \param G Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
+ * This function generates a random number between \p min inclusive and
+ * \p N exclusive.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ * The procedure complies with RFC 6979 §3.3 (deterministic ECDSA)
+ * when the RNG is a suitably parametrized instance of HMAC_DRBG
+ * and \p min is \c 1.
+ *
+ * \note There are `N - min` possible outputs. The lower bound
+ * \p min can be reached, but the upper bound \p N cannot.
+ *
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param min The minimum value to return.
+ * It must be nonnegative.
+ * \param N The upper bound of the range, exclusive.
+ * In other words, this is one plus the maximum value to return.
+ * \p N must be strictly larger than \p min.
+ * \param f_rng The RNG function to use. This must not be \c NULL.
+ * \param p_rng The RNG parameter to be passed to \p f_rng.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p min or \p N is invalid
+ * or if they are incompatible.
+ * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the implementation was
+ * unable to find a suitable value within a limited number
+ * of attempts. This has a negligible probability if \p N
+ * is significantly larger than \p min, which is the case
+ * for all usual cryptographic applications.
+ * \return Another negative error code on failure.
*/
-int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B );
+int mbedtls_mpi_random( mbedtls_mpi *X,
+ mbedtls_mpi_sint min,
+ const mbedtls_mpi *N,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
/**
- * \brief Modular inverse: X = A^-1 mod N
+ * \brief Compute the greatest common divisor: G = gcd(A, B)
*
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param N Right-hand MPI
+ * \param G The destination MPI. This must point to an initialized MPI.
+ * \param A The first operand. This must point to an initialized MPI.
+ * \param B The second operand. This must point to an initialized MPI.
*
- * \return 0 if successful,
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- * MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is <= 1,
- MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N.
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return Another negative error code on different kinds of failure.
*/
-int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N );
+int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A,
+ const mbedtls_mpi *B );
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-#if defined(MBEDTLS_DEPRECATED_WARNING)
-#define MBEDTLS_DEPRECATED __attribute__((deprecated))
-#else
-#define MBEDTLS_DEPRECATED
-#endif
/**
- * \brief Miller-Rabin primality test with error probability of
- * 2<sup>-80</sup>
+ * \brief Compute the modular inverse: X = A^-1 mod N
*
- * \deprecated Superseded by mbedtls_mpi_is_prime_ext() which allows
- * specifying the number of Miller-Rabin rounds.
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param A The MPI to calculate the modular inverse of. This must point
+ * to an initialized MPI.
+ * \param N The base of the modular inversion. This must point to an
+ * initialized MPI.
*
- * \param X MPI to check
- * \param f_rng RNG function
- * \param p_rng RNG parameter
- *
- * \return 0 if successful (probably prime),
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if X is not prime
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p N is less than
+ * or equal to one.
+ * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p has no modular inverse
+ * with respect to \p N.
*/
-MBEDTLS_DEPRECATED int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng );
-#undef MBEDTLS_DEPRECATED
-#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
+ const mbedtls_mpi *N );
/**
* \brief Miller-Rabin primality test.
@@ -764,16 +951,20 @@
* case when mbedtls_mpi_gen_prime calls this function), then
* \p rounds can be much lower.
*
- * \param X MPI to check
- * \param rounds Number of bases to perform Miller-Rabin primality test for.
- * The probability of returning 0 on a composite is at most
- * 2<sup>-2*\p rounds</sup>.
- * \param f_rng RNG function
- * \param p_rng RNG parameter
+ * \param X The MPI to check for primality.
+ * This must point to an initialized MPI.
+ * \param rounds The number of bases to perform the Miller-Rabin primality
+ * test for. The probability of returning 0 on a composite is
+ * at most 2<sup>-2*\p rounds</sup>.
+ * \param f_rng The RNG function to use. This must not be \c NULL.
+ * \param p_rng The RNG parameter to be passed to \p f_rng.
+ * This may be \c NULL if \p f_rng doesn't use
+ * a context parameter.
*
- * \return 0 if successful (probably prime),
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if X is not prime
+ * \return \c 0 if successful, i.e. \p X is probably prime.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime.
+ * \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds,
int (*f_rng)(void *, unsigned char *, size_t),
@@ -790,23 +981,30 @@
} mbedtls_mpi_gen_prime_flag_t;
/**
- * \brief Prime number generation
+ * \brief Generate a prime number.
*
- * \param X Destination MPI
- * \param nbits Required size of X in bits
- * ( 3 <= nbits <= MBEDTLS_MPI_MAX_BITS )
- * \param flags Mask of flags of type #mbedtls_mpi_gen_prime_flag_t
- * \param f_rng RNG function
- * \param p_rng RNG parameter
+ * \param X The destination MPI to store the generated prime in.
+ * This must point to an initialized MPi.
+ * \param nbits The required size of the destination MPI in bits.
+ * This must be between \c 3 and #MBEDTLS_MPI_MAX_BITS.
+ * \param flags A mask of flags of type #mbedtls_mpi_gen_prime_flag_t.
+ * \param f_rng The RNG function to use. This must not be \c NULL.
+ * \param p_rng The RNG parameter to be passed to \p f_rng.
+ * This may be \c NULL if \p f_rng doesn't use
+ * a context parameter.
*
- * \return 0 if successful (probably prime),
- * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- * MBEDTLS_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
+ * \return \c 0 if successful, in which case \p X holds a
+ * probably prime number.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if `nbits` is not between
+ * \c 3 and #MBEDTLS_MPI_MAX_BITS.
*/
int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
+#if defined(MBEDTLS_SELF_TEST)
+
/**
* \brief Checkup routine
*
@@ -814,6 +1012,8 @@
*/
int mbedtls_mpi_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST */
+
#ifdef __cplusplus
}
#endif
diff --git a/ext/mbedtls-asn1/include/mbedtls/build_info.h b/ext/mbedtls-asn1/include/mbedtls/build_info.h
new file mode 100644
index 0000000..23f85ba
--- /dev/null
+++ b/ext/mbedtls-asn1/include/mbedtls/build_info.h
@@ -0,0 +1,83 @@
+/**
+ * \file build_info.h
+ *
+ * \brief Build-time configuration info
+ *
+ * Include this file if you need to depend on the
+ * configuration options defined in mbedtls_config.h or MBEDTLS_CONFIG_FILE
+ */
+ /*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ */
+
+#ifndef MBEDTLS_BUILD_INFO_H
+#define MBEDTLS_BUILD_INFO_H
+
+/*
+ * This set of compile-time defines can be used to determine the version number
+ * of the Mbed TLS library used. Run-time variables for the same can be found in
+ * version.h
+ */
+
+/**
+ * The version number x.y.z is split into three parts.
+ * Major, Minor, Patchlevel
+ */
+#define MBEDTLS_VERSION_MAJOR 3
+#define MBEDTLS_VERSION_MINOR 0
+#define MBEDTLS_VERSION_PATCH 0
+
+/**
+ * The single version number has the following structure:
+ * MMNNPP00
+ * Major version | Minor version | Patch version
+ */
+#define MBEDTLS_VERSION_NUMBER 0x03000000
+#define MBEDTLS_VERSION_STRING "3.0.0"
+#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 3.0.0"
+
+#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/mbedtls_config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CONFIG_VERSION) && ( \
+ MBEDTLS_CONFIG_VERSION < 0x03000000 || \
+ MBEDTLS_CONFIG_VERSION > MBEDTLS_VERSION_NUMBER )
+#error "Invalid config version, defined value of MBEDTLS_CONFIG_VERSION is unsupported"
+#endif
+
+/* Target and application specific configurations
+ *
+ * Allow user to override any previous default.
+ *
+ */
+#if defined(MBEDTLS_USER_CONFIG_FILE)
+#include MBEDTLS_USER_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+#include "mbedtls/config_psa.h"
+#endif
+
+#include "mbedtls/check_config.h"
+
+#endif /* MBEDTLS_BUILD_INFO_H */
diff --git a/ext/mbedtls-asn1/include/mbedtls/check_config.h b/ext/mbedtls-asn1/include/mbedtls/check_config.h
index 425e3ea..e38892d 100644
--- a/ext/mbedtls-asn1/include/mbedtls/check_config.h
+++ b/ext/mbedtls-asn1/include/mbedtls/check_config.h
@@ -4,7 +4,7 @@
* \brief Consistency checks for configuration options
*/
/*
- * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,13 +18,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
-
-/*
- * It is recommended to include this file from your config.h
- * in order to catch dependency issues early.
*/
#ifndef MBEDTLS_CHECK_CONFIG_H
@@ -44,17 +37,21 @@
#error "MBEDTLS_PLATFORM_C is required on Windows"
#endif
-/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as
- * it would confuse config.pl. */
+/* Fix the config here. Not convenient to put an #ifdef _WIN32 in mbedtls_config.h as
+ * it would confuse config.py. */
#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
!defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_SNPRINTF_ALT
#endif
+
+#if !defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) && \
+ !defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
+#define MBEDTLS_PLATFORM_VSNPRINTF_ALT
+#endif
#endif /* _WIN32 */
-#if defined(TARGET_LIKE_MBED) && \
- ( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) )
-#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS"
+#if defined(TARGET_LIKE_MBED) && defined(MBEDTLS_NET_C)
+#error "The NET module is not available for mbed OS - please use the network functions provided by Mbed OS"
#endif
#if defined(MBEDTLS_DEPRECATED_WARNING) && \
@@ -78,10 +75,6 @@
#error "MBEDTLS_DHM_C defined, but not all prerequisites"
#endif
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) && !defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-#error "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT defined, but not all prerequisites"
-#endif
-
#if defined(MBEDTLS_CMAC_C) && \
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C)
#error "MBEDTLS_CMAC_C defined, but not all prerequisites"
@@ -98,6 +91,17 @@
#if defined(MBEDTLS_ECDSA_C) && \
( !defined(MBEDTLS_ECP_C) || \
+ !( defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) ) || \
!defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_ASN1_WRITE_C) )
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
@@ -109,20 +113,22 @@
#endif
#if defined(MBEDTLS_ECP_RESTARTABLE) && \
- ( defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \
+ ( defined(MBEDTLS_USE_PSA_CRYPTO) || \
+ defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \
defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) || \
defined(MBEDTLS_ECDSA_SIGN_ALT) || \
defined(MBEDTLS_ECDSA_VERIFY_ALT) || \
defined(MBEDTLS_ECDSA_GENKEY_ALT) || \
+ defined(MBEDTLS_ECP_INTERNAL_ALT) || \
defined(MBEDTLS_ECP_ALT) )
-#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation"
+#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative or PSA-based ECP implementation"
#endif
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
#endif
-#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \
+#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \
!defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \
@@ -133,10 +139,16 @@
!defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \
- !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) )
+ !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && \
+ !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && \
+ !defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) ) )
#error "MBEDTLS_ECP_C defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C)
+#error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites"
+#endif
+
#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \
!defined(MBEDTLS_SHA256_C))
#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
@@ -155,18 +167,18 @@
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
#endif
-#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
- ( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) )
-#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites"
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
+#define MBEDTLS_HAS_MEMSAN
#endif
-#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
- ( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \
- defined(MBEDTLS_HAVEGE_C) )
-#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too"
#endif
+#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) && !defined(MBEDTLS_HAS_MEMSAN)
+#error "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN requires building with MemorySanitizer"
+#endif
+#undef MBEDTLS_HAS_MEMSAN
#if defined(MBEDTLS_GCM_C) && ( \
- !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) )
+ !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) )
#error "MBEDTLS_GCM_C defined, but not all prerequisites"
#endif
@@ -202,8 +214,8 @@
#error "MBEDTLS_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites"
#endif
-#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C)
-#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites"
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
+#error "MBEDTLS_ECP_NO_FALLBACK defined, but no alternative implementation enabled"
#endif
#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C)
@@ -215,12 +227,14 @@
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
- ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
+ ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \
+ !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
- ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
+ ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \
+ !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
#endif
@@ -269,11 +283,27 @@
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \
+ !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) && \
+ ( !defined(MBEDTLS_SHA256_C) && \
+ !defined(MBEDTLS_SHA512_C) && \
+ !defined(MBEDTLS_SHA1_C) )
+#error "!MBEDTLS_SSL_KEEP_PEER_CERTIFICATE requires MBEDTLS_SHA512_C, MBEDTLS_SHA256_C or MBEDTLS_SHA1_C"
+#endif
+
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_MEMORY_BACKTRACE) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
+#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequesites"
+#endif
+
+#if defined(MBEDTLS_MEMORY_DEBUG) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
+#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequesites"
+#endif
+
#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
#endif
@@ -299,10 +329,6 @@
#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites"
#endif
-#if defined(MBEDTLS_PKCS11_C) && !defined(MBEDTLS_PK_C)
-#error "MBEDTLS_PKCS11_C defined, but not all prerequisites"
-#endif
-
#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites"
#endif
@@ -496,6 +522,54 @@
#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously"
#endif
+#if defined(MBEDTLS_PSA_CRYPTO_C) && \
+ !( ( ( defined(MBEDTLS_CTR_DRBG_C) || defined(MBEDTLS_HMAC_DRBG_C) ) && \
+ defined(MBEDTLS_ENTROPY_C) ) || \
+ defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) )
+#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites (missing RNG)"
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_SPM) && !defined(MBEDTLS_PSA_CRYPTO_C)
+#error "MBEDTLS_PSA_CRYPTO_SPM defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C) && \
+ ! ( defined(MBEDTLS_PSA_CRYPTO_C) && \
+ defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) )
+#error "MBEDTLS_PSA_CRYPTO_SE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \
+ ! defined(MBEDTLS_PSA_CRYPTO_C)
+#error "MBEDTLS_PSA_CRYPTO_STORAGE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
+ !( defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \
+ defined(MBEDTLS_ENTROPY_NV_SEED) )
+#error "MBEDTLS_PSA_INJECT_ENTROPY defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
+ !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
+#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with actual entropy sources"
+#endif
+
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
+ defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG"
+#endif
+
+#if defined(MBEDTLS_PSA_ITS_FILE_C) && \
+ !defined(MBEDTLS_FS_IO)
+#error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) && \
+ defined(MBEDTLS_USE_PSA_CRYPTO)
+#error "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined, but it cannot coexist with MBEDTLS_USE_PSA_CRYPTO."
+#endif
+
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) )
#error "MBEDTLS_RSA_C defined, but not all prerequisites"
@@ -511,19 +585,16 @@
#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"
#endif
-#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \
- !defined(MBEDTLS_SHA1_C) )
-#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites"
+#if defined(MBEDTLS_SHA384_C) && !defined(MBEDTLS_SHA512_C)
+#error "MBEDTLS_SHA384_C defined without MBEDTLS_SHA512_C"
#endif
-#if defined(MBEDTLS_SSL_PROTO_TLS1) && ( !defined(MBEDTLS_MD5_C) || \
- !defined(MBEDTLS_SHA1_C) )
-#error "MBEDTLS_SSL_PROTO_TLS1 defined, but not all prerequisites"
+#if defined(MBEDTLS_SHA224_C) && !defined(MBEDTLS_SHA256_C)
+#error "MBEDTLS_SHA224_C defined without MBEDTLS_SHA256_C"
#endif
-#if defined(MBEDTLS_SSL_PROTO_TLS1_1) && ( !defined(MBEDTLS_MD5_C) || \
- !defined(MBEDTLS_SHA1_C) )
-#error "MBEDTLS_SSL_PROTO_TLS1_1 defined, but not all prerequisites"
+#if defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA224_C)
+#error "MBEDTLS_SHA256_C defined without MBEDTLS_SHA224_C"
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && ( !defined(MBEDTLS_SHA1_C) && \
@@ -531,8 +602,28 @@
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && ( !defined(MBEDTLS_HKDF_C) && \
+ !defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) )
+#error "MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+ !(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) )
+#error "One or more versions of the TLS protocol are enabled " \
+ "but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx"
+#endif
+
#if defined(MBEDTLS_SSL_PROTO_DTLS) && \
- !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites"
#endif
@@ -550,28 +641,10 @@
#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites"
#endif
-#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \
- !defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
- !defined(MBEDTLS_SSL_PROTO_TLS1_2))
+#if defined(MBEDTLS_SSL_TLS_C) && !defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active"
#endif
-#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
- defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1))
-#error "Illegal protocol selection"
-#endif
-
-#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_TLS1) && \
- defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_SSL_PROTO_TLS1_1))
-#error "Illegal protocol selection"
-#endif
-
-#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
- defined(MBEDTLS_SSL_PROTO_TLS1_2) && (!defined(MBEDTLS_SSL_PROTO_TLS1) || \
- !defined(MBEDTLS_SSL_PROTO_TLS1_1)))
-#error "Illegal protocol selection"
-#endif
-
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS)
#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites"
#endif
@@ -586,21 +659,29 @@
#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites"
#endif
-#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
-#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites"
+#error "MBEDTLS_SSL_DTLS_CONNECTION_ID defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
+ defined(MBEDTLS_SSL_CID_IN_LEN_MAX) && \
+ MBEDTLS_SSL_CID_IN_LEN_MAX > 255
+#error "MBEDTLS_SSL_CID_IN_LEN_MAX too large (max 255)"
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
+ defined(MBEDTLS_SSL_CID_OUT_LEN_MAX) && \
+ MBEDTLS_SSL_CID_OUT_LEN_MAX > 255
+#error "MBEDTLS_SSL_CID_OUT_LEN_MAX too large (max 255)"
#endif
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
- !defined(MBEDTLS_SSL_PROTO_TLS1) && \
- !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites"
#endif
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
- !defined(MBEDTLS_SSL_PROTO_TLS1) && \
- !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites"
#endif
@@ -609,11 +690,6 @@
#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"
#endif
-#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \
- !defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1)
-#error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites"
-#endif
-
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \
!defined(MBEDTLS_X509_CRT_PARSE_C)
#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites"
@@ -638,6 +714,10 @@
#endif
#undef MBEDTLS_THREADING_IMPL
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_PSA_CRYPTO_C)
+#error "MBEDTLS_USE_PSA_CRYPTO defined, but not all prerequisites"
+#endif
+
#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C)
#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
#endif
@@ -683,10 +763,75 @@
#error "MBEDTLS_HAVE_INT32/MBEDTLS_HAVE_INT64 and MBEDTLS_HAVE_ASM cannot be defined simultaneously"
#endif /* (MBEDTLS_HAVE_INT32 || MBEDTLS_HAVE_INT64) && MBEDTLS_HAVE_ASM */
+#if defined(MBEDTLS_SSL_DTLS_SRTP) && ( !defined(MBEDTLS_SSL_PROTO_DTLS) )
+#error "MBEDTLS_SSL_DTLS_SRTP defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) && ( !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) )
+#error "MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH defined, but not all prerequisites"
+#endif
+
+
+
+/* Reject attempts to enable options that have been removed and that could
+ * cause a build to succeed but with features removed. */
+
+#if defined(MBEDTLS_HAVEGE_C) //no-check-names
+#error "MBEDTLS_HAVEGE_C was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/2599"
+#endif
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) //no-check-names
+#error "MBEDTLS_SSL_HW_RECORD_ACCEL was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/4031"
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) //no-check-names
+#error "MBEDTLS_SSL_PROTO_SSL3 (SSL v3.0 support) was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/4031"
+#endif
+
+#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) //no-check-names
+#error "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO (SSL v2 ClientHello support) was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/4031"
+#endif
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) //no-check-names
+#error "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT (compatibility with the buggy implementation of truncated HMAC in Mbed TLS up to 2.7) was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/4031"
+#endif
+
+#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES) //no-check-names
+#error "MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES was removed in Mbed TLS 3.0. See the ChangeLog entry if you really need SHA-1-signed certificates."
+#endif
+
+#if defined(MBEDTLS_ZLIB_SUPPORT) //no-check-names
+#error "MBEDTLS_ZLIB_SUPPORT was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/4031"
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1) //no-check-names
+#error "MBEDTLS_SSL_PROTO_TLS1 (TLS v1.0 support) was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/4286"
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) //no-check-names
+#error "MBEDTLS_SSL_PROTO_TLS1_1 (TLS v1.1 support) was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/4286"
+#endif
+
+#if defined(MBEDTLS_CHECK_PARAMS) //no-check-names
+#error "MBEDTLS_CHECK_PARAMS was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/4313"
+#endif
+
+#if defined(MBEDTLS_SSL_CID_PADDING_GRANULARITY) //no-check-names
+#error "MBEDTLS_SSL_CID_PADDING_GRANULARITY was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/4335"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY) //no-check-names
+#error "MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/4335"
+#endif
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) //no-check-names
+#error "MBEDTLS_SSL_TRUNCATED_HMAC was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/4341"
+#endif
+
/*
* Avoid warning from -pedantic. This is a convenient place for this
* workaround since this is included by every single file before the
- * #if defined(MBEDTLS_xxx_C) that results in emtpy translation units.
+ * #if defined(MBEDTLS_xxx_C) that results in empty translation units.
*/
typedef int mbedtls_iso_c_forbids_empty_translation_units;
diff --git a/ext/mbedtls-asn1/include/mbedtls/ecdsa.h b/ext/mbedtls-asn1/include/mbedtls/ecdsa.h
index 4057828..71b73ee 100644
--- a/ext/mbedtls-asn1/include/mbedtls/ecdsa.h
+++ b/ext/mbedtls-asn1/include/mbedtls/ecdsa.h
@@ -11,7 +11,7 @@
*
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -25,35 +25,41 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ECDSA_H
#define MBEDTLS_ECDSA_H
+#include "mbedtls/private_access.h"
-#include "ecp.h"
-#include "md.h"
+#include "mbedtls/build_info.h"
-/*
- * RFC-4492 page 20:
+#include "mbedtls/ecp.h"
+#include "mbedtls/md.h"
+
+/**
+ * \brief Maximum ECDSA signature size for a given curve bit size
*
+ * \param bits Curve size in bits
+ * \return Maximum signature size in bytes
+ *
+ * \note This macro returns a compile-time constant if its argument
+ * is one. It may evaluate its argument multiple times.
+ */
+/*
* Ecdsa-Sig-Value ::= SEQUENCE {
* r INTEGER,
* s INTEGER
* }
*
- * Size is at most
- * 1 (tag) + 1 (len) + 1 (initial 0) + ECP_MAX_BYTES for each of r and s,
- * twice that + 1 (tag) + 2 (len) for the sequence
- * (assuming ECP_MAX_BYTES is less than 126 for r and s,
- * and less than 124 (total len <= 255) for the sequence)
+ * For each of r and s, the value (V) may include an extra initial "0" bit.
*/
-#if MBEDTLS_ECP_MAX_BYTES > 124
-#error "MBEDTLS_ECP_MAX_BYTES bigger than expected, please fix MBEDTLS_ECDSA_MAX_LEN"
-#endif
+#define MBEDTLS_ECDSA_MAX_SIG_LEN( bits ) \
+ ( /*T,L of SEQUENCE*/ ( ( bits ) >= 61 * 8 ? 3 : 2 ) + \
+ /*T,L of r,s*/ 2 * ( ( ( bits ) >= 127 * 8 ? 3 : 2 ) + \
+ /*V of r,s*/ ( ( bits ) + 8 ) / 8 ) )
+
/** The maximal size of an ECDSA signature in Bytes. */
-#define MBEDTLS_ECDSA_MAX_LEN ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) )
+#define MBEDTLS_ECDSA_MAX_LEN MBEDTLS_ECDSA_MAX_SIG_LEN( MBEDTLS_ECP_MAX_BITS )
#ifdef __cplusplus
extern "C" {
@@ -98,12 +104,12 @@
*/
typedef struct
{
- mbedtls_ecp_restart_ctx ecp; /*!< base context for ECP restart and
+ mbedtls_ecp_restart_ctx MBEDTLS_PRIVATE(ecp); /*!< base context for ECP restart and
shared administrative info */
- mbedtls_ecdsa_restart_ver_ctx *ver; /*!< ecdsa_verify() sub-context */
- mbedtls_ecdsa_restart_sig_ctx *sig; /*!< ecdsa_sign() sub-context */
+ mbedtls_ecdsa_restart_ver_ctx *MBEDTLS_PRIVATE(ver); /*!< ecdsa_verify() sub-context */
+ mbedtls_ecdsa_restart_sig_ctx *MBEDTLS_PRIVATE(sig); /*!< ecdsa_sign() sub-context */
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
- mbedtls_ecdsa_restart_det_ctx *det; /*!< ecdsa_sign_det() sub-context */
+ mbedtls_ecdsa_restart_det_ctx *MBEDTLS_PRIVATE(det); /*!< ecdsa_sign_det() sub-context */
#endif
} mbedtls_ecdsa_restart_ctx;
@@ -115,10 +121,21 @@
#endif /* MBEDTLS_ECP_RESTARTABLE */
/**
+ * \brief This function checks whether a given group can be used
+ * for ECDSA.
+ *
+ * \param gid The ECP group ID to check.
+ *
+ * \return \c 1 if the group can be used, \c 0 otherwise
+ */
+int mbedtls_ecdsa_can_do( mbedtls_ecp_group_id gid );
+
+/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message.
*
- * \note The deterministic version is usually preferred.
+ * \note The deterministic version implemented in
+ * mbedtls_ecdsa_sign_det_ext() is usually preferred.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated
@@ -128,14 +145,22 @@
*
* \see ecp.h
*
- * \param grp The ECP group.
- * \param r The first output integer.
- * \param s The second output integer.
- * \param d The private signing key.
- * \param buf The message hash.
- * \param blen The length of \p buf.
- * \param f_rng The RNG function.
- * \param p_rng The RNG context.
+ * \param grp The context for the elliptic curve to use.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param r The MPI context in which to store the first part
+ * the signature. This must be initialized.
+ * \param s The MPI context in which to store the second part
+ * the signature. This must be initialized.
+ * \param d The private signing key. This must be initialized.
+ * \param buf The content to be signed. This is usually the hash of
+ * the original data to be signed. This must be a readable
+ * buffer of length \p blen Bytes. It may be \c NULL if
+ * \p blen is zero.
+ * \param blen The length of \p buf in Bytes.
+ * \param f_rng The RNG function. This must not be \c NULL.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be
+ * \c NULL if \p f_rng doesn't need a context parameter.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX
@@ -162,21 +187,35 @@
*
* \see ecp.h
*
- * \param grp The ECP group.
- * \param r The first output integer.
- * \param s The second output integer.
- * \param d The private signing key.
- * \param buf The message hash.
- * \param blen The length of \p buf.
- * \param md_alg The MD algorithm used to hash the message.
+ * \param grp The context for the elliptic curve to use.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param r The MPI context in which to store the first part
+ * the signature. This must be initialized.
+ * \param s The MPI context in which to store the second part
+ * the signature. This must be initialized.
+ * \param d The private signing key. This must be initialized
+ * and setup, for example through mbedtls_ecp_gen_privkey().
+ * \param buf The hashed content to be signed. This must be a readable
+ * buffer of length \p blen Bytes. It may be \c NULL if
+ * \p blen is zero.
+ * \param blen The length of \p buf in Bytes.
+ * \param md_alg The hash algorithm used to hash the original data.
+ * \param f_rng_blind The RNG function used for blinding. This must not be
+ * \c NULL.
+ * \param p_rng_blind The RNG context to be passed to \p f_rng. This may be
+ * \c NULL if \p f_rng doesn't need a context parameter.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure.
*/
-int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
- const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
- mbedtls_md_type_t md_alg );
+int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r,
+ mbedtls_mpi *s, const mbedtls_mpi *d,
+ const unsigned char *buf, size_t blen,
+ mbedtls_md_type_t md_alg,
+ int (*f_rng_blind)(void *, unsigned char *, size_t),
+ void *p_rng_blind );
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/**
@@ -191,12 +230,19 @@
*
* \see ecp.h
*
- * \param grp The ECP group.
- * \param buf The message hash.
- * \param blen The length of \p buf.
- * \param Q The public key to use for verification.
+ * \param grp The ECP group to use.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param buf The hashed content that was signed. This must be a readable
+ * buffer of length \p blen Bytes. It may be \c NULL if
+ * \p blen is zero.
+ * \param blen The length of \p buf in Bytes.
+ * \param Q The public key to use for verification. This must be
+ * initialized and setup.
* \param r The first integer of the signature.
+ * This must be initialized.
* \param s The second integer of the signature.
+ * This must be initialized.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature
@@ -205,8 +251,9 @@
* error code on failure for any other reason.
*/
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
- const unsigned char *buf, size_t blen,
- const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s);
+ const unsigned char *buf, size_t blen,
+ const mbedtls_ecp_point *Q, const mbedtls_mpi *r,
+ const mbedtls_mpi *s);
/**
* \brief This function computes the ECDSA signature and writes it
@@ -223,11 +270,6 @@
* of the Digital Signature Algorithm (DSA) and Elliptic
* Curve Digital Signature Algorithm (ECDSA)</em>.
*
- * \note The \p sig buffer must be at least twice as large as the
- * size of the curve used, plus 9. For example, 73 Bytes if
- * a 256-bit curve is used. A buffer length of
- * #MBEDTLS_ECDSA_MAX_LEN is always safe.
- *
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group
@@ -236,22 +278,36 @@
*
* \see ecp.h
*
- * \param ctx The ECDSA context.
+ * \param ctx The ECDSA context to use. This must be initialized
+ * and have a group and private key bound to it, for example
+ * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param md_alg The message digest that was used to hash the message.
- * \param hash The message hash.
- * \param hlen The length of the hash.
- * \param sig The buffer that holds the signature.
- * \param slen The length of the signature written.
- * \param f_rng The RNG function.
- * \param p_rng The RNG context.
+ * \param hash The message hash to be signed. This must be a readable
+ * buffer of length \p blen Bytes.
+ * \param hlen The length of the hash \p hash in Bytes.
+ * \param sig The buffer to which to write the signature. This must be a
+ * writable buffer of length at least twice as large as the
+ * size of the curve used, plus 9. For example, 73 Bytes if
+ * a 256-bit curve is used. A buffer length of
+ * #MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \param sig_size The size of the \p sig buffer in bytes.
+ * \param slen The address at which to store the actual length of
+ * the signature written. Must not be \c NULL.
+ * \param f_rng The RNG function. This must not be \c NULL if
+ * #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
+ * it is used only for blinding and may be set to \c NULL, but
+ * doing so is DEPRECATED.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be
+ * \c NULL if \p f_rng is \c NULL or doesn't use a context.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
* \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
-int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg,
+int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
+ mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hlen,
- unsigned char *sig, size_t *slen,
+ unsigned char *sig, size_t sig_size, size_t *slen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
@@ -265,15 +321,29 @@
* but it can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
- * \param ctx The ECDSA context.
+ * \param ctx The ECDSA context to use. This must be initialized
+ * and have a group and private key bound to it, for example
+ * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param md_alg The message digest that was used to hash the message.
- * \param hash The message hash.
- * \param hlen The length of the hash.
- * \param sig The buffer that holds the signature.
- * \param slen The length of the signature written.
- * \param f_rng The RNG function.
- * \param p_rng The RNG context.
- * \param rs_ctx The restart context (NULL disables restart).
+ * \param hash The message hash to be signed. This must be a readable
+ * buffer of length \p blen Bytes.
+ * \param hlen The length of the hash \p hash in Bytes.
+ * \param sig The buffer to which to write the signature. This must be a
+ * writable buffer of length at least twice as large as the
+ * size of the curve used, plus 9. For example, 73 Bytes if
+ * a 256-bit curve is used. A buffer length of
+ * #MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \param sig_size The size of the \p sig buffer in bytes.
+ * \param slen The address at which to store the actual length of
+ * the signature written. Must not be \c NULL.
+ * \param f_rng The RNG function. This must not be \c NULL if
+ * #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
+ * it is unused and may be set to \c NULL.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be
+ * \c NULL if \p f_rng is \c NULL or doesn't use a context.
+ * \param rs_ctx The restart context to use. This may be \c NULL to disable
+ * restarting. If it is not \c NULL, it must point to an
+ * initialized restart context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
@@ -284,66 +354,11 @@
int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hlen,
- unsigned char *sig, size_t *slen,
+ unsigned char *sig, size_t sig_size, size_t *slen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
mbedtls_ecdsa_restart_ctx *rs_ctx );
-#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
-#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
-#if defined(MBEDTLS_DEPRECATED_WARNING)
-#define MBEDTLS_DEPRECATED __attribute__((deprecated))
-#else
-#define MBEDTLS_DEPRECATED
-#endif
-/**
- * \brief This function computes an ECDSA signature and writes
- * it to a buffer, serialized as defined in <em>RFC-4492:
- * Elliptic Curve Cryptography (ECC) Cipher Suites for
- * Transport Layer Security (TLS)</em>.
- *
- * The deterministic version is defined in <em>RFC-6979:
- * Deterministic Usage of the Digital Signature Algorithm (DSA)
- * and Elliptic Curve Digital Signature Algorithm (ECDSA)</em>.
- *
- * \warning It is not thread-safe to use the same context in
- * multiple threads.
- *
- * \note The \p sig buffer must be at least twice as large as the
- * size of the curve used, plus 9. For example, 73 Bytes if a
- * 256-bit curve is used. A buffer length of
- * #MBEDTLS_ECDSA_MAX_LEN is always safe.
- *
- * \note If the bitlength of the message hash is larger than the
- * bitlength of the group order, then the hash is truncated as
- * defined in <em>Standards for Efficient Cryptography Group
- * (SECG): SEC1 Elliptic Curve Cryptography</em>, section
- * 4.1.3, step 5.
- *
- * \see ecp.h
- *
- * \deprecated Superseded by mbedtls_ecdsa_write_signature() in
- * Mbed TLS version 2.0 and later.
- *
- * \param ctx The ECDSA context.
- * \param hash The message hash.
- * \param hlen The length of the hash.
- * \param sig The buffer that holds the signature.
- * \param slen The length of the signature written.
- * \param md_alg The MD algorithm used to hash the message.
- *
- * \return \c 0 on success.
- * \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
- * \c MBEDTLS_ERR_ASN1_XXX error code on failure.
- */
-int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
- const unsigned char *hash, size_t hlen,
- unsigned char *sig, size_t *slen,
- mbedtls_md_type_t md_alg ) MBEDTLS_DEPRECATED;
-#undef MBEDTLS_DEPRECATED
-#endif /* MBEDTLS_DEPRECATED_REMOVED */
-#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
-
/**
* \brief This function reads and verifies an ECDSA signature.
*
@@ -355,11 +370,14 @@
*
* \see ecp.h
*
- * \param ctx The ECDSA context.
- * \param hash The message hash.
- * \param hlen The size of the hash.
- * \param sig The signature to read and verify.
- * \param slen The size of \p sig.
+ * \param ctx The ECDSA context to use. This must be initialized
+ * and have a group and public key bound to it.
+ * \param hash The message hash that was signed. This must be a readable
+ * buffer of length \p size Bytes.
+ * \param hlen The size of the hash \p hash.
+ * \param sig The signature to read and verify. This must be a readable
+ * buffer of length \p slen Bytes.
+ * \param slen The size of \p sig in Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
@@ -382,12 +400,17 @@
* but it can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
- * \param ctx The ECDSA context.
- * \param hash The message hash.
- * \param hlen The size of the hash.
- * \param sig The signature to read and verify.
- * \param slen The size of \p sig.
- * \param rs_ctx The restart context (NULL disables restart).
+ * \param ctx The ECDSA context to use. This must be initialized
+ * and have a group and public key bound to it.
+ * \param hash The message hash that was signed. This must be a readable
+ * buffer of length \p size Bytes.
+ * \param hlen The size of the hash \p hash.
+ * \param sig The signature to read and verify. This must be a readable
+ * buffer of length \p slen Bytes.
+ * \param slen The size of \p sig in Bytes.
+ * \param rs_ctx The restart context to use. This may be \c NULL to disable
+ * restarting. If it is not \c NULL, it must point to an
+ * initialized restart context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
@@ -409,10 +432,12 @@
* \see ecp.h
*
* \param ctx The ECDSA context to store the keypair in.
+ * This must be initialized.
* \param gid The elliptic curve to use. One of the various
* \c MBEDTLS_ECP_DP_XXX macros depending on configuration.
- * \param f_rng The RNG function.
- * \param p_rng The RNG context.
+ * \param f_rng The RNG function to use. This must not be \c NULL.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be
+ * \c NULL if \p f_rng doesn't need a context argument.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
@@ -421,40 +446,55 @@
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/**
- * \brief This function sets an ECDSA context from an EC key pair.
+ * \brief This function sets up an ECDSA context from an EC key pair.
*
* \see ecp.h
*
- * \param ctx The ECDSA context to set.
- * \param key The EC key to use.
+ * \param ctx The ECDSA context to setup. This must be initialized.
+ * \param key The EC key to use. This must be initialized and hold
+ * a private-public key pair or a public key. In the former
+ * case, the ECDSA context may be used for signature creation
+ * and verification after this call. In the latter case, it
+ * may be used for signature verification.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
*/
-int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key );
+int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx,
+ const mbedtls_ecp_keypair *key );
/**
* \brief This function initializes an ECDSA context.
*
* \param ctx The ECDSA context to initialize.
+ * This must not be \c NULL.
*/
void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx );
/**
* \brief This function frees an ECDSA context.
*
- * \param ctx The ECDSA context to free.
+ * \param ctx The ECDSA context to free. This may be \c NULL,
+ * in which case this function does nothing. If it
+ * is not \c NULL, it must be initialized.
*/
void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx );
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
- * \brief Initialize a restart context
+ * \brief Initialize a restart context.
+ *
+ * \param ctx The restart context to initialize.
+ * This must not be \c NULL.
*/
void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx );
/**
- * \brief Free the components of a restart context
+ * \brief Free the components of a restart context.
+ *
+ * \param ctx The restart context to free. This may be \c NULL,
+ * in which case this function does nothing. If it
+ * is not \c NULL, it must be initialized.
*/
void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx );
#endif /* MBEDTLS_ECP_RESTARTABLE */
diff --git a/ext/mbedtls-asn1/include/mbedtls/ecp.h b/ext/mbedtls-asn1/include/mbedtls/ecp.h
index 2fb1af4..b87114b 100644
--- a/ext/mbedtls-asn1/include/mbedtls/ecp.h
+++ b/ext/mbedtls-asn1/include/mbedtls/ecp.h
@@ -15,7 +15,7 @@
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -29,14 +29,15 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ECP_H
#define MBEDTLS_ECP_H
+#include "mbedtls/private_access.h"
-#include "bignum.h"
+#include "mbedtls/build_info.h"
+
+#include "mbedtls/bignum.h"
/*
* ECP error codes
@@ -49,12 +50,28 @@
#define MBEDTLS_ERR_ECP_RANDOM_FAILED -0x4D00 /**< Generation of random value, such as ephemeral key, failed. */
#define MBEDTLS_ERR_ECP_INVALID_KEY -0x4C80 /**< Invalid private or public key. */
#define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 /**< The buffer contains a valid signature followed by more data. */
-
-/* MBEDTLS_ERR_ECP_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED -0x4B80 /**< The ECP hardware accelerator failed. */
-
#define MBEDTLS_ERR_ECP_IN_PROGRESS -0x4B00 /**< Operation in progress, call again with the same parameters to continue. */
+/* Flags indicating whether to include code that is specific to certain
+ * types of curves. These flags are for internal library use only. */
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+#define MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+#define MBEDTLS_ECP_MONTGOMERY_ENABLED
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -68,6 +85,22 @@
* parameters. Therefore, only standardized domain parameters from trusted
* sources should be used. See mbedtls_ecp_group_load().
*/
+/* Note: when adding a new curve:
+ * - Add it at the end of this enum, otherwise you'll break the ABI by
+ * changing the numerical value for existing curves.
+ * - Increment MBEDTLS_ECP_DP_MAX below if needed.
+ * - Update the calculation of MBEDTLS_ECP_MAX_BITS below.
+ * - Add the corresponding MBEDTLS_ECP_DP_xxx_ENABLED macro definition to
+ * mbedtls_config.h.
+ * - List the curve as a dependency of MBEDTLS_ECP_C and
+ * MBEDTLS_ECDSA_C if supported in check_config.h.
+ * - Add the curve to the appropriate curve type macro
+ * MBEDTLS_ECP_yyy_ENABLED above.
+ * - Add the necessary definitions to ecp_curves.c.
+ * - Add the curve to the ecp_supported_curves array in ecp.c.
+ * - Add the curve to applicable profiles in x509_crt.c.
+ * - Add the curve to applicable presets in ssl_tls.c.
+ */
typedef enum
{
MBEDTLS_ECP_DP_NONE = 0, /*!< Curve not defined. */
@@ -93,15 +126,25 @@
*/
#define MBEDTLS_ECP_DP_MAX 12
+/*
+ * Curve types
+ */
+typedef enum
+{
+ MBEDTLS_ECP_TYPE_NONE = 0,
+ MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */
+ MBEDTLS_ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
+} mbedtls_ecp_curve_type;
+
/**
* Curve information, for use by other modules.
*/
typedef struct mbedtls_ecp_curve_info
{
- mbedtls_ecp_group_id grp_id; /*!< An internal identifier. */
- uint16_t tls_id; /*!< The TLS NamedCurve identifier. */
- uint16_t bit_size; /*!< The curve size in bits. */
- const char *name; /*!< A human-friendly name. */
+ mbedtls_ecp_group_id MBEDTLS_PRIVATE(grp_id); /*!< An internal identifier. */
+ uint16_t MBEDTLS_PRIVATE(tls_id); /*!< The TLS NamedCurve identifier. */
+ uint16_t MBEDTLS_PRIVATE(bit_size); /*!< The curve size in bits. */
+ const char *MBEDTLS_PRIVATE(name); /*!< A human-friendly name. */
} mbedtls_ecp_curve_info;
/**
@@ -117,9 +160,9 @@
*/
typedef struct mbedtls_ecp_point
{
- mbedtls_mpi X; /*!< The X coordinate of the ECP point. */
- mbedtls_mpi Y; /*!< The Y coordinate of the ECP point. */
- mbedtls_mpi Z; /*!< The Z coordinate of the ECP point. */
+ mbedtls_mpi MBEDTLS_PRIVATE(X); /*!< The X coordinate of the ECP point. */
+ mbedtls_mpi MBEDTLS_PRIVATE(Y); /*!< The Y coordinate of the ECP point. */
+ mbedtls_mpi MBEDTLS_PRIVATE(Z); /*!< The Z coordinate of the ECP point. */
}
mbedtls_ecp_point;
@@ -159,6 +202,16 @@
* additions or subtractions. Therefore, it is only an approximative modular
* reduction. It must return 0 on success and non-zero on failure.
*
+ * \note Alternative implementations of the ECP module must obey the
+ * following constraints.
+ * * Group IDs must be distinct: if two group structures have
+ * the same ID, then they must be identical.
+ * * The fields \c id, \c P, \c A, \c B, \c G, \c N,
+ * \c pbits and \c nbits must have the same type and semantics
+ * as in the built-in implementation.
+ * They must be available for reading, but direct modification
+ * of these fields does not need to be supported.
+ * They do not need to be at the same offset in the structure.
*/
typedef struct mbedtls_ecp_group
{
@@ -174,17 +227,114 @@
size_t nbits; /*!< For Short Weierstrass: The number of bits in \p P.
For Montgomery curves: the number of bits in the
private keys. */
- unsigned int h; /*!< \internal 1 if the constants are static. */
- int (*modp)(mbedtls_mpi *); /*!< The function for fast pseudo-reduction
+ /* End of public fields */
+
+ unsigned int MBEDTLS_PRIVATE(h); /*!< \internal 1 if the constants are static. */
+ int (*MBEDTLS_PRIVATE(modp))(mbedtls_mpi *); /*!< The function for fast pseudo-reduction
mod \p P (see above).*/
- int (*t_pre)(mbedtls_ecp_point *, void *); /*!< Unused. */
- int (*t_post)(mbedtls_ecp_point *, void *); /*!< Unused. */
- void *t_data; /*!< Unused. */
- mbedtls_ecp_point *T; /*!< Pre-computed points for ecp_mul_comb(). */
- size_t T_size; /*!< The number of pre-computed points. */
+ int (*MBEDTLS_PRIVATE(t_pre))(mbedtls_ecp_point *, void *); /*!< Unused. */
+ int (*MBEDTLS_PRIVATE(t_post))(mbedtls_ecp_point *, void *); /*!< Unused. */
+ void *MBEDTLS_PRIVATE(t_data); /*!< Unused. */
+ mbedtls_ecp_point *MBEDTLS_PRIVATE(T); /*!< Pre-computed points for ecp_mul_comb(). */
+ size_t MBEDTLS_PRIVATE(T_size); /*!< The number of dynamic allocated pre-computed points. */
}
mbedtls_ecp_group;
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in mbedtls_config.h, or define them using the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDTLS_ECP_WINDOW_SIZE)
+/*
+ * Maximum "window" size used for point multiplication.
+ * Default: a point where higher memory usage yields disminishing performance
+ * returns.
+ * Minimum value: 2. Maximum value: 7.
+ *
+ * Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) )
+ * points used for point multiplication. This value is directly tied to EC
+ * peak memory usage, so decreasing it by one should roughly cut memory usage
+ * by two (if large curves are in use).
+ *
+ * Reduction in size may reduce speed, but larger curves are impacted first.
+ * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1):
+ * w-size: 6 5 4 3 2
+ * 521 145 141 135 120 97
+ * 384 214 209 198 177 146
+ * 256 320 320 303 262 226
+ * 224 475 475 453 398 342
+ * 192 640 640 633 587 476
+ */
+#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< The maximum window size used. */
+#endif /* MBEDTLS_ECP_WINDOW_SIZE */
+
+#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM)
+/*
+ * Trade code size for speed on fixed-point multiplication.
+ *
+ * This speeds up repeated multiplication of the generator (that is, the
+ * multiplication in ECDSA signatures, and half of the multiplications in
+ * ECDSA verification and ECDHE) by a factor roughly 3 to 4.
+ *
+ * For each n-bit Short Weierstrass curve that is enabled, this adds 4n bytes
+ * of code size if n < 384 and 8n otherwise.
+ *
+ * Change this value to 0 to reduce code size.
+ */
+#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up. */
+#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */
+
+/* \} name SECTION: Module settings */
+
+#else /* MBEDTLS_ECP_ALT */
+#include "ecp_alt.h"
+#endif /* MBEDTLS_ECP_ALT */
+
+/**
+ * The maximum size of the groups, that is, of \c N and \c P.
+ */
+#if !defined(MBEDTLS_ECP_C)
+/* Dummy definition to help code that has optional ECP support and
+ * defines an MBEDTLS_ECP_MAX_BYTES-sized array unconditionally. */
+#define MBEDTLS_ECP_MAX_BITS 1
+/* Note: the curves must be listed in DECREASING size! */
+#elif defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS 521
+#elif defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS 512
+#elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS 448
+#elif defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS 384
+#elif defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS 384
+#elif defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS 256
+#elif defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS 256
+#elif defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS 256
+#elif defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS 255
+#elif defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS 225 // n is slightly above 2^224
+#elif defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS 224
+#elif defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS 192
+#elif defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS 192
+#else
+#error "Missing definition of MBEDTLS_ECP_MAX_BITS"
+#endif
+
+#define MBEDTLS_ECP_MAX_BYTES ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 )
+#define MBEDTLS_ECP_MAX_PT_LEN ( 2 * MBEDTLS_ECP_MAX_BYTES + 1 )
+
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
@@ -206,10 +356,10 @@
*/
typedef struct
{
- unsigned ops_done; /*!< current ops count */
- unsigned depth; /*!< call depth (0 = top-level) */
- mbedtls_ecp_restart_mul_ctx *rsm; /*!< ecp_mul_comb() sub-context */
- mbedtls_ecp_restart_muladd_ctx *ma; /*!< ecp_muladd() sub-context */
+ unsigned MBEDTLS_PRIVATE(ops_done); /*!< current ops count */
+ unsigned MBEDTLS_PRIVATE(depth); /*!< call depth (0 = top-level) */
+ mbedtls_ecp_restart_mul_ctx *MBEDTLS_PRIVATE(rsm); /*!< ecp_mul_comb() sub-context */
+ mbedtls_ecp_restart_muladd_ctx *MBEDTLS_PRIVATE(ma); /*!< ecp_muladd() sub-context */
} mbedtls_ecp_restart_ctx;
/*
@@ -250,68 +400,6 @@
#endif /* MBEDTLS_ECP_RESTARTABLE */
/**
- * \name SECTION: Module settings
- *
- * The configuration options you can set for this module are in this section.
- * Either change them in config.h, or define them using the compiler command line.
- * \{
- */
-
-#if !defined(MBEDTLS_ECP_MAX_BITS)
-/**
- * The maximum size of the groups, that is, of \c N and \c P.
- */
-#define MBEDTLS_ECP_MAX_BITS 521 /**< The maximum size of groups, in bits. */
-#endif
-
-#define MBEDTLS_ECP_MAX_BYTES ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 )
-#define MBEDTLS_ECP_MAX_PT_LEN ( 2 * MBEDTLS_ECP_MAX_BYTES + 1 )
-
-#if !defined(MBEDTLS_ECP_WINDOW_SIZE)
-/*
- * Maximum "window" size used for point multiplication.
- * Default: 6.
- * Minimum value: 2. Maximum value: 7.
- *
- * Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) )
- * points used for point multiplication. This value is directly tied to EC
- * peak memory usage, so decreasing it by one should roughly cut memory usage
- * by two (if large curves are in use).
- *
- * Reduction in size may reduce speed, but larger curves are impacted first.
- * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1):
- * w-size: 6 5 4 3 2
- * 521 145 141 135 120 97
- * 384 214 209 198 177 146
- * 256 320 320 303 262 226
- * 224 475 475 453 398 342
- * 192 640 640 633 587 476
- */
-#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< The maximum window size used. */
-#endif /* MBEDTLS_ECP_WINDOW_SIZE */
-
-#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM)
-/*
- * Trade memory for speed on fixed-point multiplication.
- *
- * This speeds up repeated multiplication of the generator (that is, the
- * multiplication in ECDSA signatures, and half of the multiplications in
- * ECDSA verification and ECDHE) by a factor roughly 3 to 4.
- *
- * The cost is increasing EC peak memory usage by a factor roughly 2.
- *
- * Change this value to 0 to reduce peak memory usage.
- */
-#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up. */
-#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */
-
-/* \} name SECTION: Module settings */
-
-#else /* MBEDTLS_ECP_ALT */
-#include "ecp_alt.h"
-#endif /* MBEDTLS_ECP_ALT */
-
-/**
* \brief The ECP key-pair structure.
*
* A generic key-pair that may be used for ECDSA and fixed ECDH, for example.
@@ -321,9 +409,9 @@
*/
typedef struct mbedtls_ecp_keypair
{
- mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
- mbedtls_mpi d; /*!< our secret value */
- mbedtls_ecp_point Q; /*!< our public value */
+ mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /*!< Elliptic curve and base point */
+ mbedtls_mpi MBEDTLS_PRIVATE(d); /*!< our secret value */
+ mbedtls_ecp_point MBEDTLS_PRIVATE(Q); /*!< our public value */
}
mbedtls_ecp_keypair;
@@ -407,10 +495,20 @@
int mbedtls_ecp_restart_is_enabled( void );
#endif /* MBEDTLS_ECP_RESTARTABLE */
+/*
+ * Get the type of a curve
+ */
+mbedtls_ecp_curve_type mbedtls_ecp_get_type( const mbedtls_ecp_group *grp );
+
/**
* \brief This function retrieves the information defined in
- * mbedtls_ecp_curve_info() for all supported curves in order
- * of preference.
+ * mbedtls_ecp_curve_info() for all supported curves.
+ *
+ * \note This function returns information about all curves
+ * supported by the library. Some curves may not be
+ * supported for all algorithms. Call mbedtls_ecdh_can_do()
+ * or mbedtls_ecdsa_can_do() to check if a curve is
+ * supported for ECDH or ECDSA.
*
* \return A statically allocated array. The last entry is 0.
*/
@@ -421,6 +519,12 @@
* identifiers of all supported curves in the order of
* preference.
*
+ * \note This function returns information about all curves
+ * supported by the library. Some curves may not be
+ * supported for all algorithms. Call mbedtls_ecdh_can_do()
+ * or mbedtls_ecdsa_can_do() to check if a curve is
+ * supported for ECDH or ECDSA.
+ *
* \return A statically allocated array,
* terminated with MBEDTLS_ECP_DP_NONE.
*/
@@ -472,7 +576,7 @@
*
* \note After this function is called, domain parameters
* for various ECP groups can be loaded through the
- * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group()
+ * mbedtls_ecp_group_load() or mbedtls_ecp_tls_read_group()
* functions.
*/
void mbedtls_ecp_group_init( mbedtls_ecp_group *grp );
@@ -493,24 +597,37 @@
/**
* \brief This function frees the components of an ECP group.
- * \param grp The group to free.
+ *
+ * \param grp The group to free. This may be \c NULL, in which
+ * case this function returns immediately. If it is not
+ * \c NULL, it must point to an initialized ECP group.
*/
void mbedtls_ecp_group_free( mbedtls_ecp_group *grp );
/**
* \brief This function frees the components of a key pair.
- * \param key The key pair to free.
+ *
+ * \param key The key pair to free. This may be \c NULL, in which
+ * case this function returns immediately. If it is not
+ * \c NULL, it must point to an initialized ECP key pair.
*/
void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key );
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
- * \brief Initialize a restart context
+ * \brief Initialize a restart context.
+ *
+ * \param ctx The restart context to initialize. This must
+ * not be \c NULL.
*/
void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx );
/**
- * \brief Free the components of a restart context
+ * \brief Free the components of a restart context.
+ *
+ * \param ctx The restart context to free. This may be \c NULL, in which
+ * case this function returns immediately. If it is not
+ * \c NULL, it must point to an initialized restart context.
*/
void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx );
#endif /* MBEDTLS_ECP_RESTARTABLE */
@@ -519,11 +636,12 @@
* \brief This function copies the contents of point \p Q into
* point \p P.
*
- * \param P The destination point.
- * \param Q The source point.
+ * \param P The destination point. This must be initialized.
+ * \param Q The source point. This must be initialized.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return Another negative error code for other kinds of failure.
*/
int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q );
@@ -531,31 +649,35 @@
* \brief This function copies the contents of group \p src into
* group \p dst.
*
- * \param dst The destination group.
- * \param src The source group.
+ * \param dst The destination group. This must be initialized.
+ * \param src The source group. This must be initialized.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return Another negative error code on other kinds of failure.
*/
-int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src );
+int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst,
+ const mbedtls_ecp_group *src );
/**
- * \brief This function sets a point to zero.
+ * \brief This function sets a point to the point at infinity.
*
- * \param pt The point to set.
+ * \param pt The point to set. This must be initialized.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return Another negative error code on other kinds of failure.
*/
int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt );
/**
- * \brief This function checks if a point is zero.
+ * \brief This function checks if a point is the point at infinity.
*
- * \param pt The point to test.
+ * \param pt The point to test. This must be initialized.
*
* \return \c 1 if the point is zero.
* \return \c 0 if the point is non-zero.
+ * \return A negative error code on failure.
*/
int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt );
@@ -565,8 +687,8 @@
* \note This assumes that the points are normalized. Otherwise,
* they may compare as "not equal" even if they are.
*
- * \param P The first point to compare.
- * \param Q The second point to compare.
+ * \param P The first point to compare. This must be initialized.
+ * \param Q The second point to compare. This must be initialized.
*
* \return \c 0 if the points are equal.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the points are not equal.
@@ -578,7 +700,7 @@
* \brief This function imports a non-zero point from two ASCII
* strings.
*
- * \param P The destination point.
+ * \param P The destination point. This must be initialized.
* \param radix The numeric base of the input.
* \param x The first affine coordinate, as a null-terminated string.
* \param y The second affine coordinate, as a null-terminated string.
@@ -593,19 +715,31 @@
* \brief This function exports a point into unsigned binary data.
*
* \param grp The group to which the point should belong.
- * \param P The point to export.
- * \param format The point format. Should be an \c MBEDTLS_ECP_PF_XXX macro.
- * \param olen The length of the output.
- * \param buf The output buffer.
- * \param buflen The length of the output buffer.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param P The point to export. This must be initialized.
+ * \param format The point format. This must be either
+ * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
+ * (For groups without these formats, this parameter is
+ * ignored. But it still has to be either of the above
+ * values.)
+ * \param olen The address at which to store the length of
+ * the output in Bytes. This must not be \c NULL.
+ * \param buf The output buffer. This must be a writable buffer
+ * of length \p buflen Bytes.
+ * \param buflen The length of the output buffer \p buf in Bytes.
*
* \return \c 0 on success.
- * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA
- * or #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure.
+ * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer
+ * is too small to hold the point.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
+ * or the export for the given group is not implemented.
+ * \return Another negative error code on other kinds of failure.
*/
-int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P,
- int format, size_t *olen,
- unsigned char *buf, size_t buflen );
+int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
+ const mbedtls_ecp_point *P,
+ int format, size_t *olen,
+ unsigned char *buf, size_t buflen );
/**
* \brief This function imports a point from unsigned binary data.
@@ -615,132 +749,183 @@
* for that.
*
* \param grp The group to which the point should belong.
- * \param P The point to import.
- * \param buf The input buffer.
- * \param ilen The length of the input.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param P The destination context to import the point to.
+ * This must be initialized.
+ * \param buf The input buffer. This must be a readable buffer
+ * of length \p ilen Bytes.
+ * \param ilen The length of the input buffer \p buf in Bytes.
*
* \return \c 0 on success.
- * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
+ * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
- * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
- * is not implemented.
- *
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the import for the
+ * given group is not implemented.
*/
-int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
- const unsigned char *buf, size_t ilen );
+int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
+ mbedtls_ecp_point *P,
+ const unsigned char *buf, size_t ilen );
/**
* \brief This function imports a point from a TLS ECPoint record.
*
- * \note On function return, \p buf is updated to point to immediately
+ * \note On function return, \p *buf is updated to point immediately
* after the ECPoint record.
*
- * \param grp The ECP group used.
+ * \param grp The ECP group to use.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
* \param pt The destination point.
* \param buf The address of the pointer to the start of the input buffer.
* \param len The length of the buffer.
*
* \return \c 0 on success.
- * \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization failure.
+ * \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization
+ * failure.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
*/
-int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
- const unsigned char **buf, size_t len );
+int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp,
+ mbedtls_ecp_point *pt,
+ const unsigned char **buf, size_t len );
/**
- * \brief This function exports a point as a TLS ECPoint record.
+ * \brief This function exports a point as a TLS ECPoint record
+ * defined in RFC 4492, Section 5.4.
*
- * \param grp The ECP group used.
- * \param pt The point format to export to. The point format is an
- * \c MBEDTLS_ECP_PF_XXX constant.
- * \param format The export format.
- * \param olen The length of the data written.
- * \param buf The buffer to write to.
- * \param blen The length of the buffer.
+ * \param grp The ECP group to use.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param pt The point to be exported. This must be initialized.
+ * \param format The point format to use. This must be either
+ * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
+ * \param olen The address at which to store the length in Bytes
+ * of the data written.
+ * \param buf The target buffer. This must be a writable buffer of
+ * length \p blen Bytes.
+ * \param blen The length of the target buffer \p buf in Bytes.
*
* \return \c 0 on success.
- * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA or
- * #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure.
+ * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid.
+ * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the target buffer
+ * is too small to hold the exported point.
+ * \return Another negative error code on other kinds of failure.
*/
-int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt,
- int format, size_t *olen,
- unsigned char *buf, size_t blen );
+int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp,
+ const mbedtls_ecp_point *pt,
+ int format, size_t *olen,
+ unsigned char *buf, size_t blen );
/**
- * \brief This function sets a group using standardized domain parameters.
+ * \brief This function sets up an ECP group context
+ * from a standardized set of domain parameters.
*
* \note The index should be a value of the NamedCurve enum,
* as defined in <em>RFC-4492: Elliptic Curve Cryptography
* (ECC) Cipher Suites for Transport Layer Security (TLS)</em>,
* usually in the form of an \c MBEDTLS_ECP_DP_XXX macro.
*
- * \param grp The destination group.
+ * \param grp The group context to setup. This must be initialized.
* \param id The identifier of the domain parameter set to load.
*
- * \return \c 0 on success,
- * \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization failure.
- * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups.
-
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p id doesn't
+ * correspond to a known group.
+ * \return Another negative error code on other kinds of failure.
*/
int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id );
/**
- * \brief This function sets a group from a TLS ECParameters record.
+ * \brief This function sets up an ECP group context from a TLS
+ * ECParameters record as defined in RFC 4492, Section 5.4.
*
- * \note \p buf is updated to point right after the ECParameters record
- * on exit.
+ * \note The read pointer \p buf is updated to point right after
+ * the ECParameters record on exit.
*
- * \param grp The destination group.
+ * \param grp The group context to setup. This must be initialized.
* \param buf The address of the pointer to the start of the input buffer.
- * \param len The length of the buffer.
+ * \param len The length of the input buffer \c *buf in Bytes.
*
* \return \c 0 on success.
- * \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization failure.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not
+ * recognized.
+ * \return Another negative error code on other kinds of failure.
*/
-int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len );
+int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp,
+ const unsigned char **buf, size_t len );
/**
- * \brief This function writes the TLS ECParameters record for a group.
+ * \brief This function extracts an elliptic curve group ID from a
+ * TLS ECParameters record as defined in RFC 4492, Section 5.4.
*
- * \param grp The ECP group used.
- * \param olen The number of Bytes written.
- * \param buf The buffer to write to.
- * \param blen The length of the buffer.
+ * \note The read pointer \p buf is updated to point right after
+ * the ECParameters record on exit.
+ *
+ * \param grp The address at which to store the group id.
+ * This must not be \c NULL.
+ * \param buf The address of the pointer to the start of the input buffer.
+ * \param len The length of the input buffer \c *buf in Bytes.
*
* \return \c 0 on success.
- * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure.
+ * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not
+ * recognized.
+ * \return Another negative error code on other kinds of failure.
*/
-int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen,
- unsigned char *buf, size_t blen );
+int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp,
+ const unsigned char **buf,
+ size_t len );
+/**
+ * \brief This function exports an elliptic curve as a TLS
+ * ECParameters record as defined in RFC 4492, Section 5.4.
+ *
+ * \param grp The ECP group to be exported.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param olen The address at which to store the number of Bytes written.
+ * This must not be \c NULL.
+ * \param buf The buffer to write to. This must be a writable buffer
+ * of length \p blen Bytes.
+ * \param blen The length of the output buffer \p buf in Bytes.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output
+ * buffer is too small to hold the exported group.
+ * \return Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp,
+ size_t *olen,
+ unsigned char *buf, size_t blen );
/**
- * \brief This function performs multiplication of a point by
- * an integer: \p R = \p m * \p P.
+ * \brief This function performs a scalar multiplication of a point
+ * by an integer: \p R = \p m * \p P.
*
* It is not thread-safe to use same group in multiple threads.
*
* \note To prevent timing attacks, this function
* executes the exact same sequence of base-field
* operations for any valid \p m. It avoids any if-branch or
- * array index depending on the value of \p m.
+ * array index depending on the value of \p m. If also uses
+ * \p f_rng to randomize some intermediate results.
*
- * \note If \p f_rng is not NULL, it is used to randomize
- * intermediate results to prevent potential timing attacks
- * targeting these results. We recommend always providing
- * a non-NULL \p f_rng. The overhead is negligible.
- *
- * \param grp The ECP group.
- * \param R The destination point.
- * \param m The integer by which to multiply.
- * \param P The point to multiply.
- * \param f_rng The RNG function.
- * \param p_rng The RNG context.
+ * \param grp The ECP group to use.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param R The point in which to store the result of the calculation.
+ * This must be initialized.
+ * \param m The integer by which to multiply. This must be initialized.
+ * \param P The point to multiply. This must be initialized.
+ * \param f_rng The RNG function. This must not be \c NULL.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be \c
+ * NULL if \p f_rng doesn't need a context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private
* key, or \p P is not a valid public key.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return Another negative error code on other kinds of failure.
*/
int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
@@ -756,12 +941,16 @@
* it can return early and restart according to the limit set
* with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
- * \param grp The ECP group.
- * \param R The destination point.
- * \param m The integer by which to multiply.
- * \param P The point to multiply.
- * \param f_rng The RNG function.
- * \param p_rng The RNG context.
+ * \param grp The ECP group to use.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param R The point in which to store the result of the calculation.
+ * This must be initialized.
+ * \param m The integer by which to multiply. This must be initialized.
+ * \param P The point to multiply. This must be initialized.
+ * \param f_rng The RNG function. This must not be \c NULL.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be \c
+ * NULL if \p f_rng doesn't need a context.
* \param rs_ctx The restart context (NULL disables restart).
*
* \return \c 0 on success.
@@ -770,12 +959,14 @@
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return Another negative error code on other kinds of failure.
*/
int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx );
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/**
* \brief This function performs multiplication and addition of two
* points by integers: \p R = \p m * \p P + \p n * \p Q
@@ -785,18 +976,31 @@
* \note In contrast to mbedtls_ecp_mul(), this function does not
* guarantee a constant execution flow and timing.
*
- * \param grp The ECP group.
- * \param R The destination point.
+ * \note This function is only defined for short Weierstrass curves.
+ * It may not be included in builds without any short
+ * Weierstrass curve.
+ *
+ * \param grp The ECP group to use.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param R The point in which to store the result of the calculation.
+ * This must be initialized.
* \param m The integer by which to multiply \p P.
- * \param P The point to multiply by \p m.
+ * This must be initialized.
+ * \param P The point to multiply by \p m. This must be initialized.
* \param n The integer by which to multiply \p Q.
+ * This must be initialized.
* \param Q The point to be multiplied by \p n.
+ * This must be initialized.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not
* valid private keys, or \p P or \p Q are not valid public
* keys.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp does not
+ * designate a short Weierstrass curve.
+ * \return Another negative error code on other kinds of failure.
*/
int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
@@ -813,12 +1017,22 @@
* but it can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
- * \param grp The ECP group.
- * \param R The destination point.
+ * \note This function is only defined for short Weierstrass curves.
+ * It may not be included in builds without any short
+ * Weierstrass curve.
+ *
+ * \param grp The ECP group to use.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param R The point in which to store the result of the calculation.
+ * This must be initialized.
* \param m The integer by which to multiply \p P.
- * \param P The point to multiply by \p m.
+ * This must be initialized.
+ * \param P The point to multiply by \p m. This must be initialized.
* \param n The integer by which to multiply \p Q.
+ * This must be initialized.
* \param Q The point to be multiplied by \p n.
+ * This must be initialized.
* \param rs_ctx The restart context (NULL disables restart).
*
* \return \c 0 on success.
@@ -826,14 +1040,18 @@
* valid private keys, or \p P or \p Q are not valid public
* keys.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp does not
+ * designate a short Weierstrass curve.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return Another negative error code on other kinds of failure.
*/
int mbedtls_ecp_muladd_restartable(
mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
const mbedtls_mpi *n, const mbedtls_ecp_point *Q,
mbedtls_ecp_restart_ctx *rs_ctx );
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
/**
* \brief This function checks that a point is a valid public key
@@ -852,38 +1070,51 @@
* structures, such as ::mbedtls_ecdh_context or
* ::mbedtls_ecdsa_context.
*
- * \param grp The curve the point should lie on.
- * \param pt The point to check.
+ * \param grp The ECP group the point should belong to.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param pt The point to check. This must be initialized.
*
* \return \c 0 if the point is a valid public key.
- * \return #MBEDTLS_ERR_ECP_INVALID_KEY on failure.
+ * \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not
+ * a valid public key for the given curve.
+ * \return Another negative error code on other kinds of failure.
*/
-int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt );
+int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp,
+ const mbedtls_ecp_point *pt );
/**
- * \brief This function checks that an \p mbedtls_mpi is a valid private
- * key for this curve.
+ * \brief This function checks that an \p mbedtls_mpi is a
+ * valid private key for this curve.
*
* \note This function uses bare components rather than an
* ::mbedtls_ecp_keypair structure to ease use with other
* structures, such as ::mbedtls_ecdh_context or
* ::mbedtls_ecdsa_context.
*
- * \param grp The group used.
- * \param d The integer to check.
+ * \param grp The ECP group the private key should belong to.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param d The integer to check. This must be initialized.
*
* \return \c 0 if the point is a valid private key.
- * \return #MBEDTLS_ERR_ECP_INVALID_KEY on failure.
+ * \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not a valid
+ * private key for the given curve.
+ * \return Another negative error code on other kinds of failure.
*/
-int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d );
+int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
+ const mbedtls_mpi *d );
/**
* \brief This function generates a private key.
*
- * \param grp The ECP group.
- * \param d The destination MPI (secret part).
- * \param f_rng The RNG function.
- * \param p_rng The RNG parameter.
+ * \param grp The ECP group to generate a private key for.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param d The destination MPI (secret part). This must be initialized.
+ * \param f_rng The RNG function. This must not be \c NULL.
+ * \param p_rng The RNG parameter to be passed to \p f_rng. This may be
+ * \c NULL if \p f_rng doesn't need a context argument.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
@@ -903,22 +1134,29 @@
* structures, such as ::mbedtls_ecdh_context or
* ::mbedtls_ecdsa_context.
*
- * \param grp The ECP group.
- * \param G The chosen base point.
+ * \param grp The ECP group to generate a key pair for.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param G The base point to use. This must be initialized
+ * and belong to \p grp. It replaces the default base
+ * point \c grp->G used by mbedtls_ecp_gen_keypair().
* \param d The destination MPI (secret part).
+ * This must be initialized.
* \param Q The destination point (public part).
- * \param f_rng The RNG function.
- * \param p_rng The RNG context.
+ * This must be initialized.
+ * \param f_rng The RNG function. This must not be \c NULL.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may
+ * be \c NULL if \p f_rng doesn't need a context argument.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
* on failure.
*/
int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
- const mbedtls_ecp_point *G,
- mbedtls_mpi *d, mbedtls_ecp_point *Q,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng );
+ const mbedtls_ecp_point *G,
+ mbedtls_mpi *d, mbedtls_ecp_point *Q,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
/**
* \brief This function generates an ECP keypair.
@@ -928,34 +1166,82 @@
* structures, such as ::mbedtls_ecdh_context or
* ::mbedtls_ecdsa_context.
*
- * \param grp The ECP group.
+ * \param grp The ECP group to generate a key pair for.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
* \param d The destination MPI (secret part).
+ * This must be initialized.
* \param Q The destination point (public part).
- * \param f_rng The RNG function.
- * \param p_rng The RNG context.
+ * This must be initialized.
+ * \param f_rng The RNG function. This must not be \c NULL.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may
+ * be \c NULL if \p f_rng doesn't need a context argument.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
* on failure.
*/
-int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng );
+int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d,
+ mbedtls_ecp_point *Q,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
/**
* \brief This function generates an ECP key.
*
* \param grp_id The ECP group identifier.
- * \param key The destination key.
- * \param f_rng The RNG function.
- * \param p_rng The RNG context.
+ * \param key The destination key. This must be initialized.
+ * \param f_rng The RNG function to use. This must not be \c NULL.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may
+ * be \c NULL if \p f_rng doesn't need a context argument.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
* on failure.
*/
int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+/**
+ * \brief This function reads an elliptic curve private key.
+ *
+ * \param grp_id The ECP group identifier.
+ * \param key The destination key.
+ * \param buf The buffer containing the binary representation of the
+ * key. (Big endian integer for Weierstrass curves, byte
+ * string for Montgomery curves.)
+ * \param buflen The length of the buffer in bytes.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_ECP_INVALID_KEY error if the key is
+ * invalid.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for
+ * the group is not implemented.
+ * \return Another negative error code on different kinds of failure.
+ */
+int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
+ const unsigned char *buf, size_t buflen );
+
+/**
+ * \brief This function exports an elliptic curve private key.
+ *
+ * \param key The private key.
+ * \param buf The output buffer for containing the binary representation
+ * of the key. (Big endian integer for Weierstrass curves, byte
+ * string for Montgomery curves.)
+ * \param buflen The total length of the buffer in bytes.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the \p key
+ representation is larger than the available space in \p buf.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for
+ * the group is not implemented.
+ * \return Another negative error code on different kinds of failure.
+ */
+int mbedtls_ecp_write_key( mbedtls_ecp_keypair *key,
+ unsigned char *buf, size_t buflen );
/**
* \brief This function checks that the keypair objects
@@ -963,16 +1249,23 @@
* same public point, and that the private key in
* \p prv is consistent with the public key.
*
- * \param pub The keypair structure holding the public key.
- * If it contains a private key, that part is ignored.
+ * \param pub The keypair structure holding the public key. This
+ * must be initialized. If it contains a private key, that
+ * part is ignored.
* \param prv The keypair structure holding the full keypair.
+ * This must be initialized.
+ * \param f_rng The RNG function. This must not be \c NULL.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be \c
+ * NULL if \p f_rng doesn't need a context.
*
* \return \c 0 on success, meaning that the keys are valid and match.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the keys are invalid or do not match.
* \return An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX
* error code on calculation failure.
*/
-int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv );
+int mbedtls_ecp_check_pub_priv(
+ const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
#if defined(MBEDTLS_SELF_TEST)
diff --git a/ext/mbedtls-asn1/include/mbedtls/error.h b/ext/mbedtls-asn1/include/mbedtls/error.h
new file mode 100644
index 0000000..9a8690d
--- /dev/null
+++ b/ext/mbedtls-asn1/include/mbedtls/error.h
@@ -0,0 +1,210 @@
+/**
+ * \file error.h
+ *
+ * \brief Error to string translation
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ */
+#ifndef MBEDTLS_ERROR_H
+#define MBEDTLS_ERROR_H
+
+#include "mbedtls/build_info.h"
+
+#include <stddef.h>
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+ !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+/**
+ * Error code layout.
+ *
+ * Currently we try to keep all error codes within the negative space of 16
+ * bits signed integers to support all platforms (-0x0001 - -0x7FFF). In
+ * addition we'd like to give two layers of information on the error if
+ * possible.
+ *
+ * For that purpose the error codes are segmented in the following manner:
+ *
+ * 16 bit error code bit-segmentation
+ *
+ * 1 bit - Unused (sign bit)
+ * 3 bits - High level module ID
+ * 5 bits - Module-dependent error code
+ * 7 bits - Low level module errors
+ *
+ * For historical reasons, low-level error codes are divided in even and odd,
+ * even codes were assigned first, and -1 is reserved for other errors.
+ *
+ * Low-level module errors (0x0002-0x007E, 0x0001-0x007F)
+ *
+ * Module Nr Codes assigned
+ * ERROR 2 0x006E 0x0001
+ * MPI 7 0x0002-0x0010
+ * GCM 3 0x0012-0x0014 0x0013-0x0013
+ * THREADING 3 0x001A-0x001E
+ * AES 5 0x0020-0x0022 0x0021-0x0025
+ * CAMELLIA 3 0x0024-0x0026 0x0027-0x0027
+ * BASE64 2 0x002A-0x002C
+ * OID 1 0x002E-0x002E 0x000B-0x000B
+ * PADLOCK 1 0x0030-0x0030
+ * DES 2 0x0032-0x0032 0x0033-0x0033
+ * CTR_DBRG 4 0x0034-0x003A
+ * ENTROPY 3 0x003C-0x0040 0x003D-0x003F
+ * NET 13 0x0042-0x0052 0x0043-0x0049
+ * ARIA 4 0x0058-0x005E
+ * ASN1 7 0x0060-0x006C
+ * CMAC 1 0x007A-0x007A
+ * PBKDF2 1 0x007C-0x007C
+ * HMAC_DRBG 4 0x0003-0x0009
+ * CCM 3 0x000D-0x0011
+ * MD5 1 0x002F-0x002F
+ * RIPEMD160 1 0x0031-0x0031
+ * SHA1 1 0x0035-0x0035 0x0073-0x0073
+ * SHA256 1 0x0037-0x0037 0x0074-0x0074
+ * SHA512 1 0x0039-0x0039 0x0075-0x0075
+ * CHACHA20 3 0x0051-0x0055
+ * POLY1305 3 0x0057-0x005B
+ * CHACHAPOLY 2 0x0054-0x0056
+ * PLATFORM 2 0x0070-0x0072
+ *
+ * High-level module nr (3 bits - 0x0...-0x7...)
+ * Name ID Nr of Errors
+ * PEM 1 9
+ * PKCS#12 1 4 (Started from top)
+ * X509 2 20
+ * PKCS5 2 4 (Started from top)
+ * DHM 3 11
+ * PK 3 15 (Started from top)
+ * RSA 4 11
+ * ECP 4 10 (Started from top)
+ * MD 5 5
+ * HKDF 5 1 (Started from top)
+ * SSL 5 2 (Started from 0x5F00)
+ * CIPHER 6 8 (Started from 0x6080)
+ * SSL 6 22 (Started from top, plus 0x6000)
+ * SSL 7 20 (Started from 0x7000, gaps at
+ * 0x7380, 0x7900-0x7980, 0x7A80-0x7E80)
+ *
+ * Module dependent error code (5 bits 0x.00.-0x.F8.)
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MBEDTLS_ERR_ERROR_GENERIC_ERROR -0x0001 /**< Generic error */
+#define MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED -0x006E /**< This is a bug in the library */
+
+#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070 /**< Hardware accelerator failed */
+#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 /**< The requested feature is not supported by the platform */
+
+/**
+ * \brief Combines a high-level and low-level error code together.
+ *
+ * Wrapper macro for mbedtls_error_add(). See that function for
+ * more details.
+ */
+#define MBEDTLS_ERROR_ADD( high, low ) \
+ mbedtls_error_add( high, low, __FILE__, __LINE__ )
+
+#if defined(MBEDTLS_TEST_HOOKS)
+/**
+ * \brief Testing hook called before adding/combining two error codes together.
+ * Only used when invasive testing is enabled via MBEDTLS_TEST_HOOKS.
+ */
+extern void (*mbedtls_test_hook_error_add)( int, int, const char *, int );
+#endif
+
+/**
+ * \brief Combines a high-level and low-level error code together.
+ *
+ * This function can be called directly however it is usually
+ * called via the #MBEDTLS_ERROR_ADD macro.
+ *
+ * While a value of zero is not a negative error code, it is still an
+ * error code (that denotes success) and can be combined with both a
+ * negative error code or another value of zero.
+ *
+ * \note When invasive testing is enabled via #MBEDTLS_TEST_HOOKS, also try to
+ * call \link mbedtls_test_hook_error_add \endlink.
+ *
+ * \param high high-level error code. See error.h for more details.
+ * \param low low-level error code. See error.h for more details.
+ * \param file file where this error code addition occurred.
+ * \param line line where this error code addition occurred.
+ */
+static inline int mbedtls_error_add( int high, int low,
+ const char *file, int line )
+{
+#if defined(MBEDTLS_TEST_HOOKS)
+ if( *mbedtls_test_hook_error_add != NULL )
+ ( *mbedtls_test_hook_error_add )( high, low, file, line );
+#endif
+ (void)file;
+ (void)line;
+
+ return( high + low );
+}
+
+/**
+ * \brief Translate a mbed TLS error code into a string representation,
+ * Result is truncated if necessary and always includes a terminating
+ * null byte.
+ *
+ * \param errnum error code
+ * \param buffer buffer to place representation in
+ * \param buflen length of the buffer
+ */
+void mbedtls_strerror( int errnum, char *buffer, size_t buflen );
+
+/**
+ * \brief Translate the high-level part of an Mbed TLS error code into a string
+ * representation.
+ *
+ * This function returns a const pointer to an un-modifiable string. The caller
+ * must not try to modify the string. It is intended to be used mostly for
+ * logging purposes.
+ *
+ * \param error_code error code
+ *
+ * \return The string representation of the error code, or \c NULL if the error
+ * code is unknown.
+ */
+const char * mbedtls_high_level_strerr( int error_code );
+
+/**
+ * \brief Translate the low-level part of an Mbed TLS error code into a string
+ * representation.
+ *
+ * This function returns a const pointer to an un-modifiable string. The caller
+ * must not try to modify the string. It is intended to be used mostly for
+ * logging purposes.
+ *
+ * \param error_code error code
+ *
+ * \return The string representation of the error code, or \c NULL if the error
+ * code is unknown.
+ */
+const char * mbedtls_low_level_strerr( int error_code );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* error.h */
diff --git a/ext/mbedtls-asn1/include/mbedtls/config.h b/ext/mbedtls-asn1/include/mbedtls/mbedtls_config.h
similarity index 100%
rename from ext/mbedtls-asn1/include/mbedtls/config.h
rename to ext/mbedtls-asn1/include/mbedtls/mbedtls_config.h
diff --git a/ext/mbedtls-asn1/include/mbedtls/md.h b/ext/mbedtls-asn1/include/mbedtls/md.h
index 8bcf766..1170bc1 100644
--- a/ext/mbedtls-asn1/include/mbedtls/md.h
+++ b/ext/mbedtls-asn1/include/mbedtls/md.h
@@ -6,7 +6,7 @@
* \author Adriaan de Jong <dejong@fox-it.com>
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -20,29 +20,21 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MD_H
#define MBEDTLS_MD_H
+#include "mbedtls/private_access.h"
#include <stddef.h>
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */
#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */
#define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */
-/* MBEDTLS_ERR_MD_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_MD_HW_ACCEL_FAILED -0x5280 /**< MD hardware accelerator failed. */
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -50,15 +42,13 @@
/**
* \brief Supported message digests.
*
- * \warning MD2, MD4, MD5 and SHA-1 are considered weak message digests and
+ * \warning MD5 and SHA-1 are considered weak message digests and
* their use constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
typedef enum {
MBEDTLS_MD_NONE=0, /**< None. */
- MBEDTLS_MD_MD2, /**< The MD2 message digest. */
- MBEDTLS_MD_MD4, /**< The MD4 message digest. */
MBEDTLS_MD_MD5, /**< The MD5 message digest. */
MBEDTLS_MD_SHA1, /**< The SHA-1 message digest. */
MBEDTLS_MD_SHA224, /**< The SHA-224 message digest. */
@@ -74,9 +64,22 @@
#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 or less */
#endif
+#if defined(MBEDTLS_SHA512_C)
+#define MBEDTLS_MD_MAX_BLOCK_SIZE 128
+#else
+#define MBEDTLS_MD_MAX_BLOCK_SIZE 64
+#endif
+
/**
- * Opaque struct defined in md_internal.h.
+ * Opaque struct.
+ *
+ * Constructed using either #mbedtls_md_info_from_string or
+ * #mbedtls_md_info_from_type.
+ *
+ * Fields can be accessed with #mbedtls_md_get_size,
+ * #mbedtls_md_get_type and #mbedtls_md_get_name.
*/
+/* Defined internally in library/md_wrap.h. */
typedef struct mbedtls_md_info_t mbedtls_md_info_t;
/**
@@ -85,19 +88,21 @@
typedef struct mbedtls_md_context_t
{
/** Information about the associated message digest. */
- const mbedtls_md_info_t *md_info;
+ const mbedtls_md_info_t *MBEDTLS_PRIVATE(md_info);
/** The digest-specific context. */
- void *md_ctx;
+ void *MBEDTLS_PRIVATE(md_ctx);
/** The HMAC part of the context. */
- void *hmac_ctx;
+ void *MBEDTLS_PRIVATE(hmac_ctx);
} mbedtls_md_context_t;
/**
* \brief This function returns the list of digests supported by the
* generic digest module.
*
+ * \note The list starts with the strongest available hashes.
+ *
* \return A statically allocated array of digests. Each element
* in the returned list is an integer belonging to the
* message-digest enumeration #mbedtls_md_type_t.
@@ -152,33 +157,6 @@
*/
void mbedtls_md_free( mbedtls_md_context_t *ctx );
-#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
-#if defined(MBEDTLS_DEPRECATED_WARNING)
-#define MBEDTLS_DEPRECATED __attribute__((deprecated))
-#else
-#define MBEDTLS_DEPRECATED
-#endif
-/**
- * \brief This function selects the message digest algorithm to use,
- * and allocates internal structures.
- *
- * It should be called after mbedtls_md_init() or mbedtls_md_free().
- * Makes it necessary to call mbedtls_md_free() later.
- *
- * \deprecated Superseded by mbedtls_md_setup() in 2.0.0
- *
- * \param ctx The context to set up.
- * \param md_info The information structure of the message-digest algorithm
- * to use.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
- * failure.
- * \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
- */
-int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) MBEDTLS_DEPRECATED;
-#undef MBEDTLS_DEPRECATED
-#endif /* MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief This function selects the message digest algorithm to use,
diff --git a/ext/mbedtls-asn1/include/mbedtls/oid.h b/ext/mbedtls-asn1/include/mbedtls/oid.h
index fcecdaf..9e68e91 100644
--- a/ext/mbedtls-asn1/include/mbedtls/oid.h
+++ b/ext/mbedtls-asn1/include/mbedtls/oid.h
@@ -2,8 +2,9 @@
* \file oid.h
*
* \brief Object Identifier (OID) database
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ */
+/*
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -17,38 +18,51 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_OID_H
#define MBEDTLS_OID_H
+#include "mbedtls/private_access.h"
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
-#include "asn1.h"
-#include "pk.h"
+#include "mbedtls/asn1.h"
+#include "mbedtls/pk.h"
#include <stddef.h>
#if defined(MBEDTLS_CIPHER_C)
-#include "cipher.h"
+#include "mbedtls/cipher.h"
#endif
#if defined(MBEDTLS_MD_C)
-#include "md.h"
-#endif
-
-#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
-#include "x509.h"
+#include "mbedtls/md.h"
#endif
#define MBEDTLS_ERR_OID_NOT_FOUND -0x002E /**< OID is not found. */
#define MBEDTLS_ERR_OID_BUF_TOO_SMALL -0x000B /**< output buffer is too small */
+/* This is for the benefit of X.509, but defined here in order to avoid
+ * having a "backwards" include of x.509.h here */
+/*
+ * X.509 extension types (internal, arbitrary values for bitsets)
+ */
+#define MBEDTLS_OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER (1 << 0)
+#define MBEDTLS_OID_X509_EXT_SUBJECT_KEY_IDENTIFIER (1 << 1)
+#define MBEDTLS_OID_X509_EXT_KEY_USAGE (1 << 2)
+#define MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES (1 << 3)
+#define MBEDTLS_OID_X509_EXT_POLICY_MAPPINGS (1 << 4)
+#define MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME (1 << 5)
+#define MBEDTLS_OID_X509_EXT_ISSUER_ALT_NAME (1 << 6)
+#define MBEDTLS_OID_X509_EXT_SUBJECT_DIRECTORY_ATTRS (1 << 7)
+#define MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS (1 << 8)
+#define MBEDTLS_OID_X509_EXT_NAME_CONSTRAINTS (1 << 9)
+#define MBEDTLS_OID_X509_EXT_POLICY_CONSTRAINTS (1 << 10)
+#define MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE (1 << 11)
+#define MBEDTLS_OID_X509_EXT_CRL_DISTRIBUTION_POINTS (1 << 12)
+#define MBEDTLS_OID_X509_EXT_INIHIBIT_ANYPOLICY (1 << 13)
+#define MBEDTLS_OID_X509_EXT_FRESHEST_CRL (1 << 14)
+#define MBEDTLS_OID_X509_EXT_NS_CERT_TYPE (1 << 16)
+
/*
* Top level OID tuples
*/
@@ -96,12 +110,15 @@
/* ISO arc for standard certificate and CRL extensions */
#define MBEDTLS_OID_ID_CE MBEDTLS_OID_ISO_CCITT_DS "\x1D" /**< id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} */
+#define MBEDTLS_OID_NIST_ALG MBEDTLS_OID_GOV "\x03\x04" /** { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) */
+
/**
* Private Internet Extensions
* { iso(1) identified-organization(3) dod(6) internet(1)
* security(5) mechanisms(5) pkix(7) }
*/
-#define MBEDTLS_OID_PKIX MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01\x05\x05\x07"
+#define MBEDTLS_OID_INTERNET MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01"
+#define MBEDTLS_OID_PKIX MBEDTLS_OID_INTERNET "\x05\x05\x07"
/*
* Arc for standard naming attributes
@@ -125,6 +142,7 @@
#define MBEDTLS_OID_AT_DN_QUALIFIER MBEDTLS_OID_AT "\x2E" /**< id-at-dnQualifier AttributeType:= {id-at 46} */
#define MBEDTLS_OID_AT_PSEUDONYM MBEDTLS_OID_AT "\x41" /**< id-at-pseudonym AttributeType:= {id-at 65} */
+#define MBEDTLS_OID_UID "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x01" /** id-domainComponent AttributeType:= {itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100) pilotAttributeType(1) uid(1)} */
#define MBEDTLS_OID_DOMAIN_COMPONENT "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19" /** id-domainComponent AttributeType:= {itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100) pilotAttributeType(1) domainComponent(25)} */
/*
@@ -147,6 +165,11 @@
#define MBEDTLS_OID_FRESHEST_CRL MBEDTLS_OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } */
/*
+ * Certificate policies
+ */
+#define MBEDTLS_OID_ANY_POLICY MBEDTLS_OID_CERTIFICATE_POLICIES "\x00" /**< anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 } */
+
+/*
* Netscape certificate extensions
*/
#define MBEDTLS_OID_NS_CERT MBEDTLS_OID_NETSCAPE "\x01"
@@ -180,6 +203,16 @@
#define MBEDTLS_OID_TIME_STAMPING MBEDTLS_OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */
#define MBEDTLS_OID_OCSP_SIGNING MBEDTLS_OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */
+/**
+ * Wi-SUN Alliance Field Area Network
+ * { iso(1) identified-organization(3) dod(6) internet(1)
+ * private(4) enterprise(1) WiSUN(45605) FieldAreaNetwork(1) }
+ */
+#define MBEDTLS_OID_WISUN_FAN MBEDTLS_OID_INTERNET "\x04\x01\x82\xe4\x25\x01"
+
+#define MBEDTLS_OID_ON MBEDTLS_OID_PKIX "\x08" /**< id-on OBJECT IDENTIFIER ::= { id-pkix 8 } */
+#define MBEDTLS_OID_ON_HW_MODULE_NAME MBEDTLS_OID_ON "\x04" /**< id-on-hardwareModuleName OBJECT IDENTIFIER ::= { id-on 4 } */
+
/*
* PKCS definition OIDs
*/
@@ -194,8 +227,6 @@
* PKCS#1 OIDs
*/
#define MBEDTLS_OID_PKCS1_RSA MBEDTLS_OID_PKCS1 "\x01" /**< rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } */
-#define MBEDTLS_OID_PKCS1_MD2 MBEDTLS_OID_PKCS1 "\x02" /**< md2WithRSAEncryption ::= { pkcs-1 2 } */
-#define MBEDTLS_OID_PKCS1_MD4 MBEDTLS_OID_PKCS1 "\x03" /**< md4WithRSAEncryption ::= { pkcs-1 3 } */
#define MBEDTLS_OID_PKCS1_MD5 MBEDTLS_OID_PKCS1 "\x04" /**< md5WithRSAEncryption ::= { pkcs-1 4 } */
#define MBEDTLS_OID_PKCS1_SHA1 MBEDTLS_OID_PKCS1 "\x05" /**< sha1WithRSAEncryption ::= { pkcs-1 5 } */
#define MBEDTLS_OID_PKCS1_SHA224 MBEDTLS_OID_PKCS1 "\x0e" /**< sha224WithRSAEncryption ::= { pkcs-1 14 } */
@@ -214,26 +245,47 @@
/*
* Digest algorithms
*/
-#define MBEDTLS_OID_DIGEST_ALG_MD2 MBEDTLS_OID_RSA_COMPANY "\x02\x02" /**< id-mbedtls_md2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 } */
-#define MBEDTLS_OID_DIGEST_ALG_MD4 MBEDTLS_OID_RSA_COMPANY "\x02\x04" /**< id-mbedtls_md4 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 4 } */
#define MBEDTLS_OID_DIGEST_ALG_MD5 MBEDTLS_OID_RSA_COMPANY "\x02\x05" /**< id-mbedtls_md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA1 MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_SHA1 /**< id-mbedtls_sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */
-#define MBEDTLS_OID_DIGEST_ALG_SHA224 MBEDTLS_OID_GOV "\x03\x04\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */
-#define MBEDTLS_OID_DIGEST_ALG_SHA256 MBEDTLS_OID_GOV "\x03\x04\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */
+#define MBEDTLS_OID_DIGEST_ALG_SHA224 MBEDTLS_OID_NIST_ALG "\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */
+#define MBEDTLS_OID_DIGEST_ALG_SHA256 MBEDTLS_OID_NIST_ALG "\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */
-#define MBEDTLS_OID_DIGEST_ALG_SHA384 MBEDTLS_OID_GOV "\x03\x04\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */
+#define MBEDTLS_OID_DIGEST_ALG_SHA384 MBEDTLS_OID_NIST_ALG "\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */
-#define MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_GOV "\x03\x04\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */
+#define MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_NIST_ALG "\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */
+
+#define MBEDTLS_OID_DIGEST_ALG_RIPEMD160 MBEDTLS_OID_TELETRUST "\x03\x02\x01" /**< id-ripemd160 OBJECT IDENTIFIER :: { iso(1) identified-organization(3) teletrust(36) algorithm(3) hashAlgorithm(2) ripemd160(1) } */
#define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
+#define MBEDTLS_OID_HMAC_SHA224 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */
+
+#define MBEDTLS_OID_HMAC_SHA256 MBEDTLS_OID_RSA_COMPANY "\x02\x09" /**< id-hmacWithSHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 } */
+
+#define MBEDTLS_OID_HMAC_SHA384 MBEDTLS_OID_RSA_COMPANY "\x02\x0A" /**< id-hmacWithSHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 } */
+
+#define MBEDTLS_OID_HMAC_SHA512 MBEDTLS_OID_RSA_COMPANY "\x02\x0B" /**< id-hmacWithSHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 } */
+
/*
* Encryption algorithms
*/
#define MBEDTLS_OID_DES_CBC MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */
#define MBEDTLS_OID_DES_EDE3_CBC MBEDTLS_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */
+#define MBEDTLS_OID_AES MBEDTLS_OID_NIST_ALG "\x01" /** aes OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1 } */
/*
+ * Key Wrapping algorithms
+ */
+/*
+ * RFC 5649
+ */
+#define MBEDTLS_OID_AES128_KW MBEDTLS_OID_AES "\x05" /** id-aes128-wrap OBJECT IDENTIFIER ::= { aes 5 } */
+#define MBEDTLS_OID_AES128_KWP MBEDTLS_OID_AES "\x08" /** id-aes128-wrap-pad OBJECT IDENTIFIER ::= { aes 8 } */
+#define MBEDTLS_OID_AES192_KW MBEDTLS_OID_AES "\x19" /** id-aes192-wrap OBJECT IDENTIFIER ::= { aes 25 } */
+#define MBEDTLS_OID_AES192_KWP MBEDTLS_OID_AES "\x1c" /** id-aes192-wrap-pad OBJECT IDENTIFIER ::= { aes 28 } */
+#define MBEDTLS_OID_AES256_KW MBEDTLS_OID_AES "\x2d" /** id-aes256-wrap OBJECT IDENTIFIER ::= { aes 45 } */
+#define MBEDTLS_OID_AES256_KWP MBEDTLS_OID_AES "\x30" /** id-aes256-wrap-pad OBJECT IDENTIFIER ::= { aes 48 } */
+/*
* PKCS#5 OIDs
*/
#define MBEDTLS_OID_PKCS5_PBKDF2 MBEDTLS_OID_PKCS5 "\x0c" /**< id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} */
@@ -243,8 +295,6 @@
/*
* PKCS#5 PBES1 algorithms
*/
-#define MBEDTLS_OID_PKCS5_PBE_MD2_DES_CBC MBEDTLS_OID_PKCS5 "\x01" /**< pbeWithMD2AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 1} */
-#define MBEDTLS_OID_PKCS5_PBE_MD2_RC2_CBC MBEDTLS_OID_PKCS5 "\x04" /**< pbeWithMD2AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 4} */
#define MBEDTLS_OID_PKCS5_PBE_MD5_DES_CBC MBEDTLS_OID_PKCS5 "\x03" /**< pbeWithMD5AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 3} */
#define MBEDTLS_OID_PKCS5_PBE_MD5_RC2_CBC MBEDTLS_OID_PKCS5 "\x06" /**< pbeWithMD5AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 6} */
#define MBEDTLS_OID_PKCS5_PBE_SHA1_DES_CBC MBEDTLS_OID_PKCS5 "\x0a" /**< pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10} */
@@ -260,8 +310,6 @@
*/
#define MBEDTLS_OID_PKCS12_PBE MBEDTLS_OID_PKCS12 "\x01" /**< pkcs-12PbeIds OBJECT IDENTIFIER ::= {pkcs-12 1} */
-#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128 MBEDTLS_OID_PKCS12_PBE "\x01" /**< pbeWithSHAAnd128BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 1} */
-#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_40 MBEDTLS_OID_PKCS12_PBE "\x02" /**< pbeWithSHAAnd40BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 2} */
#define MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC MBEDTLS_OID_PKCS12_PBE "\x03" /**< pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 3} */
#define MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC MBEDTLS_OID_PKCS12_PBE "\x04" /**< pbeWithSHAAnd2-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 4} */
#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_128_CBC MBEDTLS_OID_PKCS12_PBE "\x05" /**< pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 5} */
@@ -379,11 +427,14 @@
/**
* \brief Base OID descriptor structure
*/
-typedef struct {
- const char *asn1; /*!< OID ASN.1 representation */
- size_t asn1_len; /*!< length of asn1 */
- const char *name; /*!< official name (e.g. from RFC) */
- const char *description; /*!< human friendly description */
+typedef struct mbedtls_oid_descriptor_t
+{
+ const char *MBEDTLS_PRIVATE(asn1); /*!< OID ASN.1 representation */
+ size_t MBEDTLS_PRIVATE(asn1_len); /*!< length of asn1 */
+#if !defined(MBEDTLS_X509_REMOVE_INFO)
+ const char *MBEDTLS_PRIVATE(name); /*!< official name (e.g. from RFC) */
+ const char *MBEDTLS_PRIVATE(description); /*!< human friendly description */
+#endif
} mbedtls_oid_descriptor_t;
/**
@@ -399,7 +450,6 @@
*/
int mbedtls_oid_get_numeric_string( char *buf, size_t size, const mbedtls_asn1_buf *oid );
-#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
/**
* \brief Translate an X.509 extension OID into local values
*
@@ -409,7 +459,6 @@
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_x509_ext_type( const mbedtls_asn1_buf *oid, int *ext_type );
-#endif
/**
* \brief Translate an X.509 attribute type OID into the short name
@@ -513,8 +562,19 @@
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_md_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg );
+
+/**
+ * \brief Translate hmac algorithm OID into md_type
+ *
+ * \param oid OID to use
+ * \param md_hmac place to store message hmac algorithm
+ *
+ * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac );
#endif /* MBEDTLS_MD_C */
+#if !defined(MBEDTLS_X509_REMOVE_INFO)
/**
* \brief Translate Extended Key Usage OID into description
*
@@ -524,6 +584,17 @@
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_extended_key_usage( const mbedtls_asn1_buf *oid, const char **desc );
+#endif
+
+/**
+ * \brief Translate certificate policies OID into description
+ *
+ * \param oid OID to use
+ * \param desc place to store string pointer
+ *
+ * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_certificate_policies( const mbedtls_asn1_buf *oid, const char **desc );
/**
* \brief Translate md_type into hash algorithm OID
diff --git a/ext/mbedtls-asn1/include/mbedtls/pk.h b/ext/mbedtls-asn1/include/mbedtls/pk.h
index df3a03c..f3553cc 100644
--- a/ext/mbedtls-asn1/include/mbedtls/pk.h
+++ b/ext/mbedtls-asn1/include/mbedtls/pk.h
@@ -4,7 +4,7 @@
* \brief Public Key abstraction layer
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,31 +18,30 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PK_H
#define MBEDTLS_PK_H
+#include "mbedtls/private_access.h"
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
-#include "md.h"
+#include "mbedtls/md.h"
#if defined(MBEDTLS_RSA_C)
-#include "rsa.h"
+#include "mbedtls/rsa.h"
#endif
#if defined(MBEDTLS_ECP_C)
-#include "ecp.h"
+#include "mbedtls/ecp.h"
#endif
#if defined(MBEDTLS_ECDSA_C)
-#include "ecdsa.h"
+#include "mbedtls/ecdsa.h"
+#endif
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
#endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
@@ -64,9 +63,7 @@
#define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00 /**< Elliptic curve is unsupported (only NIST curves are supported). */
#define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980 /**< Unavailable feature, e.g. RSA disabled for RSA key. */
#define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH -0x3900 /**< The buffer contains a valid signature followed by more data. */
-
-/* MBEDTLS_ERR_PK_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_PK_HW_ACCEL_FAILED -0x3880 /**< PK hardware accelerator failed. */
+#define MBEDTLS_ERR_PK_BUFFER_TOO_SMALL -0x3880 /**< The output buffer is too small. */
#ifdef __cplusplus
extern "C" {
@@ -83,6 +80,7 @@
MBEDTLS_PK_ECDSA,
MBEDTLS_PK_RSA_ALT,
MBEDTLS_PK_RSASSA_PSS,
+ MBEDTLS_PK_OPAQUE,
} mbedtls_pk_type_t;
/**
@@ -91,12 +89,64 @@
*/
typedef struct mbedtls_pk_rsassa_pss_options
{
- mbedtls_md_type_t mgf1_hash_id;
- int expected_salt_len;
+ mbedtls_md_type_t MBEDTLS_PRIVATE(mgf1_hash_id);
+ int MBEDTLS_PRIVATE(expected_salt_len);
} mbedtls_pk_rsassa_pss_options;
/**
+ * \brief Maximum size of a signature made by mbedtls_pk_sign().
+ */
+/* We need to set MBEDTLS_PK_SIGNATURE_MAX_SIZE to the maximum signature
+ * size among the supported signature types. Do it by starting at 0,
+ * then incrementally increasing to be large enough for each supported
+ * signature mechanism.
+ *
+ * The resulting value can be 0, for example if MBEDTLS_ECDH_C is enabled
+ * (which allows the pk module to be included) but neither MBEDTLS_ECDSA_C
+ * nor MBEDTLS_RSA_C nor any opaque signature mechanism (PSA or RSA_ALT).
+ */
+#define MBEDTLS_PK_SIGNATURE_MAX_SIZE 0
+
+#if ( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_PK_RSA_ALT_SUPPORT) ) && \
+ MBEDTLS_MPI_MAX_SIZE > MBEDTLS_PK_SIGNATURE_MAX_SIZE
+/* For RSA, the signature can be as large as the bignum module allows.
+ * For RSA_ALT, the signature size is not necessarily tied to what the
+ * bignum module can do, but in the absence of any specific setting,
+ * we use that (rsa_alt_sign_wrap in library/pk_wrap.h will check). */
+#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
+#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
+#endif
+
+#if defined(MBEDTLS_ECDSA_C) && \
+ MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_PK_SIGNATURE_MAX_SIZE
+/* For ECDSA, the ecdsa module exports a constant for the maximum
+ * signature size. */
+#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
+#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
+#endif
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#if PSA_SIGNATURE_MAX_SIZE > MBEDTLS_PK_SIGNATURE_MAX_SIZE
+/* PSA_SIGNATURE_MAX_SIZE is the maximum size of a signature made
+ * through the PSA API in the PSA representation. */
+#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
+#define MBEDTLS_PK_SIGNATURE_MAX_SIZE PSA_SIGNATURE_MAX_SIZE
+#endif
+
+#if PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE + 11 > MBEDTLS_PK_SIGNATURE_MAX_SIZE
+/* The Mbed TLS representation is different for ECDSA signatures:
+ * PSA uses the raw concatenation of r and s,
+ * whereas Mbed TLS uses the ASN.1 representation (SEQUENCE of two INTEGERs).
+ * Add the overhead of ASN.1: up to (1+2) + 2 * (1+2+1) for the
+ * types, lengths (represented by up to 2 bytes), and potential leading
+ * zeros of the INTEGERs and the SEQUENCE. */
+#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
+#define MBEDTLS_PK_SIGNATURE_MAX_SIZE ( PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE + 11 )
+#endif
+#endif /* defined(MBEDTLS_USE_PSA_CRYPTO) */
+
+/**
* \brief Types for interfacing with the debug module
*/
typedef enum
@@ -111,9 +161,9 @@
*/
typedef struct mbedtls_pk_debug_item
{
- mbedtls_pk_debug_type type;
- const char *name;
- void *value;
+ mbedtls_pk_debug_type MBEDTLS_PRIVATE(type);
+ const char *MBEDTLS_PRIVATE(name);
+ void *MBEDTLS_PRIVATE(value);
} mbedtls_pk_debug_item;
/** Maximum number of item send for debugging, plus 1 */
@@ -129,8 +179,8 @@
*/
typedef struct mbedtls_pk_context
{
- const mbedtls_pk_info_t * pk_info; /**< Public key information */
- void * pk_ctx; /**< Underlying public key context */
+ const mbedtls_pk_info_t * MBEDTLS_PRIVATE(pk_info); /**< Public key information */
+ void * MBEDTLS_PRIVATE(pk_ctx); /**< Underlying public key context */
} mbedtls_pk_context;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
@@ -139,8 +189,8 @@
*/
typedef struct
{
- const mbedtls_pk_info_t * pk_info; /**< Public key information */
- void * rs_ctx; /**< Underlying restart context */
+ const mbedtls_pk_info_t * MBEDTLS_PRIVATE(pk_info); /**< Public key information */
+ void * MBEDTLS_PRIVATE(rs_ctx); /**< Underlying restart context */
} mbedtls_pk_restart_ctx;
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/* Now we can declare functions that take a pointer to that */
@@ -156,7 +206,7 @@
*/
static inline mbedtls_rsa_context *mbedtls_pk_rsa( const mbedtls_pk_context pk )
{
- return( (mbedtls_rsa_context *) (pk).pk_ctx );
+ return( (mbedtls_rsa_context *) (pk).MBEDTLS_PRIVATE(pk_ctx) );
}
#endif /* MBEDTLS_RSA_C */
@@ -169,7 +219,7 @@
*/
static inline mbedtls_ecp_keypair *mbedtls_pk_ec( const mbedtls_pk_context pk )
{
- return( (mbedtls_ecp_keypair *) (pk).pk_ctx );
+ return( (mbedtls_ecp_keypair *) (pk).MBEDTLS_PRIVATE(pk_ctx) );
}
#endif /* MBEDTLS_ECP_C */
@@ -177,12 +227,12 @@
/**
* \brief Types for RSA-alt abstraction
*/
-typedef int (*mbedtls_pk_rsa_alt_decrypt_func)( void *ctx, int mode, size_t *olen,
+typedef int (*mbedtls_pk_rsa_alt_decrypt_func)( void *ctx, size_t *olen,
const unsigned char *input, unsigned char *output,
size_t output_max_len );
typedef int (*mbedtls_pk_rsa_alt_sign_func)( void *ctx,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
- int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,
+ mbedtls_md_type_t md_alg, unsigned int hashlen,
const unsigned char *hash, unsigned char *sig );
typedef size_t (*mbedtls_pk_rsa_alt_key_len_func)( void *ctx );
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
@@ -197,23 +247,40 @@
const mbedtls_pk_info_t *mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type );
/**
- * \brief Initialize a mbedtls_pk_context (as NONE)
+ * \brief Initialize a #mbedtls_pk_context (as NONE).
+ *
+ * \param ctx The context to initialize.
+ * This must not be \c NULL.
*/
void mbedtls_pk_init( mbedtls_pk_context *ctx );
/**
- * \brief Free a mbedtls_pk_context
+ * \brief Free the components of a #mbedtls_pk_context.
+ *
+ * \param ctx The context to clear. It must have been initialized.
+ * If this is \c NULL, this function does nothing.
+ *
+ * \note For contexts that have been set up with
+ * mbedtls_pk_setup_opaque(), this does not free the underlying
+ * PSA key and you still need to call psa_destroy_key()
+ * independently if you want to destroy that key.
*/
void mbedtls_pk_free( mbedtls_pk_context *ctx );
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Initialize a restart context
+ *
+ * \param ctx The context to initialize.
+ * This must not be \c NULL.
*/
void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx );
/**
* \brief Free the components of a restart context
+ *
+ * \param ctx The context to clear. It must have been initialized.
+ * If this is \c NULL, this function does nothing.
*/
void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx );
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
@@ -222,7 +289,8 @@
* \brief Initialize a PK context with the information given
* and allocates the type-specific PK subcontext.
*
- * \param ctx Context to initialize. Must be empty (type NONE).
+ * \param ctx Context to initialize. It must not have been set
+ * up yet (type #MBEDTLS_PK_NONE).
* \param info Information to use
*
* \return 0 on success,
@@ -234,11 +302,45 @@
*/
int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/**
+ * \brief Initialize a PK context to wrap a PSA key.
+ *
+ * \note This function replaces mbedtls_pk_setup() for contexts
+ * that wrap a (possibly opaque) PSA key instead of
+ * storing and manipulating the key material directly.
+ *
+ * \param ctx The context to initialize. It must be empty (type NONE).
+ * \param key The PSA key to wrap, which must hold an ECC key pair
+ * (see notes below).
+ *
+ * \note The wrapped key must remain valid as long as the
+ * wrapping PK context is in use, that is at least between
+ * the point this function is called and the point
+ * mbedtls_pk_free() is called on this context. The wrapped
+ * key might then be independently used or destroyed.
+ *
+ * \note This function is currently only available for ECC key
+ * pairs (that is, ECC keys containing private key material).
+ * Support for other key types may be added later.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input
+ * (context already used, invalid key identifier).
+ * \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the key is not an
+ * ECC key pair.
+ * \return #MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
+ */
+int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx,
+ const psa_key_id_t key );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/**
* \brief Initialize an RSA-alt context
*
- * \param ctx Context to initialize. Must be empty (type NONE).
+ * \param ctx Context to initialize. It must not have been set
+ * up yet (type #MBEDTLS_PK_NONE).
* \param key RSA key pointer
* \param decrypt_func Decryption function
* \param sign_func Signing function
@@ -258,7 +360,7 @@
/**
* \brief Get the size in bits of the underlying key
*
- * \param ctx Context to use
+ * \param ctx The context to query. It must have been initialized.
*
* \return Key size in bits, or 0 on error
*/
@@ -266,7 +368,8 @@
/**
* \brief Get the length in bytes of the underlying key
- * \param ctx Context to use
+ *
+ * \param ctx The context to query. It must have been initialized.
*
* \return Key length in bytes, or 0 on error
*/
@@ -278,21 +381,32 @@
/**
* \brief Tell if a context can do the operation given by type
*
- * \param ctx Context to test
- * \param type Target type
+ * \param ctx The context to query. It must have been initialized.
+ * \param type The desired type.
*
- * \return 0 if context can't do the operations,
- * 1 otherwise.
+ * \return 1 if the context can do operations on the given type.
+ * \return 0 if the context cannot do the operations on the given
+ * type. This is always the case for a context that has
+ * been initialized but not set up, or that has been
+ * cleared with mbedtls_pk_free().
*/
int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type );
/**
* \brief Verify signature (including padding if relevant).
*
- * \param ctx PK context to use
- * \param md_alg Hash algorithm used (see notes)
+ * \param ctx The PK context to use. It must have been set up.
+ * \param md_alg Hash algorithm used.
+ * This can be #MBEDTLS_MD_NONE if the signature algorithm
+ * does not rely on a hash algorithm (non-deterministic
+ * ECDSA, RSA PKCS#1 v1.5).
+ * For PKCS#1 v1.5, if \p md_alg is #MBEDTLS_MD_NONE, then
+ * \p hash is the DigestInfo structure used by RFC 8017
+ * §9.2 steps 3–6. If \p md_alg is a valid hash
+ * algorithm then \p hash is the digest itself, and this
+ * function calculates the DigestInfo encoding internally.
* \param hash Hash of the message to sign
- * \param hash_len Hash length or 0 (see notes)
+ * \param hash_len Hash length
* \param sig Signature to verify
* \param sig_len Signature length
*
@@ -304,11 +418,6 @@
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
* Use \c mbedtls_pk_verify_ext( MBEDTLS_PK_RSASSA_PSS, ... )
* to verify RSASSA_PSS signatures.
- *
- * \note If hash_len is 0, then the length associated with md_alg
- * is used instead, or an error returned if it is invalid.
- *
- * \note md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0
*/
int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
@@ -322,7 +431,7 @@
* \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC
* operations. For RSA, same as \c mbedtls_pk_verify().
*
- * \param ctx PK context to use
+ * \param ctx The PK context to use. It must have been set up.
* \param md_alg Hash algorithm used (see notes)
* \param hash Hash of the message to sign
* \param hash_len Hash length or 0 (see notes)
@@ -346,7 +455,7 @@
*
* \param type Signature type (inc. possible padding type) to verify
* \param options Pointer to type-specific options, or NULL
- * \param ctx PK context to use
+ * \param ctx The PK context to use. It must have been set up.
* \param md_alg Hash algorithm used (see notes)
* \param hash Hash of the message to sign
* \param hash_len Hash length or 0 (see notes)
@@ -377,13 +486,20 @@
/**
* \brief Make signature, including padding if relevant.
*
- * \param ctx PK context to use - must hold a private key
+ * \param ctx The PK context to use. It must have been set up
+ * with a private key.
* \param md_alg Hash algorithm used (see notes)
* \param hash Hash of the message to sign
- * \param hash_len Hash length or 0 (see notes)
- * \param sig Place to write the signature
- * \param sig_len Number of bytes written
- * \param f_rng RNG function
+ * \param hash_len Hash length
+ * \param sig Place to write the signature.
+ * It must have enough room for the signature.
+ * #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough.
+ * You may use a smaller buffer if it is large enough
+ * given the key type.
+ * \param sig_size The size of the \p sig buffer in bytes.
+ * \param sig_len On successful return,
+ * the number of bytes written to \p sig.
+ * \param f_rng RNG function, must not be \c NULL.
* \param p_rng RNG parameter
*
* \return 0 on success, or a specific error code.
@@ -392,15 +508,12 @@
* There is no interface in the PK module to make RSASSA-PSS
* signatures yet.
*
- * \note If hash_len is 0, then the length associated with md_alg
- * is used instead, or an error returned if it is invalid.
- *
* \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0.
* For ECDSA, md_alg may never be MBEDTLS_MD_NONE.
*/
int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
- unsigned char *sig, size_t *sig_len,
+ unsigned char *sig, size_t sig_size, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/**
@@ -411,37 +524,45 @@
* \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC
* operations. For RSA, same as \c mbedtls_pk_sign().
*
- * \param ctx PK context to use - must hold a private key
- * \param md_alg Hash algorithm used (see notes)
+ * \param ctx The PK context to use. It must have been set up
+ * with a private key.
+ * \param md_alg Hash algorithm used (see notes for mbedtls_pk_sign())
* \param hash Hash of the message to sign
- * \param hash_len Hash length or 0 (see notes)
- * \param sig Place to write the signature
- * \param sig_len Number of bytes written
- * \param f_rng RNG function
+ * \param hash_len Hash length
+ * \param sig Place to write the signature.
+ * It must have enough room for the signature.
+ * #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough.
+ * You may use a smaller buffer if it is large enough
+ * given the key type.
+ * \param sig_size The size of the \p sig buffer in bytes.
+ * \param sig_len On successful return,
+ * the number of bytes written to \p sig.
+ * \param f_rng RNG function, must not be \c NULL.
* \param p_rng RNG parameter
* \param rs_ctx Restart context (NULL to disable restart)
*
- * \return See \c mbedtls_pk_sign(), or
+ * \return See \c mbedtls_pk_sign().
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
*/
int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
- unsigned char *sig, size_t *sig_len,
+ unsigned char *sig, size_t sig_size, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
mbedtls_pk_restart_ctx *rs_ctx );
/**
* \brief Decrypt message (including padding if relevant).
*
- * \param ctx PK context to use - must hold a private key
+ * \param ctx The PK context to use. It must have been set up
+ * with a private key.
* \param input Input to decrypt
* \param ilen Input size
* \param output Decrypted output
* \param olen Decrypted message length
* \param osize Size of the output buffer
- * \param f_rng RNG function
+ * \param f_rng RNG function, must not be \c NULL.
* \param p_rng RNG parameter
*
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
@@ -456,15 +577,17 @@
/**
* \brief Encrypt message (including padding if relevant).
*
- * \param ctx PK context to use
+ * \param ctx The PK context to use. It must have been set up.
* \param input Message to encrypt
* \param ilen Message size
* \param output Encrypted output
* \param olen Encrypted output length
* \param osize Size of the output buffer
- * \param f_rng RNG function
+ * \param f_rng RNG function, must not be \c NULL.
* \param p_rng RNG parameter
*
+ * \note \p f_rng is used for padding generation.
+ *
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
*
* \return 0 on success, or a specific error code.
@@ -479,15 +602,24 @@
*
* \param pub Context holding a public key.
* \param prv Context holding a private (and public) key.
+ * \param f_rng RNG function, must not be \c NULL.
+ * \param p_rng RNG parameter
*
- * \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA
+ * \return \c 0 on success (keys were checked and match each other).
+ * \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the keys could not
+ * be checked - in that case they may or may not match.
+ * \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA if a context is invalid.
+ * \return Another non-zero value if the keys do not match.
*/
-int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv );
+int mbedtls_pk_check_pair( const mbedtls_pk_context *pub,
+ const mbedtls_pk_context *prv,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
/**
* \brief Export debug information
*
- * \param ctx Context to use
+ * \param ctx The PK context to use. It must have been initialized.
* \param items Place to write debug items
*
* \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA
@@ -497,7 +629,7 @@
/**
* \brief Access the type name
*
- * \param ctx Context to use
+ * \param ctx The PK context to use. It must have been initialized.
*
* \return Type name on success, or "invalid PK"
*/
@@ -506,9 +638,10 @@
/**
* \brief Get the key type
*
- * \param ctx Context to use
+ * \param ctx The PK context to use. It must have been initialized.
*
- * \return Type on success, or MBEDTLS_PK_NONE
+ * \return Type on success.
+ * \return #MBEDTLS_PK_NONE for a context that has not been set up.
*/
mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx );
@@ -517,12 +650,24 @@
/**
* \brief Parse a private key in PEM or DER format
*
- * \param ctx key to be initialized
- * \param key input buffer
- * \param keylen size of the buffer
- * (including the terminating null byte for PEM data)
- * \param pwd password for decryption (optional)
- * \param pwdlen size of the password
+ * \param ctx The PK context to fill. It must have been initialized
+ * but not set up.
+ * \param key Input buffer to parse.
+ * The buffer must contain the input exactly, with no
+ * extra trailing material. For PEM, the buffer must
+ * contain a null-terminated string.
+ * \param keylen Size of \b key in bytes.
+ * For PEM data, this includes the terminating null byte,
+ * so \p keylen must be equal to `strlen(key) + 1`.
+ * \param pwd Optional password for decryption.
+ * Pass \c NULL if expecting a non-encrypted key.
+ * Pass a string of \p pwdlen bytes if expecting an encrypted
+ * key; a non-encrypted key will also be accepted.
+ * The empty password is not supported.
+ * \param pwdlen Size of the password in bytes.
+ * Ignored if \p pwd is \c NULL.
+ * \param f_rng RNG function, must not be \c NULL. Used for blinding.
+ * \param p_rng RNG parameter
*
* \note On entry, ctx must be empty, either freshly initialised
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
@@ -533,17 +678,23 @@
* \return 0 if successful, or a specific PK or PEM error code
*/
int mbedtls_pk_parse_key( mbedtls_pk_context *ctx,
- const unsigned char *key, size_t keylen,
- const unsigned char *pwd, size_t pwdlen );
+ const unsigned char *key, size_t keylen,
+ const unsigned char *pwd, size_t pwdlen,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/** \ingroup pk_module */
/**
* \brief Parse a public key in PEM or DER format
*
- * \param ctx key to be initialized
- * \param key input buffer
- * \param keylen size of the buffer
- * (including the terminating null byte for PEM data)
+ * \param ctx The PK context to fill. It must have been initialized
+ * but not set up.
+ * \param key Input buffer to parse.
+ * The buffer must contain the input exactly, with no
+ * extra trailing material. For PEM, the buffer must
+ * contain a null-terminated string.
+ * \param keylen Size of \b key in bytes.
+ * For PEM data, this includes the terminating null byte,
+ * so \p keylen must be equal to `strlen(key) + 1`.
*
* \note On entry, ctx must be empty, either freshly initialised
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
@@ -561,9 +712,16 @@
/**
* \brief Load and parse a private key
*
- * \param ctx key to be initialized
+ * \param ctx The PK context to fill. It must have been initialized
+ * but not set up.
* \param path filename to read the private key from
- * \param password password to decrypt the file (can be NULL)
+ * \param password Optional password to decrypt the file.
+ * Pass \c NULL if expecting a non-encrypted key.
+ * Pass a null-terminated string if expecting an encrypted
+ * key; a non-encrypted key will also be accepted.
+ * The empty password is not supported.
+ * \param f_rng RNG function, must not be \c NULL. Used for blinding.
+ * \param p_rng RNG parameter
*
* \note On entry, ctx must be empty, either freshly initialised
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
@@ -574,13 +732,15 @@
* \return 0 if successful, or a specific PK or PEM error code
*/
int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
- const char *path, const char *password );
+ const char *path, const char *password,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/** \ingroup pk_module */
/**
* \brief Load and parse a public key
*
- * \param ctx key to be initialized
+ * \param ctx The PK context to fill. It must have been initialized
+ * but not set up.
* \param path filename to read the public key from
*
* \note On entry, ctx must be empty, either freshly initialised
@@ -603,14 +763,14 @@
* return value to determine where you should start
* using the buffer
*
- * \param ctx private to write away
+ * \param ctx PK context which must contain a valid private key.
* \param buf buffer to write to
* \param size size of the buffer
*
* \return length of data written if successful, or a specific
* error code
*/
-int mbedtls_pk_write_key_der( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
+int mbedtls_pk_write_key_der( const mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
/**
* \brief Write a public key to a SubjectPublicKeyInfo DER structure
@@ -618,37 +778,39 @@
* return value to determine where you should start
* using the buffer
*
- * \param ctx public key to write away
+ * \param ctx PK context which must contain a valid public or private key.
* \param buf buffer to write to
* \param size size of the buffer
*
* \return length of data written if successful, or a specific
* error code
*/
-int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
+int mbedtls_pk_write_pubkey_der( const mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
#if defined(MBEDTLS_PEM_WRITE_C)
/**
* \brief Write a public key to a PEM string
*
- * \param ctx public key to write away
- * \param buf buffer to write to
- * \param size size of the buffer
+ * \param ctx PK context which must contain a valid public or private key.
+ * \param buf Buffer to write to. The output includes a
+ * terminating null byte.
+ * \param size Size of the buffer in bytes.
*
* \return 0 if successful, or a specific error code
*/
-int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
+int mbedtls_pk_write_pubkey_pem( const mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
/**
* \brief Write a private key to a PKCS#1 or SEC1 PEM string
*
- * \param ctx private to write away
- * \param buf buffer to write to
- * \param size size of the buffer
+ * \param ctx PK context which must contain a valid private key.
+ * \param buf Buffer to write to. The output includes a
+ * terminating null byte.
+ * \param size Size of the buffer in bytes.
*
* \return 0 if successful, or a specific error code
*/
-int mbedtls_pk_write_key_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
+int mbedtls_pk_write_key_pem( const mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
#endif /* MBEDTLS_PEM_WRITE_C */
#endif /* MBEDTLS_PK_WRITE_C */
@@ -663,7 +825,8 @@
*
* \param p the position in the ASN.1 data
* \param end end of the buffer
- * \param pk the key to fill
+ * \param pk The PK context to fill. It must have been initialized
+ * but not set up.
*
* \return 0 if successful, or a specific PK error code
*/
@@ -678,7 +841,7 @@
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
- * \param key public key to write away
+ * \param key PK context which must contain a valid public or private key.
*
* \return the length written or a negative error code
*/
@@ -694,6 +857,32 @@
int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n );
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/**
+ * \brief Turn an EC key into an opaque one.
+ *
+ * \warning This is a temporary utility function for tests. It might
+ * change or be removed at any time without notice.
+ *
+ * \note Only ECDSA keys are supported so far. Signing with the
+ * specified hash is the only allowed use of that key.
+ *
+ * \param pk Input: the EC key to import to a PSA key.
+ * Output: a PK context wrapping that PSA key.
+ * \param key Output: a PSA key identifier.
+ * It's the caller's responsibility to call
+ * psa_destroy_key() on that key identifier after calling
+ * mbedtls_pk_free() on the PK context.
+ * \param hash_alg The hash algorithm to allow for use with that key.
+ *
+ * \return \c 0 if successful.
+ * \return An Mbed TLS error code otherwise.
+ */
+int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
+ psa_key_id_t *key,
+ psa_algorithm_t hash_alg );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#ifdef __cplusplus
}
#endif
diff --git a/ext/mbedtls-asn1/include/mbedtls/platform.h b/ext/mbedtls-asn1/include/mbedtls/platform.h
index 89fe8a7..277a85c 100644
--- a/ext/mbedtls-asn1/include/mbedtls/platform.h
+++ b/ext/mbedtls-asn1/include/mbedtls/platform.h
@@ -13,7 +13,7 @@
* dynamically configured at runtime.
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -27,25 +27,17 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PLATFORM_H
#define MBEDTLS_PLATFORM_H
+#include "mbedtls/private_access.h"
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
#if defined(MBEDTLS_HAVE_TIME)
-#include "platform_time.h"
+#include "mbedtls/platform_time.h"
#endif
-#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070 /**< Hardware accelerator failed */
-#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 /**< The requested feature is not supported by the platform */
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -54,21 +46,37 @@
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
+ * Either change them in mbedtls_config.h or define them on the compiler command line.
* \{
*/
+/* The older Microsoft Windows common runtime provides non-conforming
+ * implementations of some standard library functions, including snprintf
+ * and vsnprintf. This affects MSVC and MinGW builds.
+ */
+#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900)
+#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF
+#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF
+#endif
+
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
-#if defined(_WIN32)
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */
#else
#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< The default \c snprintf function to use. */
#endif
#endif
+#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF)
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
+#define MBEDTLS_PLATFORM_STD_VSNPRINTF mbedtls_platform_win32_vsnprintf /**< The default \c vsnprintf function to use. */
+#else
+#define MBEDTLS_PLATFORM_STD_VSNPRINTF vsnprintf /**< The default \c vsnprintf function to use. */
+#endif
+#endif
#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< The default \c printf function to use. */
#endif
@@ -204,7 +212,7 @@
* - however it is acceptable to return -1 instead of the required length when
* the destination buffer is too short.
*/
-#if defined(_WIN32)
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
/* For Windows (inc. MSYS2), we provide our own fixed implementation */
int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... );
#endif
@@ -231,6 +239,42 @@
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
/*
+ * The function pointers for vsnprintf
+ *
+ * The vsnprintf implementation should conform to C99:
+ * - it *must* always correctly zero-terminate the buffer
+ * (except when n == 0, then it must leave the buffer untouched)
+ * - however it is acceptable to return -1 instead of the required length when
+ * the destination buffer is too short.
+ */
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
+#include <stdarg.h>
+/* For Older Windows (inc. MSYS2), we provide our own fixed implementation */
+int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg );
+#endif
+
+#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
+#include <stdarg.h>
+extern int (*mbedtls_vsnprintf)( char * s, size_t n, const char * format, va_list arg );
+
+/**
+ * \brief Set your own snprintf function pointer
+ *
+ * \param vsnprintf_func The \c vsnprintf function implementation
+ *
+ * \return \c 0
+ */
+int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n,
+ const char * format, va_list arg ) );
+#else /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
+#define mbedtls_vsnprintf MBEDTLS_PLATFORM_VSNPRINTF_MACRO
+#else
+#define mbedtls_vsnprintf vsnprintf
+#endif /* MBEDTLS_PLATFORM_VSNPRINTF_MACRO */
+#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
+
+/*
* The function pointers for exit
*/
#if defined(MBEDTLS_PLATFORM_EXIT_ALT)
@@ -320,7 +364,7 @@
*/
typedef struct mbedtls_platform_context
{
- char dummy; /**< A placeholder member, as empty structs are not portable. */
+ char MBEDTLS_PRIVATE(dummy); /**< A placeholder member, as empty structs are not portable. */
}
mbedtls_platform_context;
diff --git a/ext/mbedtls-asn1/include/mbedtls/platform_util.h b/ext/mbedtls-asn1/include/mbedtls/platform_util.h
index 164a1a0..1a0a135 100644
--- a/ext/mbedtls-asn1/include/mbedtls/platform_util.h
+++ b/ext/mbedtls-asn1/include/mbedtls/platform_util.h
@@ -5,7 +5,7 @@
* library.
*/
/*
- * Copyright (C) 2018, Arm Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -19,17 +19,11 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PLATFORM_UTIL_H
#define MBEDTLS_PLATFORM_UTIL_H
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
#include <stddef.h>
#if defined(MBEDTLS_HAVE_TIME_DATE)
@@ -41,6 +35,31 @@
extern "C" {
#endif
+/* Internal macros meant to be called only from within the library. */
+#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 )
+#define MBEDTLS_INTERNAL_VALIDATE( cond ) do { } while( 0 )
+
+/* Internal helper macros for deprecating API constants. */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+/* Deliberately don't (yet) export MBEDTLS_DEPRECATED here
+ * to avoid conflict with other headers which define and use
+ * it, too. We might want to move all these definitions here at
+ * some point for uniformity. */
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_string_constant_t;
+#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) \
+ ( (mbedtls_deprecated_string_constant_t) ( VAL ) )
+MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t;
+#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) \
+ ( (mbedtls_deprecated_numeric_constant_t) ( VAL ) )
+#undef MBEDTLS_DEPRECATED
+#else /* MBEDTLS_DEPRECATED_WARNING */
+#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL
+#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) VAL
+#endif /* MBEDTLS_DEPRECATED_WARNING */
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
/**
* \brief Securely zeroize a buffer
*
diff --git a/ext/mbedtls-asn1/include/mbedtls/private_access.h b/ext/mbedtls-asn1/include/mbedtls/private_access.h
new file mode 100644
index 0000000..98d3419
--- /dev/null
+++ b/ext/mbedtls-asn1/include/mbedtls/private_access.h
@@ -0,0 +1,32 @@
+ /**
+ * \file private_access.h
+ *
+ * \brief Macro wrapper for struct's memebrs.
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ */
+
+#ifndef MBEDTLS_PRIVATE_ACCESS_H
+#define MBEDTLS_PRIVATE_ACCESS_H
+
+#ifndef MBEDTLS_ALLOW_PRIVATE_ACCESS
+#define MBEDTLS_PRIVATE(member) private_##member
+#else
+#define MBEDTLS_PRIVATE(member) member
+#endif
+
+#endif /* MBEDTLS_PRIVATE_ACCESS_H */
diff --git a/ext/mbedtls-asn1/include/mbedtls/rsa.h b/ext/mbedtls-asn1/include/mbedtls/rsa.h
new file mode 100644
index 0000000..cffbe3b
--- /dev/null
+++ b/ext/mbedtls-asn1/include/mbedtls/rsa.h
@@ -0,0 +1,1119 @@
+/**
+ * \file rsa.h
+ *
+ * \brief This file provides an API for the RSA public-key cryptosystem.
+ *
+ * The RSA public-key cryptosystem is defined in <em>Public-Key
+ * Cryptography Standards (PKCS) #1 v1.5: RSA Encryption</em>
+ * and <em>Public-Key Cryptography Standards (PKCS) #1 v2.1:
+ * RSA Cryptography Specifications</em>.
+ *
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ */
+#ifndef MBEDTLS_RSA_H
+#define MBEDTLS_RSA_H
+#include "mbedtls/private_access.h"
+
+#include "mbedtls/build_info.h"
+
+#include "mbedtls/bignum.h"
+#include "mbedtls/md.h"
+
+#if defined(MBEDTLS_THREADING_C)
+#include "mbedtls/threading.h"
+#endif
+
+/*
+ * RSA Error codes
+ */
+#define MBEDTLS_ERR_RSA_BAD_INPUT_DATA -0x4080 /**< Bad input parameters to function. */
+#define MBEDTLS_ERR_RSA_INVALID_PADDING -0x4100 /**< Input data contains invalid padding and is rejected. */
+#define MBEDTLS_ERR_RSA_KEY_GEN_FAILED -0x4180 /**< Something failed during generation of a key. */
+#define MBEDTLS_ERR_RSA_KEY_CHECK_FAILED -0x4200 /**< Key failed to pass the validity check of the library. */
+#define MBEDTLS_ERR_RSA_PUBLIC_FAILED -0x4280 /**< The public key operation failed. */
+#define MBEDTLS_ERR_RSA_PRIVATE_FAILED -0x4300 /**< The private key operation failed. */
+#define MBEDTLS_ERR_RSA_VERIFY_FAILED -0x4380 /**< The PKCS#1 verification failed. */
+#define MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE -0x4400 /**< The output buffer for decryption is not large enough. */
+#define MBEDTLS_ERR_RSA_RNG_FAILED -0x4480 /**< The random generator failed to generate non-zeros. */
+
+/*
+ * RSA constants
+ */
+
+#define MBEDTLS_RSA_PKCS_V15 0 /**< Use PKCS#1 v1.5 encoding. */
+#define MBEDTLS_RSA_PKCS_V21 1 /**< Use PKCS#1 v2.1 encoding. */
+
+#define MBEDTLS_RSA_SIGN 1 /**< Identifier for RSA signature operations. */
+#define MBEDTLS_RSA_CRYPT 2 /**< Identifier for RSA encryption and decryption operations. */
+
+#define MBEDTLS_RSA_SALT_LEN_ANY -1
+
+/*
+ * The above constants may be used even if the RSA module is compile out,
+ * eg for alternative (PKCS#11) RSA implemenations in the PK layers.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_RSA_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief The RSA context structure.
+ */
+typedef struct mbedtls_rsa_context
+{
+ int MBEDTLS_PRIVATE(ver); /*!< Reserved for internal purposes.
+ * Do not set this field in application
+ * code. Its meaning might change without
+ * notice. */
+ size_t MBEDTLS_PRIVATE(len); /*!< The size of \p N in Bytes. */
+
+ mbedtls_mpi MBEDTLS_PRIVATE(N); /*!< The public modulus. */
+ mbedtls_mpi MBEDTLS_PRIVATE(E); /*!< The public exponent. */
+
+ mbedtls_mpi MBEDTLS_PRIVATE(D); /*!< The private exponent. */
+ mbedtls_mpi MBEDTLS_PRIVATE(P); /*!< The first prime factor. */
+ mbedtls_mpi MBEDTLS_PRIVATE(Q); /*!< The second prime factor. */
+
+ mbedtls_mpi MBEDTLS_PRIVATE(DP); /*!< <code>D % (P - 1)</code>. */
+ mbedtls_mpi MBEDTLS_PRIVATE(DQ); /*!< <code>D % (Q - 1)</code>. */
+ mbedtls_mpi MBEDTLS_PRIVATE(QP); /*!< <code>1 / (Q % P)</code>. */
+
+ mbedtls_mpi MBEDTLS_PRIVATE(RN); /*!< cached <code>R^2 mod N</code>. */
+
+ mbedtls_mpi MBEDTLS_PRIVATE(RP); /*!< cached <code>R^2 mod P</code>. */
+ mbedtls_mpi MBEDTLS_PRIVATE(RQ); /*!< cached <code>R^2 mod Q</code>. */
+
+ mbedtls_mpi MBEDTLS_PRIVATE(Vi); /*!< The cached blinding value. */
+ mbedtls_mpi MBEDTLS_PRIVATE(Vf); /*!< The cached un-blinding value. */
+
+ int MBEDTLS_PRIVATE(padding); /*!< Selects padding mode:
+ #MBEDTLS_RSA_PKCS_V15 for 1.5 padding and
+ #MBEDTLS_RSA_PKCS_V21 for OAEP or PSS. */
+ int MBEDTLS_PRIVATE(hash_id); /*!< Hash identifier of mbedtls_md_type_t type,
+ as specified in md.h for use in the MGF
+ mask generating function used in the
+ EME-OAEP and EMSA-PSS encodings. */
+#if defined(MBEDTLS_THREADING_C)
+ /* Invariant: the mutex is initialized iff ver != 0. */
+ mbedtls_threading_mutex_t MBEDTLS_PRIVATE(mutex); /*!< Thread-safety mutex. */
+#endif
+}
+mbedtls_rsa_context;
+
+#else /* MBEDTLS_RSA_ALT */
+#include "rsa_alt.h"
+#endif /* MBEDTLS_RSA_ALT */
+
+/**
+ * \brief This function initializes an RSA context.
+ *
+ * \note This function initializes the padding and the hash
+ * identifier to respectively #MBEDTLS_RSA_PKCS_V15 and
+ * #MBEDTLS_MD_NONE. See mbedtls_rsa_set_padding() for more
+ * information about those parameters.
+ *
+ * \param ctx The RSA context to initialize. This must not be \c NULL.
+ */
+void mbedtls_rsa_init( mbedtls_rsa_context *ctx );
+
+/**
+ * \brief This function sets padding for an already initialized RSA
+ * context.
+ *
+ * \note Set padding to #MBEDTLS_RSA_PKCS_V21 for the RSAES-OAEP
+ * encryption scheme and the RSASSA-PSS signature scheme.
+ *
+ * \note The \p hash_id parameter is ignored when using
+ * #MBEDTLS_RSA_PKCS_V15 padding.
+ *
+ * \note The choice of padding mode is strictly enforced for private
+ * key operations, since there might be security concerns in
+ * mixing padding modes. For public key operations it is
+ * a default value, which can be overridden by calling specific
+ * \c mbedtls_rsa_rsaes_xxx or \c mbedtls_rsa_rsassa_xxx
+ * functions.
+ *
+ * \note The hash selected in \p hash_id is always used for OEAP
+ * encryption. For PSS signatures, it is always used for
+ * making signatures, but can be overridden for verifying them.
+ * If set to #MBEDTLS_MD_NONE, it is always overridden.
+ *
+ * \param ctx The initialized RSA context to be configured.
+ * \param padding The padding mode to use. This must be either
+ * #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21.
+ * \param hash_id The hash identifier for PSS or OAEP, if \p padding is
+ * #MBEDTLS_RSA_PKCS_V21. #MBEDTLS_MD_NONE is accepted by this
+ * function but may be not suitable for some operations.
+ * Ignored if \p padding is #MBEDTLS_RSA_PKCS_V15.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_RSA_INVALID_PADDING failure:
+ * \p padding or \p hash_id is invalid.
+ */
+int mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding,
+ mbedtls_md_type_t hash_id );
+
+/**
+ * \brief This function imports a set of core parameters into an
+ * RSA context.
+ *
+ * \note This function can be called multiple times for successive
+ * imports, if the parameters are not simultaneously present.
+ *
+ * Any sequence of calls to this function should be followed
+ * by a call to mbedtls_rsa_complete(), which checks and
+ * completes the provided information to a ready-for-use
+ * public or private RSA key.
+ *
+ * \note See mbedtls_rsa_complete() for more information on which
+ * parameters are necessary to set up a private or public
+ * RSA key.
+ *
+ * \note The imported parameters are copied and need not be preserved
+ * for the lifetime of the RSA context being set up.
+ *
+ * \param ctx The initialized RSA context to store the parameters in.
+ * \param N The RSA modulus. This may be \c NULL.
+ * \param P The first prime factor of \p N. This may be \c NULL.
+ * \param Q The second prime factor of \p N. This may be \c NULL.
+ * \param D The private exponent. This may be \c NULL.
+ * \param E The public exponent. This may be \c NULL.
+ *
+ * \return \c 0 on success.
+ * \return A non-zero error code on failure.
+ */
+int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
+ const mbedtls_mpi *N,
+ const mbedtls_mpi *P, const mbedtls_mpi *Q,
+ const mbedtls_mpi *D, const mbedtls_mpi *E );
+
+/**
+ * \brief This function imports core RSA parameters, in raw big-endian
+ * binary format, into an RSA context.
+ *
+ * \note This function can be called multiple times for successive
+ * imports, if the parameters are not simultaneously present.
+ *
+ * Any sequence of calls to this function should be followed
+ * by a call to mbedtls_rsa_complete(), which checks and
+ * completes the provided information to a ready-for-use
+ * public or private RSA key.
+ *
+ * \note See mbedtls_rsa_complete() for more information on which
+ * parameters are necessary to set up a private or public
+ * RSA key.
+ *
+ * \note The imported parameters are copied and need not be preserved
+ * for the lifetime of the RSA context being set up.
+ *
+ * \param ctx The initialized RSA context to store the parameters in.
+ * \param N The RSA modulus. This may be \c NULL.
+ * \param N_len The Byte length of \p N; it is ignored if \p N == NULL.
+ * \param P The first prime factor of \p N. This may be \c NULL.
+ * \param P_len The Byte length of \p P; it ns ignored if \p P == NULL.
+ * \param Q The second prime factor of \p N. This may be \c NULL.
+ * \param Q_len The Byte length of \p Q; it is ignored if \p Q == NULL.
+ * \param D The private exponent. This may be \c NULL.
+ * \param D_len The Byte length of \p D; it is ignored if \p D == NULL.
+ * \param E The public exponent. This may be \c NULL.
+ * \param E_len The Byte length of \p E; it is ignored if \p E == NULL.
+ *
+ * \return \c 0 on success.
+ * \return A non-zero error code on failure.
+ */
+int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
+ unsigned char const *N, size_t N_len,
+ unsigned char const *P, size_t P_len,
+ unsigned char const *Q, size_t Q_len,
+ unsigned char const *D, size_t D_len,
+ unsigned char const *E, size_t E_len );
+
+/**
+ * \brief This function completes an RSA context from
+ * a set of imported core parameters.
+ *
+ * To setup an RSA public key, precisely \p N and \p E
+ * must have been imported.
+ *
+ * To setup an RSA private key, sufficient information must
+ * be present for the other parameters to be derivable.
+ *
+ * The default implementation supports the following:
+ * <ul><li>Derive \p P, \p Q from \p N, \p D, \p E.</li>
+ * <li>Derive \p N, \p D from \p P, \p Q, \p E.</li></ul>
+ * Alternative implementations need not support these.
+ *
+ * If this function runs successfully, it guarantees that
+ * the RSA context can be used for RSA operations without
+ * the risk of failure or crash.
+ *
+ * \warning This function need not perform consistency checks
+ * for the imported parameters. In particular, parameters that
+ * are not needed by the implementation might be silently
+ * discarded and left unchecked. To check the consistency
+ * of the key material, see mbedtls_rsa_check_privkey().
+ *
+ * \param ctx The initialized RSA context holding imported parameters.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the attempted derivations
+ * failed.
+ *
+ */
+int mbedtls_rsa_complete( mbedtls_rsa_context *ctx );
+
+/**
+ * \brief This function exports the core parameters of an RSA key.
+ *
+ * If this function runs successfully, the non-NULL buffers
+ * pointed to by \p N, \p P, \p Q, \p D, and \p E are fully
+ * written, with additional unused space filled leading by
+ * zero Bytes.
+ *
+ * Possible reasons for returning
+ * #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:<ul>
+ * <li>An alternative RSA implementation is in use, which
+ * stores the key externally, and either cannot or should
+ * not export it into RAM.</li>
+ * <li>A SW or HW implementation might not support a certain
+ * deduction. For example, \p P, \p Q from \p N, \p D,
+ * and \p E if the former are not part of the
+ * implementation.</li></ul>
+ *
+ * If the function fails due to an unsupported operation,
+ * the RSA context stays intact and remains usable.
+ *
+ * \param ctx The initialized RSA context.
+ * \param N The MPI to hold the RSA modulus.
+ * This may be \c NULL if this field need not be exported.
+ * \param P The MPI to hold the first prime factor of \p N.
+ * This may be \c NULL if this field need not be exported.
+ * \param Q The MPI to hold the second prime factor of \p N.
+ * This may be \c NULL if this field need not be exported.
+ * \param D The MPI to hold the private exponent.
+ * This may be \c NULL if this field need not be exported.
+ * \param E The MPI to hold the public exponent.
+ * This may be \c NULL if this field need not be exported.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the
+ * requested parameters cannot be done due to missing
+ * functionality or because of security policies.
+ * \return A non-zero return code on any other failure.
+ *
+ */
+int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
+ mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
+ mbedtls_mpi *D, mbedtls_mpi *E );
+
+/**
+ * \brief This function exports core parameters of an RSA key
+ * in raw big-endian binary format.
+ *
+ * If this function runs successfully, the non-NULL buffers
+ * pointed to by \p N, \p P, \p Q, \p D, and \p E are fully
+ * written, with additional unused space filled leading by
+ * zero Bytes.
+ *
+ * Possible reasons for returning
+ * #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:<ul>
+ * <li>An alternative RSA implementation is in use, which
+ * stores the key externally, and either cannot or should
+ * not export it into RAM.</li>
+ * <li>A SW or HW implementation might not support a certain
+ * deduction. For example, \p P, \p Q from \p N, \p D,
+ * and \p E if the former are not part of the
+ * implementation.</li></ul>
+ * If the function fails due to an unsupported operation,
+ * the RSA context stays intact and remains usable.
+ *
+ * \note The length parameters are ignored if the corresponding
+ * buffer pointers are NULL.
+ *
+ * \param ctx The initialized RSA context.
+ * \param N The Byte array to store the RSA modulus,
+ * or \c NULL if this field need not be exported.
+ * \param N_len The size of the buffer for the modulus.
+ * \param P The Byte array to hold the first prime factor of \p N,
+ * or \c NULL if this field need not be exported.
+ * \param P_len The size of the buffer for the first prime factor.
+ * \param Q The Byte array to hold the second prime factor of \p N,
+ * or \c NULL if this field need not be exported.
+ * \param Q_len The size of the buffer for the second prime factor.
+ * \param D The Byte array to hold the private exponent,
+ * or \c NULL if this field need not be exported.
+ * \param D_len The size of the buffer for the private exponent.
+ * \param E The Byte array to hold the public exponent,
+ * or \c NULL if this field need not be exported.
+ * \param E_len The size of the buffer for the public exponent.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the
+ * requested parameters cannot be done due to missing
+ * functionality or because of security policies.
+ * \return A non-zero return code on any other failure.
+ */
+int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
+ unsigned char *N, size_t N_len,
+ unsigned char *P, size_t P_len,
+ unsigned char *Q, size_t Q_len,
+ unsigned char *D, size_t D_len,
+ unsigned char *E, size_t E_len );
+
+/**
+ * \brief This function exports CRT parameters of a private RSA key.
+ *
+ * \note Alternative RSA implementations not using CRT-parameters
+ * internally can implement this function based on
+ * mbedtls_rsa_deduce_opt().
+ *
+ * \param ctx The initialized RSA context.
+ * \param DP The MPI to hold \c D modulo `P-1`,
+ * or \c NULL if it need not be exported.
+ * \param DQ The MPI to hold \c D modulo `Q-1`,
+ * or \c NULL if it need not be exported.
+ * \param QP The MPI to hold modular inverse of \c Q modulo \c P,
+ * or \c NULL if it need not be exported.
+ *
+ * \return \c 0 on success.
+ * \return A non-zero error code on failure.
+ *
+ */
+int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
+ mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP );
+
+/**
+ * \brief This function retrieves the length of RSA modulus in Bytes.
+ *
+ * \param ctx The initialized RSA context.
+ *
+ * \return The length of the RSA modulus in Bytes.
+ *
+ */
+size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx );
+
+/**
+ * \brief This function generates an RSA keypair.
+ *
+ * \note mbedtls_rsa_init() must be called before this function,
+ * to set up the RSA context.
+ *
+ * \param ctx The initialized RSA context used to hold the key.
+ * \param f_rng The RNG function to be used for key generation.
+ * This is mandatory and must not be \c NULL.
+ * \param p_rng The RNG context to be passed to \p f_rng.
+ * This may be \c NULL if \p f_rng doesn't need a context.
+ * \param nbits The size of the public key in bits.
+ * \param exponent The public exponent to use. For example, \c 65537.
+ * This must be odd and greater than \c 1.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ unsigned int nbits, int exponent );
+
+/**
+ * \brief This function checks if a context contains at least an RSA
+ * public key.
+ *
+ * If the function runs successfully, it is guaranteed that
+ * enough information is present to perform an RSA public key
+ * operation using mbedtls_rsa_public().
+ *
+ * \param ctx The initialized RSA context to check.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ *
+ */
+int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx );
+
+/**
+ * \brief This function checks if a context contains an RSA private key
+ * and perform basic consistency checks.
+ *
+ * \note The consistency checks performed by this function not only
+ * ensure that mbedtls_rsa_private() can be called successfully
+ * on the given context, but that the various parameters are
+ * mutually consistent with high probability, in the sense that
+ * mbedtls_rsa_public() and mbedtls_rsa_private() are inverses.
+ *
+ * \warning This function should catch accidental misconfigurations
+ * like swapping of parameters, but it cannot establish full
+ * trust in neither the quality nor the consistency of the key
+ * material that was used to setup the given RSA context:
+ * <ul><li>Consistency: Imported parameters that are irrelevant
+ * for the implementation might be silently dropped. If dropped,
+ * the current function does not have access to them,
+ * and therefore cannot check them. See mbedtls_rsa_complete().
+ * If you want to check the consistency of the entire
+ * content of an PKCS1-encoded RSA private key, for example, you
+ * should use mbedtls_rsa_validate_params() before setting
+ * up the RSA context.
+ * Additionally, if the implementation performs empirical checks,
+ * these checks substantiate but do not guarantee consistency.</li>
+ * <li>Quality: This function is not expected to perform
+ * extended quality assessments like checking that the prime
+ * factors are safe. Additionally, it is the responsibility of the
+ * user to ensure the trustworthiness of the source of his RSA
+ * parameters, which goes beyond what is effectively checkable
+ * by the library.</li></ul>
+ *
+ * \param ctx The initialized RSA context to check.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx );
+
+/**
+ * \brief This function checks a public-private RSA key pair.
+ *
+ * It checks each of the contexts, and makes sure they match.
+ *
+ * \param pub The initialized RSA context holding the public key.
+ * \param prv The initialized RSA context holding the private key.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
+ const mbedtls_rsa_context *prv );
+
+/**
+ * \brief This function performs an RSA public key operation.
+ *
+ * \param ctx The initialized RSA context to use.
+ * \param input The input buffer. This must be a readable buffer
+ * of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus.
+ * \param output The output buffer. This must be a writable buffer
+ * of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus.
+ *
+ * \note This function does not handle message padding.
+ *
+ * \note Make sure to set \p input[0] = 0 or ensure that
+ * input is smaller than \p N.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function performs an RSA private key operation.
+ *
+ * \note Blinding is used if and only if a PRNG is provided.
+ *
+ * \note If blinding is used, both the base of exponentation
+ * and the exponent are blinded, providing protection
+ * against some side-channel attacks.
+ *
+ * \warning It is deprecated and a security risk to not provide
+ * a PRNG here and thereby prevent the use of blinding.
+ * Future versions of the library may enforce the presence
+ * of a PRNG.
+ *
+ * \param ctx The initialized RSA context to use.
+ * \param f_rng The RNG function, used for blinding. It is mandatory.
+ * \param p_rng The RNG context to pass to \p f_rng. This may be \c NULL
+ * if \p f_rng doesn't need a context.
+ * \param input The input buffer. This must be a readable buffer
+ * of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus.
+ * \param output The output buffer. This must be a writable buffer
+ * of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ *
+ */
+int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function adds the message padding, then performs an RSA
+ * operation.
+ *
+ * It is the generic wrapper for performing a PKCS#1 encryption
+ * operation.
+ *
+ * \param ctx The initialized RSA context to use.
+ * \param f_rng The RNG to use. It is used for padding generation
+ * and it is mandatory.
+ * \param p_rng The RNG context to be passed to \p f_rng. May be
+ * \c NULL if \p f_rng doesn't need a context argument.
+ * \param ilen The length of the plaintext in Bytes.
+ * \param input The input data to encrypt. This must be a readable
+ * buffer of size \p ilen Bytes. It may be \c NULL if
+ * `ilen == 0`.
+ * \param output The output buffer. This must be a writable buffer
+ * of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ size_t ilen,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function performs a PKCS#1 v1.5 encryption operation
+ * (RSAES-PKCS1-v1_5-ENCRYPT).
+ *
+ * \param ctx The initialized RSA context to use.
+ * \param f_rng The RNG function to use. It is mandatory and used for
+ * padding generation.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may
+ * be \c NULL if \p f_rng doesn't need a context argument.
+ * \param ilen The length of the plaintext in Bytes.
+ * \param input The input data to encrypt. This must be a readable
+ * buffer of size \p ilen Bytes. It may be \c NULL if
+ * `ilen == 0`.
+ * \param output The output buffer. This must be a writable buffer
+ * of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ size_t ilen,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function performs a PKCS#1 v2.1 OAEP encryption
+ * operation (RSAES-OAEP-ENCRYPT).
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \param ctx The initnialized RSA context to use.
+ * \param f_rng The RNG function to use. This is needed for padding
+ * generation and is mandatory.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may
+ * be \c NULL if \p f_rng doesn't need a context argument.
+ * \param label The buffer holding the custom label to use.
+ * This must be a readable buffer of length \p label_len
+ * Bytes. It may be \c NULL if \p label_len is \c 0.
+ * \param label_len The length of the label in Bytes.
+ * \param ilen The length of the plaintext buffer \p input in Bytes.
+ * \param input The input data to encrypt. This must be a readable
+ * buffer of size \p ilen Bytes. It may be \c NULL if
+ * `ilen == 0`.
+ * \param output The output buffer. This must be a writable buffer
+ * of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ const unsigned char *label, size_t label_len,
+ size_t ilen,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function performs an RSA operation, then removes the
+ * message padding.
+ *
+ * It is the generic wrapper for performing a PKCS#1 decryption
+ * operation.
+ *
+ * \note The output buffer length \c output_max_len should be
+ * as large as the size \p ctx->len of \p ctx->N (for example,
+ * 128 Bytes if RSA-1024 is used) to be able to hold an
+ * arbitrary decrypted message. If it is not large enough to
+ * hold the decryption of the particular ciphertext provided,
+ * the function returns \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
+ *
+ * \param ctx The initialized RSA context to use.
+ * \param f_rng The RNG function. This is used for blinding and is
+ * mandatory; see mbedtls_rsa_private() for more.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be
+ * \c NULL if \p f_rng doesn't need a context.
+ * \param olen The address at which to store the length of
+ * the plaintext. This must not be \c NULL.
+ * \param input The ciphertext buffer. This must be a readable buffer
+ * of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus.
+ * \param output The buffer used to hold the plaintext. This must
+ * be a writable buffer of length \p output_max_len Bytes.
+ * \param output_max_len The length in Bytes of the output buffer \p output.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len );
+
+/**
+ * \brief This function performs a PKCS#1 v1.5 decryption
+ * operation (RSAES-PKCS1-v1_5-DECRYPT).
+ *
+ * \note The output buffer length \c output_max_len should be
+ * as large as the size \p ctx->len of \p ctx->N, for example,
+ * 128 Bytes if RSA-1024 is used, to be able to hold an
+ * arbitrary decrypted message. If it is not large enough to
+ * hold the decryption of the particular ciphertext provided,
+ * the function returns #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
+ *
+ * \param ctx The initialized RSA context to use.
+ * \param f_rng The RNG function. This is used for blinding and is
+ * mandatory; see mbedtls_rsa_private() for more.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be
+ * \c NULL if \p f_rng doesn't need a context.
+ * \param olen The address at which to store the length of
+ * the plaintext. This must not be \c NULL.
+ * \param input The ciphertext buffer. This must be a readable buffer
+ * of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus.
+ * \param output The buffer used to hold the plaintext. This must
+ * be a writable buffer of length \p output_max_len Bytes.
+ * \param output_max_len The length in Bytes of the output buffer \p output.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ *
+ */
+int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len );
+
+/**
+ * \brief This function performs a PKCS#1 v2.1 OAEP decryption
+ * operation (RSAES-OAEP-DECRYPT).
+ *
+ * \note The output buffer length \c output_max_len should be
+ * as large as the size \p ctx->len of \p ctx->N, for
+ * example, 128 Bytes if RSA-1024 is used, to be able to
+ * hold an arbitrary decrypted message. If it is not
+ * large enough to hold the decryption of the particular
+ * ciphertext provided, the function returns
+ * #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
+ *
+ * \param ctx The initialized RSA context to use.
+ * \param f_rng The RNG function. This is used for blinding and is
+ * mandatory.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be
+ * \c NULL if \p f_rng doesn't need a context.
+ * \param label The buffer holding the custom label to use.
+ * This must be a readable buffer of length \p label_len
+ * Bytes. It may be \c NULL if \p label_len is \c 0.
+ * \param label_len The length of the label in Bytes.
+ * \param olen The address at which to store the length of
+ * the plaintext. This must not be \c NULL.
+ * \param input The ciphertext buffer. This must be a readable buffer
+ * of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus.
+ * \param output The buffer used to hold the plaintext. This must
+ * be a writable buffer of length \p output_max_len Bytes.
+ * \param output_max_len The length in Bytes of the output buffer \p output.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ const unsigned char *label, size_t label_len,
+ size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len );
+
+/**
+ * \brief This function performs a private RSA operation to sign
+ * a message digest using PKCS#1.
+ *
+ * It is the generic wrapper for performing a PKCS#1
+ * signature.
+ *
+ * \note The \p sig buffer must be as large as the size
+ * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \note For PKCS#1 v2.1 encoding, see comments on
+ * mbedtls_rsa_rsassa_pss_sign() for details on
+ * \p md_alg and \p hash_id.
+ *
+ * \param ctx The initialized RSA context to use.
+ * \param f_rng The RNG function to use. This is mandatory and
+ * must not be \c NULL.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL
+ * if \p f_rng doesn't need a context argument.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest or raw data in Bytes.
+ * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ * output length of the corresponding hash algorithm.
+ * \param hash The buffer holding the message digest or raw data.
+ * This must be a readable buffer of at least \p hashlen Bytes.
+ * \param sig The buffer to hold the signature. This must be a writable
+ * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus. A buffer length of
+ * #MBEDTLS_MPI_MAX_SIZE is always safe.
+ *
+ * \return \c 0 if the signing operation was successful.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief This function performs a PKCS#1 v1.5 signature
+ * operation (RSASSA-PKCS1-v1_5-SIGN).
+ *
+ * \param ctx The initialized RSA context to use.
+ * \param f_rng The RNG function. This is used for blinding and is
+ * mandatory; see mbedtls_rsa_private() for more.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL
+ * if \p f_rng doesn't need a context argument.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest or raw data in Bytes.
+ * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ * output length of the corresponding hash algorithm.
+ * \param hash The buffer holding the message digest or raw data.
+ * This must be a readable buffer of at least \p hashlen Bytes.
+ * \param sig The buffer to hold the signature. This must be a writable
+ * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus. A buffer length of
+ * #MBEDTLS_MPI_MAX_SIZE is always safe.
+ *
+ * \return \c 0 if the signing operation was successful.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief This function performs a PKCS#1 v2.1 PSS signature
+ * operation (RSASSA-PSS-SIGN).
+ *
+ * \note The \c hash_id set in \p ctx by calling
+ * mbedtls_rsa_set_padding() selects the hash used for the
+ * encoding operation and for the mask generation function
+ * (MGF1). For more details on the encoding operation and the
+ * mask generation function, consult <em>RFC-3447: Public-Key
+ * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
+ * Specifications</em>.
+ *
+ * \note This function enforces that the provided salt length complies
+ * with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1 v2.2) §9.1.1
+ * step 3. The constraint is that the hash length plus the salt
+ * length plus 2 bytes must be at most the key length. If this
+ * constraint is not met, this function returns
+ * #MBEDTLS_ERR_RSA_BAD_INPUT_DATA.
+ *
+ * \param ctx The initialized RSA context to use.
+ * \param f_rng The RNG function. It is mandatory and must not be \c NULL.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL
+ * if \p f_rng doesn't need a context argument.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest or raw data in Bytes.
+ * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ * output length of the corresponding hash algorithm.
+ * \param hash The buffer holding the message digest or raw data.
+ * This must be a readable buffer of at least \p hashlen Bytes.
+ * \param saltlen The length of the salt that should be used.
+ * If passed #MBEDTLS_RSA_SALT_LEN_ANY, the function will use
+ * the largest possible salt length up to the hash length,
+ * which is the largest permitted by some standards including
+ * FIPS 186-4 §5.5.
+ * \param sig The buffer to hold the signature. This must be a writable
+ * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus. A buffer length of
+ * #MBEDTLS_MPI_MAX_SIZE is always safe.
+ *
+ * \return \c 0 if the signing operation was successful.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsassa_pss_sign_ext( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ int saltlen,
+ unsigned char *sig );
+
+/**
+ * \brief This function performs a PKCS#1 v2.1 PSS signature
+ * operation (RSASSA-PSS-SIGN).
+ *
+ * \note The \c hash_id set in \p ctx by calling
+ * mbedtls_rsa_set_padding() selects the hash used for the
+ * encoding operation and for the mask generation function
+ * (MGF1). For more details on the encoding operation and the
+ * mask generation function, consult <em>RFC-3447: Public-Key
+ * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
+ * Specifications</em>.
+ *
+ * \note This function always uses the maximum possible salt size,
+ * up to the length of the payload hash. This choice of salt
+ * size complies with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1
+ * v2.2) §9.1.1 step 3. Furthermore this function enforces a
+ * minimum salt size which is the hash size minus 2 bytes. If
+ * this minimum size is too large given the key size (the salt
+ * size, plus the hash size, plus 2 bytes must be no more than
+ * the key size in bytes), this function returns
+ * #MBEDTLS_ERR_RSA_BAD_INPUT_DATA.
+ *
+ * \param ctx The initialized RSA context to use.
+ * \param f_rng The RNG function. It is mandatory and must not be \c NULL.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL
+ * if \p f_rng doesn't need a context argument.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest or raw data in Bytes.
+ * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ * output length of the corresponding hash algorithm.
+ * \param hash The buffer holding the message digest or raw data.
+ * This must be a readable buffer of at least \p hashlen Bytes.
+ * \param sig The buffer to hold the signature. This must be a writable
+ * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus. A buffer length of
+ * #MBEDTLS_MPI_MAX_SIZE is always safe.
+ *
+ * \return \c 0 if the signing operation was successful.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief This function performs a public RSA operation and checks
+ * the message digest.
+ *
+ * This is the generic wrapper for performing a PKCS#1
+ * verification.
+ *
+ * \note For PKCS#1 v2.1 encoding, see comments on
+ * mbedtls_rsa_rsassa_pss_verify() about \p md_alg and
+ * \p hash_id.
+ *
+ * \param ctx The initialized RSA public key context to use.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest or raw data in Bytes.
+ * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ * output length of the corresponding hash algorithm.
+ * \param hash The buffer holding the message digest or raw data.
+ * This must be a readable buffer of at least \p hashlen Bytes.
+ * \param sig The buffer holding the signature. This must be a readable
+ * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus.
+ *
+ * \return \c 0 if the verify operation was successful.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ const unsigned char *sig );
+
+/**
+ * \brief This function performs a PKCS#1 v1.5 verification
+ * operation (RSASSA-PKCS1-v1_5-VERIFY).
+ *
+ * \param ctx The initialized RSA public key context to use.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest or raw data in Bytes.
+ * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ * output length of the corresponding hash algorithm.
+ * \param hash The buffer holding the message digest or raw data.
+ * This must be a readable buffer of at least \p hashlen Bytes.
+ * \param sig The buffer holding the signature. This must be a readable
+ * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus.
+ *
+ * \return \c 0 if the verify operation was successful.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ const unsigned char *sig );
+
+/**
+ * \brief This function performs a PKCS#1 v2.1 PSS verification
+ * operation (RSASSA-PSS-VERIFY).
+ *
+ * \note The \c hash_id set in \p ctx by calling
+ * mbedtls_rsa_set_padding() selects the hash used for the
+ * encoding operation and for the mask generation function
+ * (MGF1). For more details on the encoding operation and the
+ * mask generation function, consult <em>RFC-3447: Public-Key
+ * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
+ * Specifications</em>. If the \c hash_id set in \p ctx by
+ * mbedtls_rsa_set_padding() is #MBEDTLS_MD_NONE, the \p md_alg
+ * parameter is used.
+ *
+ * \param ctx The initialized RSA public key context to use.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest or raw data in Bytes.
+ * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ * output length of the corresponding hash algorithm.
+ * \param hash The buffer holding the message digest or raw data.
+ * This must be a readable buffer of at least \p hashlen Bytes.
+ * \param sig The buffer holding the signature. This must be a readable
+ * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus.
+ *
+ * \return \c 0 if the verify operation was successful.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ const unsigned char *sig );
+
+/**
+ * \brief This function performs a PKCS#1 v2.1 PSS verification
+ * operation (RSASSA-PSS-VERIFY).
+ *
+ * \note The \p sig buffer must be as large as the size
+ * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \note The \c hash_id set in \p ctx by mbedtls_rsa_set_padding() is
+ * ignored.
+ *
+ * \param ctx The initialized RSA public key context to use.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest or raw data in Bytes.
+ * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ * output length of the corresponding hash algorithm.
+ * \param hash The buffer holding the message digest or raw data.
+ * This must be a readable buffer of at least \p hashlen Bytes.
+ * \param mgf1_hash_id The message digest algorithm used for the
+ * verification operation and the mask generation
+ * function (MGF1). For more details on the encoding
+ * operation and the mask generation function, consult
+ * <em>RFC-3447: Public-Key Cryptography Standards
+ * (PKCS) #1 v2.1: RSA Cryptography
+ * Specifications</em>.
+ * \param expected_salt_len The length of the salt used in padding. Use
+ * #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length.
+ * \param sig The buffer holding the signature. This must be a readable
+ * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus.
+ *
+ * \return \c 0 if the verify operation was successful.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ mbedtls_md_type_t mgf1_hash_id,
+ int expected_salt_len,
+ const unsigned char *sig );
+
+/**
+ * \brief This function copies the components of an RSA context.
+ *
+ * \param dst The destination context. This must be initialized.
+ * \param src The source context. This must be initialized.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure.
+ */
+int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src );
+
+/**
+ * \brief This function frees the components of an RSA key.
+ *
+ * \param ctx The RSA context to free. May be \c NULL, in which case
+ * this function is a no-op. If it is not \c NULL, it must
+ * point to an initialized RSA context.
+ */
+void mbedtls_rsa_free( mbedtls_rsa_context *ctx );
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief The RSA checkup routine.
+ *
+ * \return \c 0 on success.
+ * \return \c 1 on failure.
+ */
+int mbedtls_rsa_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* rsa.h */
diff --git a/ext/mbedtls-asn1/include/mbedtls/threading.h b/ext/mbedtls-asn1/include/mbedtls/threading.h
index 92e6e6b..96cadc4 100644
--- a/ext/mbedtls-asn1/include/mbedtls/threading.h
+++ b/ext/mbedtls-asn1/include/mbedtls/threading.h
@@ -4,7 +4,7 @@
* \brief Threading abstraction layer
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,17 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_THREADING_H
#define MBEDTLS_THREADING_H
+#include "mbedtls/private_access.h"
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
#include <stdlib.h>
@@ -36,10 +31,6 @@
extern "C" {
#endif
-/* MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE is deprecated and should not be
- * used. */
-#define MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE -0x001A /**< The selected feature is not available. */
-
#define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA -0x001C /**< Bad input parameters to function. */
#define MBEDTLS_ERR_THREADING_MUTEX_ERROR -0x001E /**< Locking / unlocking / free failed with error code. */
@@ -47,8 +38,11 @@
#include <pthread.h>
typedef struct mbedtls_threading_mutex_t
{
- pthread_mutex_t mutex;
- char is_valid;
+ pthread_mutex_t MBEDTLS_PRIVATE(mutex);
+ /* is_valid is 0 after a failed init or a free, and nonzero after a
+ * successful init. This field is not considered part of the public
+ * API of Mbed TLS and may change without notice. */
+ char MBEDTLS_PRIVATE(is_valid);
} mbedtls_threading_mutex_t;
#endif
diff --git a/ext/mbedtls-asn1/src/asn1parse.c b/ext/mbedtls-asn1/src/asn1parse.c
index 171c340..83c7c58 100644
--- a/ext/mbedtls-asn1/src/asn1parse.c
+++ b/ext/mbedtls-asn1/src/asn1parse.c
@@ -1,7 +1,7 @@
/*
* Generic ASN.1 parsing
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -15,20 +15,15 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ASN1_PARSE_C)
#include "mbedtls/asn1.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -124,7 +119,7 @@
const unsigned char *end,
int *val )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 )
@@ -139,21 +134,41 @@
return( 0 );
}
-int mbedtls_asn1_get_int( unsigned char **p,
- const unsigned char *end,
- int *val )
+static int asn1_get_tagged_int( unsigned char **p,
+ const unsigned char *end,
+ int tag, int *val )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
+ if( ( ret = mbedtls_asn1_get_tag( p, end, &len, tag ) ) != 0 )
return( ret );
- if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 )
+ /*
+ * len==0 is malformed (0 must be represented as 020100 for INTEGER,
+ * or 0A0100 for ENUMERATED tags
+ */
+ if( len == 0 )
+ return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+ /* This is a cryptography library. Reject negative integers. */
+ if( ( **p & 0x80 ) != 0 )
+ return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+
+ /* Skip leading zeros. */
+ while( len > 0 && **p == 0 )
+ {
+ ++( *p );
+ --len;
+ }
+
+ /* Reject integers that don't fit in an int. This code assumes that
+ * the int type has no padding bit. */
+ if( len > sizeof( int ) )
+ return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+ if( len == sizeof( int ) && ( **p & 0x80 ) != 0 )
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
*val = 0;
-
while( len-- > 0 )
{
*val = ( *val << 8 ) | **p;
@@ -163,12 +178,26 @@
return( 0 );
}
+int mbedtls_asn1_get_int( unsigned char **p,
+ const unsigned char *end,
+ int *val )
+{
+ return( asn1_get_tagged_int( p, end, MBEDTLS_ASN1_INTEGER, val) );
+}
+
+int mbedtls_asn1_get_enum( unsigned char **p,
+ const unsigned char *end,
+ int *val )
+{
+ return( asn1_get_tagged_int( p, end, MBEDTLS_ASN1_ENUMERATED, val) );
+}
+
#if defined(MBEDTLS_BIGNUM_C)
int mbedtls_asn1_get_mpi( unsigned char **p,
const unsigned char *end,
mbedtls_mpi *X )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
@@ -185,7 +214,7 @@
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
mbedtls_asn1_bitstring *bs)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* Certificate type is a single byte bitstring */
if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
@@ -213,23 +242,124 @@
}
/*
+ * Traverse an ASN.1 "SEQUENCE OF <tag>"
+ * and call a callback for each entry found.
+ */
+int mbedtls_asn1_traverse_sequence_of(
+ unsigned char **p,
+ const unsigned char *end,
+ unsigned char tag_must_mask, unsigned char tag_must_val,
+ unsigned char tag_may_mask, unsigned char tag_may_val,
+ int (*cb)( void *ctx, int tag,
+ unsigned char *start, size_t len ),
+ void *ctx )
+{
+ int ret;
+ size_t len;
+
+ /* Get main sequence tag */
+ if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( *p + len != end )
+ return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+ while( *p < end )
+ {
+ unsigned char const tag = *(*p)++;
+
+ if( ( tag & tag_must_mask ) != tag_must_val )
+ return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+
+ if( ( ret = mbedtls_asn1_get_len( p, end, &len ) ) != 0 )
+ return( ret );
+
+ if( ( tag & tag_may_mask ) == tag_may_val )
+ {
+ if( cb != NULL )
+ {
+ ret = cb( ctx, tag, *p, len );
+ if( ret != 0 )
+ return( ret );
+ }
+ }
+
+ *p += len;
+ }
+
+ return( 0 );
+}
+
+/*
* Get a bit string without unused bits
*/
int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
size_t *len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
return( ret );
- if( (*len)-- < 2 || *(*p)++ != 0 )
+ if( *len == 0 )
return( MBEDTLS_ERR_ASN1_INVALID_DATA );
+ --( *len );
+
+ if( **p != 0 )
+ return( MBEDTLS_ERR_ASN1_INVALID_DATA );
+ ++( *p );
return( 0 );
}
+void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq )
+{
+ while( seq != NULL )
+ {
+ mbedtls_asn1_sequence *next = seq->next;
+ mbedtls_platform_zeroize( seq, sizeof( *seq ) );
+ mbedtls_free( seq );
+ seq = next;
+ }
+}
+typedef struct
+{
+ int tag;
+ mbedtls_asn1_sequence *cur;
+} asn1_get_sequence_of_cb_ctx_t;
+
+static int asn1_get_sequence_of_cb( void *ctx,
+ int tag,
+ unsigned char *start,
+ size_t len )
+{
+ asn1_get_sequence_of_cb_ctx_t *cb_ctx =
+ (asn1_get_sequence_of_cb_ctx_t *) ctx;
+ mbedtls_asn1_sequence *cur =
+ cb_ctx->cur;
+
+ if( cur->buf.p != NULL )
+ {
+ cur->next =
+ mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
+
+ if( cur->next == NULL )
+ return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
+
+ cur = cur->next;
+ }
+
+ cur->buf.p = start;
+ cur->buf.len = len;
+ cur->buf.tag = tag;
+
+ cb_ctx->cur = cur;
+ return( 0 );
+}
/*
* Parses and splits an ASN.1 "SEQUENCE OF <tag>"
@@ -239,56 +369,18 @@
mbedtls_asn1_sequence *cur,
int tag)
{
- int ret;
- size_t len;
- mbedtls_asn1_buf *buf;
-
- /* Get main sequence tag */
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( ret );
-
- if( *p + len != end )
- return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
-
- while( *p < end )
- {
- buf = &(cur->buf);
- buf->tag = **p;
-
- if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
- return( ret );
-
- buf->p = *p;
- *p += buf->len;
-
- /* Allocate and assign next pointer */
- if( *p < end )
- {
- cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1,
- sizeof( mbedtls_asn1_sequence ) );
-
- if( cur->next == NULL )
- return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
-
- cur = cur->next;
- }
- }
-
- /* Set final sequence entry's next pointer to NULL */
- cur->next = NULL;
-
- if( *p != end )
- return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
-
- return( 0 );
+ asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
+ memset( cur, 0, sizeof( mbedtls_asn1_sequence ) );
+ return( mbedtls_asn1_traverse_sequence_of(
+ p, end, 0xFF, tag, 0, 0,
+ asn1_get_sequence_of_cb, &cb_ctx ) );
}
int mbedtls_asn1_get_alg( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
@@ -332,7 +424,7 @@
const unsigned char *end,
mbedtls_asn1_buf *alg )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_asn1_buf params;
memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) );
@@ -369,7 +461,7 @@
}
}
-mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
+const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( const mbedtls_asn1_named_data *list,
const char *oid, size_t len )
{
while( list != NULL )
diff --git a/ext/mbedtls-asn1/src/platform_util.c b/ext/mbedtls-asn1/src/platform_util.c
index ca5fe4f..4e97e4d 100644
--- a/ext/mbedtls-asn1/src/platform_util.c
+++ b/ext/mbedtls-asn1/src/platform_util.c
@@ -2,7 +2,7 @@
* Common and shared functions used by multiple modules in the Mbed TLS
* library.
*
- * Copyright (C) 2018, Arm Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -16,25 +16,20 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
/*
* Ensure gmtime_r is available even with -std=c99; must be defined before
- * config.h, which pulls in glibc's features.h. Harmless on other platforms.
+ * mbedtls_config.h, which pulls in glibc's features.h. Harmless on other platforms.
*/
#if !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 200112L
#endif
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/platform.h"
#include "mbedtls/threading.h"
#include <stddef.h>
@@ -71,7 +66,10 @@
void mbedtls_platform_zeroize( void *buf, size_t len )
{
- memset_func( buf, 0, len );
+ MBEDTLS_INTERNAL_VALIDATE( len == 0 || buf != NULL );
+
+ if( len > 0 )
+ memset_func( buf, 0, len );
}
#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
@@ -86,7 +84,7 @@
#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
- _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
+ _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) )
/*
* This is a convenience shorthand macro to avoid checking the long
* preprocessor conditions above. Ideally, we could expose this macro in
@@ -100,7 +98,7 @@
#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
- _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */
+ _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */
struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
struct tm *tm_buf )
diff --git a/repository.yml b/repository.yml
index 925ede3..495f71a 100644
--- a/repository.yml
+++ b/repository.yml
@@ -20,7 +20,7 @@
repo.name: mcuboot
repo.submodules: ""
repo.versions:
- "0.0.0": "master"
+ "0.0.0": "main"
"0.9.0": "v0.9.0"
"1.0.0": "v1.0.0"
"1.1.0": "v1.1.0"
@@ -33,9 +33,10 @@
"1.7.0": "v1.7.0"
"1.7.1": "v1.7.1"
"1.7.2": "v1.7.2"
+ "1.8.0": "v1.8.0"
- "0-dev": "0.0.0" # master
- "0-latest": "1.7.2" # latest stable release
- "1-latest": "1.7.2" # latest stable release
+ "0-dev": "0.0.0" # main
+ "0-latest": "1.8.0" # latest stable release
+ "1-latest": "1.8.0" # latest stable release
- "1.0-latest": "1.7.2"
+ "1.0-latest": "1.8.0"
diff --git a/samples/mcuboot_config/mcuboot_config.template.h b/samples/mcuboot_config/mcuboot_config.template.h
index 2125792..989ec61 100644
--- a/samples/mcuboot_config/mcuboot_config.template.h
+++ b/samples/mcuboot_config/mcuboot_config.template.h
@@ -146,4 +146,14 @@
* do { do watchdog feeding here! } while (0)
*/
+/* If a OS ports support single thread mode or is bare-metal then:
+ * This macro implements call that switches CPU to an idle state, from which
+ * the CPU may be woken up by, for example, UART transmission event.
+ *
+ * Otherwise this macro should be no-op.
+ */
+#define MCUBOOT_CPU_IDLE() \
+ do { \
+ } while (0)
+
#endif /* __MCUBOOT_CONFIG_H__ */
diff --git a/scripts/assemble.py b/scripts/assemble.py
index 5ef403f..0f39fcc 100755
--- a/scripts/assemble.py
+++ b/scripts/assemble.py
@@ -127,14 +127,14 @@
print('Need to either have ZEPHYR_BASE in environment or pass in -z')
sys.exit(1)
- sys.path.insert(0, os.path.join(zephyr_base, "scripts", "dts"))
- import edtlib
+ sys.path.insert(0, os.path.join(zephyr_base, "scripts", "dts", "python-devicetree", "src"))
+ import devicetree.edtlib
board = find_board_name(args.bootdir)
dts_path = os.path.join(args.bootdir, "zephyr", board + ".dts.pre.tmp")
- edt = edtlib.EDT(dts_path, [os.path.join(zephyr_base, "dts", "bindings")],
+ edt = devicetree.edtlib.EDT(dts_path, [os.path.join(zephyr_base, "dts", "bindings")],
warn_reg_unit_address_mismatch=False)
output = Assembly(args.output, args.bootdir, edt)
diff --git a/scripts/imgtool/__init__.py b/scripts/imgtool/__init__.py
index 4f19399..ca43b8d 100644
--- a/scripts/imgtool/__init__.py
+++ b/scripts/imgtool/__init__.py
@@ -14,4 +14,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-imgtool_version = "1.7.0"
+imgtool_version = "1.8.0"
diff --git a/scripts/imgtool/encrypt_mxs40sv2.py b/scripts/imgtool/encrypt_mxs40sv2.py
new file mode 100644
index 0000000..f95a3a5
--- /dev/null
+++ b/scripts/imgtool/encrypt_mxs40sv2.py
@@ -0,0 +1,110 @@
+"""
+Copyright (c) 2021 Cypress Semiconductor Corporation
+
+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.
+"""
+import os
+import struct
+from cryptography.hazmat.primitives.ciphers import (
+ Cipher, algorithms, modes
+)
+
+NONCE_SIZE = 12
+
+class EncryptorMXS40Sv2:
+ def __init__(self, key, nonce, initial_counter=0):
+ # with open(key_path, 'rb') as f:
+ # self.key = f.read()
+ self.key = key
+ self.nonce = nonce
+ self.counter = 0
+ self.initial_counter = initial_counter
+ cipher = Cipher(algorithms.AES(key), modes.ECB())
+ self.encryptor = cipher.encryptor()
+
+ def _load(self, image_path):
+ with open(image_path, 'rb') as f:
+ image = f.read()
+ return image
+
+ def _save(self, data, output_path):
+ with open(output_path, 'wb') as f:
+ f.write(data)
+
+ def update(self, data):
+ """
+ Encrypts a byte array using a customized AES-CTR mode
+ where a counter is incremented by 16 per block.
+ A nonce format is (128 bit):
+ bits 0...31 - counter + initial values
+ bits 32...127 - random nonce
+ """
+ chunk_size = 16
+ counter = self.counter
+ ciphertext = bytes()
+ for i in range(0, len(image), chunk_size):
+ indata = struct.pack('<I', initial_counter + counter) + nonce
+ counter += chunk_size
+ cipher_block = self.encryptor.update(indata)
+ chunk = image[i:i + chunk_size]
+ ciphertext += bytes(a ^ b for a, b in zip(chunk, cipher_block))
+ self.counter = counter
+ return ciphertext
+
+ def encrypt(self, image, initial_counter=0):
+ """
+ Encrypts a byte array using a customized AES-CTR mode
+ where a counter is incremented by 16 per block.
+ A nonce format is (128 bit):
+ bits 0...31 - counter + initial values
+ bits 32...127 - random nonce
+ """
+ chunk_size = 16
+ counter = 0
+ # self.initial_counter = initial_counter
+ # counter = 0 if initial_counter is None else int(initial_counter, 0)
+ # counter = initial_counter
+ ciphertext = bytes()
+ for i in range(0, len(image), chunk_size):
+ indata = struct.pack('<I', initial_counter + counter) + self.nonce[:12]
+ counter += chunk_size
+ cipher_block = self.encryptor.update(indata)
+ chunk = image[i:i + chunk_size]
+ ciphertext += bytes(a ^ b for a, b in zip(chunk, cipher_block))
+ self.encryptor.finalize()
+ # return ciphertext, nonce
+ return ciphertext
+
+ def encrypt_image(self, input_path, initial_counter=None, output_path=None, nonce_path=None):
+ """
+ Encrypts an image each time using new random nonce.
+ Saves the nonce and the encrypted image to specified locations.
+ If the output locations are not given the output files are saved
+ in the same location as the input image with predefined names.
+ """
+ image = self._load(input_path)
+
+ nonce = os.urandom(NONCE_SIZE)
+ init = 0 if initial_counter is None else int(initial_counter, 0)
+ ciphertext, nonce = self._encrypt(image, nonce, init)
+
+ if output_path is None:
+ output_path = '{0}_{2}{1}'.format(*os.path.splitext(input_path) + ('encrypted',))
+
+ if nonce_path is None:
+ nonce_path = '{0}_{2}{1}'.format(*os.path.splitext(input_path) + ('nonce',))
+
+ self._save(ciphertext, output_path)
+ self._save(nonce, nonce_path)
+
+ return output_path, nonce_path
diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py
index ec18fa5..2a5eb59 100644
--- a/scripts/imgtool/image.py
+++ b/scripts/imgtool/image.py
@@ -1,6 +1,6 @@
# Copyright 2018 Nordic Semiconductor ASA
# Copyright 2017-2020 Linaro Limited
-# Copyright 2019-2020 Arm Limited
+# Copyright 2019-2021 Arm Limited
#
# SPDX-License-Identifier: Apache-2.0
#
@@ -51,7 +51,8 @@
# Image header flags.
IMAGE_F = {
'PIC': 0x0000001,
- 'ENCRYPTED': 0x0000004,
+ 'ENCRYPTED_AES128': 0x0000004,
+ 'ENCRYPTED_AES256': 0x0000008,
'NON_BOOTABLE': 0x0000010,
'RAM_LOAD': 0x0000020,
'ROM_FIXED': 0x0000100,
@@ -67,7 +68,7 @@
'RSA3072': 0x23,
'ED25519': 0x24,
'ENCRSA2048': 0x30,
- 'ENCKW128': 0x31,
+ 'ENCKW': 0x31,
'ENCEC256': 0x32,
'ENCX25519': 0x33,
'DEPENDENCY': 0x40,
@@ -296,7 +297,7 @@
return cipherkey, ciphermac, pubk
def create(self, key, public_key_format, enckey, dependencies=None,
- sw_type=None, custom_tlvs=None, use_random_iv=False):
+ sw_type=None, custom_tlvs=None, encrypt_keylen=128, use_random_iv=False):
self.enckey = enckey
if use_random_iv:
@@ -373,7 +374,10 @@
self.payload.extend(pad)
# This adds the header to the payload as well
- self.add_header(enckey, protected_tlv_size)
+ if encrypt_keylen == 256:
+ self.add_header(enckey, protected_tlv_size, 256)
+ else:
+ self.add_header(enckey, protected_tlv_size)
prot_tlv = TLV(self.endian, TLV_PROT_INFO_MAGIC)
@@ -441,7 +445,10 @@
self.payload = self.payload[:protected_tlv_off]
if enckey is not None:
- plainkey = os.urandom(16)
+ if encrypt_keylen == 256:
+ plainkey = os.urandom(32)
+ else:
+ plainkey = os.urandom(16)
if isinstance(enckey, rsa.RSAPublic):
cipherkey = enckey._get_public().encrypt(
@@ -476,12 +483,15 @@
self.check_trailer()
- def add_header(self, enckey, protected_tlv_size):
+ def add_header(self, enckey, protected_tlv_size, aes_length=128):
"""Install the image header."""
flags = 0
if enckey is not None:
- flags |= IMAGE_F['ENCRYPTED']
+ if aes_length == 128:
+ flags |= IMAGE_F['ENCRYPTED_AES128']
+ else:
+ flags |= IMAGE_F['ENCRYPTED_AES256']
if self.load_addr != 0:
# Indicates that this image should be loaded into RAM
# instead of run directly from flash.
diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py
index 53f4d98..941c096 100755
--- a/scripts/imgtool/main.py
+++ b/scripts/imgtool/main.py
@@ -1,7 +1,7 @@
#! /usr/bin/env python3
#
# Copyright 2017-2020 Linaro Limited
-# Copyright 2019-2020 Arm Limited
+# Copyright 2019-2021 Arm Limited
#
# SPDX-License-Identifier: Apache-2.0
#
@@ -250,6 +250,10 @@
@click.option('-E', '--encrypt', metavar='filename',
help='Encrypt image using the provided public key. '
'(Not supported in direct-xip or ram-load mode.)')
+@click.option('--encrypt-keylen', default='128',
+ type=click.Choice(['128','256']),
+ help='When encrypting the image using AES, select a 128 bit or '
+ '256 bit key len.')
@click.option('-e', '--endian', type=click.Choice(['little', 'big']),
default='little', help="Select little or big endian")
@click.option('--overwrite-only', default=False, is_flag=True,
@@ -298,9 +302,9 @@
.hex extension, otherwise binary format is used''')
def sign(key, public_key_format, align, version, pad_sig, header_size,
pad_header, slot_size, pad, confirm, max_sectors, overwrite_only,
- endian, encrypt, infile, outfile, dependencies, load_addr, hex_addr,
- erased_val, save_enctlv, security_counter, boot_record, custom_tlv,
- rom_fixed, use_random_iv):
+ endian, encrypt_keylen, encrypt, infile, outfile, dependencies,
+ load_addr, hex_addr, erased_val, save_enctlv, security_counter,
+ boot_record, custom_tlv, rom_fixed, use_random_iv):
if confirm:
# Confirmed but non-padded images don't make much sense, because
@@ -347,7 +351,7 @@
custom_tlvs[tag] = value.encode('utf-8')
img.create(key, public_key_format, enckey, dependencies, boot_record,
- custom_tlvs, use_random_iv=use_random_iv)
+ custom_tlvs, int(encrypt_keylen), use_random_iv=use_random_iv)
img.save(outfile, hex_addr)
diff --git a/sim/Cargo.lock b/sim/Cargo.lock
deleted file mode 100644
index 11aaec7..0000000
--- a/sim/Cargo.lock
+++ /dev/null
@@ -1,667 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-[[package]]
-name = "aes-ctr"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92e60aeefd2a0243bd53a42e92444e039f67c3d7f0382c9813577696e7c10bf3"
-dependencies = [
- "aes-soft",
- "aesni",
- "ctr",
- "stream-cipher",
-]
-
-[[package]]
-name = "aes-soft"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4925647ee64e5056cf231608957ce7c81e12d6d6e316b9ce1404778cc1d35fa7"
-dependencies = [
- "block-cipher",
- "byteorder",
- "opaque-debug",
-]
-
-[[package]]
-name = "aesni"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d050d39b0b7688b3a3254394c3e30a9d66c41dcf9b05b0e2dbdc623f6505d264"
-dependencies = [
- "block-cipher",
- "opaque-debug",
- "stream-cipher",
-]
-
-[[package]]
-name = "aho-corasick"
-version = "0.7.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "743ad5a418686aad3b87fd14c43badd828cf26e214a00f92a384291cf22e1811"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "anyhow"
-version = "1.0.26"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c"
-
-[[package]]
-name = "atty"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
-dependencies = [
- "hermit-abi",
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "base64"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
-
-[[package]]
-name = "block-cipher"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa136449e765dc7faa244561ccae839c394048667929af599b5d931ebe7b7f10"
-dependencies = [
- "generic-array",
-]
-
-[[package]]
-name = "bootsim"
-version = "0.1.0"
-dependencies = [
- "aes-ctr",
- "base64",
- "byteorder",
- "docopt",
- "env_logger",
- "libc",
- "log",
- "mcuboot-sys",
- "pem",
- "rand",
- "ring",
- "serde",
- "serde_derive",
- "simflash",
- "untrusted",
-]
-
-[[package]]
-name = "bumpalo"
-version = "3.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f359dc14ff8911330a51ef78022d376f25ed00248912803b58f00cb1c27f742"
-
-[[package]]
-name = "byteorder"
-version = "1.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
-
-[[package]]
-name = "cc"
-version = "1.0.50"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
-
-[[package]]
-name = "cfg-if"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
-
-[[package]]
-name = "ctr"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3592740fd55aaf61dd72df96756bd0d11e6037b89dcf30ae2e1895b267692be"
-dependencies = [
- "stream-cipher",
-]
-
-[[package]]
-name = "docopt"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f525a586d310c87df72ebcd98009e57f1cc030c8c268305287a476beb653969"
-dependencies = [
- "lazy_static",
- "regex",
- "serde",
- "strsim",
-]
-
-[[package]]
-name = "env_logger"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
-dependencies = [
- "atty",
- "humantime",
- "log",
- "regex",
- "termcolor",
-]
-
-[[package]]
-name = "generic-array"
-version = "0.14.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac746a5f3bbfdadd6106868134545e684693d54d9d44f6e9588a7d54af0bf980"
-dependencies = [
- "typenum",
- "version_check 0.9.2",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.1.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
-dependencies = [
- "cfg-if",
- "libc",
- "wasi",
-]
-
-[[package]]
-name = "heck"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
-dependencies = [
- "unicode-segmentation",
-]
-
-[[package]]
-name = "hermit-abi"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "humantime"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
-dependencies = [
- "quick-error",
-]
-
-[[package]]
-name = "js-sys"
-version = "0.3.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9"
-dependencies = [
- "wasm-bindgen",
-]
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-
-[[package]]
-name = "libc"
-version = "0.2.66"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
-
-[[package]]
-name = "log"
-version = "0.4.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "mcuboot-sys"
-version = "0.1.0"
-dependencies = [
- "cc",
- "libc",
- "log",
- "simflash",
-]
-
-[[package]]
-name = "memchr"
-version = "2.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223"
-
-[[package]]
-name = "nom"
-version = "4.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
-dependencies = [
- "memchr",
- "version_check 0.1.5",
-]
-
-[[package]]
-name = "once_cell"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
-
-[[package]]
-name = "opaque-debug"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
-
-[[package]]
-name = "pem"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59698ea79df9bf77104aefd39cc3ec990cb9693fb59c3b0a70ddf2646fdffb4b"
-dependencies = [
- "base64",
- "once_cell",
- "regex",
-]
-
-[[package]]
-name = "ppv-lite86"
-version = "0.2.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548"
-dependencies = [
- "unicode-xid",
-]
-
-[[package]]
-name = "quick-error"
-version = "1.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
-
-[[package]]
-name = "quote"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "rand"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
-dependencies = [
- "getrandom",
- "libc",
- "rand_chacha",
- "rand_core",
- "rand_hc",
- "rand_pcg",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
-dependencies = [
- "ppv-lite86",
- "rand_core",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
-dependencies = [
- "getrandom",
-]
-
-[[package]]
-name = "rand_hc"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
-dependencies = [
- "rand_core",
-]
-
-[[package]]
-name = "rand_pcg"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
-dependencies = [
- "rand_core",
-]
-
-[[package]]
-name = "regex"
-version = "1.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-syntax",
- "thread_local",
-]
-
-[[package]]
-name = "regex-syntax"
-version = "0.6.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06"
-
-[[package]]
-name = "ring"
-version = "0.16.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "741ba1704ae21999c00942f9f5944f801e977f54302af346b596287599ad1862"
-dependencies = [
- "cc",
- "lazy_static",
- "libc",
- "spin",
- "untrusted",
- "web-sys",
- "winapi",
-]
-
-[[package]]
-name = "serde"
-version = "1.0.104"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.104"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "simflash"
-version = "0.1.0"
-dependencies = [
- "log",
- "rand",
- "thiserror",
-]
-
-[[package]]
-name = "sourcefile"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3"
-
-[[package]]
-name = "spin"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
-
-[[package]]
-name = "stream-cipher"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09f8ed9974042b8c3672ff3030a69fcc03b74c47c3d1ecb7755e8a3626011e88"
-dependencies = [
- "block-cipher",
- "generic-array",
-]
-
-[[package]]
-name = "strsim"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
-
-[[package]]
-name = "syn"
-version = "1.0.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-xid",
-]
-
-[[package]]
-name = "termcolor"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
-name = "thiserror"
-version = "1.0.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "318234ffa22e0920fe9a40d7b8369b5f649d490980cf7aadcf1eb91594869b42"
-dependencies = [
- "thiserror-impl",
-]
-
-[[package]]
-name = "thiserror-impl"
-version = "1.0.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cae2447b6282786c3493999f40a9be2a6ad20cb8bd268b0a0dbf5a065535c0ab"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "thread_local"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
-dependencies = [
- "lazy_static",
-]
-
-[[package]]
-name = "typenum"
-version = "1.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
-
-[[package]]
-name = "unicode-segmentation"
-version = "1.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
-
-[[package]]
-name = "unicode-xid"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
-
-[[package]]
-name = "untrusted"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60369ef7a31de49bcb3f6ca728d4ba7300d9a1658f94c727d4cab8c8d9f4aece"
-
-[[package]]
-name = "version_check"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
-
-[[package]]
-name = "version_check"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
-
-[[package]]
-name = "wasi"
-version = "0.9.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
-
-[[package]]
-name = "wasm-bindgen"
-version = "0.2.58"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c"
-dependencies = [
- "cfg-if",
- "wasm-bindgen-macro",
-]
-
-[[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.58"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45"
-dependencies = [
- "bumpalo",
- "lazy_static",
- "log",
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.58"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3"
-dependencies = [
- "quote",
- "wasm-bindgen-macro-support",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.58"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-backend",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.58"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601"
-
-[[package]]
-name = "wasm-bindgen-webidl"
-version = "0.2.58"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef012a0d93fc0432df126a8eaf547b2dce25a8ce9212e1d3cbeef5c11157975d"
-dependencies = [
- "anyhow",
- "heck",
- "log",
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-backend",
- "weedle",
-]
-
-[[package]]
-name = "web-sys"
-version = "0.3.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b"
-dependencies = [
- "anyhow",
- "js-sys",
- "sourcefile",
- "wasm-bindgen",
- "wasm-bindgen-webidl",
-]
-
-[[package]]
-name = "weedle"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164"
-dependencies = [
- "nom",
-]
-
-[[package]]
-name = "winapi"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-util"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80"
-dependencies = [
- "winapi",
-]
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/sim/Cargo.toml b/sim/Cargo.toml
index 02f0f73..b80dbb2 100644
--- a/sim/Cargo.toml
+++ b/sim/Cargo.toml
@@ -17,30 +17,39 @@
swap-status = ["mcuboot-sys/swap-status"]
validate-primary-slot = ["mcuboot-sys/validate-primary-slot"]
enc-rsa = ["mcuboot-sys/enc-rsa"]
+enc-aes256-rsa = ["mcuboot-sys/enc-aes256-rsa"]
enc-kw = ["mcuboot-sys/enc-kw"]
+enc-aes256-kw = ["mcuboot-sys/enc-aes256-kw"]
enc-ec256 = ["mcuboot-sys/enc-ec256"]
+enc-ec256-mbedtls = ["mcuboot-sys/enc-ec256-mbedtls"]
+enc-aes256-ec256 = ["mcuboot-sys/enc-aes256-ec256"]
enc-x25519 = ["mcuboot-sys/enc-x25519"]
+enc-aes256-x25519 = ["mcuboot-sys/enc-aes256-x25519"]
bootstrap = ["mcuboot-sys/bootstrap"]
multiimage = ["mcuboot-sys/multiimage"]
+ram-load = ["mcuboot-sys/ram-load"]
+direct-xip = ["mcuboot-sys/direct-xip"]
large-write = []
downgrade-prevention = ["mcuboot-sys/downgrade-prevention"]
[dependencies]
byteorder = "1.3"
libc = "0.2"
-rand = { version = "0.7", features = ["small_rng"] }
+rand = { version = "0.8", features = ["small_rng"] }
docopt = "1.1.0"
serde = "1.0"
serde_derive = "1.0"
log = "0.4"
-env_logger = "0.7"
+env_logger = "0.9"
simflash = { path = "simflash" }
mcuboot-sys = { path = "mcuboot-sys" }
ring = "0.16.11"
-untrusted = "0.7"
+untrusted = "0.9"
pem = "0.8"
-aes-ctr = "0.4.0"
-base64 = "0.12.0"
+cipher = "0.3"
+aes = { version = "0.7.4", features = ["ctr"] }
+base64 = "0.13.0"
+typenum = "1.13.0"
# The simulator runs very slowly without optimization. A value of 1
# compiles in about half the time, but runs about 5-6 times slower. 2
@@ -48,6 +57,8 @@
# Use 2 in case that makes the code slightly more debuggable.
[profile.test]
opt-level = 2
+# debug = true
[profile.dev]
opt-level = 2
+# debug = true
diff --git a/sim/mcuboot-sys/Cargo.toml b/sim/mcuboot-sys/Cargo.toml
index ef09755..e3a00cb 100644
--- a/sim/mcuboot-sys/Cargo.toml
+++ b/sim/mcuboot-sys/Cargo.toml
@@ -30,34 +30,62 @@
# Overwrite only upgrade
overwrite-only = []
-swap-status = []
-
swap-move = []
+swap-status = []
+
# Disable validation of the primary slot
validate-primary-slot = []
# Encrypt image in the secondary slot using RSA-OAEP-2048
enc-rsa = []
+# Encrypt image in the secondary slot using AES-256-CTR and RSA-OAEP-2048
+enc-aes256-rsa = []
+
# Encrypt image in the secondary slot using AES-KW-128
enc-kw = []
+# Encrypt image in the secondary slot using AES-256-CTR and AES-KW-256
+enc-aes256-kw = []
+
# Encrypt image in the secondary slot using ECIES-P256
enc-ec256 = []
+# Encrypt image in the secondary slot using AES-256-CTR and ECIES-P256
+enc-aes256-ec256 = []
+
+# Encrypt image in the secondary slot using ECIES-P256 using Mbed TLS
+enc-ec256-mbedtls = []
+
# Encrypt image in the secondary slot using ECIES-X25519
enc-x25519 = []
+# Encrypt image in the secondary slot using AES-256-CTR and ECIES-X25519
+enc-aes256-x25519 = []
+
# Allow bootstrapping an empty/invalid primary slot from a valid secondary slot
bootstrap = []
# Support multiple images (currently 2 instead of 1).
multiimage = []
+# Support simulation of ram-loading. No swaps are performed, and the
+# image is copied to RAM before loading it.
+ram-load = []
+
+# Support simulation of direct XIP. No swaps are performed, the image
+# is directly executed out of whichever partition contains the most
+# appropriate image.
+direct-xip = []
+
# Check (in software) against version downgrades.
downgrade-prevention = []
+# Large write. Not meaningful, but present here so that the
+# full-suite tests will work for this configuration.
+large-write = []
+
[build-dependencies]
cc = "1.0.25"
diff --git a/sim/mcuboot-sys/build.rs b/sim/mcuboot-sys/build.rs
index a2206c9..1a08741 100644
--- a/sim/mcuboot-sys/build.rs
+++ b/sim/mcuboot-sys/build.rs
@@ -2,10 +2,11 @@
extern crate cc;
+use std::collections::BTreeSet;
use std::env;
use std::fs;
use std::io;
-use std::path::Path;
+use std::path::{Path, PathBuf};
fn main() {
// Feature flags.
@@ -20,37 +21,51 @@
let validate_primary_slot =
env::var("CARGO_FEATURE_VALIDATE_PRIMARY_SLOT").is_ok();
let enc_rsa = env::var("CARGO_FEATURE_ENC_RSA").is_ok();
+ let enc_aes256_rsa = env::var("CARGO_FEATURE_ENC_AES256_RSA").is_ok();
let enc_kw = env::var("CARGO_FEATURE_ENC_KW").is_ok();
+ let enc_aes256_kw = env::var("CARGO_FEATURE_ENC_AES256_KW").is_ok();
let enc_ec256 = env::var("CARGO_FEATURE_ENC_EC256").is_ok();
+ let enc_ec256_mbedtls = env::var("CARGO_FEATURE_ENC_EC256_MBEDTLS").is_ok();
+ let enc_aes256_ec256 = env::var("CARGO_FEATURE_ENC_AES256_EC256").is_ok();
let enc_x25519 = env::var("CARGO_FEATURE_ENC_X25519").is_ok();
+ let enc_aes256_x25519 = env::var("CARGO_FEATURE_ENC_AES256_X25519").is_ok();
let bootstrap = env::var("CARGO_FEATURE_BOOTSTRAP").is_ok();
let multiimage = env::var("CARGO_FEATURE_MULTIIMAGE").is_ok();
let downgrade_prevention = env::var("CARGO_FEATURE_DOWNGRADE_PREVENTION").is_ok();
+ let ram_load = env::var("CARGO_FEATURE_RAM_LOAD").is_ok();
+ let direct_xip = env::var("CARGO_FEATURE_DIRECT_XIP").is_ok();
- let mut conf = cc::Build::new();
- conf.define("__BOOTSIM__", None);
- conf.define("MCUBOOT_HAVE_LOGGING", None);
- conf.define("MCUBOOT_USE_FLASH_AREA_GET_SECTORS", None);
- conf.define("MCUBOOT_HAVE_ASSERT_H", None);
- if !swap_status {
- conf.define("MCUBOOT_MAX_IMG_SECTORS", Some("128"));
- }
- conf.define("MCUBOOT_IMAGE_NUMBER", Some(if multiimage { "2" } else { "1" }));
+ let mut conf = CachedBuild::new();
+ conf.conf.define("__BOOTSIM__", None);
+ conf.conf.define("MCUBOOT_HAVE_LOGGING", None);
+ conf.conf.define("MCUBOOT_USE_FLASH_AREA_GET_SECTORS", None);
+ conf.conf.define("MCUBOOT_HAVE_ASSERT_H", None);
+ conf.conf.define("MCUBOOT_MAX_IMG_SECTORS", Some("128"));
+ conf.conf.define("MCUBOOT_IMAGE_NUMBER", Some(if multiimage { "2" } else { "1" }));
if downgrade_prevention && !overwrite_only {
panic!("Downgrade prevention requires overwrite only");
}
if bootstrap {
- conf.define("MCUBOOT_BOOTSTRAP", None);
+ conf.conf.define("MCUBOOT_BOOTSTRAP", None);
+ conf.conf.define("MCUBOOT_OVERWRITE_ONLY_FAST", None);
}
if validate_primary_slot {
- conf.define("MCUBOOT_VALIDATE_PRIMARY_SLOT", None);
+ conf.conf.define("MCUBOOT_VALIDATE_PRIMARY_SLOT", None);
}
if downgrade_prevention {
- conf.define("MCUBOOT_DOWNGRADE_PREVENTION", None);
+ conf.conf.define("MCUBOOT_DOWNGRADE_PREVENTION", None);
+ }
+
+ if ram_load {
+ conf.conf.define("MCUBOOT_RAM_LOAD", None);
+ }
+
+ if direct_xip {
+ conf.conf.define("MCUBOOT_DIRECT_XIP", None);
}
// Currently no more than one sig type can be used simultaneously.
@@ -60,35 +75,35 @@
}
if sig_rsa || sig_rsa3072 {
- conf.define("MCUBOOT_SIGN_RSA", None);
+ conf.conf.define("MCUBOOT_SIGN_RSA", None);
// The Kconfig style defines must be added here as well because
// they are used internally by "config-rsa.h"
if sig_rsa {
- conf.define("MCUBOOT_SIGN_RSA_LEN", "2048");
- conf.define("CONFIG_BOOT_SIGNATURE_TYPE_RSA_LEN", "2048");
+ conf.conf.define("MCUBOOT_SIGN_RSA_LEN", "2048");
+ conf.conf.define("CONFIG_BOOT_SIGNATURE_TYPE_RSA_LEN", "2048");
} else {
- conf.define("MCUBOOT_SIGN_RSA_LEN", "3072");
- conf.define("CONFIG_BOOT_SIGNATURE_TYPE_RSA_LEN", "3072");
+ conf.conf.define("MCUBOOT_SIGN_RSA_LEN", "3072");
+ conf.conf.define("CONFIG_BOOT_SIGNATURE_TYPE_RSA_LEN", "3072");
}
- conf.define("MCUBOOT_USE_MBED_TLS", None);
+ conf.conf.define("MCUBOOT_USE_MBED_TLS", None);
- conf.include("../../ext/mbedtls/crypto/include");
- conf.file("../../ext/mbedtls/crypto/library/sha256.c");
+ conf.conf.include("../../ext/mbedtls/include");
+ conf.file("../../ext/mbedtls/library/sha256.c");
conf.file("csupport/keys.c");
- conf.file("../../ext/mbedtls/crypto/library/rsa.c");
- conf.file("../../ext/mbedtls/crypto/library/bignum.c");
- conf.file("../../ext/mbedtls/crypto/library/platform.c");
- conf.file("../../ext/mbedtls/crypto/library/platform_util.c");
- conf.file("../../ext/mbedtls/crypto/library/asn1parse.c");
+ conf.file("../../ext/mbedtls/library/rsa.c");
+ conf.file("../../ext/mbedtls/library/bignum.c");
+ conf.file("../../ext/mbedtls/library/platform.c");
+ conf.file("../../ext/mbedtls/library/platform_util.c");
+ conf.file("../../ext/mbedtls/library/asn1parse.c");
} else if sig_ecdsa {
- conf.define("MCUBOOT_SIGN_EC256", None);
- conf.define("MCUBOOT_USE_TINYCRYPT", None);
+ conf.conf.define("MCUBOOT_SIGN_EC256", None);
+ conf.conf.define("MCUBOOT_USE_TINYCRYPT", None);
if !enc_kw {
- conf.include("../../ext/mbedtls-asn1/include");
+ conf.conf.include("../../ext/mbedtls/include");
}
- conf.include("../../ext/tinycrypt/lib/include");
+ conf.conf.include("../../ext/tinycrypt/lib/include");
conf.file("csupport/keys.c");
@@ -97,115 +112,119 @@
conf.file("../../ext/tinycrypt/lib/source/ecc.c");
conf.file("../../ext/tinycrypt/lib/source/ecc_dsa.c");
conf.file("../../ext/tinycrypt/lib/source/ecc_platform_specific.c");
-
- conf.file("../../ext/mbedtls-asn1/src/platform_util.c");
- conf.file("../../ext/mbedtls-asn1/src/asn1parse.c");
+ conf.file("../../ext/mbedtls/library/platform_util.c");
+ conf.file("../../ext/mbedtls/library/asn1parse.c");
} else if sig_ecdsa_mbedtls {
- conf.define("MCUBOOT_SIGN_EC256", None);
- conf.define("MCUBOOT_USE_MBED_TLS", None);
+ conf.conf.define("MCUBOOT_SIGN_EC256", None);
+ conf.conf.define("MCUBOOT_USE_MBED_TLS", None);
- conf.include("../../ext/mbedtls/crypto/include");
- conf.file("../../ext/mbedtls/crypto/library/sha256.c");
+ conf.conf.include("../../ext/mbedtls/include");
+ conf.file("../../ext/mbedtls/library/sha256.c");
conf.file("csupport/keys.c");
- conf.file("../../ext/mbedtls/crypto/library/asn1parse.c");
- conf.file("../../ext/mbedtls/crypto/library/bignum.c");
- conf.file("../../ext/mbedtls/crypto/library/ecdsa.c");
- conf.file("../../ext/mbedtls/crypto/library/ecp.c");
- conf.file("../../ext/mbedtls/crypto/library/ecp_curves.c");
- conf.file("../../ext/mbedtls/crypto/library/platform.c");
- conf.file("../../ext/mbedtls/crypto/library/platform_util.c");
+ conf.file("../../ext/mbedtls/library/asn1parse.c");
+ conf.file("../../ext/mbedtls/library/bignum.c");
+ conf.file("../../ext/mbedtls/library/ecdsa.c");
+ conf.file("../../ext/mbedtls/library/ecp.c");
+ conf.file("../../ext/mbedtls/library/ecp_curves.c");
+ conf.file("../../ext/mbedtls/library/platform.c");
+ conf.file("../../ext/mbedtls/library/platform_util.c");
} else if sig_ed25519 {
- conf.define("MCUBOOT_SIGN_ED25519", None);
- conf.define("MCUBOOT_USE_TINYCRYPT", None);
+ conf.conf.define("MCUBOOT_SIGN_ED25519", None);
+ conf.conf.define("MCUBOOT_USE_TINYCRYPT", None);
- conf.include("../../ext/tinycrypt/lib/include");
- conf.include("../../ext/tinycrypt-sha512/lib/include");
- conf.include("../../ext/mbedtls-asn1/include");
+ conf.conf.include("../../ext/tinycrypt/lib/include");
+ conf.conf.include("../../ext/tinycrypt-sha512/lib/include");
+ conf.conf.include("../../ext/mbedtls/include");
conf.file("../../ext/tinycrypt/lib/source/sha256.c");
conf.file("../../ext/tinycrypt-sha512/lib/source/sha512.c");
conf.file("../../ext/tinycrypt/lib/source/utils.c");
conf.file("csupport/keys.c");
conf.file("../../ext/fiat/src/curve25519.c");
- conf.file("../../ext/mbedtls-asn1/src/platform_util.c");
- conf.file("../../ext/mbedtls-asn1/src/asn1parse.c");
+ conf.file("../../ext/mbedtls/library/platform_util.c");
+ conf.file("../../ext/mbedtls/library/asn1parse.c");
} else if !enc_ec256 && !enc_x25519 {
// No signature type, only sha256 validation. The default
// configuration file bundled with mbedTLS is sufficient.
// When using ECIES-P256 rely on Tinycrypt.
- conf.define("MCUBOOT_USE_MBED_TLS", None);
- conf.include("../../ext/mbedtls/crypto/include");
- conf.file("../../ext/mbedtls/crypto/library/sha256.c");
+ conf.conf.define("MCUBOOT_USE_MBED_TLS", None);
+ conf.conf.include("../../ext/mbedtls/include");
+ conf.file("../../ext/mbedtls/library/sha256.c");
+ conf.file("../../ext/mbedtls/library/platform_util.c");
}
if overwrite_only {
- conf.define("MCUBOOT_OVERWRITE_ONLY", None);
- conf.define("MCUBOOT_OVERWRITE_ONLY_FAST", None);
+ conf.conf.define("MCUBOOT_OVERWRITE_ONLY", None);
}
if swap_move {
- conf.define("MCUBOOT_SWAP_USING_MOVE", None);
- conf.file("../../boot/bootutil/src/swap_move.c");
+ conf.conf.define("MCUBOOT_SWAP_USING_MOVE", None);
+ } else if !overwrite_only {
+ conf.conf.define("CONFIG_BOOT_SWAP_USING_SCRATCH", None);
+ conf.conf.define("MCUBOOT_SWAP_USING_SCRATCH", None);
}
-
if swap_status {
- conf.define("MCUBOOT_SWAP_USING_STATUS", None);
- conf.define("MCUBOOT_LOG_LEVEL", "MCUBOOT_LOG_LEVEL_DEBUG");
- conf.define("MCUBOOT_MAX_IMG_SECTORS", Some("2000"));
- conf.define("CY_FLASH_ALIGN", "512");
- conf.file("../../boot/bootutil/src/swap_status.c");
- conf.file("../../boot/bootutil/src/swap_status_part.c");
- conf.file("../../boot/bootutil/src/swap_status_misc.c");
- conf.file("../../boot/bootutil/src/crc32c.c");
-// conf.file("../../boot/cypress/cy_flash_pal/cy_my_support.c");
- conf.include("../../boot/cypress/cy_flash_pal");
+ conf.conf.define("MCUBOOT_SWAP_USING_STATUS", None);
+ conf.conf.define("CY_FLASH_ALIGN", "512");
+ conf.conf.file("../../boot/bootutil/src/swap_status.c");
+ conf.conf.file("../../boot/bootutil/src/swap_status_part.c");
+ conf.conf.file("../../boot/bootutil/src/swap_status_misc.c");
+ conf.conf.file("../../boot/bootutil/src/crc32c.c");
}
- if enc_rsa {
- conf.define("MCUBOOT_ENCRYPT_RSA", None);
- conf.define("MCUBOOT_ENC_IMAGES", None);
- conf.define("MCUBOOT_USE_MBED_TLS", None);
+ if enc_rsa || enc_aes256_rsa {
+ if enc_aes256_rsa {
+ conf.conf.define("MCUBOOT_AES_256", None);
+ }
+ conf.conf.define("MCUBOOT_ENCRYPT_RSA", None);
+ conf.conf.define("MCUBOOT_ENC_IMAGES", None);
+ conf.conf.define("MCUBOOT_USE_MBED_TLS", None);
conf.file("../../boot/bootutil/src/encrypted.c");
conf.file("csupport/keys.c");
- conf.include("../../ext/mbedtls/crypto/include");
- conf.file("../../ext/mbedtls/crypto/library/sha256.c");
+ conf.conf.include("../../ext/mbedtls/include");
+ conf.conf.include("../../ext/mbedtls/library");
+ conf.file("../../ext/mbedtls/library/sha256.c");
- conf.file("../../ext/mbedtls/crypto/library/platform.c");
- conf.file("../../ext/mbedtls/crypto/library/platform_util.c");
- conf.file("../../ext/mbedtls/crypto/library/rsa.c");
- conf.file("../../ext/mbedtls/crypto/library/rsa_internal.c");
- conf.file("../../ext/mbedtls/crypto/library/md.c");
- conf.file("../../ext/mbedtls/crypto/library/aes.c");
- conf.file("../../ext/mbedtls/crypto/library/bignum.c");
- conf.file("../../ext/mbedtls/crypto/library/asn1parse.c");
+ conf.file("../../ext/mbedtls/library/platform.c");
+ conf.file("../../ext/mbedtls/library/platform_util.c");
+ conf.file("../../ext/mbedtls/library/rsa.c");
+ conf.file("../../ext/mbedtls/library/rsa_alt_helpers.c");
+ conf.file("../../ext/mbedtls/library/md.c");
+ conf.file("../../ext/mbedtls/library/aes.c");
+ conf.file("../../ext/mbedtls/library/bignum.c");
+ conf.file("../../ext/mbedtls/library/asn1parse.c");
}
- if enc_kw {
- conf.define("MCUBOOT_ENCRYPT_KW", None);
- conf.define("MCUBOOT_ENC_IMAGES", None);
+ if enc_kw || enc_aes256_kw {
+ if enc_aes256_kw {
+ conf.conf.define("MCUBOOT_AES_256", None);
+ }
+ conf.conf.define("MCUBOOT_ENCRYPT_KW", None);
+ conf.conf.define("MCUBOOT_ENC_IMAGES", None);
conf.file("../../boot/bootutil/src/encrypted.c");
conf.file("csupport/keys.c");
if sig_rsa || sig_rsa3072 {
- conf.file("../../ext/mbedtls/crypto/library/sha256.c");
+ conf.file("../../ext/mbedtls/library/sha256.c");
}
/* Simulator uses Mbed-TLS to wrap keys */
- conf.include("../../ext/mbedtls/crypto/include");
- conf.file("../../ext/mbedtls/crypto/library/platform.c");
- conf.file("../../ext/mbedtls/crypto/library/platform_util.c");
- conf.file("../../ext/mbedtls/crypto/library/nist_kw.c");
- conf.file("../../ext/mbedtls/crypto/library/cipher.c");
- conf.file("../../ext/mbedtls/crypto/library/cipher_wrap.c");
- conf.file("../../ext/mbedtls/crypto/library/aes.c");
+ conf.conf.include("../../ext/mbedtls/include");
+ conf.file("../../ext/mbedtls/library/platform.c");
+ conf.conf.include("../../ext/mbedtls/library");
+ conf.file("../../ext/mbedtls/library/platform_util.c");
+ conf.file("../../ext/mbedtls/library/nist_kw.c");
+ conf.file("../../ext/mbedtls/library/cipher.c");
+ conf.file("../../ext/mbedtls/library/cipher_wrap.c");
+ conf.file("../../ext/mbedtls/library/aes.c");
if sig_ecdsa {
- conf.define("MCUBOOT_USE_TINYCRYPT", None);
+ conf.conf.define("MCUBOOT_USE_TINYCRYPT", None);
- conf.include("../../ext/tinycrypt/lib/include");
+ conf.conf.include("../../ext/tinycrypt/lib/include");
conf.file("../../ext/tinycrypt/lib/source/utils.c");
conf.file("../../ext/tinycrypt/lib/source/sha256.c");
@@ -220,16 +239,16 @@
}
if enc_ec256 {
- conf.define("MCUBOOT_ENCRYPT_EC256", None);
- conf.define("MCUBOOT_ENC_IMAGES", None);
- conf.define("MCUBOOT_USE_TINYCRYPT", None);
- conf.define("MCUBOOT_SWAP_SAVE_ENCTLV", None);
+ conf.conf.define("MCUBOOT_ENCRYPT_EC256", None);
+ conf.conf.define("MCUBOOT_ENC_IMAGES", None);
+ conf.conf.define("MCUBOOT_USE_TINYCRYPT", None);
+ conf.conf.define("MCUBOOT_SWAP_SAVE_ENCTLV", None);
conf.file("../../boot/bootutil/src/encrypted.c");
conf.file("csupport/keys.c");
- conf.include("../../ext/mbedtls-asn1/include");
- conf.include("../../ext/tinycrypt/lib/include");
+ conf.conf.include("../../ext/mbedtls/include");
+ conf.conf.include("../../ext/tinycrypt/lib/include");
/* FIXME: fail with other signature schemes ? */
@@ -239,36 +258,59 @@
conf.file("../../ext/tinycrypt/lib/source/ecc_dsa.c");
conf.file("../../ext/tinycrypt/lib/source/ecc_platform_specific.c");
- conf.file("../../ext/mbedtls-asn1/src/platform_util.c");
- conf.file("../../ext/mbedtls-asn1/src/asn1parse.c");
+ conf.file("../../ext/mbedtls/library/platform_util.c");
+ conf.file("../../ext/mbedtls/library/asn1parse.c");
conf.file("../../ext/tinycrypt/lib/source/aes_encrypt.c");
conf.file("../../ext/tinycrypt/lib/source/aes_decrypt.c");
conf.file("../../ext/tinycrypt/lib/source/ctr_mode.c");
conf.file("../../ext/tinycrypt/lib/source/hmac.c");
conf.file("../../ext/tinycrypt/lib/source/ecc_dh.c");
+ } else if enc_ec256_mbedtls || enc_aes256_ec256 {
+ if enc_aes256_ec256 {
+ conf.conf.define("MCUBOOT_AES_256", None);
+ }
+ conf.conf.define("MCUBOOT_ENCRYPT_EC256", None);
+ conf.conf.define("MCUBOOT_ENC_IMAGES", None);
+ conf.conf.define("MCUBOOT_USE_MBED_TLS", None);
+ conf.conf.define("MCUBOOT_SWAP_SAVE_ENCTLV", None);
+
+ conf.conf.include("../../ext/mbedtls/include");
+
+ conf.file("../../boot/bootutil/src/encrypted.c");
+ conf.file("../../ext/mbedtls/library/sha256.c");
+ conf.file("../../ext/mbedtls/library/asn1parse.c");
+ conf.file("../../ext/mbedtls/library/bignum.c");
+ conf.file("../../ext/mbedtls/library/ecdh.c");
+ conf.file("../../ext/mbedtls/library/md.c");
+ conf.file("../../ext/mbedtls/library/aes.c");
+ conf.file("../../ext/mbedtls/library/ecp.c");
+ conf.file("../../ext/mbedtls/library/ecp_curves.c");
+ conf.file("../../ext/mbedtls/library/platform.c");
+ conf.file("../../ext/mbedtls/library/platform_util.c");
+ conf.file("csupport/keys.c");
}
if enc_x25519 {
- conf.define("MCUBOOT_ENCRYPT_X25519", None);
- conf.define("MCUBOOT_ENC_IMAGES", None);
- conf.define("MCUBOOT_USE_TINYCRYPT", None);
- conf.define("MCUBOOT_SWAP_SAVE_ENCTLV", None);
+ conf.conf.define("MCUBOOT_ENCRYPT_X25519", None);
+ conf.conf.define("MCUBOOT_ENC_IMAGES", None);
+ conf.conf.define("MCUBOOT_USE_TINYCRYPT", None);
+ conf.conf.define("MCUBOOT_SWAP_SAVE_ENCTLV", None);
conf.file("../../boot/bootutil/src/encrypted.c");
conf.file("csupport/keys.c");
- conf.include("../../ext/mbedtls-asn1/include");
- conf.include("../../ext/tinycrypt/lib/include");
- conf.include("../../ext/tinycrypt-sha512/lib/include");
+ conf.conf.include("../../ext/mbedtls/include");
+ conf.conf.include("../../ext/tinycrypt/lib/include");
+ conf.conf.include("../../ext/tinycrypt-sha512/lib/include");
conf.file("../../ext/fiat/src/curve25519.c");
conf.file("../../ext/tinycrypt/lib/source/utils.c");
conf.file("../../ext/tinycrypt/lib/source/sha256.c");
- conf.file("../../ext/mbedtls-asn1/src/platform_util.c");
- conf.file("../../ext/mbedtls-asn1/src/asn1parse.c");
+ conf.file("../../ext/mbedtls/library/platform_util.c");
+ conf.file("../../ext/mbedtls/library/asn1parse.c");
conf.file("../../ext/tinycrypt/lib/source/aes_encrypt.c");
conf.file("../../ext/tinycrypt/lib/source/aes_decrypt.c");
@@ -276,24 +318,48 @@
conf.file("../../ext/tinycrypt/lib/source/hmac.c");
}
+ else if enc_aes256_x25519 {
+ conf.conf.define("MCUBOOT_AES_256", None);
+ conf.conf.define("MCUBOOT_ENCRYPT_X25519", None);
+ conf.conf.define("MCUBOOT_ENC_IMAGES", None);
+ conf.conf.define("MCUBOOT_USE_MBED_TLS", None);
+ conf.conf.define("MCUBOOT_SWAP_SAVE_ENCTLV", None);
+
+ conf.file("../../boot/bootutil/src/encrypted.c");
+ conf.file("csupport/keys.c");
+
+ conf.conf.include("../../ext/mbedtls/include");
+ conf.file("../../ext/fiat/src/curve25519.c");
+ conf.file("../../ext/mbedtls/library/asn1parse.c");
+ conf.file("../../ext/mbedtls/library/platform.c");
+ conf.file("../../ext/mbedtls/library/platform_util.c");
+ conf.file("../../ext/mbedtls/library/aes.c");
+ conf.file("../../ext/mbedtls/library/sha256.c");
+ conf.file("../../ext/mbedtls/library/md.c");
+ conf.file("../../ext/mbedtls/library/sha512.c");
+ }
+
if sig_rsa && enc_kw {
- conf.define("MBEDTLS_CONFIG_FILE", Some("<config-rsa-kw.h>"));
- } else if sig_rsa || sig_rsa3072 || enc_rsa {
- conf.define("MBEDTLS_CONFIG_FILE", Some("<config-rsa.h>"));
- } else if sig_ecdsa_mbedtls {
- conf.define("MBEDTLS_CONFIG_FILE", Some("<config-ecdsa.h>"));
+ conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-rsa-kw.h>"));
+ } else if sig_rsa || sig_rsa3072 || enc_rsa || enc_aes256_rsa {
+ conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-rsa.h>"));
+ } else if sig_ecdsa_mbedtls || enc_ec256_mbedtls || enc_aes256_ec256 {
+ conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-ec.h>"));
} else if (sig_ecdsa || enc_ec256) && !enc_kw {
- conf.define("MBEDTLS_CONFIG_FILE", Some("<config-asn1.h>"));
+ conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-asn1.h>"));
} else if sig_ed25519 || enc_x25519 {
- conf.define("MBEDTLS_CONFIG_FILE", Some("<config-asn1.h>"));
- } else if enc_kw {
- conf.define("MBEDTLS_CONFIG_FILE", Some("<config-kw.h>"));
+ conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-asn1.h>"));
+ } else if enc_kw || enc_aes256_kw {
+ conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-kw.h>"));
+ } else if enc_aes256_x25519 {
+ conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-ed25519.h>"));
}
conf.file("../../boot/bootutil/src/image_validate.c");
if sig_rsa || sig_rsa3072 {
conf.file("../../boot/bootutil/src/image_rsa.c");
} else if sig_ecdsa || sig_ecdsa_mbedtls {
+ conf.conf.include("../../ext/mbedtls/include");
conf.file("../../boot/bootutil/src/image_ec256.c");
} else if sig_ed25519 {
conf.file("../../boot/bootutil/src/image_ed25519.c");
@@ -301,32 +367,33 @@
conf.file("../../boot/bootutil/src/loader.c");
conf.file("../../boot/bootutil/src/swap_misc.c");
conf.file("../../boot/bootutil/src/swap_scratch.c");
+ conf.file("../../boot/bootutil/src/swap_move.c");
conf.file("../../boot/bootutil/src/caps.c");
conf.file("../../boot/bootutil/src/bootutil_misc.c");
conf.file("../../boot/bootutil/src/bootutil_public.c");
conf.file("../../boot/bootutil/src/tlv.c");
conf.file("../../boot/bootutil/src/fault_injection_hardening.c");
conf.file("csupport/run.c");
- conf.include("../../boot/bootutil/include");
- conf.include("csupport");
- conf.include("../../boot/zephyr/include");
- conf.debug(true);
- conf.flag("-Wall");
- conf.flag("-Werror");
+ conf.conf.include("../../boot/bootutil/include");
+ conf.conf.include("csupport");
+ conf.conf.include("../../boot/zephyr/include");
+ conf.conf.debug(true);
+ conf.conf.flag("-Wall");
+ conf.conf.flag("-Werror");
// FIXME: travis-ci still uses gcc 4.8.4 which defaults to std=gnu90.
// It has incomplete std=c11 and std=c99 support but std=c99 was checked
// to build correctly so leaving it here to updated in the future...
- conf.flag("-std=c99");
+ conf.conf.flag("-std=c99");
- conf.compile("libbootutil.a");
+ conf.conf.compile("libbootutil.a");
walk_dir("../../boot").unwrap();
walk_dir("../../ext/tinycrypt/lib/source").unwrap();
walk_dir("../../ext/mbedtls-asn1").unwrap();
walk_dir("csupport").unwrap();
- walk_dir("../../ext/mbedtls/crypto/include").unwrap();
- walk_dir("../../ext/mbedtls/crypto/library").unwrap();
+ walk_dir("../../ext/mbedtls/include").unwrap();
+ walk_dir("../../ext/mbedtls/library").unwrap();
}
// Output the names of all files within a directory so that Cargo knows when to rebuild.
@@ -347,3 +414,30 @@
Ok(())
}
+
+/// Wrap the cc::Build type so that we can make sure that files are only added a single time.
+/// Other methods can be passed through as needed.
+struct CachedBuild {
+ conf: cc::Build,
+ seen: BTreeSet<PathBuf>,
+}
+
+impl CachedBuild {
+ fn new() -> CachedBuild {
+ CachedBuild {
+ conf: cc::Build::new(),
+ seen: BTreeSet::new(),
+ }
+ }
+
+ /// Works like `file` in the Build, but doesn't add a file if the same path has already been
+ /// given.
+ fn file<P: AsRef<Path>>(&mut self, p: P) -> &mut CachedBuild {
+ let p = p.as_ref();
+ if !self.seen.contains(p) {
+ self.conf.file(p);
+ self.seen.insert(p.to_owned());
+ }
+ self
+ }
+}
diff --git a/sim/mcuboot-sys/csupport/devicetree.h b/sim/mcuboot-sys/csupport/devicetree.h
index 73c7c83..22a7fe6 100644
--- a/sim/mcuboot-sys/csupport/devicetree.h
+++ b/sim/mcuboot-sys/csupport/devicetree.h
@@ -9,6 +9,8 @@
#ifndef __DEVICETREE_H__
#define __DEVICETREE_H__
+#define FLASH_AREA_ERROR 255u
+
#define FLASH_AREA_ID(x) FLASH_AREA_ID_##x
#define FLASH_AREA_ID_image_0 1
@@ -17,11 +19,16 @@
#define FLASH_AREA_ID_image_2 4
#define FLASH_AREA_ID_image_3 5
-#define FLASH_AREA_IMAGE_0 FLASH_AREA_ID(image_0)
-#define FLASH_AREA_IMAGE_1 FLASH_AREA_ID(image_1)
-#define FLASH_AREA_IMAGE_2 FLASH_AREA_ID(image_2)
-#define FLASH_AREA_IMAGE_3 FLASH_AREA_ID(image_3)
+/*
+ * PSoC6 area defines based on file:
+ * boot/cypress/MCUBootApp/sysflash/sysflash.h
+*/
+#define FLASH_AREA_IMAGE_0 1
+#define FLASH_AREA_IMAGE_1 2
+#define FLASH_AREA_IMAGE_2 4
+#define FLASH_AREA_IMAGE_3 5
+#define FLASH_AREA_IMAGE_SWAP_STATUS 7
-#define FLASH_AREA_IMAGE_SWAP_STATUS FLASH_AREA_ID(image_scratch)
+#define BOOT_MAX_SWAP_STATUS_SECTORS 64
#endif /*__DEVICETREE_H__*/
diff --git a/sim/mcuboot-sys/csupport/keys.c b/sim/mcuboot-sys/csupport/keys.c
index 8011629..f9325be 100644
--- a/sim/mcuboot-sys/csupport/keys.c
+++ b/sim/mcuboot-sys/csupport/keys.c
@@ -256,11 +256,20 @@
#endif
#if defined(MCUBOOT_ENCRYPT_KW)
+#if defined(MCUBOOT_AES_256)
+unsigned char enc_key[] = {
+ 0xE4, 0x5C, 0x51, 0x46, 0xD2, 0x1C, 0x82, 0x35, 0xCC, 0x1A, 0x19, 0xAF,
+ 0xA1, 0xF2, 0xAA, 0x20, 0xC8, 0x8C, 0x7F, 0x40, 0x6C, 0xDB, 0x22, 0xAA,
+ 0x6A, 0xB5, 0xCB, 0xAA, 0xF8, 0xB1, 0x5B, 0xB4
+};
+static unsigned int enc_key_len = 32;
+#else
unsigned char enc_key[] = {
0xd1, 0x5a, 0x04, 0x95, 0xc4, 0xc2, 0xa8, 0xff, 0x30, 0x78, 0xce, 0x49,
0xb5, 0xfc, 0xb2, 0xdd
};
static unsigned int enc_key_len = 16;
+#endif
const struct bootutil_key bootutil_enc_key = {
.key = enc_key,
.len = &enc_key_len,
diff --git a/sim/mcuboot-sys/csupport/run.c b/sim/mcuboot-sys/csupport/run.c
index fd21bfd..fd6c3ca 100644
--- a/sim/mcuboot-sys/csupport/run.c
+++ b/sim/mcuboot-sys/csupport/run.c
@@ -22,7 +22,9 @@
#include "mbedtls/nist_kw.h"
#endif
+#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
#include <bootutil/bootutil_log.h>
+#include "bootutil/crypto/common.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -90,15 +92,15 @@
return -6;
}
- if (mbedtls_asn1_get_mpi(p, end, &ctx->N) != 0) {
+ if (mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(N)) != 0) {
return -7;
}
- if (mbedtls_asn1_get_mpi(p, end, &ctx->E) != 0) {
+ if (mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(E)) != 0) {
return -8;
}
- ctx->len = mbedtls_mpi_size(&ctx->N);
+ ctx->MBEDTLS_CONTEXT_MEMBER(len) = mbedtls_mpi_size(&ctx->MBEDTLS_CONTEXT_MEMBER(N));
if (*p != end) {
return -9;
@@ -140,7 +142,12 @@
mbedtls_platform_set_calloc_free(calloc, free);
+#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+ mbedtls_rsa_init(&ctx);
+ mbedtls_rsa_set_padding(&ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
+#else
mbedtls_rsa_init(&ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
+#endif
cp = (uint8_t *)pubkey;
cpend = cp + pubkey_len;
@@ -150,8 +157,13 @@
goto done;
}
+#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+ rc = mbedtls_rsa_rsaes_oaep_encrypt(&ctx, fake_rng, NULL,
+ NULL, 0, seckey_len, seckey, encbuf);
+#else
rc = mbedtls_rsa_rsaes_oaep_encrypt(&ctx, fake_rng, NULL, MBEDTLS_RSA_PUBLIC,
NULL, 0, seckey_len, seckey, encbuf);
+#endif
if (rc) {
goto done;
}
@@ -173,6 +185,15 @@
int kw_encrypt_(const uint8_t *kek, const uint8_t *seckey, uint8_t *encbuf)
{
#ifdef MCUBOOT_ENCRYPT_KW
+#ifdef MCUBOOT_AES_256
+ int key_len = 256;
+ int out_size = 40;
+ int in_len = 32;
+#else
+ int key_len = 128;
+ int out_size = 24;
+ int in_len = 16;
+#endif
mbedtls_nist_kw_context kw;
size_t olen;
int rc;
@@ -181,13 +202,13 @@
mbedtls_nist_kw_init(&kw);
- rc = mbedtls_nist_kw_setkey(&kw, MBEDTLS_CIPHER_ID_AES, kek, 128, 1);
+ rc = mbedtls_nist_kw_setkey(&kw, MBEDTLS_CIPHER_ID_AES, kek, key_len, 1);
if (rc) {
goto done;
}
- rc = mbedtls_nist_kw_wrap(&kw, MBEDTLS_KW_MODE_KW, seckey, 16, encbuf,
- &olen, 24);
+ rc = mbedtls_nist_kw_wrap(&kw, MBEDTLS_KW_MODE_KW, seckey, in_len, encbuf,
+ &olen, out_size);
done:
mbedtls_nist_kw_free(&kw);
@@ -201,9 +222,9 @@
#endif
}
-uint16_t flash_area_align(const struct flash_area *area)
+size_t flash_area_align(const struct flash_area *area)
{
- return sim_flash_align(area->fa_device_id);
+ return (size_t)sim_flash_align(area->fa_device_id);
}
uint8_t flash_area_erased_val(const struct flash_area *area)
@@ -223,14 +244,16 @@
uint32_t num_slots;
};
-int invoke_boot_go(struct sim_context *ctx, struct area_desc *adesc)
+int invoke_boot_go(struct sim_context *ctx, struct area_desc *adesc,
+ struct boot_rsp *rsp)
{
int res;
- struct boot_rsp rsp;
struct boot_loader_state *state;
#if defined(MCUBOOT_SIGN_RSA) || \
- (defined(MCUBOOT_SIGN_EC256) && defined(MCUBOOT_USE_MBED_TLS))
+ (defined(MCUBOOT_SIGN_EC256) && defined(MCUBOOT_USE_MBED_TLS)) ||\
+ (defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS)) ||\
+ (defined(MCUBOOT_ENCRYPT_X25519) && defined(MCUBOOT_USE_MBED_TLS))
mbedtls_platform_set_calloc_free(calloc, free);
#endif
@@ -241,7 +264,7 @@
sim_set_context(ctx);
if (setjmp(ctx->boot_jmpbuf) == 0) {
- res = context_boot_go(state, &rsp);
+ res = context_boot_go(state, rsp);
sim_reset_flash_areas();
sim_reset_context();
free(state);
@@ -261,53 +284,30 @@
return malloc(size);
}
-void os_free(void *mem)
-{
- free(mem);
-}
-
-void *os_realloc(void *ptr, size_t size)
-{
- return realloc(ptr, size);
-}
-
int flash_area_id_from_multi_image_slot(int image_index, int slot)
{
switch (slot) {
case 0: return FLASH_AREA_IMAGE_PRIMARY(image_index);
case 1: return FLASH_AREA_IMAGE_SECONDARY(image_index);
case 2: return FLASH_AREA_IMAGE_SCRATCH;
-
- // case 7: return FLASH_AREA_IMAGE_SWAP_STATUS;
}
- printf("Image flash area ID not found, image=%d, slot=%d\n", image_index, slot);
+ printf("Image flash area ID not found\n");
return -1; /* flash_area_open will fail on that */
}
-int flash_area_id_from_image_slot(int slot)
-{
- return flash_area_id_from_multi_image_slot(0, slot);
-}
-
int flash_area_open(uint8_t id, const struct flash_area **area)
{
uint32_t i;
struct area_desc *flash_areas;
- // BOOT_LOG_SIM("%s: area id=%d, num_slots=%d", __func__, id, sim_get_flash_areas()->num_slots);
-
flash_areas = sim_get_flash_areas();
for (i = 0; i < flash_areas->num_slots; i++) {
- // BOOT_LOG_SIM(" * flash_areas->slots[%d].id=%d", i, flash_areas->slots[i].id);
if (flash_areas->slots[i].id == id)
- {
- // BOOT_LOG_SIM(" * found, i=%d, id=%d", i, id);
break;
- }
}
if (i == flash_areas->num_slots) {
- printf("Unsupported area id=%d\n", id);
+ printf("Unsupported area\n");
abort();
}
@@ -354,6 +354,15 @@
ctx->jumped++;
longjmp(ctx->boot_jmpbuf, 1);
}
+
+// Align offset and length to sector size
+#ifdef MCUBOOT_SWAP_USING_STATUS
+ uint32_t sect_off = off / CY_FLASH_ALIGN * CY_FLASH_ALIGN;
+ len = ((off + len - 1) / CY_FLASH_ALIGN + 1) * CY_FLASH_ALIGN - sect_off;
+ off = sect_off;
+ BOOT_LOG_SIM("%s: erase with aligment at area=%d, off=%x, len=%x", __func__, area->fa_id, off, len);
+#endif
+
return sim_flash_erase(area->fa_device_id, area->fa_off + off, len);
}
@@ -363,22 +372,20 @@
struct area *slot;
struct area_desc *flash_areas;
- // BOOT_LOG_SIM("%s: idx=%d", __func__, idx);
-
flash_areas = sim_get_flash_areas();
for (i = 0; i < flash_areas->num_slots; i++) {
if (flash_areas->slots[i].id == idx)
break;
}
if (i == flash_areas->num_slots) {
- printf("flash_area_to_sectors: Unsupported area = %d\n", idx);
+ printf("Unsupported area\n");
abort();
}
slot = &flash_areas->slots[i];
if (slot->num_areas > (uint32_t)*cnt) {
- printf("Too many areas in slot: %d > %d\n", slot->num_areas, *cnt);
+ printf("Too many areas in slot\n");
abort();
}
@@ -395,22 +402,20 @@
struct area *slot;
struct area_desc *flash_areas;
- // BOOT_LOG_SIM("%s: area id=%d", __func__, fa_id);
-
flash_areas = sim_get_flash_areas();
for (i = 0; i < flash_areas->num_slots; i++) {
if (flash_areas->slots[i].id == fa_id)
break;
}
if (i == flash_areas->num_slots) {
- printf("flash_area_get_sectors: Unsupported area = %d\n", fa_id);
+ printf("Unsupported area\n");
abort();
}
slot = &flash_areas->slots[i];
if (slot->num_areas > *count) {
- printf("Too many areas in slot: %d > %d\n", slot->num_areas, *count);
+ printf("Too many areas in slot\n");
abort();
}
@@ -433,10 +438,20 @@
return 1;
}
- printf("Unsupported image area ID=%d\n", area_id);
+ printf("Unsupported image area ID\n");
abort();
}
+uint8_t flash_area_get_device_id(const struct flash_area *fa)
+{
+ return fa->fa_device_id;
+}
+
+int flash_area_id_from_image_slot(int slot) {
+ /* For single image cases, just use the first image. */
+ return flash_area_id_from_multi_image_slot(0, slot);
+}
+
void sim_assert(int x, const char *assertion, const char *file, unsigned int line, const char *function)
{
if (!(x)) {
@@ -463,28 +478,3 @@
{
return BOOT_MAGIC_SZ;
}
-
-void mbedtls_platform_zeroize( void *buf, size_t len )
-{
- memset( buf, 0, len );
-}
-
-int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off,
- void *dst, uint32_t len)
-{
- uint8_t *mem_dest;
- int rc;
-
- mem_dest = (uint8_t *)dst;
- rc = flash_area_read(fa, off, dst, len);
- if (rc) {
- return -1;
- }
-
- for (uint8_t i = 0; i < len; i++) {
- if (mem_dest[i] != flash_area_erased_val(fa)) {
- return 0;
- }
- }
- return 1;
-}
diff --git a/sim/mcuboot-sys/csupport/storage/flash_map.h b/sim/mcuboot-sys/csupport/storage/flash_map.h
index 2a6fd56..7b20453 100644
--- a/sim/mcuboot-sys/csupport/storage/flash_map.h
+++ b/sim/mcuboot-sys/csupport/storage/flash_map.h
@@ -42,6 +42,7 @@
* and match the target offset specified in download script.
*/
#include <inttypes.h>
+#include <stddef.h>
/**
* @brief Structure describing an area on a flash device.
@@ -123,7 +124,7 @@
/*
* Alignment restriction for flash writes.
*/
-uint16_t flash_area_align(const struct flash_area *);
+size_t flash_area_align(const struct flash_area *);
/*
* What is value is read from erased flash bytes.
diff --git a/sim/mcuboot-sys/src/api.rs b/sim/mcuboot-sys/src/api.rs
index a6acd53..8d1140d 100644
--- a/sim/mcuboot-sys/src/api.rs
+++ b/sim/mcuboot-sys/src/api.rs
@@ -26,6 +26,38 @@
pub type FlashParams = HashMap<u8, FlashParamsStruct>;
+/// The `boot_rsp` structure used by boot_go.
+#[repr(C)]
+#[derive(Debug)]
+pub struct BootRsp {
+ pub br_hdr: *const ImageHeader,
+ pub flash_dev_id: u8,
+ pub image_off: u32,
+}
+
+// TODO: Don't duplicate this image header declaration.
+#[repr(C)]
+#[derive(Debug)]
+pub struct ImageHeader {
+ magic: u32,
+ load_addr: u32,
+ hdr_size: u16,
+ protect_tlv_size: u16,
+ img_size: u32,
+ flags: u32,
+ ver: ImageVersion,
+ _pad2: u32,
+}
+
+#[repr(C)]
+#[derive(Debug)]
+pub struct ImageVersion {
+ pub major: u8,
+ pub minor: u8,
+ pub revision: u16,
+ pub build_num: u32,
+}
+
pub struct CAreaDescPtr {
pub ptr: *const CAreaDesc,
}
@@ -89,9 +121,20 @@
}
}
+/// This struct describes the RAM layout of the current device. It will be stashed, per test
+/// thread, and queried by the C code.
+#[repr(C)]
+#[derive(Debug, Default)]
+pub struct BootsimRamInfo {
+ pub start: u32,
+ pub size: u32,
+ pub base: usize,
+}
+
thread_local! {
pub static THREAD_CTX: RefCell<FlashContext> = RefCell::new(FlashContext::new());
pub static SIM_CTX: RefCell<CSimContextPtr> = RefCell::new(CSimContextPtr::new());
+ pub static RAM_CTX: RefCell<BootsimRamInfo> = RefCell::new(BootsimRamInfo::default());
}
/// Set the flash device to be used by the simulation. The pointer is unsafely stashed away.
@@ -165,6 +208,32 @@
}
#[no_mangle]
+pub extern "C" fn bootsim_get_ram_info() -> *const BootsimRamInfo {
+ RAM_CTX.with(|ctx| {
+ if ctx.borrow().base == 0 {
+ // Option is messier to get a pointer out of, so just check if the base has been set to
+ // anything.
+ panic!("ram info not set, but being used");
+ }
+ ctx.as_ptr()
+ })
+}
+
+/// Store a copy of this RAM info.
+pub fn set_ram_info(info: BootsimRamInfo) {
+ RAM_CTX.with(|ctx| {
+ ctx.replace(info);
+ });
+}
+
+/// Clear out the ram info.
+pub fn clear_ram_info() {
+ RAM_CTX.with(|ctx| {
+ ctx.borrow_mut().base = 0;
+ });
+}
+
+#[no_mangle]
pub extern fn sim_flash_erase(dev_id: u8, offset: u32, size: u32) -> libc::c_int {
let mut rc: libc::c_int = -19;
THREAD_CTX.with(|ctx| {
diff --git a/sim/mcuboot-sys/src/area.rs b/sim/mcuboot-sys/src/area.rs
index f151fe4..cfbebda 100644
--- a/sim/mcuboot-sys/src/area.rs
+++ b/sim/mcuboot-sys/src/area.rs
@@ -189,8 +189,8 @@
ImageScratch = 3,
Image2 = 4,
Image3 = 5,
- //ImageSwapStatus = 7,
- //ImageSwapStatus = 3,
+// Not_used = 6,
+ ImageSwapStatus = 7,
}
impl Default for FlashId {
diff --git a/sim/mcuboot-sys/src/c.rs b/sim/mcuboot-sys/src/c.rs
index 5f518f5..5c791b8 100644
--- a/sim/mcuboot-sys/src/c.rs
+++ b/sim/mcuboot-sys/src/c.rs
@@ -1,6 +1,6 @@
// Copyright (c) 2017-2019 Linaro LTD
// Copyright (c) 2017-2019 JUUL Labs
-// Copyright (c) 2019 Arm Limited
+// Copyright (c) 2019-2021 Arm Limited
//
// SPDX-License-Identifier: Apache-2.0
@@ -10,9 +10,61 @@
use simflash::SimMultiFlash;
use crate::api;
+/// The result of an invocation of `boot_go`. This is intentionally opaque so that we can provide
+/// accessors for everything we need from this.
+#[derive(Debug)]
+pub enum BootGoResult {
+ /// This run was stopped by the flash simulation mechanism.
+ Stopped,
+ /// The bootloader ran to completion with the following data.
+ Normal {
+ result: i32,
+ asserts: u8,
+
+ resp: api::BootRsp,
+ },
+}
+
+impl BootGoResult {
+ /// Was this run interrupted.
+ pub fn interrupted(&self) -> bool {
+ matches!(self, BootGoResult::Stopped)
+ }
+
+ /// Was this boot run successful (returned 0)
+ pub fn success(&self) -> bool {
+ matches!(self, BootGoResult::Normal { result: 0, .. })
+ }
+
+ /// Success, but also no asserts.
+ pub fn success_no_asserts(&self) -> bool {
+ matches!(self, BootGoResult::Normal {
+ result: 0,
+ asserts: 0,
+ ..
+ })
+ }
+
+ /// Get the asserts count. An interrupted run will be considered to have no asserts.
+ pub fn asserts(&self) -> u8 {
+ match self {
+ BootGoResult::Normal { asserts, .. } => *asserts,
+ _ => 0,
+ }
+ }
+
+ /// Retrieve the 'resp' field that is filled in.
+ pub fn resp(&self) -> Option<&api::BootRsp> {
+ match self {
+ BootGoResult::Normal { resp, .. } => Some(resp),
+ _ => None,
+ }
+ }
+}
+
/// Invoke the bootloader on this flash device.
pub fn boot_go(multiflash: &mut SimMultiFlash, areadesc: &AreaDesc,
- counter: Option<&mut i32>, catch_asserts: bool) -> (i32, u8) {
+ counter: Option<&mut i32>, catch_asserts: bool) -> BootGoResult {
for (&dev_id, flash) in multiflash.iter_mut() {
api::set_flash(dev_id, flash);
}
@@ -26,8 +78,14 @@
c_catch_asserts: if catch_asserts { 1 } else { 0 },
boot_jmpbuf: [0; 16],
};
+ let mut rsp = api::BootRsp {
+ br_hdr: std::ptr::null(),
+ flash_dev_id: 0,
+ image_off: 0,
+ };
let result = unsafe {
- raw::invoke_boot_go(&mut sim_ctx as *mut _, &areadesc.get_c() as *const _) as i32
+ raw::invoke_boot_go(&mut sim_ctx as *mut _, &areadesc.get_c() as *const _,
+ &mut rsp as *mut _) as i32
};
let asserts = sim_ctx.c_asserts;
if let Some(c) = counter {
@@ -36,7 +94,11 @@
for &dev_id in multiflash.keys() {
api::clear_flash(dev_id);
}
- (result, asserts)
+ if result == -0x13579 {
+ BootGoResult::Stopped
+ } else {
+ BootGoResult::Normal { result, asserts, resp: rsp }
+ }
}
pub fn boot_trailer_sz(align: u32) -> u32 {
@@ -67,9 +129,12 @@
}
}
-pub fn kw_encrypt(kek: &[u8], seckey: &[u8]) -> Result<[u8; 24], &'static str> {
+pub fn kw_encrypt(kek: &[u8], seckey: &[u8], keylen: u32) -> Result<Vec<u8>, &'static str> {
unsafe {
- let mut encbuf = [0u8; 24];
+ let mut encbuf = vec![0u8; 24];
+ if keylen == 32 {
+ encbuf = vec![0u8; 40];
+ }
if raw::kw_encrypt_(kek.as_ptr(), seckey.as_ptr(), encbuf.as_mut_ptr()) == 0 {
return Ok(encbuf);
}
@@ -79,13 +144,14 @@
mod raw {
use crate::area::CAreaDesc;
- use crate::api::CSimContext;
+ use crate::api::{BootRsp, CSimContext};
extern "C" {
// This generates a warning about `CAreaDesc` not being foreign safe. There doesn't appear to
// be any way to get rid of this warning. See https://github.com/rust-lang/rust/issues/34798
// for information and tracking.
- pub fn invoke_boot_go(sim_ctx: *mut CSimContext, areadesc: *const CAreaDesc) -> libc::c_int;
+ pub fn invoke_boot_go(sim_ctx: *mut CSimContext, areadesc: *const CAreaDesc,
+ rsp: *mut BootRsp) -> libc::c_int;
pub fn boot_trailer_sz(min_write_sz: u32) -> u32;
pub fn boot_status_sz(min_write_sz: u32) -> u32;
diff --git a/sim/mcuboot-sys/src/lib.rs b/sim/mcuboot-sys/src/lib.rs
index 8acb246..bc3fc49 100644
--- a/sim/mcuboot-sys/src/lib.rs
+++ b/sim/mcuboot-sys/src/lib.rs
@@ -10,3 +10,43 @@
pub mod api;
pub use crate::area::{AreaDesc, FlashId};
+
+/// For testing the ram load feature, we need to emulate a block of RAM and be able to pass that
+/// down to the C code. The call down to boot_go should go through this object so that the buffer
+/// itself is managed properly.
+pub struct RamBlock {
+ ram: Vec<u8>,
+ offset: u32, // 32-bit offset.
+}
+
+impl RamBlock {
+ pub fn new(size: u32, offset: u32) -> RamBlock {
+ RamBlock {
+ ram: vec![0; size as usize],
+ offset: offset,
+ }
+ }
+
+ /// Borrow the RAM buffer, with 'offset' being the beginning of the buffer.
+ pub fn borrow(&self) -> &[u8] {
+ &self.ram
+ }
+
+ /// Borrow a piece of the ram, with 'offset' being the beginning of the buffer.
+ pub fn borrow_part(&self, base: usize, size: usize) -> &[u8] {
+ &self.ram[base..base+size]
+ }
+
+ pub fn invoke<F, R>(&self, act: F) -> R
+ where F: FnOnce() -> R
+ {
+ api::set_ram_info(api::BootsimRamInfo {
+ start: self.offset,
+ size: self.ram.len() as u32,
+ base: &self.ram[0] as *const u8 as usize - self.offset as usize,
+ });
+ let result = act();
+ api::clear_ram_info();
+ result
+ }
+}
diff --git a/sim/simflash/src/lib.rs b/sim/simflash/src/lib.rs
index c52f53e..e5ccb96 100644
--- a/sim/simflash/src/lib.rs
+++ b/sim/simflash/src/lib.rs
@@ -66,8 +66,6 @@
fn align(&self) -> usize;
fn erased_val(&self) -> u8;
-
- fn set_erase_by_sector(&mut self, enable: bool);
}
fn ebounds<T: AsRef<str>>(message: T) -> FlashError {
@@ -96,7 +94,6 @@
align: usize,
verify_writes: bool,
erased_val: u8,
- erase_by_sector: bool,
}
impl SimFlash {
@@ -133,11 +130,11 @@
// Scan the sector map, and return the base and offset within a sector for this given byte.
// Returns None if the value is outside of the device.
- fn get_sector(&self, offset: usize) -> Option<(usize, usize, usize)> {
+ fn get_sector(&self, offset: usize) -> Option<(usize, usize)> {
let mut offset = offset;
for (sector, &size) in self.sectors.iter().enumerate() {
if offset < size {
- return Some((sector, offset, size));
+ return Some((sector, offset));
}
offset -= size;
}
@@ -153,21 +150,8 @@
/// strict, and make sure that the passed arguments are exactly at a sector boundary, otherwise
/// return an error.
fn erase(&mut self, offset: usize, len: usize) -> Result<()> {
- let (_start, mut slen, ssize) = self.get_sector(offset).ok_or_else(|| ebounds("start"))?;
- let (end, mut elen, _) = self.get_sector(offset + len - 1).ok_or_else(|| ebounds("end"))?;
-
- let mut offset = offset;
- let mut len = len;
-
- if self.erase_by_sector {
- // info!("erase_by_sector: {:#X}/{:#X} -> {:#X}/{:#X}", offset, len, offset - slen, ssize);
-
- offset = offset - slen;
- len = ssize;
-
- slen = 0;
- elen = self.sectors[end] - 1;
- }
+ let (_start, slen) = self.get_sector(offset).ok_or_else(|| ebounds("start"))?;
+ let (end, elen) = self.get_sector(offset + len - 1).ok_or_else(|| ebounds("end"))?;
if slen != 0 {
bail!(ebounds("offset not at start of sector"));
@@ -283,10 +267,6 @@
fn erased_val(&self) -> u8 {
self.erased_val
}
-
- fn set_erase_by_sector(&mut self, enable: bool) {
- self.erase_by_sector = enable;
- }
}
/// It is possible to iterate over the sectors in the device, each element returning this.
@@ -339,6 +319,10 @@
let mut f2 = SimFlash::new(vec![16 * 1024, 16 * 1024, 16 * 1024, 64 * 1024,
128 * 1024, 128 * 1024, 128 * 1024], 1, erased_val);
test_device(&mut f2, erased_val);
+
+ // PSoC style, uniform sectors.
+ let mut f3 = SimFlash::new(vec![512usize; 1024], 512, erased_val);
+ test_device(&mut f3, erased_val);
}
}
diff --git a/sim/src/caps.rs b/sim/src/caps.rs
index c626ee6..3fbf4c3 100644
--- a/sim/src/caps.rs
+++ b/sim/src/caps.rs
@@ -1,6 +1,6 @@
// Copyright (c) 2017-2019 Linaro LTD
// Copyright (c) 2019 JUUL Labs
-// Copyright (c) 2019 Arm Limited
+// Copyright (c) 2019-2021 Arm Limited
//
// SPDX-License-Identifier: Apache-2.0
@@ -25,7 +25,10 @@
DowngradePrevention = (1 << 12),
EncX25519 = (1 << 13),
Bootstrap = (1 << 14),
- SwapUsingStatus = (1 << 15),
+ Aes256 = (1 << 15),
+ RamLoad = (1 << 16),
+ DirectXip = (1 << 17),
+ SwapUsingStatus = (1 << 18),
}
impl Caps {
@@ -39,6 +42,12 @@
pub fn get_num_images() -> usize {
(unsafe { bootutil_get_num_images() }) as usize
}
+
+ /// Query if this configuration performs some kind of upgrade by writing to flash.
+ pub fn modifies_flash() -> bool {
+ // All other configurations perform upgrades by writing to flash.
+ !(Self::RamLoad.present() || Self::DirectXip.present())
+ }
}
extern "C" {
diff --git a/sim/src/image.rs b/sim/src/image.rs
index 6bd14c5..29ddedd 100644
--- a/sim/src/image.rs
+++ b/sim/src/image.rs
@@ -1,6 +1,6 @@
// Copyright (c) 2019 Linaro LTD
// Copyright (c) 2019-2020 JUUL Labs
-// Copyright (c) 2019 Arm Limited
+// Copyright (c) 2019-2021 Arm Limited
//
// SPDX-License-Identifier: Apache-2.0
@@ -19,22 +19,26 @@
rngs::SmallRng,
};
use std::{
- collections::HashSet,
+ collections::{BTreeMap, HashSet},
io::{Cursor, Write},
mem,
slice,
};
-use aes_ctr::{
+use aes::{
+ Aes128,
Aes128Ctr,
- stream_cipher::{
- generic_array::GenericArray,
- NewStreamCipher,
- SyncStreamCipher,
- },
+ Aes256,
+ Aes256Ctr,
+ NewBlockCipher,
};
+use cipher::{
+ FromBlockCipher,
+ generic_array::GenericArray,
+ StreamCipher,
+ };
use simflash::{Flash, SimFlash, SimMultiFlash};
-use mcuboot_sys::{c, AreaDesc, FlashId};
+use mcuboot_sys::{c, AreaDesc, FlashId, RamBlock};
use crate::{
ALL_DEVICES,
DeviceName,
@@ -50,6 +54,11 @@
UpgradeInfo,
};
use crate::tlv::{ManifestGen, TlvGen, TlvFlags};
+use typenum::{U32, U16};
+
+/// For testing, use a non-zero offset for the ram-load, to make sure the offset is getting used
+/// properly, but the value is not really that important.
+const RAM_LOAD_ADDR: u32 = 1024;
/// A builder for Images. This describes a single run of the simulator,
/// capturing the configuration of a particular set of devices, including
@@ -59,6 +68,7 @@
flash: SimMultiFlash,
areadesc: AreaDesc,
slots: Vec<[SlotInfo; 2]>,
+ ram: RamData,
}
/// Images represents the state of a simulation for a given set of images.
@@ -69,6 +79,7 @@
areadesc: AreaDesc,
images: Vec<OneImage>,
total_count: Option<i32>,
+ ram: RamData,
}
/// When doing multi-image, there is an instance of this information for
@@ -83,10 +94,34 @@
/// is just the unencrypted payload. For encrypted images, we store both
/// the encrypted and the plaintext.
struct ImageData {
+ size: usize,
plain: Vec<u8>,
cipher: Option<Vec<u8>>,
}
+/// For the RamLoad test cases, we need a contiguous area of RAM to load these images into. For
+/// multi-image builds, these may not correspond with the offsets. This has to be computed early,
+/// before images are built, because each image contains the offset where the image is to be loaded
+/// in the header, which is contained within the signature.
+#[derive(Clone, Debug)]
+struct RamData {
+ places: BTreeMap<SlotKey, SlotPlace>,
+ total: u32,
+}
+
+/// Every slot is indexed by this key.
+#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
+struct SlotKey {
+ dev_id: u8,
+ base_off: usize,
+}
+
+#[derive(Clone, Debug)]
+struct SlotPlace {
+ offset: u32,
+ size: u32,
+}
+
impl ImagesBuilder {
/// Construct a new image builder for the given device. Returns
/// Some(builder) if is possible to test this configuration, or None if
@@ -148,10 +183,13 @@
slots.push([primary, secondary]);
}
+ let ram = RamData::new(&slots);
+
Ok(ImagesBuilder {
flash,
areadesc,
slots,
+ ram,
})
}
@@ -174,16 +212,17 @@
pub fn make_no_upgrade_image(self, deps: &DepTest) -> Images {
let num_images = self.num_images();
let mut flash = self.flash;
+ let ram = self.ram.clone(); // TODO: This is wasteful.
let images = self.slots.into_iter().enumerate().map(|(image_num, slots)| {
let dep: Box<dyn Depender> = if num_images > 1 {
Box::new(PairDep::new(num_images, image_num, deps))
} else {
Box::new(BoringDep::new(image_num, deps))
};
- let primaries = install_image(&mut flash, &slots[0], 42784, &*dep, false);
+ let primaries = install_image(&mut flash, &slots[0], 42784, &ram, &*dep, false);
let upgrades = match deps.depends[image_num] {
DepType::NoUpgrade => install_no_image(),
- _ => install_image(&mut flash, &slots[1], 46928, &*dep, false)
+ _ => install_image(&mut flash, &slots[1], 46928, &ram, &*dep, false)
};
OneImage {
slots,
@@ -196,6 +235,7 @@
areadesc: self.areadesc,
images,
total_count: None,
+ ram: self.ram,
}
}
@@ -205,6 +245,11 @@
mark_upgrade(&mut images.flash, &image.slots[1]);
}
+ // The count is meaningless if no flash operations are performed.
+ if !Caps::modifies_flash() {
+ return images;
+ }
+
// upgrades without fails, counts number of flash operations
let total_count = match images.run_basic_upgrade(permanent) {
Some(v) => v,
@@ -222,10 +267,11 @@
pub fn make_bad_secondary_slot_image(self) -> Images {
let mut bad_flash = self.flash;
+ let ram = self.ram.clone(); // TODO: Avoid this clone.
let images = self.slots.into_iter().enumerate().map(|(image_num, slots)| {
let dep = BoringDep::new(image_num, &NO_DEPS);
- let primaries = install_image(&mut bad_flash, &slots[0], 32784, &dep, false);
- let upgrades = install_image(&mut bad_flash, &slots[1], 41928, &dep, true);
+ let primaries = install_image(&mut bad_flash, &slots[0], 32784, &ram, &dep, false);
+ let upgrades = install_image(&mut bad_flash, &slots[1], 41928, &ram, &dep, true);
OneImage {
slots,
primaries,
@@ -236,14 +282,16 @@
areadesc: self.areadesc,
images,
total_count: None,
+ ram: self.ram,
}
}
pub fn make_erased_secondary_image(self) -> Images {
let mut flash = self.flash;
+ let ram = self.ram.clone(); // TODO: Avoid this clone.
let images = self.slots.into_iter().enumerate().map(|(image_num, slots)| {
let dep = BoringDep::new(image_num, &NO_DEPS);
- let primaries = install_image(&mut flash, &slots[0], 32784, &dep, false);
+ let primaries = install_image(&mut flash, &slots[0], 32784, &ram, &dep, false);
let upgrades = install_no_image();
OneImage {
slots,
@@ -255,15 +303,17 @@
areadesc: self.areadesc,
images,
total_count: None,
+ ram: self.ram,
}
}
pub fn make_bootstrap_image(self) -> Images {
let mut flash = self.flash;
+ let ram = self.ram.clone(); // TODO: Avoid this clone.
let images = self.slots.into_iter().enumerate().map(|(image_num, slots)| {
let dep = BoringDep::new(image_num, &NO_DEPS);
let primaries = install_no_image();
- let upgrades = install_image(&mut flash, &slots[1], 32784, &dep, false);
+ let upgrades = install_image(&mut flash, &slots[1], 32784, &ram, &dep, false);
OneImage {
slots,
primaries,
@@ -274,15 +324,14 @@
areadesc: self.areadesc,
images,
total_count: None,
+ ram: self.ram,
}
}
/// Build the Flash and area descriptor for a given device.
pub fn make_device(device: DeviceName, align: usize, erased_val: u8) -> (SimMultiFlash, AreaDesc, &'static [Caps]) {
- info!(" +++ Make new device...");
match device {
DeviceName::Stm32f4 => {
- info!("DeviceName::Stm32f4");
// STM style flash. Large sectors, with a large scratch area.
let dev = SimFlash::new(vec![16 * 1024, 16 * 1024, 16 * 1024, 16 * 1024,
64 * 1024,
@@ -300,7 +349,6 @@
(flash, areadesc, &[Caps::SwapUsingMove, Caps::SwapUsingStatus])
}
DeviceName::K64f => {
- info!("DeviceName::K64f");
// NXP style flash. Small sectors, one small sector for scratch.
let dev = SimFlash::new(vec![4096; 128], align as usize, erased_val);
@@ -316,7 +364,6 @@
(flash, areadesc, &[Caps::SwapUsingStatus])
}
DeviceName::K64fBig => {
- info!("DeviceName::K64fBig");
// Simulating an STM style flash on top of an NXP style flash. Underlying flash device
// uses small sectors, but we tell the bootloader they are large.
let dev = SimFlash::new(vec![4096; 128], align as usize, erased_val);
@@ -333,7 +380,6 @@
(flash, areadesc, &[Caps::SwapUsingMove, Caps::SwapUsingStatus])
}
DeviceName::Nrf52840 => {
- info!("DeviceName::Nrf52840");
// Simulating the flash on the nrf52840 with partitions set up so that the scratch size
// does not divide into the image size.
let dev = SimFlash::new(vec![4096; 128], align as usize, erased_val);
@@ -350,7 +396,6 @@
(flash, areadesc, &[Caps::SwapUsingStatus])
}
DeviceName::Nrf52840UnequalSlots => {
- info!("DeviceName::Nrf52840UnequalSlots");
let dev = SimFlash::new(vec![4096; 128], align as usize, erased_val);
let dev_id = 0;
@@ -364,7 +409,6 @@
(flash, areadesc, &[Caps::SwapUsingScratch, Caps::OverwriteUpgrade, Caps::SwapUsingStatus])
}
DeviceName::Nrf52840SpiFlash => {
- info!("DeviceName::Nrf52840SpiFlash");
// Simulate nrf52840 with external SPI flash. The external SPI flash
// has a larger sector size so for now store scratch on that flash.
let dev0 = SimFlash::new(vec![4096; 128], align as usize, erased_val);
@@ -384,7 +428,6 @@
(flash, areadesc, &[Caps::SwapUsingMove, Caps::SwapUsingStatus])
}
DeviceName::K64fMulti => {
- info!("DeviceName::K64fMulti");
// NXP style flash, but larger, to support multiple images.
let dev = SimFlash::new(vec![4096; 256], align as usize, erased_val);
@@ -401,32 +444,21 @@
flash.insert(dev_id, dev);
(flash, areadesc, &[Caps::SwapUsingStatus])
}
- DeviceName::PSoC6Multi => {
- info!("DeviceName::PSoC6Multi");
- // NXP style flash, but larger, to support multiple images.
+ DeviceName::PSoC6 => {
+ // PSoC style flash of 512K, single-image case
+ let dev = SimFlash::new(vec![512; 1024], align as usize, erased_val);
+ let dev_id = 0;
let mut areadesc = AreaDesc::new();
+ areadesc.add_flash_sectors(dev_id, &dev);
+ areadesc.add_image(0x018000, 0x010000, FlashId::Image0, dev_id);
+ areadesc.add_image(0x028000, 0x010000, FlashId::Image1, dev_id);
+ areadesc.add_image(0x039800, 0x001000, FlashId::ImageScratch, dev_id);
+ areadesc.add_image(0x038000, 0x001800, FlashId::ImageSwapStatus, dev_id);
+
let mut flash = SimMultiFlash::new();
-
- // let dev0 = SimFlash::new(vec![4096; 256], align as usize, 0);
- let mut dev0 = SimFlash::new(vec![512; 1024], align as usize, 0);
- dev0.set_verify_writes(false);
- dev0.set_erase_by_sector(true);
-
- areadesc.add_flash_sectors(0, &dev0);
- areadesc.add_image(0x020000, 0x020000, FlashId::Image0, 0);
- areadesc.add_image(0x040000, 0x020000, FlashId::Image1, 0);
- areadesc.add_image(0x060000, 0x008000, FlashId::ImageScratch, 0);
- flash.insert(0, dev0);
-
- // let dev1 = SimFlash::new(vec![4096; 256], align as usize, erased_val);
- // areadesc.add_flash_sectors(1, &dev1);
- // areadesc.add_image(0x080000, 0x020000, FlashId::Image2, 0);
- // areadesc.add_image(0x0a0000, 0x020000, FlashId::Image3, 1);
- // flash.insert(1, dev1);
-
- // (flash, areadesc, &[])
- (flash, areadesc, &[Caps::SwapUsingScratch, Caps::SwapUsingMove])
+ flash.insert(dev_id, dev);
+ (flash, areadesc, &[Caps::SwapUsingMove])
}
}
}
@@ -461,8 +493,7 @@
if Caps::Bootstrap.present() {
info!("Try bootstraping image in the primary");
- let (result, _) = c::boot_go(&mut flash, &self.areadesc, None, false);
- if result != 0 {
+ if !c::boot_go(&mut flash, &self.areadesc, None, false).success() {
warn!("Failed first boot");
fails += 1;
}
@@ -490,17 +521,21 @@
/// Test a simple upgrade, with dependencies given, and verify that the
/// image does as is described in the test.
pub fn run_check_deps(&self, deps: &DepTest) -> bool {
+ if !Caps::modifies_flash() {
+ return false;
+ }
+
let (flash, _) = self.try_upgrade(None, true);
self.verify_dep_images(&flash, deps)
}
fn is_swap_upgrade(&self) -> bool {
- Caps::SwapUsingScratch.present() || Caps::SwapUsingMove.present() || Caps::SwapUsingStatus.present()
+ Caps::SwapUsingScratch.present() || Caps::SwapUsingMove.present()
}
pub fn run_basic_revert(&self) -> bool {
- if Caps::OverwriteUpgrade.present() {
+ if Caps::OverwriteUpgrade.present() || !Caps::modifies_flash() {
return false;
}
@@ -522,6 +557,10 @@
}
pub fn run_perm_with_fails(&self) -> bool {
+ if !Caps::modifies_flash() {
+ return false;
+ }
+
let mut fails = 0;
let total_flash_ops = self.total_count.unwrap();
@@ -563,6 +602,10 @@
}
pub fn run_perm_with_random_fails(&self, total_fails: usize) -> bool {
+ if !Caps::modifies_flash() {
+ return false;
+ }
+
let mut fails = 0;
let total_flash_ops = self.total_count.unwrap();
let (flash, total_counts) = self.try_random_fails(total_flash_ops, total_fails);
@@ -601,7 +644,7 @@
}
pub fn run_revert_with_fails(&self) -> bool {
- if Caps::OverwriteUpgrade.present() {
+ if Caps::OverwriteUpgrade.present() || !Caps::modifies_flash() {
return false;
}
@@ -621,7 +664,7 @@
}
pub fn run_norevert(&self) -> bool {
- if Caps::OverwriteUpgrade.present() {
+ if Caps::OverwriteUpgrade.present() || !Caps::modifies_flash() {
return false;
}
@@ -631,8 +674,7 @@
info!("Try norevert");
// First do a normal upgrade...
- let (result, _) = c::boot_go(&mut flash, &self.areadesc, None, false);
- if result != 0 {
+ if !c::boot_go(&mut flash, &self.areadesc, None, false).success() {
warn!("Failed first boot");
fails += 1;
}
@@ -665,8 +707,7 @@
fails += 1;
}
- let (result, _) = c::boot_go(&mut flash, &self.areadesc, None, false);
- if result != 0 {
+ if !c::boot_go(&mut flash, &self.areadesc, None, false).success() {
warn!("Failed second boot");
fails += 1;
}
@@ -701,8 +742,7 @@
info!("Try no downgrade");
// First, do a normal upgrade.
- let (result, _) = c::boot_go(&mut flash, &self.areadesc, None, false);
- if result != 0 {
+ if !c::boot_go(&mut flash, &self.areadesc, None, false).success() {
warn!("Failed first boot");
fails += 1;
}
@@ -723,6 +763,11 @@
// image_ok set while there is no image on the secondary slot, so no revert
// should ever happen...
pub fn run_norevert_newimage(&self) -> bool {
+ if !Caps::modifies_flash() {
+ info!("Skipping run_norevert_newimage, as configuration doesn't modify flash");
+ return false;
+ }
+
let mut flash = self.flash.clone();
let mut fails = 0;
@@ -739,8 +784,7 @@
}
// Run the bootloader...
- let (result, _) = c::boot_go(&mut flash, &self.areadesc, None, false);
- if result != 0 {
+ if !c::boot_go(&mut flash, &self.areadesc, None, false).success() {
warn!("Failed first boot");
fails += 1;
}
@@ -777,6 +821,12 @@
info!("Try upgrade image with bad signature");
+ // Only perform this test if an upgrade is expected to happen.
+ if !Caps::modifies_flash() {
+ info!("Skipping upgrade image with bad signature");
+ return false;
+ }
+
self.mark_upgrades(&mut flash, 0);
self.mark_permanent_upgrades(&mut flash, 0);
self.mark_upgrades(&mut flash, 1);
@@ -788,8 +838,7 @@
}
// Run the bootloader...
- let (result, _) = c::boot_go(&mut flash, &self.areadesc, None, false);
- if result != 0 {
+ if !c::boot_go(&mut flash, &self.areadesc, None, false).success() {
warn!("Failed first boot");
fails += 1;
}
@@ -815,6 +864,10 @@
// Should detect there is a leftover trailer in an otherwise erased
// secondary slot and erase its trailer.
pub fn run_secondary_leftover_trailer(&self) -> bool {
+ if !Caps::modifies_flash() {
+ return false;
+ }
+
let mut flash = self.flash.clone();
let mut fails = 0;
@@ -825,8 +878,7 @@
self.mark_upgrades(&mut flash, 1);
// Run the bootloader...
- let (result, _) = c::boot_go(&mut flash, &self.areadesc, None, false);
- if result != 0 {
+ if !c::boot_go(&mut flash, &self.areadesc, None, false).success() {
warn!("Failed first boot");
fails += 1;
}
@@ -861,7 +913,7 @@
/// allowing for fails in the status area. This should run to the end
/// and warn that write fails were detected...
pub fn run_with_status_fails_complete(&self) -> bool {
- if !Caps::ValidatePrimarySlot.present() {
+ if !Caps::ValidatePrimarySlot.present() || !Caps::modifies_flash() {
return false;
}
@@ -873,15 +925,15 @@
self.mark_permanent_upgrades(&mut flash, 1);
self.mark_bad_status_with_rate(&mut flash, 0, 1.0);
- let (result, asserts) = c::boot_go(&mut flash, &self.areadesc, None, true);
- if result != 0 {
+ let result = c::boot_go(&mut flash, &self.areadesc, None, true);
+ if !result.success() {
warn!("Failed!");
fails += 1;
}
// Failed writes to the marked "bad" region don't assert anymore.
// Any detected assert() is happening in another part of the code.
- if asserts != 0 {
+ if result.asserts() != 0 {
warn!("At least one assert() was called");
fails += 1;
}
@@ -899,8 +951,7 @@
info!("validate primary slot enabled; \
re-run of boot_go should just work");
- let (result, _) = c::boot_go(&mut flash, &self.areadesc, None, false);
- if result != 0 {
+ if !c::boot_go(&mut flash, &self.areadesc, None, false).success() {
warn!("Failed!");
fails += 1;
}
@@ -916,7 +967,7 @@
/// allowing for fails in the status area. This should run to the end
/// and warn that write fails were detected...
pub fn run_with_status_fails_with_reset(&self) -> bool {
- if Caps::OverwriteUpgrade.present() {
+ if Caps::OverwriteUpgrade.present() || !Caps::modifies_flash() {
false
} else if Caps::ValidatePrimarySlot.present() {
@@ -932,7 +983,7 @@
self.mark_bad_status_with_rate(&mut flash, 0, 0.5);
// Should not fail, writing to bad regions does not assert
- let (_, asserts) = c::boot_go(&mut flash, &self.areadesc, Some(&mut count), true);
+ let asserts = c::boot_go(&mut flash, &self.areadesc, Some(&mut count), true).asserts();
if asserts != 0 {
warn!("At least one assert() was called");
fails += 1;
@@ -941,7 +992,7 @@
self.reset_bad_status(&mut flash, 0);
info!("Resuming an interrupted swap operation");
- let (_, asserts) = c::boot_go(&mut flash, &self.areadesc, None, true);
+ let asserts = c::boot_go(&mut flash, &self.areadesc, None, true).asserts();
// This might throw no asserts, for large sector devices, where
// a single failure writing is indistinguishable from no failure,
@@ -968,7 +1019,7 @@
self.mark_bad_status_with_rate(&mut flash, 0, 1.0);
// This is expected to fail while writing to bad regions...
- let (_, asserts) = c::boot_go(&mut flash, &self.areadesc, None, true);
+ let asserts = c::boot_go(&mut flash, &self.areadesc, None, true).asserts();
if asserts == 0 {
warn!("No assert() detected");
fails += 1;
@@ -978,6 +1029,78 @@
}
}
+ /// Test the direct XIP configuration. With this mode, flash images are never moved, and the
+ /// bootloader merely selects which partition is the proper one to boot.
+ pub fn run_direct_xip(&self) -> bool {
+ if !Caps::DirectXip.present() {
+ return false;
+ }
+
+ // Clone the flash so we can tell if unchanged.
+ let mut flash = self.flash.clone();
+
+ let result = c::boot_go(&mut flash, &self.areadesc, None, true);
+
+ // Ensure the boot was successful.
+ let resp = if let Some(resp) = result.resp() {
+ resp
+ } else {
+ panic!("Boot didn't return a valid result");
+ };
+
+ // This configuration should always try booting from the first upgrade slot.
+ if let Some((offset, _, dev_id)) = self.areadesc.find(FlashId::Image1) {
+ assert_eq!(offset, resp.image_off as usize);
+ assert_eq!(dev_id, resp.flash_dev_id);
+ } else {
+ panic!("Unable to find upgrade image");
+ }
+ false
+ }
+
+ /// Test the ram-loading.
+ pub fn run_ram_load(&self) -> bool {
+ if !Caps::RamLoad.present() {
+ return false;
+ }
+
+ // Clone the flash so we can tell if unchanged.
+ let mut flash = self.flash.clone();
+
+ // Setup ram based on the ram configuration we determined earlier for the images.
+ let ram = RamBlock::new(self.ram.total - RAM_LOAD_ADDR, RAM_LOAD_ADDR);
+
+ // println!("Ram: {:#?}", self.ram);
+
+ // Verify that the images area loaded into this.
+ let result = ram.invoke(|| c::boot_go(&mut flash, &self.areadesc, None, true));
+ if !result.success() {
+ error!("Failed to execute ram-load");
+ return true;
+ }
+
+ // Verify each image.
+ for image in &self.images {
+ let place = self.ram.lookup(&image.slots[0]);
+ let ram_image = ram.borrow_part(place.offset as usize - RAM_LOAD_ADDR as usize,
+ place.size as usize);
+ let src_sz = image.upgrades.size();
+ if src_sz > ram_image.len() {
+ error!("Image ended up too large, nonsensical");
+ return true;
+ }
+ let src_image = &image.upgrades.plain[0..src_sz];
+ let ram_image = &ram_image[0..src_sz];
+ if ram_image != src_image {
+ error!("Image not loaded correctly");
+ return true;
+ }
+
+ }
+
+ return false;
+ }
+
/// Adds a new flash area that fails statistically
fn mark_bad_status_with_rate(&self, flash: &mut SimMultiFlash, slot: usize,
rate: f32) {
@@ -1028,18 +1151,18 @@
let mut counter = stop.unwrap_or(0);
let (first_interrupted, count) = match c::boot_go(&mut flash, &self.areadesc, Some(&mut counter), false) {
- (-0x13579, _) => (true, stop.unwrap()),
- (0, _) => (false, -counter),
- (x, _) => panic!("Unknown return: {}", x),
+ x if x.interrupted() => (true, stop.unwrap()),
+ x if x.success() => (false, -counter),
+ x => panic!("Unknown return: {:?}", x),
};
counter = 0;
if first_interrupted {
// fl.dump();
match c::boot_go(&mut flash, &self.areadesc, Some(&mut counter), false) {
- (-0x13579, _) => panic!("Shouldn't stop again"),
- (0, _) => (),
- (x, _) => panic!("Unknown return: {}", x),
+ x if x.interrupted() => panic!("Shouldn't stop again"),
+ x if x.success() => (),
+ x => panic!("Unknown return: {:?}", x),
}
}
@@ -1052,7 +1175,7 @@
// fl.write_file("image0.bin").unwrap();
for i in 0 .. count {
info!("Running boot pass {}", i + 1);
- assert_eq!(c::boot_go(&mut flash, &self.areadesc, None, false), (0, 0));
+ assert!(c::boot_go(&mut flash, &self.areadesc, None, false).success_no_asserts());
}
flash
}
@@ -1062,8 +1185,7 @@
let mut fails = 0;
let mut counter = stop;
- let (x, _) = c::boot_go(&mut flash, &self.areadesc, Some(&mut counter), false);
- if x != -0x13579 {
+ if !c::boot_go(&mut flash, &self.areadesc, Some(&mut counter), false).interrupted() {
warn!("Should have stopped test at interruption point");
fails += 1;
}
@@ -1075,8 +1197,7 @@
fails += 1;
}
- let (x, _) = c::boot_go(&mut flash, &self.areadesc, None, false);
- if x != 0 {
+ if !c::boot_go(&mut flash, &self.areadesc, None, false).success() {
warn!("Should have finished test upgrade");
fails += 1;
}
@@ -1104,14 +1225,12 @@
// Do Revert
let mut counter = stop;
- let (x, _) = c::boot_go(&mut flash, &self.areadesc, Some(&mut counter), false);
- if x != -0x13579 {
+ if !c::boot_go(&mut flash, &self.areadesc, Some(&mut counter), false).interrupted() {
warn!("Should have stopped revert at interruption point");
fails += 1;
}
- let (x, _) = c::boot_go(&mut flash, &self.areadesc, None, false);
- if x != 0 {
+ if !c::boot_go(&mut flash, &self.areadesc, None, false).success() {
warn!("Should have finished revert upgrade");
fails += 1;
}
@@ -1138,8 +1257,7 @@
fails += 1;
}
- let (x, _) = c::boot_go(&mut flash, &self.areadesc, None, false);
- if x != 0 {
+ if !c::boot_go(&mut flash, &self.areadesc, None, false).success() {
warn!("Should have finished 3rd boot");
fails += 1;
}
@@ -1166,20 +1284,20 @@
let mut resets = vec![0i32; count];
let mut remaining_ops = total_ops;
for reset in &mut resets {
- let reset_counter = rng.gen_range(1, remaining_ops / 2);
+ let reset_counter = rng.gen_range(1 ..= remaining_ops / 2);
let mut counter = reset_counter;
match c::boot_go(&mut flash, &self.areadesc, Some(&mut counter), false) {
- (0, _) | (-0x13579, _) => (),
- (x, _) => panic!("Unknown return: {}", x),
+ x if x.interrupted() => (),
+ x => panic!("Unknown return: {:?}", x),
}
remaining_ops -= reset_counter;
*reset = reset_counter;
}
match c::boot_go(&mut flash, &self.areadesc, None, false) {
- (-0x13579, _) => panic!("Should not be have been interrupted!"),
- (0, _) => (),
- (x, _) => panic!("Unknown return: {}", x),
+ x if x.interrupted() => panic!("Should not be have been interrupted!"),
+ x if x.success() => (),
+ x => panic!("Unknown return: {:?}", x),
}
(flash, resets)
@@ -1266,6 +1384,40 @@
}
}
+impl RamData {
+ // TODO: This is not correct. The second slot of each image should be at the same address as
+ // the primary.
+ fn new(slots: &[[SlotInfo; 2]]) -> RamData {
+ let mut addr = RAM_LOAD_ADDR;
+ let mut places = BTreeMap::new();
+ // println!("Setup:-------------");
+ for imgs in slots {
+ for si in imgs {
+ // println!("Setup: si: {:?}", si);
+ let offset = addr;
+ let size = si.len as u32;
+ places.insert(SlotKey {
+ dev_id: si.dev_id,
+ base_off: si.base_off,
+ }, SlotPlace { offset, size });
+ // println!(" load: offset: {}, size: {}", offset, size);
+ }
+ addr += imgs[0].len as u32;
+ }
+ RamData {
+ places,
+ total: addr,
+ }
+ }
+
+ /// Lookup the ram data associated with a given flash partition. We just panic if not present,
+ /// because all slots used should be in the map.
+ fn lookup(&self, slot: &SlotInfo) -> &SlotPlace {
+ self.places.get(&SlotKey{dev_id: slot.dev_id, base_off: slot.base_off})
+ .expect("RamData should contain all slots")
+ }
+}
+
/// Show the flash layout.
#[allow(dead_code)]
fn show_flash(flash: &dyn Flash) {
@@ -1280,6 +1432,7 @@
/// Install a "program" into the given image. This fakes the image header, or at least all of the
/// fields used by the given code. Returns a copy of the image that was written.
fn install_image(flash: &mut SimMultiFlash, slot: &SlotInfo, len: usize,
+ ram: &RamData,
deps: &dyn Depender, bad_sig: bool) -> ImageData {
let offset = slot.base_off;
let slot_len = slot.len;
@@ -1294,10 +1447,17 @@
const HDR_SIZE: usize = 32;
+ let place = ram.lookup(&slot);
+ let load_addr = if Caps::RamLoad.present() {
+ place.offset
+ } else {
+ 0
+ };
+
// Generate a boot header. Note that the size doesn't include the header.
let header = ImageHeader {
magic: tlv.get_magic(),
- load_addr: 0,
+ load_addr,
hdr_size: HDR_SIZE as u16,
protect_tlv_size: tlv.protect_size(),
img_size: len as u32,
@@ -1329,17 +1489,27 @@
tlv.add_bytes(&b_img);
// Generate encrypted images
- let flag = TlvFlags::ENCRYPTED as u32;
- let is_encrypted = (tlv.get_flags() & flag) == flag;
+ let flag = TlvFlags::ENCRYPTED_AES128 as u32 | TlvFlags::ENCRYPTED_AES256 as u32;
+ let is_encrypted = (tlv.get_flags() & flag) != 0;
let mut b_encimg = vec![];
if is_encrypted {
+ let flag = TlvFlags::ENCRYPTED_AES256 as u32;
+ let aes256 = (tlv.get_flags() & flag) == flag;
tlv.generate_enc_key();
let enc_key = tlv.get_enc_key();
- let key = GenericArray::from_slice(enc_key.as_slice());
let nonce = GenericArray::from_slice(&[0; 16]);
- let mut cipher = Aes128Ctr::new(&key, &nonce);
b_encimg = b_img.clone();
- cipher.apply_keystream(&mut b_encimg);
+ if aes256 {
+ let key: &GenericArray<u8, U32> = GenericArray::from_slice(enc_key.as_slice());
+ let block = Aes256::new(&key);
+ let mut cipher = Aes256Ctr::from_block_cipher(block, &nonce);
+ cipher.apply_keystream(&mut b_encimg);
+ } else {
+ let key: &GenericArray<u8, U16> = GenericArray::from_slice(enc_key.as_slice());
+ let block = Aes128::new(&key);
+ let mut cipher = Aes128Ctr::from_block_cipher(block, &nonce);
+ cipher.apply_keystream(&mut b_encimg);
+ }
}
// Build the TLV itself.
@@ -1357,6 +1527,7 @@
// Pad the buffer to a multiple of the flash alignment.
let align = dev.align();
+ let image_sz = buf.len();
while buf.len() % align != 0 {
buf.push(dev.erased_val());
}
@@ -1399,6 +1570,7 @@
dev.read(offset, &mut copy).unwrap();
ImageData {
+ size: image_sz,
plain: copy,
cipher: enc_copy,
}
@@ -1425,6 +1597,7 @@
}
ImageData {
+ size: image_sz,
plain: copy,
cipher: enc_copy,
}
@@ -1434,6 +1607,7 @@
/// Install no image. This is used when no upgrade happens.
fn install_no_image() -> ImageData {
ImageData {
+ size: 0,
plain: vec![],
cipher: None,
}
@@ -1443,32 +1617,36 @@
if Caps::EcdsaP224.present() {
panic!("Ecdsa P224 not supported in Simulator");
}
+ let mut aes_key_size = 128;
+ if Caps::Aes256.present() {
+ aes_key_size = 256;
+ }
if Caps::EncKw.present() {
if Caps::RSA2048.present() {
- TlvGen::new_rsa_kw()
+ TlvGen::new_rsa_kw(aes_key_size)
} else if Caps::EcdsaP256.present() {
- TlvGen::new_ecdsa_kw()
+ TlvGen::new_ecdsa_kw(aes_key_size)
} else {
- TlvGen::new_enc_kw()
+ TlvGen::new_enc_kw(aes_key_size)
}
} else if Caps::EncRsa.present() {
if Caps::RSA2048.present() {
- TlvGen::new_sig_enc_rsa()
+ TlvGen::new_sig_enc_rsa(aes_key_size)
} else {
- TlvGen::new_enc_rsa()
+ TlvGen::new_enc_rsa(aes_key_size)
}
} else if Caps::EncEc256.present() {
if Caps::EcdsaP256.present() {
- TlvGen::new_ecdsa_ecies_p256()
+ TlvGen::new_ecdsa_ecies_p256(aes_key_size)
} else {
- TlvGen::new_ecies_p256()
+ TlvGen::new_ecies_p256(aes_key_size)
}
} else if Caps::EncX25519.present() {
if Caps::Ed25519.present() {
- TlvGen::new_ed25519_ecies_x25519()
+ TlvGen::new_ed25519_ecies_x25519(aes_key_size)
} else {
- TlvGen::new_ecies_x25519()
+ TlvGen::new_ecies_x25519(aes_key_size)
}
} else {
// The non-encrypted configuration.
@@ -1499,6 +1677,10 @@
_ => panic!("Invalid slot requested"),
}
}
+
+ fn size(&self) -> usize {
+ self.size
+ }
}
/// Verify that given image is present in the flash at the given offset.
@@ -1691,6 +1873,7 @@
const BOOT_FLAG_UNSET: Option<u8> = Some(3);
/// Write out the magic so that the loader tries doing an upgrade.
+#[cfg(not(feature = "swap-status"))]
pub fn mark_upgrade(flash: &mut SimMultiFlash, slot: &SlotInfo) {
let dev = flash.get_mut(&slot.dev_id).unwrap();
let align = dev.align();
@@ -1707,8 +1890,24 @@
}
}
+/// Write out the magic so that the loader tries doing an upgrade.
+#[cfg(feature = "swap-status")]
+pub fn mark_upgrade(flash: &mut SimMultiFlash, slot: &SlotInfo) {
+ let dev = flash.get_mut(&slot.dev_id).unwrap();
+ let align = dev.align();
+ let offset = slot.trailer_off + c::boot_max_align() * 4;
+ let mask = align - 1;
+ let sector_off = offset & !mask;
+ let mut buf = vec![dev.erased_val(); align];
+ dev.read(sector_off, &mut buf).unwrap();
+ buf[(offset & mask)..].copy_from_slice(MAGIC);
+ dev.erase(sector_off, align).unwrap();
+ dev.write(sector_off, &buf).unwrap();
+}
+
/// Writes the image_ok flag which, guess what, tells the bootloader
/// the this image is ok (not a test, and no revert is to be performed).
+#[cfg(not(feature = "swap-status"))]
fn mark_permanent_upgrade(flash: &mut SimMultiFlash, slot: &SlotInfo) {
// Overwrite mode always is permanent, and only the magic is used in
// the trailer. To avoid problems with large write sizes, don't try to
@@ -1725,9 +1924,32 @@
dev.write(off, &ok[..align]).unwrap();
}
+/// Writes the image_ok flag which, guess what, tells the bootloader
+/// the this image is ok (not a test, and no revert is to be performed).
+#[cfg(feature = "swap-status")]
+fn mark_permanent_upgrade(flash: &mut SimMultiFlash, slot: &SlotInfo) {
+ // Overwrite mode always is permanent, and only the magic is used in
+ // the trailer. To avoid problems with large write sizes, don't try to
+ // set anything in this case.
+ if Caps::OverwriteUpgrade.present() {
+ return;
+ }
+
+ let dev = flash.get_mut(&slot.dev_id).unwrap();
+ let align:usize = dev.align();
+ let mask:usize = align - 1;
+ let ok_off:usize = slot.trailer_off + c::boot_max_align() * 3;
+ let sector_off:usize = ok_off & !mask;
+ let mut buf = vec![dev.erased_val(); align];
+ dev.read(sector_off, &mut buf).unwrap();
+ buf[ok_off & mask] = 1u8;
+ dev.erase(sector_off, align).unwrap();
+ dev.write(sector_off, &buf[..align]).unwrap();
+}
+
// Drop some pseudo-random gibberish onto the data.
fn splat(data: &mut [u8], seed: usize) {
- let mut seed_block = [0u8; 16];
+ let mut seed_block = [0u8; 32];
let mut buf = Cursor::new(&mut seed_block[..]);
buf.write_u32::<LittleEndian>(0x135782ea).unwrap();
buf.write_u32::<LittleEndian>(0x92184728).unwrap();
@@ -1754,11 +1976,18 @@
}
#[cfg(not(feature = "large-write"))]
+#[cfg(not(feature = "swap-status"))]
fn test_alignments() -> &'static [usize] {
&[1, 2, 4, 8]
}
#[cfg(feature = "large-write")]
+#[cfg(not(feature = "swap-status"))]
fn test_alignments() -> &'static [usize] {
&[1, 2, 4, 8, 128, 512]
}
+
+#[cfg(feature = "swap-status")]
+fn test_alignments() -> &'static [usize] {
+ &[512]
+}
diff --git a/sim/src/lib.rs b/sim/src/lib.rs
index 4203c0e..69f13f1 100644
--- a/sim/src/lib.rs
+++ b/sim/src/lib.rs
@@ -63,8 +63,10 @@
#[derive(Copy, Clone, Debug, Deserialize)]
pub enum DeviceName {
- Stm32f4, K64f, K64fBig, K64fMulti, Nrf52840, Nrf52840SpiFlash,
- Nrf52840UnequalSlots, PSoC6Multi,
+ Stm32f4,
+ K64f, K64fBig, K64fMulti,
+ Nrf52840, Nrf52840SpiFlash, Nrf52840UnequalSlots,
+ PSoC6
}
pub static ALL_DEVICES: &[DeviceName] = &[
@@ -75,7 +77,7 @@
DeviceName::Nrf52840,
DeviceName::Nrf52840SpiFlash,
DeviceName::Nrf52840UnequalSlots,
- DeviceName::PSoC6Multi,
+ DeviceName::PSoC6
];
impl fmt::Display for DeviceName {
@@ -88,7 +90,7 @@
DeviceName::Nrf52840 => "nrf52840",
DeviceName::Nrf52840SpiFlash => "Nrf52840SpiFlash",
DeviceName::Nrf52840UnequalSlots => "Nrf52840UnequalSlots",
- DeviceName::PSoC6Multi => "psoc6multi",
+ DeviceName::PSoC6 => "PSoC6"
};
f.write_str(name)
}
diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs
index b6c3c96..6680b4f 100644
--- a/sim/src/tlv.rs
+++ b/sim/src/tlv.rs
@@ -1,5 +1,6 @@
// Copyright (c) 2017-2020 Linaro LTD
// Copyright (c) 2017-2020 JUUL Labs
+// Copyright (c) 2021 Arm Limited
//
// SPDX-License-Identifier: Apache-2.0
@@ -16,6 +17,8 @@
use byteorder::{
LittleEndian, WriteBytesExt,
};
+use cipher::FromBlockCipher;
+use crate::caps::Caps;
use crate::image::ImageVersion;
use log::info;
use ring::{digest, rand, agreement, hkdf, hmac};
@@ -27,15 +30,19 @@
ECDSA_P256_SHA256_ASN1_SIGNING,
Ed25519KeyPair,
};
-use aes_ctr::{
+use aes::{
+ Aes128,
Aes128Ctr,
- stream_cipher::{
- generic_array::GenericArray,
- NewStreamCipher,
- SyncStreamCipher,
- },
+ Aes256,
+ Aes256Ctr,
+ NewBlockCipher
+};
+use cipher::{
+ generic_array::GenericArray,
+ StreamCipher,
};
use mcuboot_sys::c;
+use typenum::{U16, U32};
#[repr(u16)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -49,7 +56,7 @@
RSA3072 = 0x23,
ED25519 = 0x24,
ENCRSA2048 = 0x30,
- ENCKW128 = 0x31,
+ ENCKW = 0x31,
ENCEC256 = 0x32,
ENCX25519 = 0x33,
DEPENDENCY = 0x40,
@@ -59,8 +66,9 @@
pub enum TlvFlags {
PIC = 0x01,
NON_BOOTABLE = 0x02,
- ENCRYPTED = 0x04,
+ ENCRYPTED_AES128 = 0x04,
RAM_LOAD = 0x20,
+ ENCRYPTED_AES256 = 0x08,
}
/// A generator for manifests. The format of the manifest can be either a
@@ -115,8 +123,6 @@
version: ImageVersion,
}
-const AES_KEY_LEN: usize = 16;
-
impl TlvGen {
/// Construct a new tlv generator that will only contain a hash of the data.
#[allow(dead_code)]
@@ -160,81 +166,126 @@
}
#[allow(dead_code)]
- pub fn new_enc_rsa() -> TlvGen {
+ pub fn new_enc_rsa(aes_key_size: u32) -> TlvGen {
+ let flag = if aes_key_size == 256 {
+ TlvFlags::ENCRYPTED_AES256 as u32
+ } else {
+ TlvFlags::ENCRYPTED_AES128 as u32
+ };
TlvGen {
- flags: TlvFlags::ENCRYPTED as u32,
+ flags: flag,
kinds: vec![TlvKinds::SHA256, TlvKinds::ENCRSA2048],
..Default::default()
}
}
#[allow(dead_code)]
- pub fn new_sig_enc_rsa() -> TlvGen {
+ pub fn new_sig_enc_rsa(aes_key_size: u32) -> TlvGen {
+ let flag = if aes_key_size == 256 {
+ TlvFlags::ENCRYPTED_AES256 as u32
+ } else {
+ TlvFlags::ENCRYPTED_AES128 as u32
+ };
TlvGen {
- flags: TlvFlags::ENCRYPTED as u32,
+ flags: flag,
kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCRSA2048],
..Default::default()
}
}
#[allow(dead_code)]
- pub fn new_enc_kw() -> TlvGen {
+ pub fn new_enc_kw(aes_key_size: u32) -> TlvGen {
+ let flag = if aes_key_size == 256 {
+ TlvFlags::ENCRYPTED_AES256 as u32
+ } else {
+ TlvFlags::ENCRYPTED_AES128 as u32
+ };
TlvGen {
- flags: TlvFlags::ENCRYPTED as u32,
- kinds: vec![TlvKinds::SHA256, TlvKinds::ENCKW128],
+ flags: flag,
+ kinds: vec![TlvKinds::SHA256, TlvKinds::ENCKW],
..Default::default()
}
}
#[allow(dead_code)]
- pub fn new_rsa_kw() -> TlvGen {
+ pub fn new_rsa_kw(aes_key_size: u32) -> TlvGen {
+ let flag = if aes_key_size == 256 {
+ TlvFlags::ENCRYPTED_AES256 as u32
+ } else {
+ TlvFlags::ENCRYPTED_AES128 as u32
+ };
TlvGen {
- flags: TlvFlags::ENCRYPTED as u32,
- kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCKW128],
+ flags: flag,
+ kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCKW],
..Default::default()
}
}
#[allow(dead_code)]
- pub fn new_ecdsa_kw() -> TlvGen {
+ pub fn new_ecdsa_kw(aes_key_size: u32) -> TlvGen {
+ let flag = if aes_key_size == 256 {
+ TlvFlags::ENCRYPTED_AES256 as u32
+ } else {
+ TlvFlags::ENCRYPTED_AES128 as u32
+ };
TlvGen {
- flags: TlvFlags::ENCRYPTED as u32,
- kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256, TlvKinds::ENCKW128],
+ flags: flag,
+ kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256, TlvKinds::ENCKW],
..Default::default()
}
}
#[allow(dead_code)]
- pub fn new_ecies_p256() -> TlvGen {
+ pub fn new_ecies_p256(aes_key_size: u32) -> TlvGen {
+ let flag = if aes_key_size == 256 {
+ TlvFlags::ENCRYPTED_AES256 as u32
+ } else {
+ TlvFlags::ENCRYPTED_AES128 as u32
+ };
TlvGen {
- flags: TlvFlags::ENCRYPTED as u32,
+ flags: flag,
kinds: vec![TlvKinds::SHA256, TlvKinds::ENCEC256],
..Default::default()
}
}
#[allow(dead_code)]
- pub fn new_ecdsa_ecies_p256() -> TlvGen {
+ pub fn new_ecdsa_ecies_p256(aes_key_size: u32) -> TlvGen {
+ let flag = if aes_key_size == 256 {
+ TlvFlags::ENCRYPTED_AES256 as u32
+ } else {
+ TlvFlags::ENCRYPTED_AES128 as u32
+ };
TlvGen {
- flags: TlvFlags::ENCRYPTED as u32,
+ flags: flag,
kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256, TlvKinds::ENCEC256],
..Default::default()
}
}
#[allow(dead_code)]
- pub fn new_ecies_x25519() -> TlvGen {
+ pub fn new_ecies_x25519(aes_key_size: u32) -> TlvGen {
+ let flag = if aes_key_size == 256 {
+ TlvFlags::ENCRYPTED_AES256 as u32
+ } else {
+ TlvFlags::ENCRYPTED_AES128 as u32
+ };
TlvGen {
- flags: TlvFlags::ENCRYPTED as u32,
+ flags: flag,
kinds: vec![TlvKinds::SHA256, TlvKinds::ENCX25519],
..Default::default()
}
}
#[allow(dead_code)]
- pub fn new_ed25519_ecies_x25519() -> TlvGen {
+ pub fn new_ed25519_ecies_x25519(aes_key_size: u32) -> TlvGen {
+ let flag = if aes_key_size == 256 {
+ TlvFlags::ENCRYPTED_AES256 as u32
+ } else {
+ TlvFlags::ENCRYPTED_AES128 as u32
+ };
TlvGen {
- flags: TlvFlags::ENCRYPTED as u32,
+ flags: flag,
kinds: vec![TlvKinds::SHA256, TlvKinds::ED25519, TlvKinds::ENCX25519],
..Default::default()
}
@@ -248,7 +299,12 @@
/// Retrieve the header flags for this configuration. This can be called at any time.
fn get_flags(&self) -> u32 {
- self.flags
+ // For the RamLoad case, add in the flag for this feature.
+ if Caps::RamLoad.present() {
+ self.flags | (TlvFlags::RAM_LOAD as u32)
+ } else {
+ self.flags
+ }
}
/// Add bytes to the covered hash.
@@ -479,20 +535,28 @@
result.extend_from_slice(&encbuf);
}
- if self.kinds.contains(&TlvKinds::ENCKW128) {
- let key_bytes = base64::decode(
- include_str!("../../enc-aes128kw.b64").trim()).unwrap();
-
+ if self.kinds.contains(&TlvKinds::ENCKW) {
+ let flag = TlvFlags::ENCRYPTED_AES256 as u32;
+ let aes256 = (self.get_flags() & flag) == flag;
+ let key_bytes = if aes256 {
+ base64::decode(
+ include_str!("../../enc-aes256kw.b64").trim()).unwrap()
+ } else {
+ base64::decode(
+ include_str!("../../enc-aes128kw.b64").trim()).unwrap()
+ };
let cipherkey = self.get_enc_key();
let cipherkey = cipherkey.as_slice();
- let encbuf = match c::kw_encrypt(&key_bytes, cipherkey) {
+ let keylen = if aes256 { 32 } else { 16 };
+ let encbuf = match c::kw_encrypt(&key_bytes, cipherkey, keylen) {
Ok(v) => v,
Err(_) => panic!("Failed to encrypt secret key"),
};
- assert!(encbuf.len() == 24);
- result.write_u16::<LittleEndian>(TlvKinds::ENCKW128 as u16).unwrap();
- result.write_u16::<LittleEndian>(24).unwrap();
+ let size = if aes256 { 40 } else { 24 };
+ assert!(encbuf.len() == size);
+ result.write_u16::<LittleEndian>(TlvKinds::ENCKW as u16).unwrap();
+ result.write_u16::<LittleEndian>(size as u16).unwrap();
result.extend_from_slice(&encbuf);
}
@@ -503,7 +567,6 @@
pem::parse(include_bytes!("../../enc-x25519-pub.pem").as_ref()).unwrap()
};
assert_eq!(key_bytes.tag, "PUBLIC KEY");
-
let rng = rand::SystemRandom::new();
let alg = if self.kinds.contains(&TlvKinds::ENCEC256) {
&agreement::ECDH_P256
@@ -535,15 +598,19 @@
}
}
+ let flag = TlvFlags::ENCRYPTED_AES256 as u32;
+ let aes256 = (self.get_flags() & flag) == flag;
+
let derived_key = match agreement::agree_ephemeral(
pk, &peer_pubk, ring::error::Unspecified, |shared| {
let salt = hkdf::Salt::new(hkdf::HKDF_SHA256, &[]);
let prk = salt.extract(&shared);
- let okm = match prk.expand(&[b"MCUBoot_ECIES_v1"], OkmLen(48)) {
+ let okm_len = if aes256 { 64 } else { 48 };
+ let okm = match prk.expand(&[b"MCUBoot_ECIES_v1"], OkmLen(okm_len)) {
Ok(okm) => okm,
Err(_) => panic!("Failed building HKDF OKM"),
};
- let mut buf = [0u8; 48];
+ let mut buf = if aes256 { vec![0u8; 64] } else { vec![0u8; 48] };
match okm.fill(&mut buf) {
Ok(_) => Ok(buf),
Err(_) => panic!("Failed generating HKDF output"),
@@ -554,13 +621,22 @@
Err(_) => panic!("Failed building HKDF"),
};
- let key = GenericArray::from_slice(&derived_key[..16]);
let nonce = GenericArray::from_slice(&[0; 16]);
- let mut cipher = Aes128Ctr::new(&key, &nonce);
let mut cipherkey = self.get_enc_key();
- cipher.apply_keystream(&mut cipherkey);
+ if aes256 {
+ let key: &GenericArray<u8, U32> = GenericArray::from_slice(&derived_key[..32]);
+ let block = Aes256::new(&key);
+ let mut cipher = Aes256Ctr::from_block_cipher(block, &nonce);
+ cipher.apply_keystream(&mut cipherkey);
+ } else {
+ let key: &GenericArray<u8, U16> = GenericArray::from_slice(&derived_key[..16]);
+ let block = Aes128::new(&key);
+ let mut cipher = Aes128Ctr::from_block_cipher(block, &nonce);
+ cipher.apply_keystream(&mut cipherkey);
+ }
- let key = hmac::Key::new(hmac::HMAC_SHA256, &derived_key[16..]);
+ let size = if aes256 { 32 } else { 16 };
+ let key = hmac::Key::new(hmac::HMAC_SHA256, &derived_key[size..]);
let tag = hmac::sign(&key, &cipherkey);
let mut buf = vec![];
@@ -569,13 +645,15 @@
buf.append(&mut cipherkey);
if self.kinds.contains(&TlvKinds::ENCEC256) {
- assert!(buf.len() == 113);
+ let size = if aes256 { 129 } else { 113 };
+ assert!(buf.len() == size);
result.write_u16::<LittleEndian>(TlvKinds::ENCEC256 as u16).unwrap();
- result.write_u16::<LittleEndian>(113).unwrap();
+ result.write_u16::<LittleEndian>(size as u16).unwrap();
} else {
- assert!(buf.len() == 80);
+ let size = if aes256 { 96 } else { 80 };
+ assert!(buf.len() == size);
result.write_u16::<LittleEndian>(TlvKinds::ENCX25519 as u16).unwrap();
- result.write_u16::<LittleEndian>(80).unwrap();
+ result.write_u16::<LittleEndian>(size as u16).unwrap();
}
result.extend_from_slice(&buf);
}
@@ -590,7 +668,13 @@
fn generate_enc_key(&mut self) {
let rng = rand::SystemRandom::new();
- let mut buf = vec![0u8; AES_KEY_LEN];
+ let flag = TlvFlags::ENCRYPTED_AES256 as u32;
+ let aes256 = (self.get_flags() & flag) == flag;
+ let mut buf = if aes256 {
+ vec![0u8; 32]
+ } else {
+ vec![0u8; 16]
+ };
if rng.fill(&mut buf).is_err() {
panic!("Error generating encrypted key");
}
@@ -599,7 +683,7 @@
}
fn get_enc_key(&self) -> Vec<u8> {
- if self.enc_key.len() != AES_KEY_LEN {
+ if self.enc_key.len() != 32 && self.enc_key.len() != 16 {
panic!("No random key was generated");
}
self.enc_key.clone()
diff --git a/sim/tests/core.rs b/sim/tests/core.rs
index 4e2d9c1..995c372 100644
--- a/sim/tests/core.rs
+++ b/sim/tests/core.rs
@@ -22,9 +22,11 @@
/// A single test, after setting up logging and such. Within the $body,
/// $arg will be bound to each device.
+/// The "$skip_feature" allows to set a feature for which this test will be skipped.
macro_rules! test_shell {
- ($name:ident, $arg: ident, $body:expr) => {
+ ($name:ident, $arg:ident, $body:expr, $skip_feature:expr) => {
#[test]
+ #[cfg_attr(feature = $skip_feature, ignore)]
fn $name() {
testlog::setup();
ImagesBuilder::each_device(|$arg| {
@@ -36,28 +38,34 @@
/// A typical test calls a particular constructor, and runs a given test on
/// that constructor.
+/// The "$skip_feature" allows to set a feature for which this test will be skipped.
macro_rules! sim_test {
- ($name:ident, $maker:ident($($margs:expr),*), $test:ident($($targs:expr),*)) => {
+ ($name:ident, $maker:ident($($margs:expr),*), $test:ident($($targs:expr),*), $skip_feature:expr) => {
test_shell!($name, r, {
let image = r.$maker($($margs),*);
dump_image(&image, stringify!($name));
assert!(!image.$test($($targs),*));
- });
+ }, $skip_feature);
};
}
-sim_test!(bad_secondary_slot, make_bad_secondary_slot_image(), run_signfail_upgrade());
-sim_test!(secondary_trailer_leftover, make_erased_secondary_image(), run_secondary_leftover_trailer());
-sim_test!(bootstrap, make_bootstrap_image(), run_bootstrap());
-sim_test!(norevert_newimage, make_no_upgrade_image(&NO_DEPS), run_norevert_newimage());
-sim_test!(basic_revert, make_image(&NO_DEPS, true), run_basic_revert());
-sim_test!(revert_with_fails, make_image(&NO_DEPS, false), run_revert_with_fails());
-sim_test!(perm_with_fails, make_image(&NO_DEPS, true), run_perm_with_fails());
-sim_test!(perm_with_random_fails, make_image(&NO_DEPS, true), run_perm_with_random_fails(5));
-sim_test!(norevert, make_image(&NO_DEPS, true), run_norevert());
-sim_test!(status_write_fails_complete, make_image(&NO_DEPS, true), run_with_status_fails_complete());
-sim_test!(status_write_fails_with_reset, make_image(&NO_DEPS, true), run_with_status_fails_with_reset());
-sim_test!(downgrade_prevention, make_image(&REV_DEPS, true), run_nodowngrade());
+sim_test!(bad_secondary_slot, make_bad_secondary_slot_image(), run_signfail_upgrade(), "");
+sim_test!(secondary_trailer_leftover, make_erased_secondary_image(), run_secondary_leftover_trailer(), "");
+sim_test!(bootstrap, make_bootstrap_image(), run_bootstrap(), "");
+sim_test!(norevert_newimage, make_no_upgrade_image(&NO_DEPS), run_norevert_newimage(), "");
+sim_test!(basic_revert, make_image(&NO_DEPS, true), run_basic_revert(), "");
+sim_test!(revert_with_fails, make_image(&NO_DEPS, false), run_revert_with_fails(), "");
+sim_test!(perm_with_fails, make_image(&NO_DEPS, true), run_perm_with_fails(), "");
+sim_test!(perm_with_random_fails, make_image(&NO_DEPS, true), run_perm_with_random_fails(5), "");
+sim_test!(norevert, make_image(&NO_DEPS, true), run_norevert(), "");
+sim_test!(status_write_fails_complete, make_image(&NO_DEPS, true), run_with_status_fails_complete(), "");
+
+sim_test!(status_write_fails_with_reset, make_image(&NO_DEPS, true),
+ run_with_status_fails_with_reset(), "swap-status");
+sim_test!(downgrade_prevention, make_image(&REV_DEPS, true), run_nodowngrade(), "");
+
+sim_test!(direct_xip_first, make_no_upgrade_image(&NO_DEPS), run_direct_xip(), "");
+sim_test!(ram_load_first, make_no_upgrade_image(&NO_DEPS), run_ram_load(), "");
// Test various combinations of incorrect dependencies.
test_shell!(dependency_combos, r, {
@@ -71,7 +79,7 @@
dump_image(&image, "dependency_combos");
assert!(!image.run_check_deps(&dep));
}
-});
+}, "");
/// These are the variants of dependencies we will test.
pub static TEST_DEPS: &[DepTest] = &[