diff --git a/.github/workflows/examples-k32w.yaml b/.github/workflows/examples-k32w.yaml
index 9885e1e43788b6..38f86e5b6f7a6d 100644
--- a/.github/workflows/examples-k32w.yaml
+++ b/.github/workflows/examples-k32w.yaml
@@ -34,7 +34,7 @@ jobs:
if: github.actor != 'restyled-io[bot]'
container:
- image: connectedhomeip/chip-build-k32w:0.5.84
+ image: connectedhomeip/chip-build-k32w:0.5.87
volumes:
- "/tmp/bloat_reports:/tmp/bloat_reports"
steps:
@@ -82,15 +82,15 @@ jobs:
timeout-minutes: 5
run: |
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
- k32w k32w061+release light \
- out/artifacts/k32w-light-release-no-ota/chip-k32w061-light-example \
+ k32w k32w0+release light \
+ out/artifacts/k32w-light-release-no-ota/chip-k32w0x-light-example \
/tmp/bloat_reports/
- name: Get lock size stats
timeout-minutes: 5
run: |
.environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
- k32w k32w061+release lock \
- out/artifacts/k32w-lock-low-power-release/chip-k32w061-lock-example \
+ k32w k32w0+release lock \
+ out/artifacts/k32w-lock-low-power-release/chip-k32w0x-lock-example \
/tmp/bloat_reports/
- name: Uploading Size Reports
uses: actions/upload-artifact@v2
diff --git a/examples/lighting-app/nxp/k32w/k32w0/BUILD.gn b/examples/lighting-app/nxp/k32w/k32w0/BUILD.gn
index 5e811f8900e0d8..c19ccbac46f23a 100644
--- a/examples/lighting-app/nxp/k32w/k32w0/BUILD.gn
+++ b/examples/lighting-app/nxp/k32w/k32w0/BUILD.gn
@@ -21,7 +21,6 @@ import("${k32w0_sdk_build_root}/k32w0_sdk.gni")
import("${chip_root}/src/crypto/crypto.gni")
import("${chip_root}/src/lib/core/core.gni")
-import("${chip_root}/src/lib/core/core.gni")
import("${chip_root}/src/platform/device.gni")
if (chip_pw_tokenizer_logging) {
@@ -66,7 +65,7 @@ k32w0_sdk("sdk") {
}
k32w0_executable("light_app") {
- output_name = "chip-k32w061-light-example"
+ output_name = "chip-k32w0x-light-example"
sources = [
"${k32w0_platform_dir}/util/LEDWidget.cpp",
@@ -103,7 +102,7 @@ k32w0_executable("light_app") {
cflags = [ "-Wconversion" ]
- ldscript = "${k32w0_platform_dir}/app/ldscripts/chip-k32w061-linker.ld"
+ ldscript = "${k32w0_platform_dir}/app/ldscripts/chip-k32w0x-linker.ld"
inputs = [ ldscript ]
@@ -118,15 +117,24 @@ k32w0_executable("light_app") {
]
}
+ if (chip_enable_ota_requestor) {
+ ldflags += [
+ "-Wl,--defsym",
+ "-Wl,__app_load_address__=0x4000",
+ "-Wl,--defsym",
+ "-Wl,__app_stated_size__=0x99A00",
+ ]
+ }
+
output_dir = root_out_dir
}
if (chip_pw_tokenizer_logging) {
pw_tokenizer_database("light_app.database") {
- database = "$root_build_dir/chip-k32w061-light-example-database.bin"
+ database = "$root_build_dir/chip-k32w0x-light-example-database.bin"
create = "binary"
deps = [ ":light_app" ]
- optional_paths = [ "$root_build_dir/chip-k32w061-light-example" ]
+ optional_paths = [ "$root_build_dir/chip-k32w0x-light-example" ]
}
}
diff --git a/examples/lighting-app/nxp/k32w/k32w0/README.md b/examples/lighting-app/nxp/k32w/k32w0/README.md
index 51385c7d0edba2..6b638d0660447a 100644
--- a/examples/lighting-app/nxp/k32w/k32w0/README.md
+++ b/examples/lighting-app/nxp/k32w/k32w0/README.md
@@ -174,24 +174,23 @@ will be initiated.
In order to build the Project CHIP example, we recommend using a Linux
distribution (the demo-application was compiled on Ubuntu 20.04).
-- Download [K32W061 SDK 2.6.4 for Project CHIP](https://mcuxpresso.nxp.com/).
+- Download [K32W0 SDK 2.6.6 for Project CHIP](https://mcuxpresso.nxp.com/).
Creating an nxp.com account is required before being able to download the
SDK. Once the account is created, login and follow the steps for downloading
- SDK_2_6_4_K32W061DK6. The SDK Builder UI selection should be similar with
- the one from the image below.
+ SDK_2_6_6_K32W061DK6 (required for K32W061 flavor). The SDK Builder UI
+ selection should be similar with the one from the image below.
![MCUXpresso SDK Download](../../../../platform/nxp/k32w/k32w0/doc/images/mcux-sdk-download.JPG)
- Start building the application either with Secure Element or without
- without Secure Element
```
-user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_K32W061_SDK_ROOT=/home/user/Desktop/SDK_2_6_4_K32W061DK6/
-user@ubuntu:~/Desktop/git/connectedhomeip$ ./third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh
+user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_K32W0_SDK_ROOT=/home/user/Desktop/SDK_2_6_6_K32W061DK6/
user@ubuntu:~/Desktop/git/connectedhomeip$ source ./scripts/activate.sh
user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/lighting-app/nxp/k32w/k32w0
-user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w0$ gn gen out/debug --args="k32w0_sdk_root=\"${NXP_K32W061_SDK_ROOT}\" chip_with_OM15082=1 chip_with_ot_cli=0 is_debug=false chip_crypto=\"mbedtls\" chip_with_se05x=0 mbedtls_use_tinycrypt=true chip_pw_tokenizer_logging=true mbedtls_repo=\"//third_party/connectedhomeip/third_party/nxp/libs/mbedtls\""
+user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w0$ gn gen out/debug --args="k32w0_sdk_root=\"${NXP_K32W0_SDK_ROOT}\" chip_with_OM15082=1 chip_with_ot_cli=0 is_debug=false chip_crypto=\"tinycrypt\" chip_with_se05x=0 chip_pw_tokenizer_logging=true mbedtls_repo=\"//third_party/connectedhomeip/third_party/nxp/libs/mbedtls\""
user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w0$ ninja -C out/debug
-user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w0$ $NXP_K32W061_SDK_ROOT/tools/imagetool/sign_images.sh out/debug/
+user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w0$ $NXP_K32W0_SDK_ROOT/tools/imagetool/sign_images.sh out/debug/
```
- with Secure element
@@ -201,8 +200,9 @@ user@ubuntu:~/Desktop/git/connectedhomeip/examples/lighting-app/nxp/k32w/k32w0$
Note that option chip_enable_ota_requestor=false are required for building with
Secure Element. These can be changed if building without Secure Element
-Note that "patch_k32w_sdk.sh" script must be run for patching the K32W061 SDK
-2.6.4.
+ - for K32W041AM flavor:
+ Exactly the same steps as above but set build_for_k32w041am=1 in the gn command.
+ Also, select the K32W041AM SDK from the SDK Builder.
Also, in case the OM15082 Expansion Board is not attached to the DK6 board, the
build argument (chip_with_OM15082) inside the gn build instruction should be set
@@ -225,7 +225,7 @@ pycrypto 2.6.1
pycryptodome 3.9.8
```
-The resulting output file can be found in out/debug/chip-k32w061-light-example.
+The resulting output file can be found in out/debug/chip-k32w0x-light-example.
@@ -235,8 +235,8 @@ Program the firmware using the official
[OpenThread Flash Instructions](https://github.com/openthread/ot-nxp/tree/main/src/k32w0/k32w061#flash-binaries).
All you have to do is to replace the Openthread binaries from the above
-documentation with _out/debug/chip-k32w061-light-example.bin_ if DK6Programmer
-is used or with _out/debug/chip-k32w061-light-example_ if MCUXpresso is used.
+documentation with _out/debug/chip-k32w0x-light-example.bin_ if DK6Programmer is
+used or with _out/debug/chip-k32w0x-light-example_ if MCUXpresso is used.
@@ -252,8 +252,10 @@ needed for parsing the hashed scripts.
### Detokenizer script
The python3 script detokenizer.py is a script that decodes the tokenized logs
-either from a file or from a serial port. The script can be used in the
-following ways:
+either from a file or from a serial port. It is located in the following path
+`examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py`.
+
+The script can be used in the following ways:
```
usage: detokenizer.py serial [-h] -i INPUT -d DATABASE [-o OUTPUT]
@@ -268,7 +270,7 @@ the serial to decode from.
The third parameter is _-d DATABASE_ and represents the path to the token
database to be used for decoding. The default path is
-_out/debug/chip-k32w061-light-example-database.bin_ after a successful build.
+_out/debug/chip-k32w0x-light-example-database.bin_ after a successful build.
The forth parameter is _-o OUTPUT_ and it represents the path to the output file
where the decoded logs will be stored. This parameter is required for file usage
@@ -284,7 +286,12 @@ argument _chip_pw_tokenizer_logging=true_ was used.
The detokenizer script must be run inside the example's folder after a
successful run of the _scripts/activate.sh_ script. The pw_tokenizer module used
-by the script is loaded by the environment.
+by the script is loaded by the environment. An example of running the
+detokenizer script to see logs of a lighting app:
+
+```
+python3 ../../../../../examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py serial -i /dev/ttyACM0 -d out/debug/chip-k32w0x-light-example-database.bin -o device.txt
+```
@@ -318,11 +325,12 @@ Note: This solution is temporary.
In order to use the tinycrypt ecc operations, use the following build arguments:
- Build without Secure element (_chip_with_se05x=0_), with tinycrypt enabled
- (_mbedtls_use_tinycrypt=true_) and with the `NXPmicro/mbedtls` library
+ (_chip_crypto=\"tinycrypt\"_) and with the `NXPmicro/mbedtls` library
(_mbedtls_repo=`\"//third_party/connectedhomeip/third_party/nxp/libs/mbedtls\"`_).
-To disable tinycrypt ecc operations, simply build without
-_mbedtls_use_tinycrypt=true_ and without _mbedtls_repo_.
+To disable tinycrypt ecc operations, simply build with _chip_crypto=\"mbedtls\"_
+and with or without _mbedtls_repo_. If used with _mbedtls_repo_ the mbedtls
+implementation from `NXPmicro/mbedtls` library will be used.
@@ -406,7 +414,7 @@ CD04 -> 0x4CD pages of 512-bytes (= 614,5kB)
DK6Programmer can be used for flashing the application:
```
-DK6Programmer.exe -V2 -s -P 1000000 -Y -p FLASH@0x4000="chip-k32w061-light-example.bin"
+DK6Programmer.exe -V2 -s -P 1000000 -Y -p FLASH@0x4000="chip-k32w0x-light-example.bin"
```
If debugging is needed, MCUXpresso can be used then for flashing the
@@ -461,9 +469,9 @@ doru@computer1:~/connectedhomeip$ : ./scripts/examples/gn_build_example.sh examp
Build OTA image and start the OTA Provider Application:
```
-doru@computer1:~/connectedhomeip$ : ./src/app/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 1 -vs "1.0" -da sha256 chip-k32w061-light-example.bin chip-k32w061-light-example.ota
+doru@computer1:~/connectedhomeip$ : ./src/app/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 1 -vs "1.0" -da sha256 chip-k32w0x-light-example.bin chip-k32w0x-light-example.ota
doru@computer1:~/connectedhomeip$ : rm -rf /tmp/chip_*
-doru@computer1:~/connectedhomeip$ : ./out/ota-provider-app/chip-ota-provider-app -f chip-k32w061-light-example.ota
+doru@computer1:~/connectedhomeip$ : ./out/ota-provider-app/chip-ota-provider-app -f chip-k32w0x-light-example.ota
```
Build Linux chip-tool:
diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/main.cpp b/examples/lighting-app/nxp/k32w/k32w0/main/main.cpp
index f3c4096c4d5a8a..58091c8fba4dae 100644
--- a/examples/lighting-app/nxp/k32w/k32w0/main/main.cpp
+++ b/examples/lighting-app/nxp/k32w/k32w0/main/main.cpp
@@ -43,6 +43,8 @@ extern InitFunc __init_array_end;
/* needed for FreeRtos Heap 4 */
uint8_t __attribute__((section(".heap"))) ucHeap[HEAP_SIZE];
+extern "C" void sched_enable();
+
extern "C" void main_task(void const * argument)
{
CHIP_ERROR err = CHIP_NO_ERROR;
@@ -85,6 +87,11 @@ extern "C" void main_task(void const * argument)
goto exit;
}
+ /* Enable the MAC scheduler after BLEManagerImpl::_Init() and V2MMAC_Enable().
+ * This is needed to register properly the active protocols.
+ */
+ sched_enable();
+
err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice);
if (err != CHIP_NO_ERROR)
{
diff --git a/examples/lock-app/nxp/k32w/k32w0/BUILD.gn b/examples/lock-app/nxp/k32w/k32w0/BUILD.gn
index 744bbeb839e402..57d4498ce98ad0 100644
--- a/examples/lock-app/nxp/k32w/k32w0/BUILD.gn
+++ b/examples/lock-app/nxp/k32w/k32w0/BUILD.gn
@@ -22,6 +22,12 @@ import("${k32w0_sdk_build_root}/k32w0_executable.gni")
import("${k32w0_sdk_build_root}/k32w0_sdk.gni")
import("${chip_root}/src/crypto/crypto.gni")
+import("${chip_root}/src/lib/core/core.gni")
+
+if (chip_pw_tokenizer_logging) {
+ import("//build_overrides/pigweed.gni")
+ import("$dir_pw_tokenizer/database.gni")
+}
assert(current_os == "freertos")
@@ -59,7 +65,7 @@ k32w0_sdk("sdk") {
}
k32w0_executable("lock_app") {
- output_name = "chip-k32w061-lock-example"
+ output_name = "chip-k32w0x-lock-example"
sources = [
"${k32w0_platform_dir}/util/LEDWidget.cpp",
@@ -100,15 +106,26 @@ k32w0_executable("lock_app") {
output_dir = root_out_dir
- ldscript = "${k32w0_platform_dir}/app/ldscripts/chip-k32w061-linker.ld"
+ ldscript = "${k32w0_platform_dir}/app/ldscripts/chip-k32w0x-linker.ld"
inputs = [ ldscript ]
ldflags = [ "-T" + rebase_path(ldscript, root_build_dir) ]
}
+if (chip_pw_tokenizer_logging) {
+ pw_tokenizer_database("lock_app.database") {
+ database = "$root_build_dir/chip-k32w0x-lock-example-database.bin"
+ create = "binary"
+ deps = [ ":lock_app" ]
+ optional_paths = [ "$root_build_dir/chip-k32w0x-lock-example" ]
+ }
+}
group("k32w0") {
deps = [ ":lock_app" ]
+ if (chip_pw_tokenizer_logging) {
+ deps += [ ":lock_app.database" ]
+ }
}
group("default") {
diff --git a/examples/lock-app/nxp/k32w/k32w0/README.md b/examples/lock-app/nxp/k32w/k32w0/README.md
index 68be3c11ae03b9..9c1ef8ef3170f2 100644
--- a/examples/lock-app/nxp/k32w/k32w0/README.md
+++ b/examples/lock-app/nxp/k32w/k32w0/README.md
@@ -25,8 +25,15 @@ network.
- [Flashing and debugging](#flashdebug)
- [Known Issues](#knownissues)
- [Testing the example](#testing-the-example)
+- [Pigweed Tokenizer](#tokenizer)
+ - [Detokenizer script](#detokenizer)
+ - [Notes](#detokenizer-notes)
+ - [Known issues](#detokenizer-known-issues)
+- [Tinycrypt ECC operations](#tinycrypt)
-
+ - [Building steps](#tinycrypt-building-steps)
+
+
@@ -165,10 +172,10 @@ will be initiated.
In order to build the Project CHIP example, we recommend using a Linux
distribution (the demo-application was compiled on Ubuntu 20.04).
-- Download [K32W061 SDK 2.6.4 for Project CHIP](https://mcuxpresso.nxp.com/).
+- Download [K32W061 SDK 2.6.6 for Project CHIP](https://mcuxpresso.nxp.com/).
Creating an nxp.com account is required before being able to download the
SDK. Once the account is created, login and follow the steps for downloading
- SDK_2_6_4_K32W061DK6. The SDK Builder UI selection should be similar with
+ SDK_2_6_6_K32W061DK6. The SDK Builder UI selection should be similar with
the one from the image below.
![MCUXpresso SDK Download](../../../../platform/nxp/k32w/k32w0/doc/images/mcux-sdk-download.JPG)
@@ -177,25 +184,16 @@ distribution (the demo-application was compiled on Ubuntu 20.04).
- without Secure Element
```
-user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_K32W061_SDK_ROOT=/home/user/Desktop/SDK_2_6_4_K32W061DK6/
-user@ubuntu:~/Desktop/git/connectedhomeip$ ./third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh
+user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_K32W0_SDK_ROOT=/home/user/Desktop/SDK_2_6_6_K32W061DK6/
user@ubuntu:~/Desktop/git/connectedhomeip$ source ./scripts/activate.sh
user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/lock-app/nxp/k32w/k32w0/
-user@ubuntu:~/Desktop/git/connectedhomeip/examples/lock-app/nxp/k32w/k32w0$ gn gen out/debug --args="k32w0_sdk_root=\"${NXP_K32W061_SDK_ROOT}\" chip_with_OM15082=1 chip_with_ot_cli=0 is_debug=false chip_crypto=\"mbedtls\" chip_with_se05x=0"
+user@ubuntu:~/Desktop/git/connectedhomeip/examples/lock-app/nxp/k32w/k32w0$ gn gen out/debug --args="k32w0_sdk_root=\"${NXP_K32W0_SDK_ROOT}\" chip_with_OM15082=1 chip_with_ot_cli=0 is_debug=false chip_crypto=\"tinycrypt\" chip_with_se05x=0 chip_pw_tokenizer_logging=true mbedtls_repo=\"//third_party/connectedhomeip/third_party/nxp/libs/mbedtls\""
user@ubuntu:~/Desktop/git/connectedhomeip/examples/lock-app/nxp/k32w/k32w0$ ninja -C out/debug
-user@ubuntu:~/Desktop/git/connectedhomeip/examples/lock-app/nxp/k32w/k32w0$ $NXP_K32W061_SDK_ROOT/tools/imagetool/sign_images.sh out/debug/
+user@ubuntu:~/Desktop/git/connectedhomeip/examples/lock-app/nxp/k32w/k32w0$ $NXP_K32W0_SDK_ROOT/tools/imagetool/sign_images.sh out/debug/
```
- with Secure element
- Exactly the same steps as above but set chip_with_se05x=1 in the gn command
- and add arguments chip_pw_tokenizer_logging=true chip_enable_ota_requestor=false
-
-Note that options chip_pw_tokenizer_logging=true and
-chip_enable_ota_requestor=false are required for building with Secure Element.
-These can be changed if building without Secure Element
-
-Note that "patch_k32w_sdk.sh" script must be run for patching the K32W061 SDK
-2.6.4.
+ Exactly the same steps as above but set chip_with_se05x=1 in the gn command.
Also, in case the OM15082 Expansion Board is not attached to the DK6 board, the
build argument (chip_with_OM15082) inside the gn build instruction should be set
@@ -218,7 +216,7 @@ pycrypto 2.6.1
pycryptodome 3.9.8
```
-The resulting output file can be found in out/debug/chip-k32w061-lock-example.
+The resulting output file can be found in out/debug/chip-k32w0x-lock-example.
@@ -228,8 +226,8 @@ Program the firmware using the official
[OpenThread Flash Instructions](https://github.com/openthread/ot-nxp/tree/main/src/k32w0/k32w061#flash-binaries).
All you have to do is to replace the Openthread binaries from the above
-documentation with _out/debug/chip-k32w061-lock-example.bin_ if DK6Programmer is
-used or with _out/debug/chip-k32w061-lock-example_ if MCUXpresso is used.
+documentation with _out/debug/chip-k32w0x-lock-example.bin_ if DK6Programmer is
+used or with _out/debug/chip-k32w0x-lock-example_ if MCUXpresso is used.
@@ -282,3 +280,97 @@ for step-by-step instructions.
See
[Unlocking the Future of Project CHIP Webinar](https://www.nxp.com/design/training/unlocking-the-future-of-project-chip:TIP-EEE-UNLOCKING-THE-FUTURE-OF-PROJECT-CHIP)
for an in-depth analysis of NXP capabilities for Project CHIP.
+
+
+
+## Pigweed tokenizer
+
+The tokenizer is a pigweed module that allows hashing the strings. This greatly
+reduces the flash needed for logs. The module can be enabled by building with
+the gn argument _chip_pw_tokenizer_logging=true_. The detokenizer script is
+needed for parsing the hashed scripts.
+
+
+
+### Detokenizer script
+
+The python3 script detokenizer.py is a script that decodes the tokenized logs
+either from a file or from a serial port. It is located in the following path
+`examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py`.
+
+The script can be used in the following ways:
+
+```
+usage: detokenizer.py serial [-h] -i INPUT -d DATABASE [-o OUTPUT]
+usage: detokenizer.py file [-h] -i INPUT -d DATABASE -o OUTPUT
+```
+
+The first parameter is either _serial_ or _file_ and it selects between decoding
+from a file or from a serial port.
+
+The second parameter is _-i INPUT_ and it must se set to the path of the file or
+the serial to decode from.
+
+The third parameter is _-d DATABASE_ and represents the path to the token
+database to be used for decoding. The default path is
+_out/debug/chip-k32w0x-lock-example-database.bin_ after a successful build.
+
+The forth parameter is _-o OUTPUT_ and it represents the path to the output file
+where the decoded logs will be stored. This parameter is required for file usage
+and optional for serial usage. If not provided when used with serial port, it
+will show the decoded log only at the stdout and not save it to file.
+
+
+
+### Notes
+
+The token database is created automatically after building the binary if the
+argument _chip_pw_tokenizer_logging=true_ was used.
+
+The detokenizer script must be run inside the example's folder after a
+successful run of the _scripts/activate.sh_ script. The pw_tokenizer module used
+by the script is loaded by the environment. An example of running the
+detokenizer script to see logs of a lock app:
+
+```
+python3 ../../../../../examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py serial -i /dev/ttyACM0 -d out/debug/chip-k32w0x-lock-example-database.bin -o device.txt
+```
+
+
+
+### Known issues
+
+The building process will not update the token database if it already exists. In
+case that new strings are added and the database already exists in the output
+folder, it must be deleted so that it will be recreated at the next build.
+
+Not all tokens will be decoded. This is due to a gcc/pw_tokenizer issue. The
+pw_tokenizer creates special elf sections using attributes where the tokens and
+strings will be stored. This sections will be used by the database creation
+script. For template C++ functions, gcc ignores these attributes and places all
+the strings by default in the .rodata section. As a result the database creation
+script won't find them in the special-created sections.
+
+If run, closed and rerun with the serial option on the same serial port, the
+detokenization script will get stuck and not show any logs. The solution is to
+unplug and plug the board and then rerun the script.
+
+
+
+## Tinycrypt ECC operations
+
+
+
+### Building steps
+
+Note: This solution is temporary.
+
+In order to use the tinycrypt ecc operations, use the following build arguments:
+
+- Build without Secure element (_chip_with_se05x=0_), with tinycrypt enabled
+ (_chip_crypto=\"tinycrypt\"_) and with the `NXPmicro/mbedtls` library
+ (_mbedtls_repo=`\"//third_party/connectedhomeip/third_party/nxp/libs/mbedtls\"`_).
+
+To disable tinycrypt ecc operations, simply build with _chip_crypto=\"mbedtls\"_
+and with or without _mbedtls_repo_. If used with _mbedtls_repo_ the mbedtls
+implementation from `NXPmicro/mbedtls` library will be used.
diff --git a/examples/lock-app/nxp/k32w/k32w0/args.gni b/examples/lock-app/nxp/k32w/k32w0/args.gni
index a1b757c6612439..2ace8356337891 100644
--- a/examples/lock-app/nxp/k32w/k32w0/args.gni
+++ b/examples/lock-app/nxp/k32w/k32w0/args.gni
@@ -20,5 +20,3 @@ k32w0_sdk_target = get_label_info(":sdk", "label_no_toolchain")
chip_stack_lock_tracking = "fatal"
chip_enable_ble = true
-
-chip_progress_logging = false
diff --git a/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp
index 015784f6d6e8dd..3a78c9c7f632c4 100644
--- a/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp
+++ b/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp
@@ -166,12 +166,14 @@ CHIP_ERROR AppTask::Init()
void LockOpenThreadTask(void)
{
+ PWR_DisallowDeviceToSleep();
chip::DeviceLayer::ThreadStackMgr().LockThreadStack();
}
void UnlockOpenThreadTask(void)
{
chip::DeviceLayer::ThreadStackMgr().UnlockThreadStack();
+ PWR_AllowDeviceToSleep();
}
void AppTask::InitServer(intptr_t arg)
@@ -728,9 +730,10 @@ void AppTask::DispatchEvent(AppEvent * aEvent)
{
aEvent->Handler(aEvent->param);
}
+ else
#endif
- if (aEvent->Handler)
+ if (aEvent->Handler)
{
aEvent->Handler(aEvent);
}
diff --git a/examples/lock-app/nxp/k32w/k32w0/main/main.cpp b/examples/lock-app/nxp/k32w/k32w0/main/main.cpp
index 216f98328503ee..a792030a7c78b0 100644
--- a/examples/lock-app/nxp/k32w/k32w0/main/main.cpp
+++ b/examples/lock-app/nxp/k32w/k32w0/main/main.cpp
@@ -36,8 +36,11 @@ using namespace ::chip::Inet;
using namespace ::chip::DeviceLayer;
using namespace ::chip::Logging;
+#define ENABLE_LOW_POWER_LOGS 0
+
#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode)
#include "Keyboard.h"
+#include "OtaSupport.h"
#include "PWR_Configuration.h"
#include "PWR_Interface.h"
#include "RNG_Interface.h"
@@ -46,6 +49,8 @@ using namespace ::chip::Logging;
#include "radio.h"
#endif
+#include "MacSched.h"
+
typedef void (*InitFunc)(void);
extern InitFunc __init_array_start;
extern InitFunc __init_array_end;
@@ -55,6 +60,7 @@ extern InitFunc __init_array_end;
extern "C" void vMMAC_IntHandlerBbc();
extern "C" void vMMAC_IntHandlerPhy();
extern "C" void BOARD_SetClockForPowerMode(void);
+extern "C" void stopM2();
static void dm_switch_wakeupCallBack(void);
static void dm_switch_preSleepCallBack(void);
@@ -77,6 +83,8 @@ static sDualModeAppStates dualModeStates;
#define THREAD_WARM_BOOT_INIT_DURATION_DEFAULT_VALUE 4000
#endif
+extern "C" void sched_enable();
+
/* needed for FreeRtos Heap 4 */
uint8_t __attribute__((section(".heap"))) ucHeap[HEAP_SIZE];
@@ -100,7 +108,9 @@ extern "C" void main_task(void const * argument)
#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode)
PWR_Init();
- PWR_vAddRamRetention((uint32_t) &ucHeap[0], sizeof(ucHeap));
+ /* Internal - MATTER-303: keep in retention the entire RAM1 for the moment */
+ PWR_vAddRamRetention((uint32_t) 0x4020000, 0x10000);
+
PWR_RegisterLowPowerExitCallback(dm_switch_wakeupCallBack);
PWR_RegisterLowPowerEnterCallback(dm_switch_preSleepCallBack);
@@ -132,6 +142,11 @@ extern "C" void main_task(void const * argument)
goto exit;
}
+ /* Enable the MAC scheduler after BLEManagerImpl::_Init() and V2MMAC_Enable().
+ * This is needed to register properly the active protocols.
+ */
+ sched_enable();
+
#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode)
dualModeStates.threadWarmBootInitTime = THREAD_WARM_BOOT_INIT_DURATION_DEFAULT_VALUE;
dualModeStates.threadInitialized = TRUE;
@@ -197,10 +212,15 @@ uint32_t dm_switch_get15_4InitWakeUpTime(void)
extern "C" bleResult_t App_PostCallbackMessage(appCallbackHandler_t handler, appCallbackParam_t param)
{
AppEvent event;
- event.Type = AppEvent::kEventType_Lp;
+ event.Type = AppEvent::kEventType_Lp;
+
event.Handler = handler;
event.param = param;
+#if ENABLE_LOW_POWER_LOGS
+ K32W_LOG("App_PostCallbackMessage %d", (uint32_t) param);
+#endif
+
GetAppTask().PostEvent(&event);
return gBleSuccess_c;
@@ -210,6 +230,11 @@ static void dm_switch_wakeupCallBack(void)
{
BOARD_SetClockForWakeup();
+#if ENABLE_LOW_POWER_LOGS
+ K32W_LOG("dm_switch_wakeupCallBack");
+ K32W_LOG("Warm up time actual value: %d", dualModeStates.threadWarmBootInitTime);
+#endif
+
RNG_Init();
SecLib_Init();
@@ -218,25 +243,37 @@ static void dm_switch_wakeupCallBack(void)
PWR_WakeupReason_t wakeReason = PWR_GetWakeupReason();
if (wakeReason.Bits.FromBLE_LLTimer == 1)
{
- SWITCH_DBG_LOG("woken up from LL");
+#if ENABLE_LOW_POWER_LOGS
+ K32W_LOG("woken up from LL");
+#endif
}
else if (wakeReason.Bits.FromKeyBoard == 1)
{
- SWITCH_DBG_LOG("woken up from FromKeyBoard");
+#if ENABLE_LOW_POWER_LOGS
+ K32W_LOG("woken up from FromKeyBoard");
+#endif
}
else if (wakeReason.Bits.FromTMR == 1)
{
- SWITCH_DBG_LOG("woken up from TMR");
+#if ENABLE_LOW_POWER_LOGS
+ K32W_LOG("woken up from TMR");
+#endif
}
dm_lp_wakeup();
}
static void dm_switch_preSleepCallBack(void)
{
- SWITCH_DBG_LOG("sleeping");
+#if ENABLE_LOW_POWER_LOGS
+ K32W_LOG("dm_switch_preSleepCallBack");
+#endif
if (dualModeStates.threadInitialized)
{
+ /* stop the internal MAC Scheduler timer */
+ stopM2();
+ /* disable the MAC scheduler */
+ sched_disable();
otPlatRadioDisable(NULL);
dualModeStates.threadInitialized = FALSE;
}
@@ -251,6 +288,12 @@ static void dm_switch_preSleepCallBack(void)
BOARD_SetClockForPowerMode();
}
+extern "C" void vDynStopAll(void)
+{
+ vDynRequestState(E_DYN_SLAVE, E_DYN_STATE_OFF);
+ vDynRequestState(E_DYN_MASTER, E_DYN_STATE_OFF);
+}
+
void dm_switch_init15_4AfterWakeUp(void)
{
uint32_t tick1 = 0;
@@ -271,8 +314,13 @@ void dm_switch_init15_4AfterWakeUp(void)
{
tick2 = PWR_Get32kTimestamp();
dualModeStates.threadWarmBootInitTime = ((tick2 - tick1) * 15625u) >> 9;
+
/* Add a margin of 1 ms */
dualModeStates.threadWarmBootInitTime += 1000;
+
+#if ENABLE_LOW_POWER_LOGS
+ K32W_LOG("Calibration: %d", dualModeStates.threadWarmBootInitTime);
+#endif
}
}
@@ -287,6 +335,8 @@ static void ThreadExitSleep()
/* Radio must be re-enabled after waking up from sleep.
* The module is completely disabled in power down mode */
otPlatRadioEnable(NULL);
+ sched_enable();
+
dualModeStates.threadInitialized = TRUE;
/* wake up the Thread stack and check if any processing needs to be done */
diff --git a/examples/platform/nxp/k32w/k32w0/app/ldscripts/chip-k32w061-linker.ld b/examples/platform/nxp/k32w/k32w0/app/ldscripts/chip-k32w0x-linker.ld
similarity index 93%
rename from examples/platform/nxp/k32w/k32w0/app/ldscripts/chip-k32w061-linker.ld
rename to examples/platform/nxp/k32w/k32w0/app/ldscripts/chip-k32w0x-linker.ld
index 3bb028d183d9dd..359a9ef790336d 100644
--- a/examples/platform/nxp/k32w/k32w0/app/ldscripts/chip-k32w061-linker.ld
+++ b/examples/platform/nxp/k32w/k32w0/app/ldscripts/chip-k32w0x-linker.ld
@@ -28,7 +28,7 @@
/**
* @file
- * GCC linker script for K32W061.
+ * GCC linker script for K32W061/K32W041.
*/
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
@@ -58,13 +58,15 @@ m_app_start = DEFINED(__app_load_address__) ? __app_load_address__ :
m_app_meta_data = 0x400;
/* 640K (Total Flash size) - 16K (SSBL + SSBL update region) - 8.5K (PSECT) - m_app_meta_data */
-m_app_size = DEFINED(__app_stated_size__) ? __app_stated_size__ : 0x9FC00;
+m_app_size = DEFINED(__app_stated_size__) ? __app_stated_size__ : 0x9DE00;
MEMORY
{
- Flash640 (rx) : ORIGIN = m_app_start, LENGTH = m_app_size
- RAM0 (rwx) : ORIGIN = 0x4000400, LENGTH = 0x0015c00 /* 87K bytes (alias RAM) */
- RAM1 (rwx) : ORIGIN = 0x4020000, LENGTH = 0x10000 /* 64K bytes (alias RAM2) */
+ Flash640 (rx) : ORIGIN = m_app_start, LENGTH = m_app_size
+
+ SCRATCH_RAM(rwx) : ORIGIN = 0x4000000, LENGTH = 0x400 /* 1K bytes (alias SCRATCH_RAM) */
+ RAM0 (rwx) : ORIGIN = 0x4000400, LENGTH = 0x0015c00 /* 87K bytes (alias RAM) */
+ RAM1 (rwx) : ORIGIN = 0x4020000, LENGTH = 0x10000 /* 64K bytes (alias RAM2) */
}
/* Define a symbol for the top of each memory region */
@@ -234,6 +236,13 @@ SECTIONS
. = ALIGN(4);
__interrupts_ram_end__ = .; /* Define a global symbol at data end */
} > RAM0
+ .scratch_area (NOLOAD): ALIGN(4)
+ {
+ __scratch_area_start__ = .;
+ . = ALIGN(4) ;
+ . += 0x400;
+ __scratch_area_top__ = .;
+ } > SCRATCH_RAM
/* MAIN DATA SECTION */
.uninit_RESERVED : ALIGN(4)
@@ -340,6 +349,8 @@ SECTIONS
PROVIDE(Chip_LOWPOWER_ChipSoftwareReset = 0x03003fa1);
PROVIDE(_pvHeapStart = _heap);
PROVIDE(_pvHeapLimit = _pvHeapStart + (HEAP_SIZE));
+ PROVIDE(_scratch_buf_start = __scratch_area_start__);
+ PROVIDE(_scratch_buf_end = __scratch_area_top__);
__StackLimit = _vStackTop - STACK_SIZE;
}
diff --git a/examples/platform/nxp/k32w/k32w0/app/project_include/OpenThreadConfig.h b/examples/platform/nxp/k32w/k32w0/app/project_include/OpenThreadConfig.h
index 667574786bb91e..ef95988da9ab24 100644
--- a/examples/platform/nxp/k32w/k32w0/app/project_include/OpenThreadConfig.h
+++ b/examples/platform/nxp/k32w/k32w0/app/project_include/OpenThreadConfig.h
@@ -96,6 +96,8 @@
#undef OPENTHREAD_CONFIG_PLATFORM_CSL_UNCERT
+#define UART_USE_SERIAL_MGR 1
+
//#define OPENTHREAD_CONFIG_LOG_LEVEL OT_LOG_LEVEL_DEBG
// Use the NXP-supplied default platform configuration for remainder
diff --git a/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c b/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c
index 5bdb70c6ee21fc..e6a445c1c086ff 100644
--- a/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c
+++ b/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c
@@ -236,7 +236,14 @@ extern void OTAIdleActivities(void);
void vApplicationIdleHook(void)
{
+ // Data queued by PDM will be written to external flash
+ // when PDM_vIdleTask is called. Interrupts are disabled
+ // to ensure there is no context switch during the actual
+ // writing, thus avoiding race conditions.
+ OSA_InterruptDisable();
PDM_vIdleTask(PDM_MAX_WRITES_INFINITE);
+ OSA_InterruptEnable();
+
OTAIdleActivities();
BOARD_ActionOnIdle();
}
diff --git a/examples/lighting-app/nxp/k32w/k32w0/detokenizer.py b/examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py
similarity index 100%
rename from examples/lighting-app/nxp/k32w/k32w0/detokenizer.py
rename to examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py
diff --git a/examples/shell/nxp/k32w/k32w0/BUILD.gn b/examples/shell/nxp/k32w/k32w0/BUILD.gn
index 505373a42bf860..f6c4039783a5dd 100644
--- a/examples/shell/nxp/k32w/k32w0/BUILD.gn
+++ b/examples/shell/nxp/k32w/k32w0/BUILD.gn
@@ -57,7 +57,7 @@ k32w0_sdk("sdk") {
}
k32w0_executable("shell_app") {
- output_name = "chip-k32w061-shell-example"
+ output_name = "chip-k32w0x-shell-example"
sources = [
"${k32w0_platform_dir}/util/LEDWidget.cpp",
@@ -79,7 +79,7 @@ k32w0_executable("shell_app") {
output_dir = root_out_dir
- ldscript = "${k32w0_platform_dir}/app/ldscripts/chip-k32w061-linker.ld"
+ ldscript = "${k32w0_platform_dir}/app/ldscripts/chip-k32w0x-linker.ld"
inputs = [ ldscript ]
diff --git a/gn_build.sh b/gn_build.sh
index 86e2ff6889c6d3..0615a1833ef40d 100755
--- a/gn_build.sh
+++ b/gn_build.sh
@@ -154,14 +154,14 @@ fi
# K32W SDK setup
k32w_sdk_args=""
-if [[ -d "$NXP_K32W061_SDK_ROOT" ]]; then
- k32w_sdk_args+="k32w0_sdk_root=\"$NXP_K32W061_SDK_ROOT\""
+if [[ -d "$NXP_K32W0_SDK_ROOT" ]]; then
+ k32w_sdk_args+="k32w0_sdk_root=\"$NXP_K32W0_SDK_ROOT\""
extra_args+=" $k32w0_sdk_args enable_k32w_builds=true"
fi
echo
-if [[ ! -d "$NXP_K32W061_SDK_ROOT" ]]; then
- echo "Hint: Set \$NXP_K32W061_SDK_ROOT to enable building for K32W061"
+if [[ ! -d "$NXP_K32W0_SDK_ROOT" ]]; then
+ echo "Hint: Set \$NXP_K32W0_SDK_ROOT to enable building for K32W061"
else
echo 'To build the K32W lock sample as a standalone project':
echo "(cd $CHIP_ROOT/examples/lock-app/nxp/k32w/k32w0; gn gen out/debug --args='$k32w_sdk_args'; ninja -C out/debug)"
diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py
index a4d3d859558bca..0ae6f05a9f328e 100755
--- a/scripts/build/build/targets.py
+++ b/scripts/build/build/targets.py
@@ -534,7 +534,7 @@ def K32WTargets():
target = Target('k32w', K32WBuilder)
yield target.Extend('light-ota-se', app=K32WApp.LIGHT, release=True, disable_ble=True, se05x=True).GlobBlacklist("Only on demand build")
- yield target.Extend('light-release-no-ota', app=K32WApp.LIGHT, tokenizer=True, disable_ota=True, release=True)
+ yield target.Extend('light-release-no-ota', app=K32WApp.LIGHT, tokenizer=True, disable_ota=True, release=True, tinycrypt=True)
yield target.Extend('shell-release', app=K32WApp.SHELL, release=True)
yield target.Extend('lock-release', app=K32WApp.LOCK, release=True)
yield target.Extend('lock-low-power-release', app=K32WApp.LOCK,
diff --git a/scripts/build/builders/k32w.py b/scripts/build/builders/k32w.py
index ea446ec8a40e88..39828157e934eb 100644
--- a/scripts/build/builders/k32w.py
+++ b/scripts/build/builders/k32w.py
@@ -35,11 +35,13 @@ def ExampleName(self):
def AppNamePrefix(self):
if self == K32WApp.LIGHT:
- return 'chip-k32w061-light-example'
+ return 'chip-k32w0x-light-example'
elif self == K32WApp.LOCK:
- return 'chip-k32w061-lock-example'
+ return 'chip-k32w0x-lock-example'
elif self == K32WApp.SHELL:
- return 'chip-k32w061-shell-example'
+ return 'chip-k32w0x-shell-example'
+ elif self == K32WApp.CONTACT:
+ return 'chip-k32w0x-contact-example'
else:
raise Exception('Unknown app type: %r' % self)
@@ -58,7 +60,8 @@ def __init__(self,
tokenizer: bool = False,
disable_ble: bool = False,
disable_ota: bool = False,
- se05x: bool = False):
+ se05x: bool = False,
+ tinycrypt: bool = False):
super(K32WBuilder, self).__init__(
root=app.BuildRoot(root),
runner=runner)
@@ -70,10 +73,11 @@ def __init__(self,
self.disable_ble = disable_ble
self.disable_ota = disable_ota
self.se05x = se05x
+ self.tinycrypt = tinycrypt
def GnBuildArgs(self):
args = [
- 'k32w0_sdk_root="%s"' % os.environ['NXP_K32W061_SDK_ROOT'],
+ 'k32w0_sdk_root="%s"' % os.environ['NXP_K32W0_SDK_ROOT'],
]
if self.low_power:
@@ -96,6 +100,9 @@ def GnBuildArgs(self):
if self.se05x:
args.append('chip_with_se05x=true')
+ if self.tinycrypt:
+ args.append('chip_crypto=\"tinycrypt\" mbedtls_repo=\"//third_party/connectedhomeip/third_party/nxp/libs/mbedtls\"')
+
return args
def generate(self):
diff --git a/scripts/build/test.py b/scripts/build/test.py
index 5559847adf50d9..056d34166a40ef 100644
--- a/scripts/build/test.py
+++ b/scripts/build/test.py
@@ -44,7 +44,7 @@ def build_actual_output(root: str, out: str, args: List[str]) -> List[str]:
'TIZEN_SDK_SYSROOT': 'TEST_TIZEN_SDK_SYSROOT',
'TELINK_ZEPHYR_SDK_DIR': 'TELINK_ZEPHYR_SDK_DIR',
'SYSROOT_AARCH64': 'SYSROOT_AARCH64',
- 'NXP_K32W061_SDK_ROOT': 'TEST_NXP_K32W061_SDK_ROOT',
+ 'NXP_K32W0_SDK_ROOT': 'TEST_NXP_K32W0_SDK_ROOT',
'IMX_SDK_ROOT': 'IMX_SDK_ROOT',
'TI_SYSCONFIG_ROOT': 'TEST_TI_SYSCONFIG_ROOT',
})
diff --git a/scripts/build/testdata/build_all_except_host.txt b/scripts/build/testdata/build_all_except_host.txt
index fa887aca49fb73..e365f295f08c20 100644
--- a/scripts/build/testdata/build_all_except_host.txt
+++ b/scripts/build/testdata/build_all_except_host.txt
@@ -858,27 +858,27 @@ gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/exa
{root}/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh
# Generating k32w-light-ota-se
-gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/lighting-app/nxp/k32w/k32w0 '--args=k32w0_sdk_root="TEST_NXP_K32W061_SDK_ROOT" chip_with_low_power=0 is_debug=false chip_enable_ble=false chip_with_se05x=true' {out}/k32w-light-ota-se
+gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/lighting-app/nxp/k32w/k32w0 '--args=k32w0_sdk_root="TEST_NXP_K32W0_SDK_ROOT" chip_with_low_power=0 is_debug=false chip_enable_ble=false chip_with_se05x=true' {out}/k32w-light-ota-se
{root}/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh
# Generating k32w-light-release-no-ota
-gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/lighting-app/nxp/k32w/k32w0 '--args=k32w0_sdk_root="TEST_NXP_K32W061_SDK_ROOT" chip_with_low_power=0 chip_pw_tokenizer_logging=true is_debug=false chip_enable_ota_requestor=false' {out}/k32w-light-release-no-ota
+gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/lighting-app/nxp/k32w/k32w0 '--args=k32w0_sdk_root="TEST_NXP_K32W0_SDK_ROOT" chip_with_low_power=0 chip_pw_tokenizer_logging=true is_debug=false chip_enable_ota_requestor=false chip_crypto="tinycrypt" mbedtls_repo="//third_party/connectedhomeip/third_party/nxp/libs/mbedtls"' {out}/k32w-light-release-no-ota
{root}/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh
# Generating k32w-lock-low-power-release
-gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/lock-app/nxp/k32w/k32w0 '--args=k32w0_sdk_root="TEST_NXP_K32W061_SDK_ROOT" chip_with_low_power=1 is_debug=false' {out}/k32w-lock-low-power-release
+gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/lock-app/nxp/k32w/k32w0 '--args=k32w0_sdk_root="TEST_NXP_K32W0_SDK_ROOT" chip_with_low_power=1 is_debug=false' {out}/k32w-lock-low-power-release
{root}/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh
# Generating k32w-lock-release
-gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/lock-app/nxp/k32w/k32w0 '--args=k32w0_sdk_root="TEST_NXP_K32W061_SDK_ROOT" chip_with_low_power=0 is_debug=false' {out}/k32w-lock-release
+gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/lock-app/nxp/k32w/k32w0 '--args=k32w0_sdk_root="TEST_NXP_K32W0_SDK_ROOT" chip_with_low_power=0 is_debug=false' {out}/k32w-lock-release
{root}/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh
# Generating k32w-shell-release
-gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/shell/nxp/k32w/k32w0 '--args=k32w0_sdk_root="TEST_NXP_K32W061_SDK_ROOT" chip_with_low_power=0 is_debug=false' {out}/k32w-shell-release
+gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/shell/nxp/k32w/k32w0 '--args=k32w0_sdk_root="TEST_NXP_K32W0_SDK_ROOT" chip_with_low_power=0 is_debug=false' {out}/k32w-shell-release
# Generating config mbed-CY8CPROTO_062_4343W-all-clusters-debug
mbed-tools configure -t GCC_ARM -m CY8CPROTO_062_4343W -p {root}/examples/all-clusters-app/mbed -o {out}/mbed-CY8CPROTO_062_4343W-all-clusters-debug --mbed-os-path {root}/third_party/mbed-os/repo
diff --git a/scripts/examples/k32w_se_example.sh b/scripts/examples/k32w_se_example.sh
index 27c0b5a29fe48c..9815dc9f49a06c 100755
--- a/scripts/examples/k32w_se_example.sh
+++ b/scripts/examples/k32w_se_example.sh
@@ -27,5 +27,5 @@ env
"$(dirname "$0")"/../../third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh
-gn gen --check --fail-on-unused-args --root="$1" "$2" --args="k32w0_sdk_root=\"$NXP_K32W061_SDK_ROOT\" is_debug=false chip_crypto=\"mbedtls\" chip_with_se05x=1"
+gn gen --check --fail-on-unused-args --root="$1" "$2" --args="k32w0_sdk_root=\"$NXP_K32W0_SDK_ROOT\" is_debug=false chip_crypto=\"mbedtls\" chip_with_se05x=1"
ninja -C "$2"
diff --git a/src/crypto/BUILD.gn b/src/crypto/BUILD.gn
index 359bb9d289cf0a..a5e176c3fe5212 100644
--- a/src/crypto/BUILD.gn
+++ b/src/crypto/BUILD.gn
@@ -57,6 +57,8 @@ if (chip_crypto == "openssl") {
import("//build_overrides/boringssl.gni")
} else if (chip_crypto == "mbedtls") {
import("//build_overrides/mbedtls.gni")
+} else if (chip_crypto == "tinycrypt") {
+ import("//build_overrides/mbedtls.gni")
}
static_library("crypto") {
@@ -99,6 +101,9 @@ static_library("crypto") {
# BoringSSL is close enough to OpenSSL that isd uses same PAL, with minor #ifdef differences
sources += [ "CHIPCryptoPALOpenSSL.cpp" ]
public_deps += [ "${boringssl_root}:boringssl" ]
+ } else if (chip_crypto == "tinycrypt") {
+ sources += [ "CHIPCryptoPALTinyCrypt.cpp" ]
+ public_deps += [ "${mbedtls_root}:mbedtls" ]
} else {
assert(false, "Invalid CHIP crypto")
}
diff --git a/src/crypto/CHIPCryptoPALTinyCrypt.cpp b/src/crypto/CHIPCryptoPALTinyCrypt.cpp
new file mode 100644
index 00000000000000..2b86f418cb27d3
--- /dev/null
+++ b/src/crypto/CHIPCryptoPALTinyCrypt.cpp
@@ -0,0 +1,1500 @@
+/*
+ *
+ * Copyright (c) 2020-2022 Project CHIP Authors
+ *
+ * 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.
+ */
+
+/**
+ * @file
+ * mbedTLS based implementation of CHIP crypto primitives
+ */
+
+#include "CHIPCryptoPAL.h"
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#include
+#endif // defined(MBEDTLS_X509_CRT_PARSE_C)
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+namespace chip {
+namespace Crypto {
+
+#define MAX_ERROR_STR_LEN 128
+#define NUM_BYTES_IN_SHA256_HASH 32
+
+// In mbedTLS 3.0.0 direct access to structure fields was replaced with using MBEDTLS_PRIVATE macro.
+#if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
+#define CHIP_CRYPTO_PAL_PRIVATE(x) MBEDTLS_PRIVATE(x)
+#else
+#define CHIP_CRYPTO_PAL_PRIVATE(x) x
+#endif
+
+#if (MBEDTLS_VERSION_NUMBER >= 0x03000000 && MBEDTLS_VERSION_NUMBER < 0x03010000)
+#define CHIP_CRYPTO_PAL_PRIVATE_X509(x) MBEDTLS_PRIVATE(x)
+#else
+#define CHIP_CRYPTO_PAL_PRIVATE_X509(x) x
+#endif
+
+typedef struct
+{
+ bool mInitialized;
+ bool mDRBGSeeded;
+ mbedtls_ctr_drbg_context mDRBGCtxt;
+ mbedtls_entropy_context mEntropy;
+} EntropyContext;
+
+static EntropyContext gsEntropyContext;
+
+static void _log_mbedTLS_error(int error_code)
+{
+ if (error_code != 0 && error_code != UECC_SUCCESS)
+ {
+#if defined(MBEDTLS_ERROR_C)
+ char error_str[MAX_ERROR_STR_LEN];
+ mbedtls_strerror(error_code, error_str, sizeof(error_str));
+ ChipLogError(Crypto, "mbedTLS error: %s", error_str);
+#else
+ // Error codes defined in 16-bit negative hex numbers. Ease lookup by printing likewise
+ ChipLogError(Crypto, "mbedTLS error: -0x%04X", -static_cast(error_code));
+#endif
+ }
+}
+
+static bool _isValidTagLength(size_t tag_length)
+{
+ if (tag_length == 8 || tag_length == 12 || tag_length == 16)
+ {
+ return true;
+ }
+ return false;
+}
+
+static bool _isValidKeyLength(size_t length)
+{
+ // 16 bytes key for AES-CCM-128, 32 for AES-CCM-256
+ if (length == 16 || length == 32)
+ {
+ return true;
+ }
+ return false;
+}
+
+CHIP_ERROR AES_CCM_encrypt(const uint8_t * plaintext, size_t plaintext_length, const uint8_t * aad, size_t aad_length,
+ const uint8_t * key, size_t key_length, const uint8_t * nonce, size_t nonce_length, uint8_t * ciphertext,
+ uint8_t * tag, size_t tag_length)
+{
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = 1;
+
+ mbedtls_ccm_context context;
+ mbedtls_ccm_init(&context);
+
+ VerifyOrExit(plaintext != nullptr || plaintext_length == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(ciphertext != nullptr || plaintext_length == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(key != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(_isValidKeyLength(key_length), error = CHIP_ERROR_UNSUPPORTED_ENCRYPTION_TYPE);
+ VerifyOrExit(nonce != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(nonce_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(tag != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(_isValidTagLength(tag_length), error = CHIP_ERROR_INVALID_ARGUMENT);
+ if (aad_length > 0)
+ {
+ VerifyOrExit(aad != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
+ }
+
+ // Size of key = key_length * number of bits in a byte (8)
+ // Cast is safe because we called _isValidKeyLength above.
+ result =
+ mbedtls_ccm_setkey(&context, MBEDTLS_CIPHER_ID_AES, Uint8::to_const_uchar(key), static_cast(key_length * 8));
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+
+ // Encrypt
+ result = mbedtls_ccm_encrypt_and_tag(&context, plaintext_length, Uint8::to_const_uchar(nonce), nonce_length,
+ Uint8::to_const_uchar(aad), aad_length, Uint8::to_const_uchar(plaintext),
+ Uint8::to_uchar(ciphertext), Uint8::to_uchar(tag), tag_length);
+ _log_mbedTLS_error(result);
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+
+exit:
+ mbedtls_ccm_free(&context);
+ return error;
+}
+
+CHIP_ERROR AES_CCM_decrypt(const uint8_t * ciphertext, size_t ciphertext_len, const uint8_t * aad, size_t aad_len,
+ const uint8_t * tag, size_t tag_length, const uint8_t * key, size_t key_length, const uint8_t * nonce,
+ size_t nonce_length, uint8_t * plaintext)
+{
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = 1;
+
+ mbedtls_ccm_context context;
+ mbedtls_ccm_init(&context);
+
+ VerifyOrExit(plaintext != nullptr || ciphertext_len == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(ciphertext != nullptr || ciphertext_len == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(tag != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(_isValidTagLength(tag_length), error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(key != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(_isValidKeyLength(key_length), error = CHIP_ERROR_UNSUPPORTED_ENCRYPTION_TYPE);
+ VerifyOrExit(nonce != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(nonce_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
+ if (aad_len > 0)
+ {
+ VerifyOrExit(aad != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
+ }
+
+ // Size of key = key_length * number of bits in a byte (8)
+ // Cast is safe because we called _isValidKeyLength above.
+ result =
+ mbedtls_ccm_setkey(&context, MBEDTLS_CIPHER_ID_AES, Uint8::to_const_uchar(key), static_cast(key_length * 8));
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+
+ // Decrypt
+ result = mbedtls_ccm_auth_decrypt(&context, ciphertext_len, Uint8::to_const_uchar(nonce), nonce_length,
+ Uint8::to_const_uchar(aad), aad_len, Uint8::to_const_uchar(ciphertext),
+ Uint8::to_uchar(plaintext), Uint8::to_const_uchar(tag), tag_length);
+ _log_mbedTLS_error(result);
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+
+exit:
+ mbedtls_ccm_free(&context);
+ return error;
+}
+
+CHIP_ERROR Hash_SHA256(const uint8_t * data, const size_t data_length, uint8_t * out_buffer)
+{
+ // zero data length hash is supported.
+ VerifyOrReturnError(data != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(out_buffer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+
+#if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
+ const int result = mbedtls_sha256(Uint8::to_const_uchar(data), data_length, Uint8::to_uchar(out_buffer), 0);
+#else
+ const int result = mbedtls_sha256_ret(Uint8::to_const_uchar(data), data_length, Uint8::to_uchar(out_buffer), 0);
+#endif
+
+ VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR Hash_SHA1(const uint8_t * data, const size_t data_length, uint8_t * out_buffer)
+{
+ // zero data length hash is supported.
+ VerifyOrReturnError(out_buffer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+
+#if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
+ const int result = mbedtls_sha1(Uint8::to_const_uchar(data), data_length, Uint8::to_uchar(out_buffer));
+#else
+ const int result = mbedtls_sha1_ret(Uint8::to_const_uchar(data), data_length, Uint8::to_uchar(out_buffer));
+#endif
+
+ VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL);
+
+ return CHIP_NO_ERROR;
+}
+
+static_assert(kMAX_Hash_SHA256_Context_Size >= sizeof(mbedtls_sha256_context),
+ "kMAX_Hash_SHA256_Context_Size is too small for the size of underlying mbedtls_sha256_context");
+
+static inline mbedtls_sha256_context * to_inner_hash_sha256_context(HashSHA256OpaqueContext * context)
+{
+ return SafePointerCast(context);
+}
+
+Hash_SHA256_stream::Hash_SHA256_stream(void)
+{
+ mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext);
+ mbedtls_sha256_init(context);
+}
+
+Hash_SHA256_stream::~Hash_SHA256_stream(void)
+{
+ mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext);
+ mbedtls_sha256_free(context);
+ Clear();
+}
+
+CHIP_ERROR Hash_SHA256_stream::Begin(void)
+{
+ mbedtls_sha256_context * const context = to_inner_hash_sha256_context(&mContext);
+
+#if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
+ const int result = mbedtls_sha256_starts(context, 0);
+#else
+ const int result = mbedtls_sha256_starts_ret(context, 0);
+#endif
+
+ VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR Hash_SHA256_stream::AddData(const ByteSpan data)
+{
+ mbedtls_sha256_context * const context = to_inner_hash_sha256_context(&mContext);
+
+#if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
+ const int result = mbedtls_sha256_update(context, Uint8::to_const_uchar(data.data()), data.size());
+#else
+ const int result = mbedtls_sha256_update_ret(context, Uint8::to_const_uchar(data.data()), data.size());
+#endif
+
+ VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR Hash_SHA256_stream::GetDigest(MutableByteSpan & out_buffer)
+{
+ mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext);
+
+ // Back-up context as we are about to finalize the hash to extract digest.
+ mbedtls_sha256_context previous_ctx;
+ mbedtls_sha256_init(&previous_ctx);
+ mbedtls_sha256_clone(&previous_ctx, context);
+
+ // Pad + compute digest, then finalize context. It is restored next line to continue.
+ CHIP_ERROR result = Finish(out_buffer);
+
+ // Restore context prior to finalization.
+ mbedtls_sha256_clone(context, &previous_ctx);
+ mbedtls_sha256_free(&previous_ctx);
+
+ return result;
+}
+
+CHIP_ERROR Hash_SHA256_stream::Finish(MutableByteSpan & out_buffer)
+{
+ VerifyOrReturnError(out_buffer.size() >= kSHA256_Hash_Length, CHIP_ERROR_BUFFER_TOO_SMALL);
+ mbedtls_sha256_context * const context = to_inner_hash_sha256_context(&mContext);
+
+#if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
+ const int result = mbedtls_sha256_finish(context, Uint8::to_uchar(out_buffer.data()));
+#else
+ const int result = mbedtls_sha256_finish_ret(context, Uint8::to_uchar(out_buffer.data()));
+#endif
+
+ VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL);
+ out_buffer = out_buffer.SubSpan(0, kSHA256_Hash_Length);
+
+ return CHIP_NO_ERROR;
+}
+
+void Hash_SHA256_stream::Clear(void)
+{
+ mbedtls_platform_zeroize(this, sizeof(*this));
+}
+
+CHIP_ERROR HKDF_sha::HKDF_SHA256(const uint8_t * secret, const size_t secret_length, const uint8_t * salt, const size_t salt_length,
+ const uint8_t * info, const size_t info_length, uint8_t * out_buffer, size_t out_length)
+{
+ VerifyOrReturnError(secret != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(secret_length > 0, CHIP_ERROR_INVALID_ARGUMENT);
+
+ // Salt is optional
+ if (salt_length > 0)
+ {
+ VerifyOrReturnError(salt != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+ }
+
+ VerifyOrReturnError(info_length > 0, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(info != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(out_length > 0, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(out_buffer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+
+ const mbedtls_md_info_t * const md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
+ VerifyOrReturnError(md != nullptr, CHIP_ERROR_INTERNAL);
+
+ const int result = mbedtls_hkdf(md, Uint8::to_const_uchar(salt), salt_length, Uint8::to_const_uchar(secret), secret_length,
+ Uint8::to_const_uchar(info), info_length, Uint8::to_uchar(out_buffer), out_length);
+ _log_mbedTLS_error(result);
+ VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR HMAC_sha::HMAC_SHA256(const uint8_t * key, size_t key_length, const uint8_t * message, size_t message_length,
+ uint8_t * out_buffer, size_t out_length)
+{
+ VerifyOrReturnError(key != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(key_length > 0, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(message != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(message_length > 0, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(out_length >= kSHA256_Hash_Length, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(out_buffer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+
+ const mbedtls_md_info_t * const md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
+ VerifyOrReturnError(md != nullptr, CHIP_ERROR_INTERNAL);
+
+ const int result =
+ mbedtls_md_hmac(md, Uint8::to_const_uchar(key), key_length, Uint8::to_const_uchar(message), message_length, out_buffer);
+
+ _log_mbedTLS_error(result);
+ VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR PBKDF2_sha256::pbkdf2_sha256(const uint8_t * password, size_t plen, const uint8_t * salt, size_t slen,
+ unsigned int iteration_count, uint32_t key_length, uint8_t * output)
+{
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = 0;
+ const mbedtls_md_info_t * md_info;
+ mbedtls_md_context_t md_ctxt;
+ constexpr int use_hmac = 1;
+
+ bool free_md_ctxt = false;
+
+ VerifyOrExit(password != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(plen > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(salt != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(slen >= kSpake2p_Min_PBKDF_Salt_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(slen <= kSpake2p_Max_PBKDF_Salt_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(key_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(output != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
+
+ md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
+ VerifyOrExit(md_info != nullptr, error = CHIP_ERROR_INTERNAL);
+
+ mbedtls_md_init(&md_ctxt);
+ free_md_ctxt = true;
+
+ result = mbedtls_md_setup(&md_ctxt, md_info, use_hmac);
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+
+ result = mbedtls_pkcs5_pbkdf2_hmac(&md_ctxt, Uint8::to_const_uchar(password), plen, Uint8::to_const_uchar(salt), slen,
+ iteration_count, key_length, Uint8::to_uchar(output));
+
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+
+exit:
+ _log_mbedTLS_error(result);
+
+ if (free_md_ctxt)
+ {
+ mbedtls_md_free(&md_ctxt);
+ }
+
+ return error;
+}
+
+static EntropyContext * get_entropy_context()
+{
+ if (!gsEntropyContext.mInitialized)
+ {
+ mbedtls_entropy_init(&gsEntropyContext.mEntropy);
+ mbedtls_ctr_drbg_init(&gsEntropyContext.mDRBGCtxt);
+
+ gsEntropyContext.mInitialized = true;
+ }
+
+ return &gsEntropyContext;
+}
+
+static mbedtls_ctr_drbg_context * get_drbg_context()
+{
+ EntropyContext * const context = get_entropy_context();
+
+ mbedtls_ctr_drbg_context * const drbgCtxt = &context->mDRBGCtxt;
+
+ if (!context->mDRBGSeeded)
+ {
+ const int status = mbedtls_ctr_drbg_seed(drbgCtxt, mbedtls_entropy_func, &context->mEntropy, nullptr, 0);
+ if (status != 0)
+ {
+ _log_mbedTLS_error(status);
+ return nullptr;
+ }
+
+ context->mDRBGSeeded = true;
+ }
+
+ return drbgCtxt;
+}
+
+CHIP_ERROR add_entropy_source(entropy_source fn_source, void * p_source, size_t threshold)
+{
+ VerifyOrReturnError(fn_source != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+
+ EntropyContext * const entropy_ctxt = get_entropy_context();
+ VerifyOrReturnError(entropy_ctxt != nullptr, CHIP_ERROR_INTERNAL);
+
+ const int result =
+ mbedtls_entropy_add_source(&entropy_ctxt->mEntropy, fn_source, p_source, threshold, MBEDTLS_ENTROPY_SOURCE_STRONG);
+ VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR DRBG_get_bytes(uint8_t * out_buffer, const size_t out_length)
+{
+ VerifyOrReturnError(out_buffer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(out_length > 0, CHIP_ERROR_INVALID_ARGUMENT);
+
+ mbedtls_ctr_drbg_context * const drbg_ctxt = get_drbg_context();
+ VerifyOrReturnError(drbg_ctxt != nullptr, CHIP_ERROR_INTERNAL);
+
+ const int result = mbedtls_ctr_drbg_random(drbg_ctxt, Uint8::to_uchar(out_buffer), out_length);
+ VerifyOrReturnError(result == 0, CHIP_ERROR_INTERNAL);
+
+ return CHIP_NO_ERROR;
+}
+
+static int CryptoRNG(void * ctxt, uint8_t * out_buffer, size_t out_length)
+{
+ return (chip::Crypto::DRBG_get_bytes(out_buffer, out_length) == CHIP_NO_ERROR) ? 0 : 1;
+}
+
+mbedtls_ecp_group_id MapECPGroupId(SupportedECPKeyTypes keyType)
+{
+ switch (keyType)
+ {
+ case SupportedECPKeyTypes::ECP256R1:
+ return MBEDTLS_ECP_DP_SECP256R1;
+ default:
+ return MBEDTLS_ECP_DP_NONE;
+ }
+}
+
+static inline mbedtls_uecc_keypair * to_keypair(P256KeypairContext * context)
+{
+ return SafePointerCast(context);
+}
+
+static inline const mbedtls_uecc_keypair * to_const_keypair(const P256KeypairContext * context)
+{
+ return SafePointerCast(context);
+}
+
+CHIP_ERROR P256Keypair::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_length, P256ECDSASignature & out_signature) const
+{
+ VerifyOrReturnError(mInitialized, CHIP_ERROR_INCORRECT_STATE);
+ VerifyOrReturnError((msg != nullptr) && (msg_length > 0), CHIP_ERROR_INVALID_ARGUMENT);
+
+ uint8_t digest[kSHA256_Hash_Length];
+ memset(&digest[0], 0, sizeof(digest));
+ ReturnErrorOnFailure(Hash_SHA256(msg, msg_length, &digest[0]));
+
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = UECC_FAILURE;
+
+ const mbedtls_uecc_keypair * keypair = to_const_keypair(&mKeypair);
+
+ result = uECC_sign(keypair->private_key, digest, sizeof(digest), out_signature.Bytes());
+
+ VerifyOrExit(result == UECC_SUCCESS, error = CHIP_ERROR_INTERNAL);
+ VerifyOrExit(out_signature.SetLength(kP256_ECDSA_Signature_Length_Raw) == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL);
+
+ keypair = nullptr;
+
+exit:
+ return error;
+}
+
+CHIP_ERROR P256PublicKey::ECDSA_validate_msg_signature(const uint8_t * msg, const size_t msg_length,
+ const P256ECDSASignature & signature) const
+{
+#if defined(MBEDTLS_ECDSA_C)
+ VerifyOrReturnError((msg != nullptr) && (msg_length > 0), CHIP_ERROR_INVALID_ARGUMENT);
+
+ uint8_t digest[kSHA256_Hash_Length];
+ memset(&digest[0], 0, sizeof(digest));
+ ReturnErrorOnFailure(Hash_SHA256(msg, msg_length, &digest[0]));
+
+ return ECDSA_validate_hash_signature(&digest[0], sizeof(digest), signature);
+#else
+ return CHIP_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+CHIP_ERROR P256PublicKey::ECDSA_validate_hash_signature(const uint8_t * hash, const size_t hash_length,
+ const P256ECDSASignature & signature) const
+{
+ VerifyOrReturnError(hash != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(hash_length == kSHA256_Hash_Length, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(signature.Length() == kP256_ECDSA_Signature_Length_Raw, CHIP_ERROR_INVALID_ARGUMENT);
+
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = UECC_FAILURE;
+
+ const uint8_t * public_key = *this;
+
+ // Fully padded raw uncompressed points expected, first byte is always 0x04 i.e uncompressed
+ result = uECC_verify(public_key + 1, hash, hash_length, Uint8::to_const_uchar(signature.ConstBytes()));
+ VerifyOrExit(result == UECC_SUCCESS, error = CHIP_ERROR_INVALID_SIGNATURE);
+
+exit:
+ return error;
+}
+
+CHIP_ERROR P256Keypair::ECDH_derive_secret(const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const
+{
+#if defined(MBEDTLS_ECDH_C)
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = 0;
+ size_t secret_length = (out_secret.Length() == 0) ? out_secret.Capacity() : out_secret.Length();
+
+ const mbedtls_uecc_keypair * keypair = to_const_keypair(&mKeypair);
+
+ VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
+
+ // Fully padded raw uncompressed points expected, first byte is always 0x04 i.e uncompressed
+ result = uECC_shared_secret(remote_public_key.ConstBytes() + 1, keypair->private_key, Uint8::to_uchar(out_secret));
+ VerifyOrExit(result == UECC_SUCCESS, error = CHIP_ERROR_INTERNAL);
+
+ SuccessOrExit(out_secret.SetLength(secret_length));
+
+exit:
+ keypair = nullptr;
+ _log_mbedTLS_error(result);
+ return error;
+#else
+ return CHIP_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+void ClearSecretData(uint8_t * buf, size_t len)
+{
+ mbedtls_platform_zeroize(buf, len);
+}
+
+// THE BELOW IS FROM `third_party/openthread/repo/third_party/mbedtls/repo/library/constant_time.c` since
+// mbedtls_ct_memcmp is not available on Linux somehow :(
+int mbedtls_ct_memcmp_copy(const void * a, const void * b, size_t n)
+{
+ size_t i;
+ volatile const unsigned char * A = (volatile const unsigned char *) a;
+ volatile const unsigned char * B = (volatile const unsigned char *) b;
+ volatile unsigned char diff = 0;
+
+ for (i = 0; i < n; i++)
+ {
+ /* Read volatile data in order before computing diff.
+ * This avoids IAR compiler warning:
+ * 'the order of volatile accesses is undefined ..' */
+ unsigned char x = A[i], y = B[i];
+ diff |= x ^ y;
+ }
+
+ return ((int) diff);
+}
+
+bool IsBufferContentEqualConstantTime(const void * a, const void * b, size_t n)
+{
+ return mbedtls_ct_memcmp_copy(a, b, n) == 0;
+}
+
+CHIP_ERROR P256Keypair::Initialize()
+{
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = UECC_FAILURE;
+
+ Clear();
+
+ mbedtls_uecc_keypair * keypair = to_keypair(&mKeypair);
+
+ result = uECC_make_key(keypair->public_key, keypair->private_key);
+ VerifyOrExit(result == UECC_SUCCESS, error = CHIP_ERROR_INTERNAL);
+
+ // Fully padded raw uncompressed points expected, first byte is always 0x04 i.e uncompressed
+ Uint8::to_uchar(mPublicKey)[0] = 0x04;
+ memcpy(Uint8::to_uchar(mPublicKey) + 1, keypair->public_key, 2 * NUM_ECC_BYTES);
+
+ keypair = nullptr;
+ mInitialized = true;
+
+exit:
+ _log_mbedTLS_error(result);
+ return error;
+}
+
+CHIP_ERROR P256Keypair::Serialize(P256SerializedKeypair & output) const
+{
+ const mbedtls_uecc_keypair * keypair = to_const_keypair(&mKeypair);
+ size_t len = output.Length() == 0 ? output.Capacity() : output.Length();
+ Encoding::BufferWriter bbuf(output, len);
+ uint8_t privkey[kP256_PrivateKey_Length];
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = 0;
+
+ bbuf.Put(mPublicKey, mPublicKey.Length());
+
+ VerifyOrExit(bbuf.Available() == sizeof(privkey), error = CHIP_ERROR_INTERNAL);
+ VerifyOrExit(sizeof(keypair->private_key) <= bbuf.Available(), error = CHIP_ERROR_INTERNAL);
+
+ memcpy(privkey, keypair->private_key, sizeof(privkey));
+
+ bbuf.Put(privkey, sizeof(privkey));
+ VerifyOrExit(bbuf.Fit(), error = CHIP_ERROR_BUFFER_TOO_SMALL);
+
+ output.SetLength(bbuf.Needed());
+
+exit:
+ memset(privkey, 0, sizeof(privkey));
+ _log_mbedTLS_error(result);
+ return error;
+}
+
+CHIP_ERROR P256Keypair::Deserialize(P256SerializedKeypair & input)
+{
+ int result = 0;
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ Encoding::BufferWriter bbuf(mPublicKey, mPublicKey.Length());
+
+ Clear();
+
+ mbedtls_uecc_keypair * keypair = to_keypair(&mKeypair);
+
+ // Fully padded raw uncompressed points expected, first byte is always 0x04 i.e uncompressed
+ memcpy(keypair->public_key, Uint8::to_uchar(input) + 1, 2 * NUM_ECC_BYTES);
+ memcpy(keypair->private_key, Uint8::to_uchar(input) + mPublicKey.Length(), NUM_ECC_BYTES);
+
+ keypair = nullptr;
+
+ VerifyOrExit(input.Length() == mPublicKey.Length() + kP256_PrivateKey_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
+ bbuf.Put((const uint8_t *) input, mPublicKey.Length());
+ VerifyOrExit(bbuf.Fit(), error = CHIP_ERROR_NO_MEMORY);
+
+ mInitialized = true;
+
+ _log_mbedTLS_error(result);
+
+exit:
+ return error;
+}
+
+void P256Keypair::Clear()
+{
+ if (mInitialized)
+ {
+ mbedtls_uecc_keypair * keypair = to_keypair(&mKeypair);
+ memset(keypair, 0, sizeof(mbedtls_uecc_keypair));
+ mInitialized = false;
+ }
+}
+
+P256Keypair::~P256Keypair()
+{
+ Clear();
+}
+
+CHIP_ERROR P256Keypair::NewCertificateSigningRequest(uint8_t * out_csr, size_t & csr_length) const
+{
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = 0;
+ size_t out_length;
+
+ mbedtls_x509write_csr csr;
+ mbedtls_x509write_csr_init(&csr);
+
+ mbedtls_pk_context pk;
+ pk.CHIP_CRYPTO_PAL_PRIVATE(pk_info) = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
+ pk.CHIP_CRYPTO_PAL_PRIVATE(pk_ctx) = to_keypair(&mKeypair);
+ VerifyOrExit(pk.CHIP_CRYPTO_PAL_PRIVATE(pk_info) != nullptr, error = CHIP_ERROR_INTERNAL);
+
+ VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
+
+ mbedtls_x509write_csr_set_key(&csr, &pk);
+
+ mbedtls_x509write_csr_set_md_alg(&csr, MBEDTLS_MD_SHA256);
+
+ // TODO: mbedTLS CSR parser fails if the subject name is not set (or if empty).
+ // CHIP Spec doesn't specify the subject name that can be used.
+ // Figure out the correct value and update this code.
+ result = mbedtls_x509write_csr_set_subject_name(&csr, "O=CSR");
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+
+ result = mbedtls_x509write_csr_der(&csr, out_csr, csr_length, CryptoRNG, nullptr);
+ VerifyOrExit(result > 0, error = CHIP_ERROR_INTERNAL);
+ VerifyOrExit(CanCastTo(result), error = CHIP_ERROR_INTERNAL);
+
+ out_length = static_cast(result);
+ result = 0;
+ VerifyOrExit(out_length <= csr_length, error = CHIP_ERROR_INTERNAL);
+
+ if (csr_length != out_length)
+ {
+ // mbedTLS API writes the CSR at the end of the provided buffer.
+ // Let's move it to the start of the buffer.
+ size_t offset = csr_length - out_length;
+ memmove(out_csr, &out_csr[offset], out_length);
+ }
+
+ csr_length = out_length;
+
+exit:
+ mbedtls_x509write_csr_free(&csr);
+
+ _log_mbedTLS_error(result);
+ return error;
+}
+
+CHIP_ERROR VerifyCertificateSigningRequest(const uint8_t * csr_buf, size_t csr_length, P256PublicKey & pubkey)
+{
+#if defined(MBEDTLS_X509_CSR_PARSE_C)
+ // TODO: For some embedded targets, mbedTLS library doesn't have mbedtls_x509_csr_parse_der, and mbedtls_x509_csr_parse_free.
+ // Taking a step back, embedded targets likely will not process CSR requests. Adding this action item to reevaluate
+ // this if there's a need for this processing for embedded targets.
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ size_t pubkey_size = 0;
+
+ mbedtls_ecp_keypair * keypair = nullptr;
+
+ P256ECDSASignature signature;
+ MutableByteSpan out_raw_sig_span(signature.Bytes(), signature.Capacity());
+
+ mbedtls_x509_csr csr;
+ mbedtls_x509_csr_init(&csr);
+
+ int result = mbedtls_x509_csr_parse_der(&csr, csr_buf, csr_length);
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+
+ // Verify the signature algorithm and public key type
+ VerifyOrExit(csr.CHIP_CRYPTO_PAL_PRIVATE(sig_md) == MBEDTLS_MD_SHA256, error = CHIP_ERROR_UNSUPPORTED_SIGNATURE_TYPE);
+ VerifyOrExit(csr.CHIP_CRYPTO_PAL_PRIVATE(sig_pk) == MBEDTLS_PK_ECDSA, error = CHIP_ERROR_WRONG_KEY_TYPE);
+
+ keypair = mbedtls_pk_ec(csr.CHIP_CRYPTO_PAL_PRIVATE_X509(pk));
+
+ // Copy the public key from the CSR
+ result = mbedtls_ecp_point_write_binary(&keypair->CHIP_CRYPTO_PAL_PRIVATE(grp), &keypair->CHIP_CRYPTO_PAL_PRIVATE(Q),
+ MBEDTLS_ECP_PF_UNCOMPRESSED, &pubkey_size, Uint8::to_uchar(pubkey), pubkey.Length());
+
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+ VerifyOrExit(pubkey_size == pubkey.Length(), error = CHIP_ERROR_INTERNAL);
+
+ // Convert DER signature to raw signature
+ error = EcdsaAsn1SignatureToRaw(kP256_FE_Length,
+ ByteSpan{ csr.CHIP_CRYPTO_PAL_PRIVATE(sig).CHIP_CRYPTO_PAL_PRIVATE_X509(p),
+ csr.CHIP_CRYPTO_PAL_PRIVATE(sig).CHIP_CRYPTO_PAL_PRIVATE_X509(len) },
+ out_raw_sig_span);
+
+ VerifyOrExit(error == CHIP_NO_ERROR, error = CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrExit(out_raw_sig_span.size() == (kP256_FE_Length * 2), error = CHIP_ERROR_INTERNAL);
+ signature.SetLength(out_raw_sig_span.size());
+
+ // Verify the signature using the public key
+ error = pubkey.ECDSA_validate_msg_signature(csr.CHIP_CRYPTO_PAL_PRIVATE_X509(cri).CHIP_CRYPTO_PAL_PRIVATE_X509(p),
+ csr.CHIP_CRYPTO_PAL_PRIVATE_X509(cri).CHIP_CRYPTO_PAL_PRIVATE_X509(len), signature);
+
+ SuccessOrExit(error);
+
+exit:
+ mbedtls_x509_csr_free(&csr);
+ _log_mbedTLS_error(result);
+ return error;
+#else
+ ChipLogError(Crypto, "MBEDTLS_X509_CSR_PARSE_C is not enabled. CSR cannot be parsed");
+ return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
+#endif
+}
+
+typedef struct Spake2p_Context
+{
+ const mbedtls_md_info_t * md_info;
+ uECC_word_t M[2 * NUM_ECC_WORDS];
+ uECC_word_t N[2 * NUM_ECC_WORDS];
+ uECC_word_t X[2 * NUM_ECC_WORDS];
+ uECC_word_t Y[2 * NUM_ECC_WORDS];
+ uECC_word_t L[2 * NUM_ECC_WORDS];
+ uECC_word_t Z[2 * NUM_ECC_WORDS];
+ uECC_word_t V[2 * NUM_ECC_WORDS];
+
+ uECC_word_t w0[NUM_ECC_WORDS];
+ uECC_word_t w1[NUM_ECC_WORDS];
+ uECC_word_t xy[NUM_ECC_WORDS];
+ uECC_word_t tempbn[NUM_ECC_WORDS];
+} Spake2p_Context;
+
+static inline Spake2p_Context * to_inner_spake2p_context(Spake2pOpaqueContext * context)
+{
+ return SafePointerCast(context);
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::InitInternal(void)
+{
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = 0;
+
+ Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
+
+ memset(context, 0, sizeof(Spake2p_Context));
+
+ M = context->M;
+ N = context->N;
+ X = context->X;
+ Y = context->Y;
+ L = context->L;
+ V = context->V;
+ Z = context->Z;
+
+ w0 = context->w0;
+ w1 = context->w1;
+ xy = context->xy;
+ tempbn = context->tempbn;
+
+ G = curve_G;
+
+ return error;
+
+exit:
+ _log_mbedTLS_error(result);
+ Clear();
+ return error;
+}
+
+void Spake2p_P256_SHA256_HKDF_HMAC::Clear()
+{
+ VerifyOrReturn(state != CHIP_SPAKE2P_STATE::PREINIT);
+
+ Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
+ memset(&context->M, 0, 2 * NUM_ECC_WORDS * sizeof(uECC_word_t));
+ memset(&context->N, 0, 2 * NUM_ECC_WORDS * sizeof(uECC_word_t));
+ memset(&context->X, 0, 2 * NUM_ECC_WORDS * sizeof(uECC_word_t));
+ memset(&context->Y, 0, 2 * NUM_ECC_WORDS * sizeof(uECC_word_t));
+ memset(&context->L, 0, 2 * NUM_ECC_WORDS * sizeof(uECC_word_t));
+ memset(&context->Z, 0, 2 * NUM_ECC_WORDS * sizeof(uECC_word_t));
+ memset(&context->V, 0, 2 * NUM_ECC_WORDS * sizeof(uECC_word_t));
+
+ memset(&context->w0, 0, NUM_ECC_WORDS * sizeof(uECC_word_t));
+ memset(&context->w1, 0, NUM_ECC_WORDS * sizeof(uECC_word_t));
+ memset(&context->xy, 0, NUM_ECC_WORDS * sizeof(uECC_word_t));
+ memset(&context->tempbn, 0, NUM_ECC_WORDS * sizeof(uECC_word_t));
+
+ G = NULL;
+ state = CHIP_SPAKE2P_STATE::PREINIT;
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::Mac(const uint8_t * key, size_t key_len, const uint8_t * in, size_t in_len,
+ MutableByteSpan & out_span)
+{
+ HMAC_sha hmac;
+ VerifyOrReturnError(out_span.size() >= kSHA256_Hash_Length, CHIP_ERROR_BUFFER_TOO_SMALL);
+ ReturnErrorOnFailure(hmac.HMAC_SHA256(key, key_len, in, in_len, out_span.data(), kSHA256_Hash_Length));
+ out_span = out_span.SubSpan(0, kSHA256_Hash_Length);
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::MacVerify(const uint8_t * key, size_t key_len, const uint8_t * mac, size_t mac_len,
+ const uint8_t * in, size_t in_len)
+{
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = 0;
+
+ uint8_t computed_mac[kSHA256_Hash_Length];
+ MutableByteSpan computed_mac_span{ computed_mac };
+ VerifyOrExit(mac_len == kSHA256_Hash_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
+
+ SuccessOrExit(error = Mac(key, key_len, in, in_len, computed_mac_span));
+ VerifyOrExit(computed_mac_span.size() == mac_len, error = CHIP_ERROR_INTERNAL);
+
+ VerifyOrExit(IsBufferContentEqualConstantTime(mac, computed_mac, kSHA256_Hash_Length), error = CHIP_ERROR_INTERNAL);
+
+exit:
+ _log_mbedTLS_error(result);
+ return error;
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FELoad(const uint8_t * in, size_t in_len, void * fe)
+{
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = 0;
+
+ uECC_word_t tmp[2 * NUM_ECC_WORDS] = { 0 };
+ uECC_vli_bytesToNative(tmp, in, NUM_ECC_BYTES);
+
+ uECC_vli_mmod((uECC_word_t *) fe, tmp, curve_n);
+
+exit:
+ _log_mbedTLS_error(result);
+ return error;
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEWrite(const void * fe, uint8_t * out, size_t out_len)
+{
+ uECC_vli_nativeToBytes(out, NUM_ECC_BYTES, (const unsigned int *) fe);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEGenerate(void * fe)
+{
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = 0;
+
+ mbedtls_uecc_keypair keypair;
+
+ result = UECC_FAILURE;
+
+ result = uECC_make_key(keypair.public_key, keypair.private_key);
+ VerifyOrExit(result == UECC_SUCCESS, error = CHIP_ERROR_INTERNAL);
+
+ uECC_vli_bytesToNative((uECC_word_t *) fe, keypair.private_key, NUM_ECC_BYTES);
+
+exit:
+ _log_mbedTLS_error(result);
+ return error;
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEMul(void * fer, const void * fe1, const void * fe2)
+{
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = 0;
+
+ uECC_vli_modMult((uECC_word_t *) fer, (const uECC_word_t *) fe1, (const uECC_word_t *) fe2, (const uECC_word_t *) curve_n);
+
+exit:
+ _log_mbedTLS_error(result);
+ return error;
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointLoad(const uint8_t * in, size_t in_len, void * R)
+{
+ uint8_t tmp[2 * NUM_ECC_BYTES];
+
+ // Fully padded raw uncompressed points expected, first byte is always 0x04 i.e uncompressed
+ memcpy(tmp, in + 1, 2 * NUM_ECC_BYTES);
+
+ uECC_vli_bytesToNative((uECC_word_t *) R, tmp, NUM_ECC_BYTES);
+ uECC_vli_bytesToNative((uECC_word_t *) R + NUM_ECC_WORDS, tmp + NUM_ECC_BYTES, NUM_ECC_BYTES);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointWrite(const void * R, uint8_t * out, size_t out_len)
+{
+ memset(out, 0, out_len);
+
+ // Fully padded raw uncompressed points expected, first byte is always 0x04 i.e uncompressed
+ out[0] = 0x04;
+ uECC_vli_nativeToBytes(out + 1, NUM_ECC_BYTES, (uECC_word_t *) R);
+ uECC_vli_nativeToBytes(out + NUM_ECC_BYTES + 1, NUM_ECC_BYTES, (uECC_word_t *) R + NUM_ECC_WORDS);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointMul(void * R, const void * P1, const void * fe1)
+{
+
+ if (EccPoint_mult_safer((uECC_word_t *) R, (const uECC_word_t *) P1, (const uECC_word_t *) fe1) != UECC_SUCCESS)
+ {
+ return CHIP_ERROR_INTERNAL;
+ }
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointAddMul(void * R, const void * P1, const void * fe1, const void * P2,
+ const void * fe2)
+{
+ uECC_word_t R1[2 * NUM_ECC_WORDS];
+ uECC_word_t R2[2 * NUM_ECC_WORDS];
+ uECC_word_t z[NUM_ECC_WORDS];
+ uint8_t ret = UECC_SUCCESS;
+
+ if (EccPoint_mult_safer(R1, (const uECC_word_t *) P1, (const uECC_word_t *) fe1) != UECC_SUCCESS)
+ {
+ return CHIP_ERROR_INTERNAL;
+ }
+
+ if (EccPoint_mult_safer(R2, (const uECC_word_t *) P2, (const uECC_word_t *) fe2) != UECC_SUCCESS)
+ {
+ return CHIP_ERROR_INTERNAL;
+ }
+
+ uECC_vli_modSub(z, R2, R1, curve_p);
+ XYcZ_add(R1, R1 + NUM_ECC_WORDS, R2, R2 + NUM_ECC_WORDS);
+ uECC_vli_modInv(z, z, curve_p);
+ apply_z(R2, R2 + NUM_ECC_WORDS, z);
+
+ memcpy((uECC_word_t *) R, R2, 2 * NUM_ECC_BYTES);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointInvert(void * R)
+{
+ uECC_word_t tmp[NUM_ECC_WORDS] = { 0 };
+
+ uECC_vli_sub(tmp, curve_p, (uECC_word_t *) R + NUM_ECC_WORDS);
+ memcpy((uECC_word_t *) R + NUM_ECC_WORDS, tmp, NUM_ECC_BYTES);
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointCofactorMul(void * R)
+{
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::ComputeL(uint8_t * Lout, size_t * L_len, const uint8_t * w1in, size_t w1in_len)
+{
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ int result = 0;
+
+ result = UECC_SUCCESS;
+ uECC_word_t tmp[2 * NUM_ECC_WORDS];
+ uECC_word_t w1_bn[NUM_ECC_WORDS];
+ uECC_word_t L_tmp[2 * NUM_ECC_WORDS];
+
+ uECC_vli_bytesToNative(tmp, w1in, NUM_ECC_BYTES);
+
+ uECC_vli_mmod(w1_bn, tmp, curve_n);
+
+ result = EccPoint_mult_safer(L_tmp, curve_G, w1_bn);
+ VerifyOrExit(result == UECC_SUCCESS, error = CHIP_ERROR_INTERNAL);
+
+ // Fully padded raw uncompressed points expected, first byte is always 0x04 i.e uncompressed
+ Lout[0] = 0x04;
+ uECC_vli_nativeToBytes(Lout + 1, NUM_ECC_BYTES, L_tmp);
+ uECC_vli_nativeToBytes(Lout + NUM_ECC_BYTES + 1, NUM_ECC_BYTES, L_tmp + NUM_ECC_WORDS);
+
+exit:
+ _log_mbedTLS_error(result);
+
+ return error;
+}
+
+CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointIsValid(void * R)
+{
+ if (uECC_valid_point((const uECC_word_t *) R) != 0)
+ {
+ return CHIP_ERROR_INTERNAL;
+ }
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR ValidateCertificateChain(const uint8_t * rootCertificate, size_t rootCertificateLen, const uint8_t * caCertificate,
+ size_t caCertificateLen, const uint8_t * leafCertificate, size_t leafCertificateLen,
+ CertificateChainValidationResult & result)
+{
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ mbedtls_x509_crt certChain;
+ mbedtls_x509_crt rootCert;
+ int mbedResult;
+ uint32_t flags;
+
+ result = CertificateChainValidationResult::kInternalFrameworkError;
+
+ VerifyOrReturnError(rootCertificate != nullptr && rootCertificateLen != 0,
+ (result = CertificateChainValidationResult::kRootArgumentInvalid, CHIP_ERROR_INVALID_ARGUMENT));
+ VerifyOrReturnError(caCertificate != nullptr && caCertificateLen != 0,
+ (result = CertificateChainValidationResult::kICAArgumentInvalid, CHIP_ERROR_INVALID_ARGUMENT));
+ VerifyOrReturnError(leafCertificate != nullptr && leafCertificateLen != 0,
+ (result = CertificateChainValidationResult::kLeafArgumentInvalid, CHIP_ERROR_INVALID_ARGUMENT));
+
+ mbedtls_x509_crt_init(&certChain);
+ mbedtls_x509_crt_init(&rootCert);
+
+ /* Start of chain */
+ mbedResult = mbedtls_x509_crt_parse(&certChain, Uint8::to_const_uchar(leafCertificate), leafCertificateLen);
+ VerifyOrExit(mbedResult == 0, (result = CertificateChainValidationResult::kLeafFormatInvalid, error = CHIP_ERROR_INTERNAL));
+
+ /* Add the intermediate to the chain */
+ mbedResult = mbedtls_x509_crt_parse(&certChain, Uint8::to_const_uchar(caCertificate), caCertificateLen);
+ VerifyOrExit(mbedResult == 0, (result = CertificateChainValidationResult::kICAFormatInvalid, error = CHIP_ERROR_INTERNAL));
+
+ /* Parse the root cert */
+ mbedResult = mbedtls_x509_crt_parse(&rootCert, Uint8::to_const_uchar(rootCertificate), rootCertificateLen);
+ VerifyOrExit(mbedResult == 0, (result = CertificateChainValidationResult::kRootFormatInvalid, error = CHIP_ERROR_INTERNAL));
+
+ /* Verify the chain against the root */
+ mbedResult = mbedtls_x509_crt_verify(&certChain, &rootCert, NULL, NULL, &flags, NULL, NULL);
+
+ switch (mbedResult)
+ {
+ case 0:
+ VerifyOrExit(flags == 0, (result = CertificateChainValidationResult::kInternalFrameworkError, error = CHIP_ERROR_INTERNAL));
+ result = CertificateChainValidationResult::kSuccess;
+ break;
+ case MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:
+ result = CertificateChainValidationResult::kChainInvalid;
+ error = CHIP_ERROR_CERT_NOT_TRUSTED;
+ break;
+ default:
+ SuccessOrExit((result = CertificateChainValidationResult::kInternalFrameworkError, error = CHIP_ERROR_INTERNAL));
+ }
+
+exit:
+ _log_mbedTLS_error(mbedResult);
+ mbedtls_x509_crt_free(&certChain);
+ mbedtls_x509_crt_free(&rootCert);
+
+#else
+ (void) rootCertificate;
+ (void) rootCertificateLen;
+ (void) caCertificate;
+ (void) caCertificateLen;
+ (void) leafCertificate;
+ (void) leafCertificateLen;
+ (void) result;
+ CHIP_ERROR error = CHIP_ERROR_NOT_IMPLEMENTED;
+#endif // defined(MBEDTLS_X509_CRT_PARSE_C)
+
+ return error;
+}
+
+inline bool IsTimeGreaterThanEqual(const mbedtls_x509_time * const timeA, const mbedtls_x509_time * const timeB)
+{
+
+ // checks if two values are different and if yes, then returns first > second.
+#define RETURN_STRICTLY_GREATER_IF_DIFFERENT(component) \
+ { \
+ auto valueA = timeA->CHIP_CRYPTO_PAL_PRIVATE_X509(component); \
+ auto valueB = timeB->CHIP_CRYPTO_PAL_PRIVATE_X509(component); \
+ \
+ if (valueA != valueB) \
+ { \
+ return valueA > valueB; \
+ } \
+ }
+
+ RETURN_STRICTLY_GREATER_IF_DIFFERENT(year);
+ RETURN_STRICTLY_GREATER_IF_DIFFERENT(mon);
+ RETURN_STRICTLY_GREATER_IF_DIFFERENT(day);
+ RETURN_STRICTLY_GREATER_IF_DIFFERENT(hour);
+ RETURN_STRICTLY_GREATER_IF_DIFFERENT(min);
+ RETURN_STRICTLY_GREATER_IF_DIFFERENT(sec);
+
+ // all above are equal
+ return true;
+}
+
+CHIP_ERROR IsCertificateValidAtIssuance(const ByteSpan & referenceCertificate, const ByteSpan & toBeEvaluatedCertificate)
+{
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ mbedtls_x509_crt mbedReferenceCertificate;
+ mbedtls_x509_crt mbedToBeEvaluatedCertificate;
+ mbedtls_x509_time refNotBeforeTime;
+ mbedtls_x509_time tbeNotBeforeTime;
+ mbedtls_x509_time tbeNotAfterTime;
+ int result;
+
+ VerifyOrReturnError(!referenceCertificate.empty() && !toBeEvaluatedCertificate.empty(), CHIP_ERROR_INVALID_ARGUMENT);
+
+ mbedtls_x509_crt_init(&mbedReferenceCertificate);
+ mbedtls_x509_crt_init(&mbedToBeEvaluatedCertificate);
+
+ result = mbedtls_x509_crt_parse(&mbedReferenceCertificate, Uint8::to_const_uchar(referenceCertificate.data()),
+ referenceCertificate.size());
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+
+ result = mbedtls_x509_crt_parse(&mbedToBeEvaluatedCertificate, Uint8::to_const_uchar(toBeEvaluatedCertificate.data()),
+ toBeEvaluatedCertificate.size());
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+
+ refNotBeforeTime = mbedReferenceCertificate.CHIP_CRYPTO_PAL_PRIVATE_X509(valid_from);
+ tbeNotBeforeTime = mbedToBeEvaluatedCertificate.CHIP_CRYPTO_PAL_PRIVATE_X509(valid_from);
+ tbeNotAfterTime = mbedToBeEvaluatedCertificate.CHIP_CRYPTO_PAL_PRIVATE_X509(valid_to);
+
+ // check if referenceCertificate is issued at or after tbeCertificate's notBefore timestamp
+ VerifyOrExit(IsTimeGreaterThanEqual(&refNotBeforeTime, &tbeNotBeforeTime), error = CHIP_ERROR_CERT_EXPIRED);
+
+ // check if referenceCertificate is issued at or before tbeCertificate's notAfter timestamp
+ VerifyOrExit(IsTimeGreaterThanEqual(&tbeNotAfterTime, &refNotBeforeTime), error = CHIP_ERROR_CERT_EXPIRED);
+
+exit:
+ _log_mbedTLS_error(result);
+ mbedtls_x509_crt_free(&mbedReferenceCertificate);
+ mbedtls_x509_crt_free(&mbedToBeEvaluatedCertificate);
+
+#else
+ (void) referenceCertificate;
+ (void) toBeEvaluatedCertificate;
+ CHIP_ERROR error = CHIP_ERROR_NOT_IMPLEMENTED;
+#endif // defined(MBEDTLS_X509_CRT_PARSE_C)
+
+ return error;
+}
+
+CHIP_ERROR IsCertificateValidAtCurrentTime(const ByteSpan & certificate)
+{
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ mbedtls_x509_crt mbedCertificate;
+ int result;
+
+ VerifyOrReturnError(!certificate.empty(), CHIP_ERROR_INVALID_ARGUMENT);
+
+ mbedtls_x509_crt_init(&mbedCertificate);
+
+ result = mbedtls_x509_crt_parse(&mbedCertificate, Uint8::to_const_uchar(certificate.data()), certificate.size());
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+
+ // check if certificate's notBefore timestamp is earlier than or equal to current time.
+ result = mbedtls_x509_time_is_past(&mbedCertificate.CHIP_CRYPTO_PAL_PRIVATE_X509(valid_from));
+ VerifyOrExit(result == 1, error = CHIP_ERROR_CERT_EXPIRED);
+
+ // check if certificate's notAfter timestamp is later than current time.
+ result = mbedtls_x509_time_is_future(&mbedCertificate.CHIP_CRYPTO_PAL_PRIVATE_X509(valid_to));
+ VerifyOrExit(result == 1, error = CHIP_ERROR_CERT_EXPIRED);
+
+exit:
+ _log_mbedTLS_error(result);
+ mbedtls_x509_crt_free(&mbedCertificate);
+
+#else
+ (void) certificate;
+ CHIP_ERROR error = CHIP_ERROR_NOT_IMPLEMENTED;
+#endif // defined(MBEDTLS_X509_CRT_PARSE_C)
+
+ return error;
+}
+
+CHIP_ERROR ExtractPubkeyFromX509Cert(const ByteSpan & certificate, Crypto::P256PublicKey & pubkey)
+{
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ mbedtls_x509_crt mbed_cert;
+ mbedtls_ecp_keypair * keypair = nullptr;
+ size_t pubkey_size = 0;
+
+ mbedtls_x509_crt_init(&mbed_cert);
+
+ int result = mbedtls_x509_crt_parse(&mbed_cert, Uint8::to_const_uchar(certificate.data()), certificate.size());
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+
+ VerifyOrExit(mbedtls_pk_get_type(&(mbed_cert.CHIP_CRYPTO_PAL_PRIVATE_X509(pk))) == MBEDTLS_PK_ECKEY,
+ error = CHIP_ERROR_INVALID_ARGUMENT);
+
+ keypair = mbedtls_pk_ec(mbed_cert.CHIP_CRYPTO_PAL_PRIVATE_X509(pk));
+ VerifyOrExit(keypair->CHIP_CRYPTO_PAL_PRIVATE(grp).id == MapECPGroupId(pubkey.Type()), error = CHIP_ERROR_INVALID_ARGUMENT);
+ // Copy the public key from the cert in raw point format
+ result =
+ mbedtls_ecp_point_write_binary(&keypair->CHIP_CRYPTO_PAL_PRIVATE(grp), &keypair->CHIP_CRYPTO_PAL_PRIVATE(Q),
+ MBEDTLS_ECP_PF_UNCOMPRESSED, &pubkey_size, Uint8::to_uchar(pubkey.Bytes()), pubkey.Length());
+
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+ VerifyOrExit(pubkey_size == pubkey.Length(), error = CHIP_ERROR_INTERNAL);
+
+exit:
+ _log_mbedTLS_error(result);
+ mbedtls_x509_crt_free(&mbed_cert);
+
+#else
+ (void) certificate;
+ (void) pubkey;
+ CHIP_ERROR error = CHIP_ERROR_NOT_IMPLEMENTED;
+#endif // defined(MBEDTLS_X509_CRT_PARSE_C)
+
+ return error;
+}
+
+namespace {
+
+CHIP_ERROR ExtractKIDFromX509Cert(bool extractSKID, const ByteSpan & certificate, MutableByteSpan & kid)
+{
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ mbedtls_x509_crt mbed_cert;
+ unsigned char * p;
+ const unsigned char * end;
+ size_t len;
+
+ constexpr uint8_t sOID_Extension_SubjectKeyIdentifier[] = { 0x55, 0x1D, 0x0E };
+ constexpr uint8_t sOID_Extension_AuthorityKeyIdentifier[] = { 0x55, 0x1D, 0x23 };
+
+ mbedtls_x509_crt_init(&mbed_cert);
+
+ int result = mbedtls_x509_crt_parse(&mbed_cert, Uint8::to_const_uchar(certificate.data()), certificate.size());
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+
+ // TODO: The mbedTLS team is working on supporting SKID and AKID extensions processing.
+ // Once it is supported, this code should be updated.
+
+ p = mbed_cert.CHIP_CRYPTO_PAL_PRIVATE_X509(v3_ext).CHIP_CRYPTO_PAL_PRIVATE_X509(p);
+ end = mbed_cert.CHIP_CRYPTO_PAL_PRIVATE_X509(v3_ext).CHIP_CRYPTO_PAL_PRIVATE_X509(p) +
+ mbed_cert.CHIP_CRYPTO_PAL_PRIVATE_X509(v3_ext).CHIP_CRYPTO_PAL_PRIVATE_X509(len);
+ result = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
+ VerifyOrExit(result == 0, error = CHIP_ERROR_WRONG_CERT_TYPE);
+
+ while (p < end)
+ {
+ result = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
+ VerifyOrExit(result == 0, error = CHIP_ERROR_WRONG_CERT_TYPE);
+ result = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID);
+ VerifyOrExit(result == 0, error = CHIP_ERROR_WRONG_CERT_TYPE);
+
+ bool extractCurrentExtSKID = extractSKID && (sizeof(sOID_Extension_SubjectKeyIdentifier) == len) &&
+ (memcmp(p, sOID_Extension_SubjectKeyIdentifier, len) == 0);
+ bool extractCurrentExtAKID = !extractSKID && (sizeof(sOID_Extension_AuthorityKeyIdentifier) == len) &&
+ (memcmp(p, sOID_Extension_AuthorityKeyIdentifier, len) == 0);
+ p += len;
+
+ int is_critical = 0;
+ result = mbedtls_asn1_get_bool(&p, end, &is_critical);
+ VerifyOrExit(result == 0 || result == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG, error = CHIP_ERROR_WRONG_CERT_TYPE);
+
+ result = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
+ VerifyOrExit(result == 0, error = CHIP_ERROR_WRONG_CERT_TYPE);
+
+ if (extractCurrentExtSKID || extractCurrentExtAKID)
+ {
+ if (extractCurrentExtSKID)
+ {
+ result = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
+ VerifyOrExit(result == 0, error = CHIP_ERROR_WRONG_CERT_TYPE);
+ }
+ else
+ {
+ result = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
+ VerifyOrExit(result == 0, error = CHIP_ERROR_WRONG_CERT_TYPE);
+ result = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONTEXT_SPECIFIC);
+ VerifyOrExit(result == 0, error = CHIP_ERROR_WRONG_CERT_TYPE);
+ // Other optional fields, authorityCertIssuer and authorityCertSerialNumber,
+ // will be skipped if present.
+ }
+ VerifyOrExit(len == kSubjectKeyIdentifierLength, error = CHIP_ERROR_WRONG_CERT_TYPE);
+ VerifyOrExit(len <= kid.size(), error = CHIP_ERROR_BUFFER_TOO_SMALL);
+ memcpy(kid.data(), p, len);
+ if (kid.size() > len)
+ {
+ kid.reduce_size(len);
+ }
+ break;
+ }
+ p += len;
+ }
+
+exit:
+ _log_mbedTLS_error(result);
+ mbedtls_x509_crt_free(&mbed_cert);
+
+#else
+ (void) certificate;
+ (void) kid;
+ CHIP_ERROR error = CHIP_ERROR_NOT_IMPLEMENTED;
+#endif // defined(MBEDTLS_X509_CRT_PARSE_C)
+
+ return error;
+}
+
+} // namespace
+
+CHIP_ERROR ExtractSKIDFromX509Cert(const ByteSpan & certificate, MutableByteSpan & skid)
+{
+ return ExtractKIDFromX509Cert(true, certificate, skid);
+}
+
+CHIP_ERROR ExtractAKIDFromX509Cert(const ByteSpan & certificate, MutableByteSpan & akid)
+{
+ return ExtractKIDFromX509Cert(false, certificate, akid);
+}
+
+CHIP_ERROR ExtractVIDPIDFromX509Cert(const ByteSpan & certificate, AttestationCertVidPid & vidpid)
+{
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ constexpr uint8_t sOID_AttributeType_CommonName[] = { 0x55, 0x04, 0x03 };
+ constexpr uint8_t sOID_AttributeType_MatterVendorId[] = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x02, 0x01 };
+ constexpr uint8_t sOID_AttributeType_MatterProductId[] = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x02, 0x02 };
+
+ CHIP_ERROR error = CHIP_NO_ERROR;
+ mbedtls_x509_crt mbed_cert;
+ mbedtls_asn1_named_data * dnIterator = nullptr;
+ AttestationCertVidPid vidpidFromCN;
+
+ mbedtls_x509_crt_init(&mbed_cert);
+
+ int result = mbedtls_x509_crt_parse(&mbed_cert, Uint8::to_const_uchar(certificate.data()), certificate.size());
+ VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
+
+ for (dnIterator = &mbed_cert.CHIP_CRYPTO_PAL_PRIVATE_X509(subject); dnIterator != nullptr;
+ dnIterator = dnIterator->CHIP_CRYPTO_PAL_PRIVATE_X509(next))
+ {
+ size_t oid_len = dnIterator->CHIP_CRYPTO_PAL_PRIVATE_X509(oid).CHIP_CRYPTO_PAL_PRIVATE_X509(len);
+ uint8_t * oid_p = dnIterator->CHIP_CRYPTO_PAL_PRIVATE_X509(oid).CHIP_CRYPTO_PAL_PRIVATE_X509(p);
+ size_t val_len = dnIterator->CHIP_CRYPTO_PAL_PRIVATE_X509(val).CHIP_CRYPTO_PAL_PRIVATE_X509(len);
+ uint8_t * val_p = dnIterator->CHIP_CRYPTO_PAL_PRIVATE_X509(val).CHIP_CRYPTO_PAL_PRIVATE_X509(p);
+
+ if (oid_p != nullptr && val_p != nullptr)
+ {
+ DNAttrType attrType = DNAttrType::kUnspecified;
+ if ((oid_len == sizeof(sOID_AttributeType_CommonName)) && (memcmp(sOID_AttributeType_CommonName, oid_p, oid_len) == 0))
+ {
+ attrType = DNAttrType::kCommonName;
+ }
+ else if ((oid_len == sizeof(sOID_AttributeType_MatterVendorId)) &&
+ (memcmp(sOID_AttributeType_MatterVendorId, oid_p, oid_len) == 0))
+ {
+ attrType = DNAttrType::kMatterVID;
+ }
+ else if ((oid_len == sizeof(sOID_AttributeType_MatterProductId)) &&
+ (memcmp(sOID_AttributeType_MatterProductId, oid_p, oid_len) == 0))
+ {
+ attrType = DNAttrType::kMatterPID;
+ }
+
+ error = ExtractVIDPIDFromAttributeString(attrType, ByteSpan(val_p, val_len), vidpid, vidpidFromCN);
+ SuccessOrExit(error);
+ }
+ }
+
+ // If Matter Attributes were not found use values extracted from the CN Attribute,
+ // which might be uninitialized as well.
+ if (!vidpid.Initialized())
+ {
+ vidpid = vidpidFromCN;
+ }
+
+exit:
+ _log_mbedTLS_error(result);
+ mbedtls_x509_crt_free(&mbed_cert);
+
+#else
+ (void) certificate;
+ (void) vidpid;
+ CHIP_ERROR error = CHIP_ERROR_NOT_IMPLEMENTED;
+#endif // defined(MBEDTLS_X509_CRT_PARSE_C)
+
+ return error;
+}
+
+} // namespace Crypto
+} // namespace chip
diff --git a/src/crypto/CHIPCryptoPALmbedTLS.cpp b/src/crypto/CHIPCryptoPALmbedTLS.cpp
index 5dbce1d3d62f8f..59b11d1e34a681 100644
--- a/src/crypto/CHIPCryptoPALmbedTLS.cpp
+++ b/src/crypto/CHIPCryptoPALmbedTLS.cpp
@@ -44,13 +44,6 @@
#include
#include
-#if defined(MBEDTLS_USE_TINYCRYPT)
-#include
-#include
-#include
-#include
-#endif // defined(MBEDTLS_USE_TINYCRYPT)
-
#include
#include
#include
@@ -93,11 +86,7 @@ static EntropyContext gsEntropyContext;
static void _log_mbedTLS_error(int error_code)
{
-#if defined(MBEDTLS_USE_TINYCRYPT)
- if (error_code != 0 && error_code != UECC_SUCCESS)
-#else
if (error_code != 0)
-#endif
{
#if defined(MBEDTLS_ERROR_C)
char error_str[MAX_ERROR_STR_LEN];
@@ -496,24 +485,6 @@ static int CryptoRNG(void * ctxt, uint8_t * out_buffer, size_t out_length)
return (chip::Crypto::DRBG_get_bytes(out_buffer, out_length) == CHIP_NO_ERROR) ? 0 : 1;
}
-#if defined(MBEDTLS_USE_TINYCRYPT)
-
-static int uecc_rng_wrapper(uint8_t * dest, unsigned int size)
-{
- int ret;
-
- ret = CryptoRNG(NULL, dest, size);
-
- return (ret == 0) ? size : 0;
-}
-
-static int uECC_is_rng_set(void)
-{
- return (uecc_rng_wrapper == uECC_get_rng()) ? 1 : 0;
-}
-
-#endif
-
mbedtls_ecp_group_id MapECPGroupId(SupportedECPKeyTypes keyType)
{
switch (keyType)
@@ -525,20 +496,6 @@ mbedtls_ecp_group_id MapECPGroupId(SupportedECPKeyTypes keyType)
}
}
-#if defined(MBEDTLS_USE_TINYCRYPT)
-
-static inline mbedtls_uecc_keypair * to_keypair(P256KeypairContext * context)
-{
- return SafePointerCast(context);
-}
-
-static inline const mbedtls_uecc_keypair * to_const_keypair(const P256KeypairContext * context)
-{
- return SafePointerCast(context);
-}
-
-#else
-
static inline mbedtls_ecp_keypair * to_keypair(P256KeypairContext * context)
{
return SafePointerCast(context);
@@ -549,8 +506,6 @@ static inline const mbedtls_ecp_keypair * to_const_keypair(const P256KeypairCont
return SafePointerCast(context);
}
-#endif
-
CHIP_ERROR P256Keypair::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_length, P256ECDSASignature & out_signature) const
{
VerifyOrReturnError(mInitialized, CHIP_ERROR_INCORRECT_STATE);
@@ -560,24 +515,9 @@ CHIP_ERROR P256Keypair::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_len
memset(&digest[0], 0, sizeof(digest));
ReturnErrorOnFailure(Hash_SHA256(msg, msg_length, &digest[0]));
-#if defined(MBEDTLS_USE_TINYCRYPT)
- CHIP_ERROR error = CHIP_NO_ERROR;
- int result = UECC_FAILURE;
-
- const mbedtls_uecc_keypair * keypair = to_const_keypair(&mKeypair);
-
- result = uECC_sign(keypair->private_key, digest, sizeof(digest), out_signature.Bytes());
-
- VerifyOrExit(result == UECC_SUCCESS, error = CHIP_ERROR_INTERNAL);
- VerifyOrExit(out_signature.SetLength(kP256_ECDSA_Signature_Length_Raw) == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL);
-
- keypair = nullptr;
-
-exit:
- return error;
-#elif defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_ECDSA_C)
CHIP_ERROR error = CHIP_NO_ERROR;
- int result = 0;
+ int result = 0;
mbedtls_mpi r, s;
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
@@ -638,29 +578,13 @@ CHIP_ERROR P256PublicKey::ECDSA_validate_msg_signature(const uint8_t * msg, cons
CHIP_ERROR P256PublicKey::ECDSA_validate_hash_signature(const uint8_t * hash, const size_t hash_length,
const P256ECDSASignature & signature) const
{
-#if defined(MBEDTLS_USE_TINYCRYPT)
- VerifyOrReturnError(hash != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
- VerifyOrReturnError(hash_length == kSHA256_Hash_Length, CHIP_ERROR_INVALID_ARGUMENT);
- VerifyOrReturnError(signature.Length() == kP256_ECDSA_Signature_Length_Raw, CHIP_ERROR_INVALID_ARGUMENT);
-
- CHIP_ERROR error = CHIP_NO_ERROR;
- int result = UECC_FAILURE;
-
- const uint8_t * public_key = *this;
-
- // Fully padded raw uncompressed points expected, first byte is always 0x04 i.e uncompressed
- result = uECC_verify(public_key + 1, hash, hash_length, Uint8::to_const_uchar(signature.ConstBytes()));
- VerifyOrExit(result == UECC_SUCCESS, error = CHIP_ERROR_INVALID_SIGNATURE);
-
-exit:
- return error;
-#elif defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_ECDSA_C)
VerifyOrReturnError(hash != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(hash_length == kSHA256_Hash_Length, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(signature.Length() == kP256_ECDSA_Signature_Length_Raw, CHIP_ERROR_INVALID_ARGUMENT);
CHIP_ERROR error = CHIP_NO_ERROR;
- int result = 0;
+ int result = 0;
mbedtls_mpi r, s;
mbedtls_mpi_init(&r);
@@ -712,26 +636,6 @@ CHIP_ERROR P256Keypair::ECDH_derive_secret(const P256PublicKey & remote_public_k
{
#if defined(MBEDTLS_ECDH_C)
-#if defined(MBEDTLS_USE_TINYCRYPT)
- CHIP_ERROR error = CHIP_NO_ERROR;
- int result = 0;
- size_t secret_length = (out_secret.Length() == 0) ? out_secret.Capacity() : out_secret.Length();
-
- const mbedtls_uecc_keypair * keypair = to_const_keypair(&mKeypair);
-
- VerifyOrExit(mInitialized, error = CHIP_ERROR_INCORRECT_STATE);
-
- // Fully padded raw uncompressed points expected, first byte is always 0x04 i.e uncompressed
- result = uECC_shared_secret(remote_public_key.ConstBytes() + 1, keypair->private_key, Uint8::to_uchar(out_secret));
- VerifyOrExit(result == UECC_SUCCESS, error = CHIP_ERROR_INTERNAL);
-
- SuccessOrExit(out_secret.SetLength(secret_length));
-
-exit:
- keypair = nullptr;
- _log_mbedTLS_error(result);
- return error;
-#else
CHIP_ERROR error = CHIP_NO_ERROR;
int result = 0;
size_t secret_length = (out_secret.Length() == 0) ? out_secret.Capacity() : out_secret.Length();
@@ -771,7 +675,6 @@ CHIP_ERROR P256Keypair::ECDH_derive_secret(const P256PublicKey & remote_public_k
mbedtls_ecp_point_free(&ecp_pubkey);
_log_mbedTLS_error(result);
return error;
-#endif
#else
return CHIP_ERROR_NOT_IMPLEMENTED;
@@ -811,34 +714,8 @@ bool IsBufferContentEqualConstantTime(const void * a, const void * b, size_t n)
CHIP_ERROR P256Keypair::Initialize()
{
-#if defined(MBEDTLS_USE_TINYCRYPT)
- CHIP_ERROR error = CHIP_NO_ERROR;
- int result = UECC_FAILURE;
-
- Clear();
-
- mbedtls_uecc_keypair * keypair = to_keypair(&mKeypair);
- if (!uECC_is_rng_set())
- {
- uECC_set_rng(&uecc_rng_wrapper);
- }
-
- result = uECC_make_key(keypair->public_key, keypair->private_key);
- VerifyOrExit(result == UECC_SUCCESS, error = CHIP_ERROR_INTERNAL);
-
- // Fully padded raw uncompressed points expected, first byte is always 0x04 i.e uncompressed
- Uint8::to_uchar(mPublicKey)[0] = 0x04;
- memcpy(Uint8::to_uchar(mPublicKey) + 1, keypair->public_key, 2 * NUM_ECC_BYTES);
-
- keypair = nullptr;
- mInitialized = true;
-
-exit:
- _log_mbedTLS_error(result);
- return error;
-#else
CHIP_ERROR error = CHIP_NO_ERROR;
- int result = 0;
+ int result = 0;
size_t pubkey_size = 0;
@@ -858,7 +735,7 @@ CHIP_ERROR P256Keypair::Initialize()
VerifyOrExit(result == 0, error = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(pubkey_size == mPublicKey.Length(), error = CHIP_ERROR_INVALID_ARGUMENT);
- keypair = nullptr;
+ keypair = nullptr;
mInitialized = true;
exit:
@@ -870,42 +747,16 @@ CHIP_ERROR P256Keypair::Initialize()
_log_mbedTLS_error(result);
return error;
-#endif
}
CHIP_ERROR P256Keypair::Serialize(P256SerializedKeypair & output) const
{
-#if defined(MBEDTLS_USE_TINYCRYPT)
- const mbedtls_uecc_keypair * keypair = to_const_keypair(&mKeypair);
- size_t len = output.Length() == 0 ? output.Capacity() : output.Length();
- Encoding::BufferWriter bbuf(output, len);
- uint8_t privkey[kP256_PrivateKey_Length];
- CHIP_ERROR error = CHIP_NO_ERROR;
- int result = 0;
-
- bbuf.Put(mPublicKey, mPublicKey.Length());
-
- VerifyOrExit(bbuf.Available() == sizeof(privkey), error = CHIP_ERROR_INTERNAL);
- VerifyOrExit(sizeof(keypair->private_key) <= bbuf.Available(), error = CHIP_ERROR_INTERNAL);
-
- memcpy(privkey, keypair->private_key, sizeof(privkey));
-
- bbuf.Put(privkey, sizeof(privkey));
- VerifyOrExit(bbuf.Fit(), error = CHIP_ERROR_BUFFER_TOO_SMALL);
-
- output.SetLength(bbuf.Needed());
-
-exit:
- memset(privkey, 0, sizeof(privkey));
- _log_mbedTLS_error(result);
- return error;
-#else
const mbedtls_ecp_keypair * keypair = to_const_keypair(&mKeypair);
- size_t len = output.Length() == 0 ? output.Capacity() : output.Length();
+ size_t len = output.Length() == 0 ? output.Capacity() : output.Length();
Encoding::BufferWriter bbuf(output, len);
uint8_t privkey[kP256_PrivateKey_Length];
CHIP_ERROR error = CHIP_NO_ERROR;
- int result = 0;
+ int result = 0;
bbuf.Put(mPublicKey, mPublicKey.Length());
@@ -925,44 +776,13 @@ CHIP_ERROR P256Keypair::Serialize(P256SerializedKeypair & output) const
ClearSecretData(privkey, sizeof(privkey));
_log_mbedTLS_error(result);
return error;
-#endif
}
CHIP_ERROR P256Keypair::Deserialize(P256SerializedKeypair & input)
{
-#if defined(MBEDTLS_USE_TINYCRYPT)
- int result = 0;
- CHIP_ERROR error = CHIP_NO_ERROR;
- Encoding::BufferWriter bbuf(mPublicKey, mPublicKey.Length());
-
- Clear();
-
- mbedtls_uecc_keypair * keypair = to_keypair(&mKeypair);
- if (!uECC_is_rng_set())
- {
- uECC_set_rng(&uecc_rng_wrapper);
- }
-
- // Fully padded raw uncompressed points expected, first byte is always 0x04 i.e uncompressed
- memcpy(keypair->public_key, Uint8::to_uchar(input) + 1, 2 * NUM_ECC_BYTES);
- memcpy(keypair->private_key, Uint8::to_uchar(input) + mPublicKey.Length(), NUM_ECC_BYTES);
-
- keypair = nullptr;
-
- VerifyOrExit(input.Length() == mPublicKey.Length() + kP256_PrivateKey_Length, error = CHIP_ERROR_INVALID_ARGUMENT);
- bbuf.Put((const uint8_t *) input, mPublicKey.Length());
- VerifyOrExit(bbuf.Fit(), error = CHIP_ERROR_NO_MEMORY);
-
- mInitialized = true;
-
- _log_mbedTLS_error(result);
-
-exit:
- return error;
-#else
Encoding::BufferWriter bbuf(mPublicKey, mPublicKey.Length());
- int result = 0;
+ int result = 0;
CHIP_ERROR error = CHIP_NO_ERROR;
Clear();
@@ -993,22 +813,15 @@ CHIP_ERROR P256Keypair::Deserialize(P256SerializedKeypair & input)
exit:
_log_mbedTLS_error(result);
return error;
-#endif
}
void P256Keypair::Clear()
{
if (mInitialized)
{
-#if defined(MBEDTLS_USE_TINYCRYPT)
- mbedtls_uecc_keypair * keypair = to_keypair(&mKeypair);
- memset(keypair, 0, sizeof(mbedtls_uecc_keypair));
- mInitialized = false;
-#else
mbedtls_ecp_keypair * keypair = to_keypair(&mKeypair);
mbedtls_ecp_keypair_free(keypair);
mInitialized = false;
-#endif
}
}
@@ -1134,21 +947,6 @@ CHIP_ERROR VerifyCertificateSigningRequest(const uint8_t * csr_buf, size_t csr_l
typedef struct Spake2p_Context
{
-#if defined(MBEDTLS_USE_TINYCRYPT)
- const mbedtls_md_info_t * md_info;
- uECC_word_t M[2 * NUM_ECC_WORDS];
- uECC_word_t N[2 * NUM_ECC_WORDS];
- uECC_word_t X[2 * NUM_ECC_WORDS];
- uECC_word_t Y[2 * NUM_ECC_WORDS];
- uECC_word_t L[2 * NUM_ECC_WORDS];
- uECC_word_t Z[2 * NUM_ECC_WORDS];
- uECC_word_t V[2 * NUM_ECC_WORDS];
-
- uECC_word_t w0[NUM_ECC_WORDS];
- uECC_word_t w1[NUM_ECC_WORDS];
- uECC_word_t xy[NUM_ECC_WORDS];
- uECC_word_t tempbn[NUM_ECC_WORDS];
-#else
mbedtls_ecp_group curve;
const mbedtls_md_info_t * md_info;
mbedtls_ecp_point M;
@@ -1163,7 +961,6 @@ typedef struct Spake2p_Context
mbedtls_mpi w1;
mbedtls_mpi xy;
mbedtls_mpi tempbn;
-#endif
} Spake2p_Context;
static inline Spake2p_Context * to_inner_spake2p_context(Spake2pOpaqueContext * context)
@@ -1180,27 +977,6 @@ CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::InitInternal(void)
memset(context, 0, sizeof(Spake2p_Context));
-#if defined(MBEDTLS_USE_TINYCRYPT)
- M = context->M;
- N = context->N;
- X = context->X;
- Y = context->Y;
- L = context->L;
- V = context->V;
- Z = context->Z;
-
- w0 = context->w0;
- w1 = context->w1;
- xy = context->xy;
- tempbn = context->tempbn;
-
- G = curve_G;
-
- if (!uECC_is_rng_set())
- {
- uECC_set_rng(&uecc_rng_wrapper);
- }
-#else
mbedtls_ecp_group_init(&context->curve);
result = mbedtls_ecp_group_load(&context->curve, MBEDTLS_ECP_DP_SECP256R1);
VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
@@ -1227,14 +1003,13 @@ CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::InitInternal(void)
mbedtls_mpi_init(&context->w1);
mbedtls_mpi_init(&context->xy);
mbedtls_mpi_init(&context->tempbn);
- w0 = &context->w0;
- w1 = &context->w1;
- xy = &context->xy;
+ w0 = &context->w0;
+ w1 = &context->w1;
+ xy = &context->xy;
tempbn = &context->tempbn;
- G = &context->curve.G;
+ G = &context->curve.G;
order = &context->curve.N;
-#endif
return error;
@@ -1249,22 +1024,6 @@ void Spake2p_P256_SHA256_HKDF_HMAC::Clear()
VerifyOrReturn(state != CHIP_SPAKE2P_STATE::PREINIT);
Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
-#if defined(MBEDTLS_USE_TINYCRYPT)
- memset(&context->M, 0, 2 * NUM_ECC_WORDS * sizeof(uECC_word_t));
- memset(&context->N, 0, 2 * NUM_ECC_WORDS * sizeof(uECC_word_t));
- memset(&context->X, 0, 2 * NUM_ECC_WORDS * sizeof(uECC_word_t));
- memset(&context->Y, 0, 2 * NUM_ECC_WORDS * sizeof(uECC_word_t));
- memset(&context->L, 0, 2 * NUM_ECC_WORDS * sizeof(uECC_word_t));
- memset(&context->Z, 0, 2 * NUM_ECC_WORDS * sizeof(uECC_word_t));
- memset(&context->V, 0, 2 * NUM_ECC_WORDS * sizeof(uECC_word_t));
-
- memset(&context->w0, 0, NUM_ECC_WORDS * sizeof(uECC_word_t));
- memset(&context->w1, 0, NUM_ECC_WORDS * sizeof(uECC_word_t));
- memset(&context->xy, 0, NUM_ECC_WORDS * sizeof(uECC_word_t));
- memset(&context->tempbn, 0, NUM_ECC_WORDS * sizeof(uECC_word_t));
-
- G = NULL;
-#else
mbedtls_ecp_point_free(&context->M);
mbedtls_ecp_point_free(&context->N);
mbedtls_ecp_point_free(&context->X);
@@ -1279,7 +1038,6 @@ void Spake2p_P256_SHA256_HKDF_HMAC::Clear()
mbedtls_mpi_free(&context->tempbn);
mbedtls_ecp_group_free(&context->curve);
-#endif
state = CHIP_SPAKE2P_STATE::PREINIT;
}
@@ -1318,18 +1076,11 @@ CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FELoad(const uint8_t * in, size_t in_l
CHIP_ERROR error = CHIP_NO_ERROR;
int result = 0;
-#if defined(MBEDTLS_USE_TINYCRYPT)
- uECC_word_t tmp[2 * NUM_ECC_WORDS] = { 0 };
- uECC_vli_bytesToNative(tmp, in, NUM_ECC_BYTES);
-
- uECC_vli_mmod((uECC_word_t *) fe, tmp, curve_n);
-#else
result = mbedtls_mpi_read_binary((mbedtls_mpi *) fe, Uint8::to_const_uchar(in), in_len);
VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
result = mbedtls_mpi_mod_mpi((mbedtls_mpi *) fe, (mbedtls_mpi *) fe, (const mbedtls_mpi *) order);
VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
-#endif
exit:
_log_mbedTLS_error(result);
@@ -1338,14 +1089,10 @@ CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FELoad(const uint8_t * in, size_t in_l
CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEWrite(const void * fe, uint8_t * out, size_t out_len)
{
-#if defined(MBEDTLS_USE_TINYCRYPT)
- uECC_vli_nativeToBytes(out, NUM_ECC_BYTES, (const unsigned int *) fe);
-#else
if (mbedtls_mpi_write_binary((const mbedtls_mpi *) fe, Uint8::to_uchar(out), out_len) != 0)
{
return CHIP_ERROR_INTERNAL;
}
-#endif
return CHIP_NO_ERROR;
}
@@ -1354,21 +1101,10 @@ CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEGenerate(void * fe)
CHIP_ERROR error = CHIP_NO_ERROR;
int result = 0;
-#if defined(MBEDTLS_USE_TINYCRYPT)
- mbedtls_uecc_keypair keypair;
-
- result = UECC_FAILURE;
-
- result = uECC_make_key(keypair.public_key, keypair.private_key);
- VerifyOrExit(result == UECC_SUCCESS, error = CHIP_ERROR_INTERNAL);
-
- uECC_vli_bytesToNative((uECC_word_t *) fe, keypair.private_key, NUM_ECC_BYTES);
-#else
Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
result = mbedtls_ecp_gen_privkey(&context->curve, (mbedtls_mpi *) fe, CryptoRNG, nullptr);
VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
-#endif
exit:
_log_mbedTLS_error(result);
@@ -1380,15 +1116,11 @@ CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEMul(void * fer, const void * fe1, co
CHIP_ERROR error = CHIP_NO_ERROR;
int result = 0;
-#if defined(MBEDTLS_USE_TINYCRYPT)
- uECC_vli_modMult((uECC_word_t *) fer, (const uECC_word_t *) fe1, (const uECC_word_t *) fe2, (const uECC_word_t *) curve_n);
-#else
result = mbedtls_mpi_mul_mpi((mbedtls_mpi *) fer, (const mbedtls_mpi *) fe1, (const mbedtls_mpi *) fe2);
VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
result = mbedtls_mpi_mod_mpi((mbedtls_mpi *) fer, (mbedtls_mpi *) fer, (const mbedtls_mpi *) order);
VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
-#endif
exit:
_log_mbedTLS_error(result);
@@ -1397,22 +1129,12 @@ CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::FEMul(void * fer, const void * fe1, co
CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointLoad(const uint8_t * in, size_t in_len, void * R)
{
-#if defined(MBEDTLS_USE_TINYCRYPT)
- uint8_t tmp[2 * NUM_ECC_BYTES];
-
- // Fully padded raw uncompressed points expected, first byte is always 0x04 i.e uncompressed
- memcpy(tmp, in + 1, 2 * NUM_ECC_BYTES);
-
- uECC_vli_bytesToNative((uECC_word_t *) R, tmp, NUM_ECC_BYTES);
- uECC_vli_bytesToNative((uECC_word_t *) R + NUM_ECC_WORDS, tmp + NUM_ECC_BYTES, NUM_ECC_BYTES);
-#else
Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
if (mbedtls_ecp_point_read_binary(&context->curve, (mbedtls_ecp_point *) R, Uint8::to_const_uchar(in), in_len) != 0)
{
return CHIP_ERROR_INTERNAL;
}
-#endif
return CHIP_NO_ERROR;
}
@@ -1421,12 +1143,6 @@ CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointWrite(const void * R, uint8_t * o
{
memset(out, 0, out_len);
-#if defined(MBEDTLS_USE_TINYCRYPT)
- // Fully padded raw uncompressed points expected, first byte is always 0x04 i.e uncompressed
- out[0] = 0x04;
- uECC_vli_nativeToBytes(out + 1, NUM_ECC_BYTES, (uECC_word_t *) R);
- uECC_vli_nativeToBytes(out + NUM_ECC_BYTES + 1, NUM_ECC_BYTES, (uECC_word_t *) R + NUM_ECC_WORDS);
-#else
size_t mbedtls_out_len = out_len;
Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
@@ -1436,22 +1152,16 @@ CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointWrite(const void * R, uint8_t * o
{
return CHIP_ERROR_INTERNAL;
}
-#endif
return CHIP_NO_ERROR;
}
CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointMul(void * R, const void * P1, const void * fe1)
{
-
-#if defined(MBEDTLS_USE_TINYCRYPT)
- if (EccPoint_mult_safer((uECC_word_t *) R, (const uECC_word_t *) P1, (const uECC_word_t *) fe1) != UECC_SUCCESS)
-#else
Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
if (mbedtls_ecp_mul(&context->curve, (mbedtls_ecp_point *) R, (const mbedtls_mpi *) fe1, (const mbedtls_ecp_point *) P1,
CryptoRNG, nullptr) != 0)
-#endif
{
return CHIP_ERROR_INTERNAL;
}
@@ -1462,29 +1172,6 @@ CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointMul(void * R, const void * P1, co
CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointAddMul(void * R, const void * P1, const void * fe1, const void * P2,
const void * fe2)
{
-#if defined(MBEDTLS_USE_TINYCRYPT)
- uECC_word_t R1[2 * NUM_ECC_WORDS];
- uECC_word_t R2[2 * NUM_ECC_WORDS];
- uECC_word_t z[NUM_ECC_WORDS];
- uint8_t ret = UECC_SUCCESS;
-
- if (EccPoint_mult_safer(R1, (const uECC_word_t *) P1, (const uECC_word_t *) fe1) != UECC_SUCCESS)
- {
- return CHIP_ERROR_INTERNAL;
- }
-
- if (EccPoint_mult_safer(R2, (const uECC_word_t *) P2, (const uECC_word_t *) fe2) != UECC_SUCCESS)
- {
- return CHIP_ERROR_INTERNAL;
- }
-
- uECC_vli_modSub(z, R2, R1, curve_p);
- XYcZ_add(R1, R1 + NUM_ECC_WORDS, R2, R2 + NUM_ECC_WORDS);
- uECC_vli_modInv(z, z, curve_p);
- apply_z(R2, R2 + NUM_ECC_WORDS, z);
-
- memcpy((uECC_word_t *) R, R2, 2 * NUM_ECC_BYTES);
-#else
Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
if (mbedtls_ecp_muladd(&context->curve, (mbedtls_ecp_point *) R, (const mbedtls_mpi *) fe1, (const mbedtls_ecp_point *) P1,
@@ -1492,27 +1179,19 @@ CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointAddMul(void * R, const void * P1,
{
return CHIP_ERROR_INTERNAL;
}
-#endif
return CHIP_NO_ERROR;
}
CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointInvert(void * R)
{
-#if defined(MBEDTLS_USE_TINYCRYPT)
- uECC_word_t tmp[NUM_ECC_WORDS] = { 0 };
-
- uECC_vli_sub(tmp, curve_p, (uECC_word_t *) R + NUM_ECC_WORDS);
- memcpy((uECC_word_t *) R + NUM_ECC_WORDS, tmp, NUM_ECC_BYTES);
-#else
- mbedtls_ecp_point * Rp = (mbedtls_ecp_point *) R;
+ mbedtls_ecp_point * Rp = (mbedtls_ecp_point *) R;
Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
if (mbedtls_mpi_sub_mpi(&Rp->CHIP_CRYPTO_PAL_PRIVATE(Y), &context->curve.P, &Rp->CHIP_CRYPTO_PAL_PRIVATE(Y)) != 0)
{
return CHIP_ERROR_INTERNAL;
}
-#endif
return CHIP_NO_ERROR;
}
@@ -1527,24 +1206,6 @@ CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::ComputeL(uint8_t * Lout, size_t * L_le
CHIP_ERROR error = CHIP_NO_ERROR;
int result = 0;
-#if defined(MBEDTLS_USE_TINYCRYPT)
- result = UECC_SUCCESS;
- uECC_word_t tmp[2 * NUM_ECC_WORDS];
- uECC_word_t w1_bn[NUM_ECC_WORDS];
- uECC_word_t L_tmp[2 * NUM_ECC_WORDS];
-
- uECC_vli_bytesToNative(tmp, w1in, NUM_ECC_BYTES);
-
- uECC_vli_mmod(w1_bn, tmp, curve_n);
-
- result = EccPoint_mult_safer(L_tmp, curve_G, w1_bn);
- VerifyOrExit(result == UECC_SUCCESS, error = CHIP_ERROR_INTERNAL);
-
- // Fully padded raw uncompressed points expected, first byte is always 0x04 i.e uncompressed
- Lout[0] = 0x04;
- uECC_vli_nativeToBytes(Lout + 1, NUM_ECC_BYTES, L_tmp);
- uECC_vli_nativeToBytes(Lout + NUM_ECC_BYTES + 1, NUM_ECC_BYTES, L_tmp + NUM_ECC_WORDS);
-#else
mbedtls_ecp_group curve;
mbedtls_mpi w1_bn;
mbedtls_ecp_point Ltemp;
@@ -1569,28 +1230,21 @@ CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::ComputeL(uint8_t * Lout, size_t * L_le
result = mbedtls_ecp_point_write_binary(&curve, &Ltemp, MBEDTLS_ECP_PF_UNCOMPRESSED, L_len, Uint8::to_uchar(Lout), *L_len);
VerifyOrExit(result == 0, error = CHIP_ERROR_INTERNAL);
-#endif
exit:
_log_mbedTLS_error(result);
-#if !defined(MBEDTLS_USE_TINYCRYPT)
mbedtls_ecp_point_free(&Ltemp);
mbedtls_mpi_free(&w1_bn);
mbedtls_ecp_group_free(&curve);
-#endif
return error;
}
CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::PointIsValid(void * R)
{
-#if defined(MBEDTLS_USE_TINYCRYPT)
- if (uECC_valid_point((const uECC_word_t *) R) != 0)
-#else
Spake2p_Context * context = to_inner_spake2p_context(&mSpake2pContext);
if (mbedtls_ecp_check_pubkey(&context->curve, (mbedtls_ecp_point *) R) != 0)
-#endif
{
return CHIP_ERROR_INTERNAL;
}
diff --git a/src/crypto/crypto.gni b/src/crypto/crypto.gni
index 80d94e042224c7..c77f91a4823083 100644
--- a/src/crypto/crypto.gni
+++ b/src/crypto/crypto.gni
@@ -30,5 +30,5 @@ if (chip_crypto == "") {
assert(
chip_crypto == "mbedtls" || chip_crypto == "openssl" ||
- chip_crypto == "boringssl",
- "Please select a valid crypto implementation: mbedtls, openssl, boringssl")
+ chip_crypto == "tinycrypt" || chip_crypto == "boringssl",
+ "Please select a valid crypto implementation: mbedtls, openssl, tinycrypt, boringssl")
diff --git a/src/lib/shell/streamer_k32w.cpp b/src/lib/shell/streamer_k32w.cpp
index ee0887766a8fb2..68523e7a2c44ff 100644
--- a/src/lib/shell/streamer_k32w.cpp
+++ b/src/lib/shell/streamer_k32w.cpp
@@ -28,7 +28,7 @@
#include
#include "SerialManager.h"
-extern uint8_t mOtSerMgrIfLog;
+extern uint8_t gShellSerMgrIf;
namespace chip {
namespace Shell {
@@ -48,7 +48,7 @@ ssize_t streamer_k32w_read(streamer_t * streamer, char * buffer, size_t length)
uint16_t bytesRead = 0;
(void) streamer;
- Serial_Read(mOtSerMgrIfLog, (uint8_t *) buffer, length, &bytesRead);
+ Serial_Read(gShellSerMgrIf, (uint8_t *) buffer, length, &bytesRead);
return bytesRead;
}
diff --git a/src/platform/nxp/k32w/k32w0/BLEManagerImpl.cpp b/src/platform/nxp/k32w/k32w0/BLEManagerImpl.cpp
index ce2c4a235cdaa8..f8e6518b2d466a 100644
--- a/src/platform/nxp/k32w/k32w0/BLEManagerImpl.cpp
+++ b/src/platform/nxp/k32w/k32w0/BLEManagerImpl.cpp
@@ -184,6 +184,7 @@ CHIP_ERROR BLEManagerImpl::_Init()
VerifyOrExit(bleAppCreated == pdPASS, err = CHIP_ERROR_INCORRECT_STATE);
/* BLE Radio Init */
+ XCVR_TemperatureUpdate(BOARD_GetTemperature());
VerifyOrExit(XCVR_Init(BLE_MODE, DR_2MBPS) == gXcvrSuccess_c, err = CHIP_ERROR_INCORRECT_STATE);
/* Create BLE Controller Task */
diff --git a/src/platform/nxp/k32w/k32w0/BUILD.gn b/src/platform/nxp/k32w/k32w0/BUILD.gn
index dddeef7374b20a..e813d8253c48bd 100644
--- a/src/platform/nxp/k32w/k32w0/BUILD.gn
+++ b/src/platform/nxp/k32w/k32w0/BUILD.gn
@@ -47,8 +47,6 @@ static_library("k32w0") {
"NFCManagerImpl.h",
"PlatformManagerImpl.cpp",
"PlatformManagerImpl.h",
- "RamStorage.cpp",
- "RamStorage.h",
"ble_function_mux.c",
]
diff --git a/src/platform/nxp/k32w/k32w0/K32W0Config.cpp b/src/platform/nxp/k32w/k32w0/K32W0Config.cpp
index bab9d1eb2e618b..c22f4c5a862312 100644
--- a/src/platform/nxp/k32w/k32w0/K32W0Config.cpp
+++ b/src/platform/nxp/k32w/k32w0/K32W0Config.cpp
@@ -36,7 +36,8 @@ namespace chip {
namespace DeviceLayer {
namespace Internal {
-static ramBufferDescriptor * ramDescr;
+osaMutexId_t K32WConfig::pdmMutexHandle = NULL;
+static ramBufferDescriptor * ramDescr = NULL;
constexpr uint16_t kNvmIdChipConfigData = 0x5000;
constexpr uint16_t kRamBufferInitialSize = 3072;
@@ -47,6 +48,8 @@ CHIP_ERROR K32WConfig::Init()
int pdmStatus;
/* Initialise the Persistent Data Manager */
+ pdmMutexHandle = OSA_MutexCreate();
+ VerifyOrExit((NULL != pdmMutexHandle), err = CHIP_ERROR_NO_MEMORY);
pdmStatus = PDM_Init();
SuccessOrExit(err = MapPdmInitStatus(pdmStatus));
@@ -57,9 +60,38 @@ CHIP_ERROR K32WConfig::Init()
}
exit:
+ if (err != CHIP_NO_ERROR)
+ {
+ if (pdmMutexHandle)
+ {
+ OSA_MutexDestroy(pdmMutexHandle);
+ }
+ if (ramDescr)
+ {
+ free(ramDescr);
+ }
+ }
return err;
}
+void K32WConfig::MutexLock(osaMutexId_t mutexId, uint32_t millisec)
+{
+ osaStatus_t status = OSA_MutexLock(mutexId, millisec);
+ if (osaStatus_Success != status)
+ {
+ ChipLogProgress(DeviceLayer, "OSA mutex lock failed.");
+ }
+}
+
+void K32WConfig::MutexUnlock(osaMutexId_t mutexId)
+{
+ osaStatus_t status = OSA_MutexUnlock(mutexId);
+ if (osaStatus_Success != status)
+ {
+ ChipLogProgress(DeviceLayer, "OSA mutex unlock failed.");
+ }
+}
+
CHIP_ERROR K32WConfig::ReadConfigValue(Key key, bool & val)
{
CHIP_ERROR err;
@@ -139,53 +171,119 @@ CHIP_ERROR K32WConfig::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & val
CHIP_ERROR K32WConfig::WriteConfigValue(Key key, bool val)
{
CHIP_ERROR err;
- rsError status;
PDM_teStatus pdmStatus;
+ rsError ramStatus = RS_ERROR_NONE;
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
- status = ramStorageSet(&ramDescr, key, (uint8_t *) &val, sizeof(bool));
- SuccessOrExit(err = MapRamStorageStatus(status));
+ MutexLock(pdmMutexHandle, osaWaitForever_c);
+
+ /* first delete all occurrences of "key" */
+ ramStorageDelete(ramDescr, key, -1);
+
+ /* resize RAM Buffer if needed */
+ ramStatus = ramStorageResize(&ramDescr, key, (uint8_t *) &val, sizeof(bool));
+ SuccessOrExit(err = MapRamStorageStatus(ramStatus));
+
+ /* add to RAM buffer */
+ ramStatus = ramStorageSet(ramDescr, key, (uint8_t *) &val, sizeof(bool));
+ SuccessOrExit(err = MapRamStorageStatus(ramStatus));
+
+ /* schedule flash writing */
+ pdmStatus = PDM_eSaveRecordDataInIdleTask(kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize);
+ SuccessOrExit(err = MapPdmStatus(pdmStatus));
+
+exit:
+ MutexUnlock(pdmMutexHandle);
+ return err;
+}
+
+CHIP_ERROR K32WConfig::WriteConfigValueSync(Key key, bool val)
+{
+ CHIP_ERROR err;
+ PDM_teStatus pdmStatus;
+ rsError ramStatus = RS_ERROR_NONE;
+
+ VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
+ MutexLock(pdmMutexHandle, osaWaitForever_c);
+
+ /* first delete all occurrences of "key" */
+ ramStorageDelete(ramDescr, key, -1);
- pdmStatus =
- PDM_eSaveRecordDataInIdleTask((uint16_t) kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize);
+ /* resize RAM Buffer if needed */
+ ramStatus = ramStorageResize(&ramDescr, key, (uint8_t *) &val, sizeof(bool));
+ SuccessOrExit(err = MapRamStorageStatus(ramStatus));
+
+ /* add to RAM buffer */
+ ramStatus = ramStorageSet(ramDescr, key, (uint8_t *) &val, sizeof(bool));
+ SuccessOrExit(err = MapRamStorageStatus(ramStatus));
+
+ // Interrupts are disabled to ensure there is no context switch during the actual
+ // writing, thus avoiding race conditions.
+ OSA_InterruptDisable();
+ pdmStatus = PDM_eSaveRecordData(kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize);
+ OSA_InterruptEnable();
SuccessOrExit(err = MapPdmStatus(pdmStatus));
+
exit:
+ MutexUnlock(pdmMutexHandle);
return err;
}
CHIP_ERROR K32WConfig::WriteConfigValue(Key key, uint32_t val)
{
CHIP_ERROR err;
- rsError status;
PDM_teStatus pdmStatus;
+ rsError ramStatus = RS_ERROR_NONE;
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
- status = ramStorageSet(&ramDescr, key, (uint8_t *) &val, sizeof(uint32_t));
- SuccessOrExit(err = MapRamStorageStatus(status));
+ MutexLock(pdmMutexHandle, osaWaitForever_c);
+
+ /* first delete all occurrences of "key" */
+ ramStorageDelete(ramDescr, key, -1);
- pdmStatus =
- PDM_eSaveRecordDataInIdleTask((uint16_t) kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize);
+ /* resize RAM Buffer if needed */
+ ramStatus = ramStorageResize(&ramDescr, key, (uint8_t *) &val, sizeof(uint32_t));
+ SuccessOrExit(err = MapRamStorageStatus(ramStatus));
+
+ /* add to RAM buffer */
+ ramStatus = ramStorageSet(ramDescr, key, (uint8_t *) &val, sizeof(uint32_t));
+ SuccessOrExit(err = MapRamStorageStatus(ramStatus));
+
+ /* schedule flash writing */
+ pdmStatus = PDM_eSaveRecordDataInIdleTask(kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize);
SuccessOrExit(err = MapPdmStatus(pdmStatus));
exit:
+ MutexUnlock(pdmMutexHandle);
return err;
}
CHIP_ERROR K32WConfig::WriteConfigValue(Key key, uint64_t val)
{
CHIP_ERROR err;
- rsError status;
PDM_teStatus pdmStatus;
+ rsError ramStatus = RS_ERROR_NONE;
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
- status = ramStorageSet(&ramDescr, key, (uint8_t *) &val, sizeof(uint64_t));
- SuccessOrExit(err = MapRamStorageStatus(status));
+ MutexLock(pdmMutexHandle, osaWaitForever_c);
+
+ /* first delete all occurrences of "key" */
+ ramStorageDelete(ramDescr, key, -1);
+
+ /* resize RAM Buffer if needed */
+ ramStatus = ramStorageResize(&ramDescr, key, (uint8_t *) &val, sizeof(uint64_t));
+ SuccessOrExit(err = MapRamStorageStatus(ramStatus));
- pdmStatus =
- PDM_eSaveRecordDataInIdleTask((uint16_t) kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize);
+ /* add to RAM buffer */
+ ramStatus = ramStorageSet(ramDescr, key, (uint8_t *) &val, sizeof(uint64_t));
+ SuccessOrExit(err = MapRamStorageStatus(ramStatus));
+
+ /* schedule flash writing */
+ pdmStatus = PDM_eSaveRecordDataInIdleTask(kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize);
SuccessOrExit(err = MapPdmStatus(pdmStatus));
exit:
+ MutexUnlock(pdmMutexHandle);
return err;
}
@@ -198,26 +296,35 @@ CHIP_ERROR K32WConfig::WriteConfigValueStr(Key key, const char * str, size_t str
{
CHIP_ERROR err;
PDM_teStatus pdmStatus;
- rsError status;
+ rsError ramStatus = RS_ERROR_NONE;
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
+ MutexLock(pdmMutexHandle, osaWaitForever_c);
- if (str != NULL)
+ if (!str)
{
- status = ramStorageSet(&ramDescr, key, (uint8_t *) str, strLen);
- SuccessOrExit(err = MapRamStorageStatus(status));
-
- pdmStatus =
- PDM_eSaveRecordDataInIdleTask((uint16_t) kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize);
- SuccessOrExit(err = MapPdmStatus(pdmStatus));
+ ramStatus = ramStorageDelete(ramDescr, key, -1);
+ SuccessOrExit(err = MapRamStorageStatus(ramStatus));
}
else
{
- err = ClearConfigValue(key);
- SuccessOrExit(err);
+ /* first delete all occurrences of "key" */
+ ramStorageDelete(ramDescr, key, -1);
+
+ /* resize RAM Buffer if needed */
+ ramStatus = ramStorageResize(&ramDescr, key, (uint8_t *) str, strLen);
+ SuccessOrExit(err = MapRamStorageStatus(ramStatus));
+
+ /* add to RAM buffer */
+ ramStatus = ramStorageSet(ramDescr, key, (uint8_t *) str, strLen);
+ SuccessOrExit(err = MapRamStorageStatus(ramStatus));
+
+ /* schedule flash writing */
+ pdmStatus = PDM_eSaveRecordDataInIdleTask(kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize);
}
exit:
+ MutexUnlock(pdmMutexHandle);
return err;
}
@@ -239,14 +346,15 @@ CHIP_ERROR K32WConfig::ClearConfigValue(Key key)
PDM_teStatus pdmStatus;
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
- status = ramStorageDelete(ramDescr, key, 0);
+ MutexLock(pdmMutexHandle, osaWaitForever_c);
+ status = ramStorageDelete(ramDescr, key, -1);
SuccessOrExit(err = MapRamStorageStatus(status));
- pdmStatus =
- PDM_eSaveRecordDataInIdleTask((uint16_t) kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize);
+ pdmStatus = PDM_eSaveRecordDataInIdleTask(kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize);
SuccessOrExit(err = MapPdmStatus(pdmStatus));
exit:
+ MutexUnlock(pdmMutexHandle);
return err;
}
@@ -269,14 +377,18 @@ CHIP_ERROR K32WConfig::FactoryResetConfig(void)
CHIP_ERROR err = CHIP_NO_ERROR;
PDM_teStatus pdmStatus;
+ MutexLock(pdmMutexHandle, osaWaitForever_c);
FactoryResetConfigInternal(kMinConfigKey_ChipConfig, kMaxConfigKey_ChipConfig);
FactoryResetConfigInternal(kMinConfigKey_KVSKey, kMaxConfigKey_KVSKey);
FactoryResetConfigInternal(kMinConfigKey_KVSValue, kMaxConfigKey_KVSValue);
- pdmStatus = PDM_eSaveRecordData((uint16_t) kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize);
+ pdmStatus = PDM_eSaveRecordData(kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize);
SuccessOrExit(err = MapPdmStatus(pdmStatus));
exit:
+ free((void *) ramDescr);
+ ramDescr = NULL;
+ MutexUnlock(pdmMutexHandle);
return err;
}
@@ -284,7 +396,7 @@ void K32WConfig::FactoryResetConfigInternal(Key firstKey, Key lastKey)
{
for (Key key = firstKey; key <= lastKey; key++)
{
- ramStorageDelete(ramDescr, key, 0);
+ ramStorageDelete(ramDescr, key, -1);
}
}
diff --git a/src/platform/nxp/k32w/k32w0/K32W0Config.h b/src/platform/nxp/k32w/k32w0/K32W0Config.h
index 803149947a7a71..cc8919cf21ebb9 100644
--- a/src/platform/nxp/k32w/k32w0/K32W0Config.h
+++ b/src/platform/nxp/k32w/k32w0/K32W0Config.h
@@ -29,7 +29,9 @@
#include
#include "PDM.h"
-#include "RamStorage.h"
+#include "fsl_os_abstraction.h"
+#include "pdm_ram_storage_glue.h"
+#include "ram_storage.h"
namespace chip {
namespace DeviceLayer {
@@ -122,6 +124,7 @@ class K32WConfig
static CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen);
static CHIP_ERROR ReadConfigValueCounter(uint8_t counterIdx, uint32_t & val);
static CHIP_ERROR WriteConfigValue(Key key, bool val);
+ static CHIP_ERROR WriteConfigValueSync(Key key, bool val);
static CHIP_ERROR WriteConfigValue(Key key, uint32_t val);
static CHIP_ERROR WriteConfigValue(Key key, uint64_t val);
static CHIP_ERROR WriteConfigValueStr(Key key, const char * str);
@@ -135,6 +138,12 @@ class K32WConfig
static void RunConfigUnitTest(void);
+ // Log error wrappers for OSA mutex lock/unlock.
+ static void MutexLock(osaMutexId_t mutexId, uint32_t millisec);
+ static void MutexUnlock(osaMutexId_t mutexId);
+
+ static osaMutexId_t pdmMutexHandle;
+
protected:
static constexpr uint8_t GetPDMId(uint32_t key);
static constexpr uint8_t GetRecordKey(uint32_t key);
diff --git a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp b/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp
index 8cd1914211f121..f2fbd071bc3654 100644
--- a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp
+++ b/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp
@@ -93,10 +93,14 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t
{
// This is the ID of the actual data
pdmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(pdmIdKvsValue, keyId);
+ ChipLogProgress(DeviceLayer, "KVS, get the value of Matter key [%s] with PDM id: %i", key, pdmInternalId);
err = chip::DeviceLayer::Internal::K32WConfig::ReadConfigValueBin(pdmInternalId, (uint8_t *) value, value_size, read_bytes);
*read_bytes_size = read_bytes;
-
- ChipLogProgress(DeviceLayer, "KVS, get Matter key [%s] with PDM id: %i", key, pdmInternalId);
+ }
+ else
+ {
+ ChipLogProgress(DeviceLayer, "KVS, error in getting the value of Matter key [%s]. Key not found in persistent storage.",
+ key);
}
exit:
@@ -118,15 +122,9 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value,
keyId = GetStringKeyId(key, &freeKeyId);
- // Key already exists
- if (keyId < kMaxNumberOfKeys)
- {
- // Update just the value in this case
- putKey = false;
- }
- else
+ // Key does not exist. Write both key and value in persistent storage.
+ if (kMaxNumberOfKeys == keyId)
{
- // Need to write both the value and the string key
putKey = true;
keyId = freeKeyId;
}
diff --git a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h b/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h
index 0b0a09178ed44d..df942779fe4bc2 100644
--- a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h
+++ b/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h
@@ -1,3 +1,4 @@
+
/*
*
* Copyright (c) 2021 Project CHIP Authors
diff --git a/src/platform/nxp/k32w/k32w0/Logging.cpp b/src/platform/nxp/k32w/k32w0/Logging.cpp
index eca2baf51216c1..da545b6c7aff85 100644
--- a/src/platform/nxp/k32w/k32w0/Logging.cpp
+++ b/src/platform/nxp/k32w/k32w0/Logging.cpp
@@ -28,7 +28,6 @@ static constexpr uint8_t category_max_len_bytes = 3;
#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD
static bool isLogInitialized;
-extern uint8_t gOtLogUartInstance;
extern "C" uint32_t otPlatAlarmMilliGetNow(void);
namespace chip {
@@ -108,8 +107,7 @@ void ENFORCE_FORMAT(1, 0) GenericLog(const char * format, va_list arg, const cha
if (!isLogInitialized)
{
- isLogInitialized = true;
- gOtLogUartInstance = 0;
+ isLogInitialized = true;
otPlatUartEnable();
}
diff --git a/src/platform/nxp/k32w/k32w0/OTAImageProcessorImpl.cpp b/src/platform/nxp/k32w/k32w0/OTAImageProcessorImpl.cpp
index 27deee3fece95f..a44d0cb1dfec6e 100644
--- a/src/platform/nxp/k32w/k32w0/OTAImageProcessorImpl.cpp
+++ b/src/platform/nxp/k32w/k32w0/OTAImageProcessorImpl.cpp
@@ -83,7 +83,11 @@ void OTAImageProcessorImpl::TriggerNewRequestForData()
{
if (mDownloader)
{
+ // The chip lock needs to be taken here to avoid having race conditions
+ // when trying to read attributes during OTA transfer. See https://github.com/project-chip/connectedhomeip/issues/18327
+ PlatformMgr().LockChipStack();
this->mDownloader->FetchNextData();
+ PlatformMgr().UnlockChipStack();
}
}
@@ -209,7 +213,7 @@ bool OTAImageProcessorImpl::IsFirstImageRun()
{
bool firstRun = false;
- if (CHIP_NO_ERROR == (K32WConfig::ReadConfigValue(K32WConfig::kConfigKey_FirstRunOfOTAImage, firstRun)))
+ if (CHIP_NO_ERROR == K32WConfig::ReadConfigValue(K32WConfig::kConfigKey_FirstRunOfOTAImage, firstRun))
{
return firstRun;
}
@@ -276,9 +280,7 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context)
OTA_CommitImage(NULL);
if (OTA_ImageAuthenticate() == gOtaImageAuthPass_c)
{
-
- /* TODO internal: MATTER-126 */
- /*if (CHIP_NO_ERROR == K32WConfig::WriteConfigValue(K32WConfig::kConfigKey_FirstRunOfOTAImage, firstRun)) */
+ if (CHIP_NO_ERROR == K32WConfig::WriteConfigValueSync(K32WConfig::kConfigKey_FirstRunOfOTAImage, firstRun))
{
/* Set the necessary information to inform the SSBL that a new image is available */
DeviceLayer::ConfigurationMgr().StoreSoftwareVersion(imageProcessor->mSoftwareVersion);
@@ -286,10 +288,14 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context)
ChipLogProgress(SoftwareUpdate, "OTA image authentication success. Device will reboot with the new image!");
ResetMCU();
}
+ else
+ {
+ ChipLogProgress(SoftwareUpdate, "Failed to write kConfigKey_FirstRunOfOTAImage key.");
+ }
}
else
{
- ChipLogError(SoftwareUpdate, "Image authentication error");
+ ChipLogError(SoftwareUpdate, "Image authentication error.");
}
}
diff --git a/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.cpp b/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.cpp
index 911b2e9ad73d71..4e7240c1f32202 100644
--- a/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.cpp
+++ b/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.cpp
@@ -35,9 +35,12 @@
#include
#endif
+#if defined(MBEDTLS_USE_TINYCRYPT)
+#include "ecc.h"
+#endif
+
#include
-#include "K32W061.h"
#include "MemManager.h"
#include "RNG_Interface.h"
#include "TimersManager.h"
@@ -49,6 +52,10 @@ namespace DeviceLayer {
PlatformManagerImpl PlatformManagerImpl::sInstance;
+#if defined(MBEDTLS_USE_TINYCRYPT)
+osaMutexId_t PlatformManagerImpl::rngMutexHandle = NULL;
+#endif
+
CHIP_ERROR PlatformManagerImpl::InitBoardFwk(void)
{
CHIP_ERROR err = CHIP_NO_ERROR;
@@ -93,6 +100,18 @@ static int app_entropy_source(void * data, unsigned char * output, size_t len, s
return 0;
}
+#if defined(MBEDTLS_USE_TINYCRYPT)
+int PlatformManagerImpl::uECC_RNG_Function(uint8_t * dest, unsigned int size)
+{
+ int res;
+ OSA_MutexLock(rngMutexHandle, osaWaitForever_c);
+ res = (chip::Crypto::DRBG_get_bytes(dest, size) == CHIP_NO_ERROR) ? size : 0;
+ OSA_MutexUnlock(rngMutexHandle);
+
+ return res;
+}
+#endif
+
CHIP_ERROR PlatformManagerImpl::_InitChipStack(void)
{
uint32_t chipType;
@@ -123,6 +142,13 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void)
err = chip::Crypto::add_entropy_source(app_entropy_source, NULL, 16);
SuccessOrExit(err);
+#if defined(MBEDTLS_USE_TINYCRYPT)
+ /* Set RNG function for tinycrypt operations. */
+ rngMutexHandle = OSA_MutexCreate();
+ VerifyOrExit((NULL != rngMutexHandle), err = CHIP_ERROR_NO_MEMORY);
+ uECC_set_rng(PlatformManagerImpl::uECC_RNG_Function);
+#endif
+
// Call _InitChipStack() on the generic implementation base class
// to finish the initialization process.
err = Internal::GenericPlatformManagerImpl_FreeRTOS::_InitChipStack();
diff --git a/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.h b/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.h
index 70ece1cdf11f3c..6e241c1dbd62b8 100644
--- a/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.h
+++ b/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.h
@@ -25,6 +25,7 @@
#pragma once
+#include "fsl_os_abstraction.h"
#include
namespace chip {
@@ -51,6 +52,17 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener
System::Clock::Timestamp GetStartTime() { return mStartTime; }
CHIP_ERROR InitBoardFwk(void);
+#if defined(MBEDTLS_USE_TINYCRYPT)
+ // Since the RNG callback will be called from multiple threads,
+ // use this mutex to lock/unlock the call to Matter RNG API, which
+ // uses some global variables.
+ static osaMutexId_t rngMutexHandle;
+ // Callback used by tinycrypt to generate random numbers.
+ // It must be set before calling any sign operations,
+ // which are used in both Matter and OT threads.
+ static int uECC_RNG_Function(uint8_t * dest, unsigned int size);
+#endif
+
private:
// ===== Methods that implement the PlatformManager abstract interface.
diff --git a/src/platform/nxp/k32w/k32w0/SystemPlatformConfig.h b/src/platform/nxp/k32w/k32w0/SystemPlatformConfig.h
index a589a86223d16d..f7514dcb68bec9 100644
--- a/src/platform/nxp/k32w/k32w0/SystemPlatformConfig.h
+++ b/src/platform/nxp/k32w/k32w0/SystemPlatformConfig.h
@@ -37,7 +37,7 @@ struct ChipDeviceEvent;
// ==================== Platform Adaptations ====================
#define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME 1
#define CHIP_SYSTEM_CONFIG_EVENT_OBJECT_TYPE const struct ::chip::DeviceLayer::ChipDeviceEvent *
-#define CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE 11
+#define CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE 7
// ========== Platform-specific Configuration Overrides =========
diff --git a/src/platform/nxp/k32w/k32w0/ThreadStackManagerImpl.cpp b/src/platform/nxp/k32w/k32w0/ThreadStackManagerImpl.cpp
index 7f5d4961ba41e4..78ccc1b9b0abf3 100644
--- a/src/platform/nxp/k32w/k32w0/ThreadStackManagerImpl.cpp
+++ b/src/platform/nxp/k32w/k32w0/ThreadStackManagerImpl.cpp
@@ -107,3 +107,8 @@ extern "C" void otPlatFree(void * aPtr)
{
return CHIPPlatformMemoryFree(aPtr);
}
+
+extern "C" void * otPlatRealloc(void * p, size_t aSize)
+{
+ return CHIPPlatformMemoryRealloc(p, aSize);
+}
diff --git a/third_party/nxp/k32w0_sdk/BUILD.gn b/third_party/nxp/k32w0_sdk/BUILD.gn
index f2307bafa95ca4..79d2e2a6ee1a6a 100644
--- a/third_party/nxp/k32w0_sdk/BUILD.gn
+++ b/third_party/nxp/k32w0_sdk/BUILD.gn
@@ -29,6 +29,13 @@ group("k32w0_sdk") {
public_deps = [ k32w0_sdk_target ]
}
+if (chip_crypto == "tinycrypt") {
+ assert(
+ mbedtls_repo ==
+ "//third_party/connectedhomeip/third_party/nxp/libs/mbedtls",
+ "mbedtls_repo must be set to nxp mbedtls-tinycrypt library when chip_crypto == \"tinycrypt\"")
+}
+
config("mbedtls_k32w0_config") {
defines = [
"MBEDTLS_CONFIG_FILE=",
@@ -53,7 +60,7 @@ config("mbedtls_k32w0_config") {
]
}
- if (mbedtls_use_tinycrypt) {
+ if (chip_crypto == "tinycrypt") {
defines += [
"MBEDTLS_USE_TINYCRYPT",
"MBEDTLS_OPTIMIZE_TINYCRYPT_ASM",
@@ -62,7 +69,7 @@ config("mbedtls_k32w0_config") {
include_dirs = [ chip_root ]
- if (mbedtls_use_tinycrypt) {
+ if (chip_crypto == "tinycrypt") {
include_dirs += [ "${mbedtls_repo}/repo/include/tinycrypt" ]
}
}
@@ -73,7 +80,7 @@ mbedtls_target("mbedtls") {
"${k32w0_sdk_root}/middleware/mbedtls/port/ksdk/ksdk_mbedtls.c",
]
- if (mbedtls_use_tinycrypt) {
+ if (chip_crypto == "tinycrypt") {
sources += [
"${mbedtls_repo}/repo/tinycrypt/ecc.c",
"${mbedtls_repo}/repo/tinycrypt/ecc_dh.c",
diff --git a/third_party/nxp/k32w0_sdk/k32w0_sdk.gni b/third_party/nxp/k32w0_sdk/k32w0_sdk.gni
index a0aa55ada6b4be..d0aa619d6a6968 100644
--- a/third_party/nxp/k32w0_sdk/k32w0_sdk.gni
+++ b/third_party/nxp/k32w0_sdk/k32w0_sdk.gni
@@ -24,12 +24,19 @@ import("${chip_root}/src/platform/nxp/k32w/k32w0/args.gni")
declare_args() {
# Location of the k32w0 SDK.
- k32w0_sdk_root = getenv("NXP_K32W061_SDK_ROOT")
+ k32w0_sdk_root = getenv("NXP_K32W0_SDK_ROOT")
chip_with_DK6 = true
chip_with_OM15082 = 0
chip_with_ot_cli = 0
chip_with_low_power = 0
- mbedtls_use_tinycrypt = false
+ build_for_k32w061 = 1
+ build_for_k32w041am = 0
+ build_for_k32w041a = 0
+ build_for_k32w041 = 0
+ device = "K32W061"
+ board = "k32w061dk6"
+ chip_with_ntag = 1
+ chip_with_high_power = 0
}
assert(k32w0_sdk_root != "", "k32w0_sdk_root must be specified")
@@ -57,6 +64,54 @@ template("k32w0_sdk") {
chip_with_ot_cli == 0 && chip_with_se05x == 0),
"Please disable low power if expansion board, openthread CLI or SE is needed!")
+ if (build_for_k32w041am == 1 || build_for_k32w041a == 1 ||
+ build_for_k32w041 == 1) {
+ build_for_k32w061 = 0
+ }
+
+ if (build_for_k32w061 == 1) {
+ assert(build_for_k32w061 == 1 && build_for_k32w041am == 0 &&
+ build_for_k32w041a == 0 && build_for_k32w041 == 0,
+ "Please build for only one platform")
+ device = "K32W061"
+ board = "k32w061dk6"
+ chip_with_ntag = 1
+ chip_with_high_power = 0
+ }
+ if (build_for_k32w041am == 1) {
+ assert(build_for_k32w041am == 1 && build_for_k32w061 == 0 &&
+ build_for_k32w041a == 0 && build_for_k32w041 == 0,
+ "Please build for only one platform")
+ device = "K32W041AM"
+ board = "k32w041amdk6"
+ chip_with_high_power = 1
+ chip_with_ntag = 0
+ }
+ if (build_for_k32w041a == 1) {
+ assert(build_for_k32w041a == 1 && build_for_k32w061 == 0 &&
+ build_for_k32w041am == 0 && build_for_k32w041 == 0,
+ "Please build for only one platform")
+ device = "K32W041A"
+ board = "k32w041adk6"
+ chip_with_high_power = 1
+ chip_with_ntag = 0
+ }
+ if (build_for_k32w041 == 1) {
+ assert(build_for_k32w041 == 1 && build_for_k32w061 == 0 &&
+ build_for_k32w041am == 0 && build_for_k32w041a == 0,
+ "Please build for only one platform")
+ device = "K32W041"
+ board = "k32w041dk6"
+ chip_with_ntag = 0
+ chip_with_high_power = 0
+ }
+
+ print("device:", device)
+ print("board:", board)
+ print("ntag:", chip_with_ntag)
+ print("high power:", chip_with_high_power)
+ device_lowercase = string_replace(board, "dk6", "")
+
sdk_target_name = target_name
config("${sdk_target_name}_config") {
@@ -72,14 +127,23 @@ template("k32w0_sdk") {
if (chip_with_DK6) {
if (chip_with_low_power != 0) {
- _sdk_include_dirs += [ "${k32w0_sdk_root}/boards/k32w061dk6/wireless_examples/openthread/lped/bm" ]
+ _sdk_include_dirs += [ "${k32w0_sdk_root}/boards/${board}/wireless_examples/openthread/lped/bm" ]
} else {
- _sdk_include_dirs += [ "${k32w0_sdk_root}/boards/k32w061dk6/wireless_examples/openthread/reed/bm" ]
+ _sdk_include_dirs += [ "${k32w0_sdk_root}/boards/${board}/wireless_examples/openthread/reed/bm" ]
}
}
if (chip_with_low_power != 0) {
- _sdk_include_dirs += [ "${k32w0_sdk_root}/boards/k32w061dk6/wireless_examples/hybrid/ble_ot/lped_ble_wuart/ble_802_15_4_common" ]
+ _sdk_include_dirs += [ "${k32w0_sdk_root}/boards/${board}/wireless_examples/hybrid/ble_ot/lped_ble_wuart/ble_802_15_4_common" ]
+ }
+
+ if (chip_with_ntag != 0) {
+ _sdk_include_dirs += [
+ "${k32w0_sdk_root}/middleware/ntag_i2c_plus/HAL_I2C/inc",
+ "${k32w0_sdk_root}/middleware/ntag_i2c_plus/HAL_NTAG/inc",
+ "${k32w0_sdk_root}/middleware/ntag_i2c_plus/inc",
+ "${k32w0_sdk_root}/middleware/ntag_i2c_plus/HAL_TMR/inc",
+ ]
}
_sdk_include_dirs += [
@@ -87,16 +151,12 @@ template("k32w0_sdk") {
"${k32w0_sdk_root}/CMSIS/Include",
"${k32w0_sdk_root}/components/serial_manager",
"${k32w0_sdk_root}/components/uart",
- "${k32w0_sdk_root}/devices/K32W061",
- "${k32w0_sdk_root}/devices/K32W061/drivers",
- "${k32w0_sdk_root}/devices/K32W061/utilities",
- "${k32w0_sdk_root}/devices/K32W061/utilities/debug_console",
- "${k32w0_sdk_root}/devices/K32W061/utilities/str",
+ "${k32w0_sdk_root}/devices/${device}",
+ "${k32w0_sdk_root}/devices/${device}/drivers",
+ "${k32w0_sdk_root}/devices/${device}/utilities",
+ "${k32w0_sdk_root}/devices/${device}/utilities/debug_console",
+ "${k32w0_sdk_root}/devices/${device}/utilities/str",
"${k32w0_sdk_root}/middleware/mbedtls/port/ksdk",
- "${k32w0_sdk_root}/middleware/ntag_i2c_plus/HAL_I2C/inc",
- "${k32w0_sdk_root}/middleware/ntag_i2c_plus/HAL_NTAG/inc",
- "${k32w0_sdk_root}/middleware/ntag_i2c_plus/inc",
- "${k32w0_sdk_root}/middleware/ntag_i2c_plus/HAL_TMR/inc",
"${k32w0_sdk_root}/middleware/wireless/ble_controller/interface",
"${k32w0_sdk_root}/middleware/wireless/bluetooth/application/common",
"${k32w0_sdk_root}/middleware/wireless/bluetooth/application/common/gatt_db",
@@ -112,7 +172,7 @@ template("k32w0_sdk") {
"${k32w0_sdk_root}/middleware/wireless/framework/Keyboard/Interface",
"${k32w0_sdk_root}/middleware/wireless/framework/LED/Interface",
"${k32w0_sdk_root}/middleware/wireless/framework/Lists",
- "${k32w0_sdk_root}/middleware/wireless/framework/LowPower/Interface/k32w061dk6",
+ "${k32w0_sdk_root}/middleware/wireless/framework/LowPower/Interface/${board}",
"${k32w0_sdk_root}/middleware/wireless/framework/MemManager/Interface",
"${k32w0_sdk_root}/middleware/wireless/framework/Messaging/Interface",
"${k32w0_sdk_root}/middleware/wireless/framework/ModuleInfo",
@@ -137,9 +197,9 @@ template("k32w0_sdk") {
]
libs = [
- "${k32w0_sdk_root}/middleware/wireless/ble_controller/lib/lib_ble_controller.a",
- "${k32w0_sdk_root}//middleware/wireless/bluetooth/host/lib/lib_ble_5-0_host_peripheral_cm4_noFP.a",
- "${k32w0_sdk_root}/middleware/wireless/ieee-802.15.4/lib/libMiniMac_Dynamic_MMAC.a",
+ "${k32w0_sdk_root}/middleware/wireless/ble_controller/lib/lib_ble_controller_peripheral_commissioning.a",
+ "${k32w0_sdk_root}//middleware/wireless/bluetooth/host/lib/lib_ble_5-0_host_matter_cm4_noFP.a",
+ "${k32w0_sdk_root}/middleware/wireless/ieee-802.15.4/lib/libMiniMac_Sched.a",
"${k32w0_sdk_root}/middleware/wireless/framework/PDM/Library/libPDM_extFlash.a",
"${k32w0_sdk_root}/middleware/wireless/framework/SecLib/lib_crypto_m4.a",
"${k32w0_sdk_root}/middleware/wireless/framework/XCVR/lib/libRadio.a",
@@ -148,18 +208,20 @@ template("k32w0_sdk") {
defines = [
"gPWR_CpuClk_48MHz=1",
"gMainThreadPriority_c=5",
- "CPU_K32W061HN",
"CPU_JN518X",
"CPU_JN518X_REV=2",
"JENNIC_CHIP_FAMILY_NAME=_JN518x",
+ "MAC_PROTO_TAG=1",
+ "JENNIC_CHIP_FAMILY_JN518x",
"gPWR_LDOMEM_0_9V_PD=0",
"SDK_DEBUGCONSOLE=DEBUGCONSOLE_REDIRECT_TO_SDK",
+ "PRINTF_ADVANCED_ENABLE",
"NO_SYSCORECLK_UPD=0",
"USE_RTOS=1",
"USE_SDK_OSA=0",
"gSerialManagerMaxInterfaces_c=2",
"FSL_RTOS_FREE_RTOS=1",
- "gTotalHeapSize_c=0xB000",
+ "gTotalHeapSize_c=0xC8BC",
"gUartDebugConsole_d=1",
"DEBUG_SERIAL_INTERFACE_INSTANCE=0",
"APP_SERIAL_INTERFACE_INSTANCE=1",
@@ -168,6 +230,7 @@ template("k32w0_sdk") {
"gOtaEepromPostedOperations_d=1",
"gOtaVerifyWrite_d=0",
"gExternalFlashIsCiphered_d=1",
+ "PDM_USE_DYNAMIC_MEMORY=1",
"gBootData_None_c=1",
"PROGRAM_PAGE_SZ=256",
"configFRTOS_MEMORY_SCHEME=4",
@@ -220,6 +283,7 @@ template("k32w0_sdk") {
"PDM_EXT_FLASH=1",
"gEepromType_d=gEepromDevice_MX25R8035F_c",
"gPdmNbSegments=63",
+ "gRadioUsePdm_d=1",
]
if (chip_with_OM15082 != 0) {
@@ -266,6 +330,34 @@ template("k32w0_sdk") {
]
}
+ if (build_for_k32w061 == 1) {
+ defines += [ "CPU_K32W061HN" ]
+ } else if (build_for_k32w041am == 1) {
+ defines += [ "CPU_K32W041AMZ" ]
+ } else if (build_for_k32w041a == 1) {
+ defines += [ "CPU_K32W041AZ" ]
+ } else if (build_for_k32w041 == 1) {
+ defines += [ "CPU_K32W041HN" ]
+ }
+
+ if (chip_with_high_power == 1) {
+ defines += [
+ "K32WMCM_APP_BUILD",
+ "JENNIC_CHIP_FAMILY_JN518x",
+ ]
+ _sdk_include_dirs += [
+ "${k32w0_sdk_root}/middleware/wireless/ieee-802.15.4/Include",
+ "${k32w0_sdk_root}/middleware/wireless/ieee-802.15.4/mMac/Include",
+ ]
+ }
+
+ if (chip_with_ntag == 1) {
+ defines += [
+ "CONFIG_CHIP_NFC_COMMISSIONING=1",
+ "CHIP_DEVICE_CONFIG_ENABLE_NFC=1",
+ ]
+ }
+
if (defined(invoker.defines)) {
defines += invoker.defines
}
@@ -309,35 +401,31 @@ template("k32w0_sdk") {
"${k32w0_sdk_root}/components/serial_manager/serial_manager.c",
"${k32w0_sdk_root}/components/serial_manager/serial_port_uart.c",
"${k32w0_sdk_root}/components/uart/usart_adapter.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_adc.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_aes.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_clock.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_common.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_ctimer.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_flash.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_flexcomm.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_fmeas.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_gpio.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_i2c.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_i2c_freertos.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_inputmux.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_ntag.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_pint.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_power.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_reset.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_rng.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_rtc.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_sha.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_spifi.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_usart.c",
- "${k32w0_sdk_root}/devices/K32W061/drivers/fsl_wtimer.c",
- "${k32w0_sdk_root}/devices/K32W061/mcuxpresso/startup_k32w061.c",
- "${k32w0_sdk_root}/devices/K32W061/system_K32W061.c",
- "${k32w0_sdk_root}/devices/K32W061/utilities/debug_console/fsl_debug_console.c",
- "${k32w0_sdk_root}/devices/K32W061/utilities/str/fsl_str.c",
- "${k32w0_sdk_root}/middleware/ntag_i2c_plus/HAL_I2C/i2c_jn_fsl.c",
- "${k32w0_sdk_root}/middleware/ntag_i2c_plus/HAL_NTAG/ntag_driver.c",
- "${k32w0_sdk_root}/middleware/ntag_i2c_plus/HAL_TMR/timer_driver_jn.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_adc.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_aes.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_clock.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_common.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_ctimer.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_flash.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_flexcomm.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_fmeas.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_gpio.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_i2c.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_i2c_freertos.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_inputmux.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_pint.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_power.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_reset.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_rng.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_rtc.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_sha.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_spifi.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_usart.c",
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_wtimer.c",
+ "${k32w0_sdk_root}/devices/${device}/mcuxpresso/startup_${device_lowercase}.c",
+ "${k32w0_sdk_root}/devices/${device}/system_${device}.c",
+ "${k32w0_sdk_root}/devices/${device}/utilities/debug_console/fsl_debug_console.c",
+ "${k32w0_sdk_root}/devices/${device}/utilities/str/fsl_str.c",
"${k32w0_sdk_root}/middleware/wireless/ble_controller/config/controller_config.c",
"${k32w0_sdk_root}/middleware/wireless/bluetooth/application/common/ble_conn_manager.c",
"${k32w0_sdk_root}/middleware/wireless/bluetooth/application/common/ble_host_tasks.c",
@@ -351,9 +439,9 @@ template("k32w0_sdk") {
"${k32w0_sdk_root}/middleware/wireless/framework/LED/Source/LED.c",
"${k32w0_sdk_root}/middleware/wireless/framework/Lists/GenericList.c",
"${k32w0_sdk_root}/middleware/wireless/framework/Logging/Source/dbg_logging.c",
- "${k32w0_sdk_root}/middleware/wireless/framework/LowPower/Source/k32w061dk6/PWR.c",
- "${k32w0_sdk_root}/middleware/wireless/framework/LowPower/Source/k32w061dk6/PWRLib.c",
- "${k32w0_sdk_root}/middleware/wireless/framework/LowPower/Source/k32w061dk6/PWR_setjmp.S",
+ "${k32w0_sdk_root}/middleware/wireless/framework/LowPower/Source/${board}/PWR.c",
+ "${k32w0_sdk_root}/middleware/wireless/framework/LowPower/Source/${board}/PWRLib.c",
+ "${k32w0_sdk_root}/middleware/wireless/framework/LowPower/Source/${board}/PWR_setjmp.S",
"${k32w0_sdk_root}/middleware/wireless/framework/MemManager/Source/MemManager.c",
"${k32w0_sdk_root}/middleware/wireless/framework/Messaging/Source/Messaging.c",
"${k32w0_sdk_root}/middleware/wireless/framework/OSAbstraction/Source/fsl_os_abstraction_free_rtos.c",
@@ -379,37 +467,36 @@ template("k32w0_sdk") {
]
if (chip_with_DK6) {
- if (chip_with_low_power != 0) {
+ sources += [
+ "${k32w0_sdk_root}/boards/${board}/wireless_examples/openthread/reed/bm/board.c",
+ "${k32w0_sdk_root}/boards/${board}/wireless_examples/openthread/reed/bm/board_utility.c",
+ "${k32w0_sdk_root}/boards/${board}/wireless_examples/openthread/reed/bm/hardware_init.c",
+ ]
+
+ if (chip_with_se05x != 0) {
sources += [
- "${k32w0_sdk_root}/boards/k32w061dk6/wireless_examples/openthread/lped/bm/board.c",
- "${k32w0_sdk_root}/boards/k32w061dk6/wireless_examples/openthread/lped/bm/board_utility.c",
- "${k32w0_sdk_root}/boards/k32w061dk6/wireless_examples/openthread/lped/bm/clock_config.c",
- "${k32w0_sdk_root}/boards/k32w061dk6/wireless_examples/openthread/lped/bm/hardware_init.c",
- "${k32w0_sdk_root}/boards/k32w061dk6/wireless_examples/openthread/lped/bm/pin_mux.c",
+ "${chip_root}/third_party/simw-top-mini/repo/demos/ksdk/common/boards/DK6/wireless_examples/chip/clock_config.c",
+ "${chip_root}/third_party/simw-top-mini/repo/demos/ksdk/common/boards/DK6/wireless_examples/chip/pin_mux.c",
]
} else {
sources += [
- "${k32w0_sdk_root}/boards/k32w061dk6/wireless_examples/openthread/reed/bm/board.c",
- "${k32w0_sdk_root}/boards/k32w061dk6/wireless_examples/openthread/reed/bm/board_utility.c",
- "${k32w0_sdk_root}/boards/k32w061dk6/wireless_examples/openthread/reed/bm/hardware_init.c",
+ "${k32w0_sdk_root}/boards/${board}/wireless_examples/openthread/reed/bm/clock_config.c",
+ "${k32w0_sdk_root}/boards/${board}/wireless_examples/openthread/reed/bm/pin_mux.c",
]
-
- if (chip_with_se05x != 0) {
- sources += [
- "${chip_root}/third_party/simw-top-mini/repo/demos/ksdk/common/boards/DK6/wireless_examples/chip/clock_config.c",
- "${chip_root}/third_party/simw-top-mini/repo/demos/ksdk/common/boards/DK6/wireless_examples/chip/pin_mux.c",
- ]
- } else {
- sources += [
- "${k32w0_sdk_root}/boards/k32w061dk6/wireless_examples/openthread/reed/bm/clock_config.c",
- "${k32w0_sdk_root}/boards/k32w061dk6/wireless_examples/openthread/reed/bm/pin_mux.c",
- ]
- }
}
}
if (chip_with_low_power != 0) {
- sources += [ "${k32w0_sdk_root}/boards/k32w061dk6/wireless_examples/hybrid/ble_ot/lped_ble_wuart/ble_802_15_4_common/app_dual_mode_low_power.c" ]
+ sources += [ "${k32w0_sdk_root}/boards/${board}/wireless_examples/hybrid/ble_ot/lped_ble_wuart/ble_802_15_4_common/app_dual_mode_low_power.c" ]
+ }
+
+ if (chip_with_ntag != 0) {
+ sources += [
+ "${k32w0_sdk_root}/devices/${device}/drivers/fsl_ntag.c",
+ "${k32w0_sdk_root}/middleware/ntag_i2c_plus/HAL_I2C/i2c_jn_fsl.c",
+ "${k32w0_sdk_root}/middleware/ntag_i2c_plus/HAL_NTAG/ntag_driver.c",
+ "${k32w0_sdk_root}/middleware/ntag_i2c_plus/HAL_TMR/timer_driver_jn.c",
+ ]
}
if (!defined(public_deps)) {
diff --git a/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh b/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh
index 417731e01f5216..1ae747ee5dcf23 100755
--- a/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh
+++ b/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh
@@ -1,10 +1,12 @@
#!/bin/bash
-if [[ ! -d $NXP_K32W061_SDK_ROOT ]]; then
- echo "NXP_K32W061_SDK_ROOT is not set"
+if [[ ! -d $NXP_K32W0_SDK_ROOT ]]; then
+ echo "NXP_K32W0_SDK_ROOT is not set"
exit 1
fi
+board=$(ls "$NXP_K32W0_SDK_ROOT"/boards)
+
convert_to_dos() {
[[ $(file -b - <$1) != *"CRLF"* ]] && sed -i 's/$/\r/' "$1"
@@ -13,59 +15,5 @@ convert_to_dos() {
SOURCE=${BASH_SOURCE[0]}
SOURCE_DIR=$(cd "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd)
-convert_to_dos "$NXP_K32W061_SDK_ROOT"/boards/k32w061dk6/wireless_examples/openthread/reed/bm/gpio_pins.h
-patch -N --binary -d "$NXP_K32W061_SDK_ROOT"/boards/k32w061dk6/wireless_examples/openthread/reed/bm -p1 <"$SOURCE_DIR/gpio_pins_h.patch"
-
-convert_to_dos "$NXP_K32W061_SDK_ROOT"/boards/k32w061dk6/wireless_examples/hybrid/ble_ot/lped_ble_wuart/ble_802_15_4_common/app_dual_mode_low_power.h
-patch -N --binary -d "$NXP_K32W061_SDK_ROOT"/boards/k32w061dk6/wireless_examples/hybrid/ble_ot/lped_ble_wuart/ble_802_15_4_common -p1 <"$SOURCE_DIR/app_dual_mode_low_power_h.patch"
-
-convert_to_dos "$NXP_K32W061_SDK_ROOT"/boards/k32w061dk6/wireless_examples/hybrid/ble_ot/lped_ble_wuart/ble_802_15_4_common/app_dual_mode_switch.h
-patch -N --binary -d "$NXP_K32W061_SDK_ROOT"/boards/k32w061dk6/wireless_examples/hybrid/ble_ot/lped_ble_wuart/ble_802_15_4_common -p1 <"$SOURCE_DIR/app_dual_mode_switch_h.patch"
-
-convert_to_dos "$NXP_K32W061_SDK_ROOT"/middleware/wireless/framework/SecLib/SecLib.h
-patch -N --binary -d "$NXP_K32W061_SDK_ROOT"/middleware/wireless/framework/SecLib -p1 <"$SOURCE_DIR/SecLib_h.patch"
-
-convert_to_dos "$NXP_K32W061_SDK_ROOT"/middleware/wireless/framework/OtaSupport/Source/OtaUtils.c
-patch -N --binary -d "$NXP_K32W061_SDK_ROOT"/middleware/wireless/framework/OtaSupport/Source -p1 <"$SOURCE_DIR/OtaUtils_c.patch"
-
-convert_to_dos "$NXP_K32W061_SDK_ROOT"/middleware/wireless/framework/OtaSupport/Source/OtaSupport.c
-patch -N --binary -d "$NXP_K32W061_SDK_ROOT"/middleware/wireless/framework/OtaSupport/Source -p1 <"$SOURCE_DIR/OtaSupport_c.patch"
-
-convert_to_dos "$NXP_K32W061_SDK_ROOT"/middleware/wireless/bluetooth/host/interface/ble_utils.h
-patch -N --binary -d "$NXP_K32W061_SDK_ROOT"/middleware/wireless/bluetooth/host/interface -p1 <"$SOURCE_DIR/ble_utils_h.patch"
-
-convert_to_dos "$NXP_K32W061_SDK_ROOT"/middleware/wireless/framework/Flash/External/Source/Eeprom_MX25R8035F.c
-patch -N --binary -d "$NXP_K32W061_SDK_ROOT"/middleware/wireless/framework/Flash/External/Source -p1 <"$SOURCE_DIR/Eeprom_MX25R8035F_c.patch"
-
-convert_to_dos "$NXP_K32W061_SDK_ROOT"/middleware/wireless/framework/MemManager/Interface/MemManager.h
-patch -N --binary -d "$NXP_K32W061_SDK_ROOT"/middleware/wireless/framework/MemManager/Interface -p1 <"$SOURCE_DIR/MemManager_h.patch"
-
-#internal: THREADIP-3660
-patch -N --binary -d ./third_party/openthread/ot-nxp/src/k32w0/platform -p1 <"$SOURCE_DIR/settings_k32w_c.patch"
-
-SIGN_FILE_PATH="$NXP_K32W061_SDK_ROOT"/tools/imagetool/sign_images.sh
-convert_to_dos "$SIGN_FILE_PATH"
-patch -N --binary -d "$NXP_K32W061_SDK_ROOT"/tools/imagetool/ -p1 <"$SOURCE_DIR/sign_images_sh.patch"
-sed -i 's/\r$//' "$SIGN_FILE_PATH"
-
-echo "Downloading PDM and BLE libraries from NXP server..."
-
-rm -rf patch_for_K32W061_SDK_2_6_4.zip patch_for_K32W061_SDK_2_6_4
-wget https://www.nxp.com/downloads/en/libraries/patch_for_K32W061_SDK_2_6_4.zip
-exitCode=$?
-if [ "$exitCode" -ne 0 ]; then
- echo "Download error"
- exit
-fi
-
-unzip patch_for_K32W061_SDK_2_6_4.zip
-cp patch_for_K32W061_SDK_2_6_4/controller_config.c "$NXP_K32W061_SDK_ROOT"/middleware/wireless/ble_controller/config/
-cp patch_for_K32W061_SDK_2_6_4/controller_interface.h "$NXP_K32W061_SDK_ROOT"/middleware/wireless/ble_controller/interface/
-cp patch_for_K32W061_SDK_2_6_4/lib_ble_controller.a "$NXP_K32W061_SDK_ROOT"/middleware/wireless/ble_controller/lib/
-cp patch_for_K32W061_SDK_2_6_4/libPDM_extFlash.a "$NXP_K32W061_SDK_ROOT"/middleware/wireless/framework/PDM/Library/
-
-rm -rf patch_for_K32W061_SDK_2_6_4.zip
-rm -rf patch_for_K32W061_SDK_2_6_4
-
-echo "K32W SDK MR3 QP1 was patched!"
+echo "SDK 2.6.6 doesn't need any patching!"
exit 0
diff --git a/third_party/openthread/ot-nxp b/third_party/openthread/ot-nxp
index 7a55fa48f51188..611561714fed15 160000
--- a/third_party/openthread/ot-nxp
+++ b/third_party/openthread/ot-nxp
@@ -1 +1 @@
-Subproject commit 7a55fa48f51188f24135b9e57834ae57acf2e0ff
+Subproject commit 611561714fed15d8046c30933f3d3b84b6a9908c
diff --git a/third_party/openthread/platforms/nxp/k32w/k32w0/BUILD.gn b/third_party/openthread/platforms/nxp/k32w/k32w0/BUILD.gn
index b942608b82ac9b..c6946d3d1d06ab 100644
--- a/third_party/openthread/platforms/nxp/k32w/k32w0/BUILD.gn
+++ b/third_party/openthread/platforms/nxp/k32w/k32w0/BUILD.gn
@@ -23,7 +23,11 @@ import("${chip_root}/third_party/nxp/k32w0_sdk/k32w0_sdk.gni")
openthread_nxp_root = "${chip_root}/third_party/openthread/ot-nxp"
config("openthread_k32w0_config") {
- include_dirs = [ "${openthread_nxp_root}/src/k32w0/k32w061" ]
+ include_dirs = [
+ "${openthread_nxp_root}/src/k32w0/k32w061",
+ "${openthread_nxp_root}/src/k32w0/platform",
+ "${openthread_nxp_root}/src/common",
+ ]
include_dirs += [ "${chip_root}/examples/platform/nxp/k32w/k32w0" ]
if (is_clang) {
@@ -52,14 +56,16 @@ source_set("openthread_mbedtls_config_k32w0") {
source_set("libopenthread-k32w0") {
sources = [
+ "${openthread_nxp_root}/src/common/ram_storage.c",
"${openthread_nxp_root}/src/k32w0/platform/alarm.c",
"${openthread_nxp_root}/src/k32w0/platform/diag.c",
"${openthread_nxp_root}/src/k32w0/platform/entropy.c",
"${openthread_nxp_root}/src/k32w0/platform/flash.c",
+ "${openthread_nxp_root}/src/k32w0/platform/flash_pdm.c",
"${openthread_nxp_root}/src/k32w0/platform/logging.c",
"${openthread_nxp_root}/src/k32w0/platform/misc.c",
+ "${openthread_nxp_root}/src/k32w0/platform/pdm_ram_storage_glue.c",
"${openthread_nxp_root}/src/k32w0/platform/radio.c",
- "${openthread_nxp_root}/src/k32w0/platform/settings_k32w.c",
"${openthread_nxp_root}/src/k32w0/platform/system.c",
"${openthread_nxp_root}/src/k32w0/platform/uart.c",
]