[OIS] Add PSA crypto backend support (#27387)

This commit allows the selection of PSA as the cryptographic
algorithm used when building Matter CryptoPAL with the Open
IoT SDK.
The GitHub CI workflow for the SDK examples/unit tests has been
updated to building and tesitng the lock-app example and unit-tests
with both mbedtls and psa cryptographic algorithms.

Add call to psa_crypto_init()

The Matter PSA implementation still uses some underlying MbedTLS
functions (including random number generation). To use these
functions however a call to psa_crypto_init() is required.
Extend Matter Python builder with crypto backend options.

Enable ECP optimization.

Signed-off-by: Anna Bridge <anna.bridge@arm.com>
diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt
index d068ecd..7969832 100644
--- a/.github/.wordlist.txt
+++ b/.github/.wordlist.txt
@@ -1072,6 +1072,7 @@
 ProxyValid
 ProxyView
 PRs
+PSA
 PSCAN
 PSECT
 PSK
diff --git a/.github/workflows/examples-openiotsdk.yaml b/.github/workflows/examples-openiotsdk.yaml
index 03c2670..ceb24a8 100644
--- a/.github/workflows/examples-openiotsdk.yaml
+++ b/.github/workflows/examples-openiotsdk.yaml
@@ -32,7 +32,7 @@
 jobs:
     openiotsdk:
         name: Open IoT SDK examples building
-        timeout-minutes: 90
+        timeout-minutes: 120
 
         env:
             TEST_NETWORK_NAME: OIStest
@@ -97,21 +97,21 @@
                     examples/shell/openiotsdk/build/chip-openiotsdk-shell-example.elf \
                     /tmp/bloat_reports/
 
-            - name: Build lock-app example
-              id: build_lock_app
+            - name: Build lock-app example (mbedtls)
+              id: build_lock_app_mbedtls
               timeout-minutes: 10
               run: |
-                  scripts/examples/openiotsdk_example.sh lock-app
+                  scripts/examples/openiotsdk_example.sh -b mbedtls lock-app
                   .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
-                    openiotsdk release lock-app \
+                    openiotsdk release lock-app-mbedtls \
                     examples/lock-app/openiotsdk/build/chip-openiotsdk-lock-app-example.elf \
                     /tmp/bloat_reports/
 
-            - name: Build unit tests
-              id: build_unit_tests
+            - name: Build unit tests (mbedtls)
+              id: build_unit_tests_mbedtls
               timeout-minutes: 10
               run: |
-                  scripts/examples/openiotsdk_example.sh unit-tests
+                  scripts/examples/openiotsdk_example.sh -b mbedtls unit-tests
 
             - name: "Test: shell example"
               if: steps.build_shell.outcome == 'success'
@@ -120,8 +120,8 @@
                   scripts/run_in_python_env.sh out/venv \
                     'scripts/examples/openiotsdk_example.sh --no-activate -C test shell'
 
-            - name: "Test: lock-app example"
-              if: steps.build_lock_app.outcome == 'success'
+            - name: "Test: lock-app example (mbedtls)"
+              if: steps.build_lock_app_mbedtls.outcome == 'success'
               timeout-minutes: 5
               run: |
                   scripts/setup/openiotsdk/network_setup.sh -n $TEST_NETWORK_NAME up
@@ -129,8 +129,40 @@
                     'scripts/run_in_ns.sh ${TEST_NETWORK_NAME}ns scripts/examples/openiotsdk_example.sh --no-activate -C test -n ${TEST_NETWORK_NAME}tap lock-app'
                   scripts/setup/openiotsdk/network_setup.sh -n $TEST_NETWORK_NAME down
 
-            - name: "Test: unit-tests"
-              if: steps.build_unit_tests.outcome == 'success'
+            - name: "Test: unit-tests (mbedtls)"
+              if: steps.build_unit_tests_mbedtls.outcome == 'success'
+              timeout-minutes: 40
+              run: |
+                  scripts/run_in_python_env.sh out/venv \
+                    'scripts/examples/openiotsdk_example.sh --no-activate -C test unit-tests'
+
+            - name: Build lock-app example (psa)
+              id: build_lock_app_psa
+              timeout-minutes: 10
+              run: |
+                  scripts/examples/openiotsdk_example.sh -c -b psa lock-app
+                  .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
+                    openiotsdk release lock-app-psa \
+                    examples/lock-app/openiotsdk/build/chip-openiotsdk-lock-app-example.elf \
+                    /tmp/bloat_reports/
+
+            - name: Build unit tests (psa)
+              id: build_unit_tests_psa
+              timeout-minutes: 10
+              run: |
+                  scripts/examples/openiotsdk_example.sh -b psa unit-tests
+
+            - name: "Test: lock-app example (psa)"
+              if: steps.build_lock_app_psa.outcome == 'success'
+              timeout-minutes: 5
+              run: |
+                  scripts/setup/openiotsdk/network_setup.sh -n $TEST_NETWORK_NAME up
+                  scripts/run_in_python_env.sh out/venv \
+                    'scripts/run_in_ns.sh ${TEST_NETWORK_NAME}ns scripts/examples/openiotsdk_example.sh --no-activate -C test -n ${TEST_NETWORK_NAME}tap lock-app'
+                  scripts/setup/openiotsdk/network_setup.sh -n $TEST_NETWORK_NAME down
+
+            - name: "Test: unit-tests (psa)"
+              if: steps.build_unit_tests_psa.outcome == 'success'
               timeout-minutes: 40
               run: |
                   scripts/run_in_python_env.sh out/venv \
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 8516b5b..bb0c8ba 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -251,6 +251,7 @@
                 "-Cbuild",
                 "-d${input:openiotsdkDebugMode}",
                 "-l${input:openiotsdkLwipDebug}",
+                "-b${input:openiotsdkCryptoBackend}",
                 "${input:openiotsdkExample}"
             ],
             "group": "build",
@@ -271,6 +272,7 @@
                 "-Cbuild",
                 "-d${input:openiotsdkDebugMode}",
                 "-l${input:openiotsdkLwipDebug}",
+                "-b${input:openiotsdkCryptoBackend}",
                 "unit-tests"
             ],
             "group": "build",
@@ -481,6 +483,13 @@
             "default": "false"
         },
         {
+            "type": "pickString",
+            "id": "openiotsdkCryptoBackend",
+            "description": "Which Crypto algorithm do you wish to use?",
+            "options": ["mbedtls", "psa"],
+            "default": "mbedtls"
+        },
+        {
             "type": "command",
             "id": "openiotsdkExample",
             "command": "shellCommand.execute",
diff --git a/config/openiotsdk/CMakeLists.txt b/config/openiotsdk/CMakeLists.txt
index 7f55958..43f9fca 100644
--- a/config/openiotsdk/CMakeLists.txt
+++ b/config/openiotsdk/CMakeLists.txt
@@ -62,6 +62,7 @@
 matter_add_gn_arg_bool  ("chip_error_logging"                   CONFIG_CHIP_ERROR_LOGGING)
 matter_add_gn_arg_bool  ("chip_openiotsdk_use_tfm"              TFM_SUPPORT)
 matter_add_gn_arg_bool  ("chip_openiotsdk_use_psa_ps"           CONFIG_CHIP_OPEN_IOT_SDK_USE_PSA_PS)
+matter_add_gn_arg_string("chip_crypto"                          "${CONFIG_CHIP_CRYPTO}")
 if (TARGET cmsis-rtos-api)
     matter_add_gn_arg_string("target_os"                        "cmsis-rtos")
 endif()
diff --git a/config/openiotsdk/chip-gn/args.gni b/config/openiotsdk/chip-gn/args.gni
index fd9edf9..12ffb66 100644
--- a/config/openiotsdk/chip-gn/args.gni
+++ b/config/openiotsdk/chip-gn/args.gni
@@ -31,7 +31,6 @@
 lwip_platform = "external"
 chip_system_config_use_sockets = false
 
-chip_crypto = "mbedtls"
 chip_external_mbedtls = true
 
 custom_toolchain = "${chip_root}/config/openiotsdk/chip-gn/toolchain:openiotsdk"
diff --git a/config/openiotsdk/cmake/chip.cmake b/config/openiotsdk/cmake/chip.cmake
index bdef587..6e1a78b 100644
--- a/config/openiotsdk/cmake/chip.cmake
+++ b/config/openiotsdk/cmake/chip.cmake
@@ -21,7 +21,7 @@
 
 get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH)
 
-# Default CHIP build configuration 
+# Default CHIP build configuration
 set(CONFIG_CHIP_PROJECT_CONFIG "main/include/CHIPProjectConfig.h" CACHE STRING "")
 set(CONFIG_CHIP_LIB_TESTS NO CACHE BOOL "")
 set(CONFIG_CHIP_LIB_SHELL NO CACHE BOOL "")
@@ -32,6 +32,7 @@
 set(CONFIG_CHIP_ERROR_LOGGING YES CACHE BOOL "Enable logging at error level")
 
 set(CONFIG_CHIP_OPEN_IOT_SDK_USE_PSA_PS NO CACHE BOOL "Enable using PSA Protected Storage")
+set(CONFIG_CHIP_CRYPTO "mbedtls" CACHE STRING "Matter crypto backend. Mbedtls as default")
 
 if(CONFIG_CHIP_OPEN_IOT_SDK_USE_PSA_PS AND NOT TFM_SUPPORT)
     message( FATAL_ERROR "You can not use PSA Protected Storage without TF-M support" )
@@ -53,8 +54,14 @@
     add_dependencies(chip-gn tfm-ns-interface)
 endif()
 
+if ("${CONFIG_CHIP_CRYPTO}" STREQUAL "psa")
+    target_compile_definitions(chip
+        INTERFACE
+            CONFIG_CHIP_CRYPTO_PSA)
+endif()
+
 function(chip_add_data_model target scope model_name)
-    target_include_directories(${target} 
+    target_include_directories(${target}
         PUBLIC
             ${GEN_DIR}/app-common
             ${GEN_DIR}/${model_name}-app
diff --git a/config/openiotsdk/cmake/sdk.cmake b/config/openiotsdk/cmake/sdk.cmake
index 61cd704..6f391bd 100644
--- a/config/openiotsdk/cmake/sdk.cmake
+++ b/config/openiotsdk/cmake/sdk.cmake
@@ -27,7 +27,7 @@
 # Open IoT SDK targets passed to CHIP build
 list(APPEND CONFIG_CHIP_EXTERNAL_TARGETS)
 
-# Additional Open IoT SDK build configuration 
+# Additional Open IoT SDK build configuration
 set(TFM_SUPPORT NO CACHE BOOL "Add Trusted Firmware-M (TF-M) support to application")
 set(TFM_NS_APP_VERSION "0.0.0" CACHE STRING "TF-M non-secure application version (in the x.x.x format)")
 set(CONFIG_CHIP_OPEN_IOT_SDK_LWIP_DEBUG NO CACHE BOOL "Enable LwIP debug logs")
@@ -82,7 +82,7 @@
     set(TFM_PLATFORM ${OPEN_IOT_SDK_EXAMPLE_COMMON}/tf-m/targets/an552)
     set(TFM_PSA_FIRMWARE_UPDATE ON)
     set(MCUBOOT_IMAGE_VERSION_NS ${TFM_NS_APP_VERSION})
-    set(TFM_CMAKE_ARGS "-DCONFIG_TFM_ENABLE_FP=ON;-DTFM_PROFILE=profile_medium;-DTFM_EXCEPTION_INFO_DUMP=ON;-DCONFIG_TFM_HALT_ON_CORE_PANIC=ON;-DTFM_ISOLATION_LEVEL=1")
+    set(TFM_CMAKE_ARGS "-DCONFIG_TFM_ENABLE_FP=ON;-DTFM_PROFILE=profile_medium;-DTFM_EXCEPTION_INFO_DUMP=ON;-DCONFIG_TFM_HALT_ON_CORE_PANIC=ON;-DTFM_ISOLATION_LEVEL=1;-DTFM_MBEDCRYPTO_PLATFORM_EXTRA_CONFIG_PATH=${OPEN_IOT_SDK_CONFIG}/mbedtls/mbedtls_config_psa.h;-DMBEDCRYPTO_BUILD_TYPE=${CMAKE_BUILD_TYPE};-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
     if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
         set(TFM_CMAKE_ARGS "${TFM_CMAKE_ARGS};-DMCUBOOT_LOG_LEVEL=INFO;-DTFM_SPM_LOG_LEVEL=TFM_SPM_LOG_LEVEL_DEBUG;-DTFM_PARTITION_LOG_LEVEL=TFM_PARTITION_LOG_LEVEL_INFO")
     else()
@@ -117,24 +117,24 @@
 # Add RTOS configuration headers
 # Link cmsis-rtos-api against a concrete implementation
 if(TARGET cmsis-rtos-api)
-    target_include_directories(cmsis-core 
-        INTERFACE 
+    target_include_directories(cmsis-core
+        INTERFACE
             cmsis-config
     )
-    
+
     target_compile_definitions(cmsis-rtos-api
         PUBLIC
             DOMAIN_NS=$<IF:$<BOOL:${TFM_SUPPORT}>,1,0>
     )
 
     if(TARGET freertos-kernel)
-        target_include_directories(freertos-kernel 
-            PUBLIC 
+        target_include_directories(freertos-kernel
+            PUBLIC
                 freertos-config
         )
 
-        target_link_libraries(freertos-kernel 
-            PUBLIC 
+        target_link_libraries(freertos-kernel
+            PUBLIC
                 cmsis-core
         )
 
@@ -250,14 +250,6 @@
     )
 endif()
 
-if("mbedtls" IN_LIST IOTSDK_FETCH_LIST)
-    list(APPEND CONFIG_CHIP_EXTERNAL_TARGETS
-        mbedtls
-        mbedtls-config
-        mbedtls-threading-cmsis-rtos 
-    )
-endif()
-
 if("lwip" IN_LIST IOTSDK_FETCH_LIST)
     list(APPEND CONFIG_CHIP_EXTERNAL_TARGETS
         lwipcore
@@ -282,6 +274,15 @@
     )
 endif()
 
+# Note: Mbed TLS must appear after TF-M otherwise psa from mbed TLS is used
+if("mbedtls" IN_LIST IOTSDK_FETCH_LIST)
+    list(APPEND CONFIG_CHIP_EXTERNAL_TARGETS
+        mbedtls
+        mbedtls-config
+        mbedtls-threading-cmsis-rtos
+    )
+endif()
+
 # Additional Open IoT SDK port components
 
 # Add Open IoT SDK storage source
diff --git a/config/openiotsdk/lwip/user_lwipopts.h b/config/openiotsdk/lwip/user_lwipopts.h
index 48d8d4a..1e02add 100644
--- a/config/openiotsdk/lwip/user_lwipopts.h
+++ b/config/openiotsdk/lwip/user_lwipopts.h
@@ -49,6 +49,11 @@
  */
 #define LWIP_RAW (1)
 
+/**
+ * Disable DHCP as the IP6 link local address can be used.
+ */
+#define LWIP_DHCP 0
+
 #ifdef LWIP_DEBUG
 
 // Debug Options
diff --git a/config/openiotsdk/mbedtls/mbedtls_config.h b/config/openiotsdk/mbedtls/mbedtls_config.h
index 316d43c..b5927a0 100644
--- a/config/openiotsdk/mbedtls/mbedtls_config.h
+++ b/config/openiotsdk/mbedtls/mbedtls_config.h
@@ -2692,7 +2692,7 @@
  *           or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
  *
  */
-#define MBEDTLS_PSA_CRYPTO_C
+//#define MBEDTLS_PSA_CRYPTO_C
 
 /**
  * \def MBEDTLS_PSA_CRYPTO_SE_C
@@ -3313,8 +3313,8 @@
 //#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT      384 /**< Maximum size of (re)seed buffer */
 
 /* ECP options */
-//#define MBEDTLS_ECP_WINDOW_SIZE            4 /**< Maximum window size used */
-//#define MBEDTLS_ECP_FIXED_POINT_OPTIM      1 /**< Enable fixed-point speed-up */
+#define MBEDTLS_ECP_WINDOW_SIZE 6       /**< Maximum window size used */
+#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */
 
 /* Entropy options */
 //#define MBEDTLS_ENTROPY_MAX_SOURCES                20 /**< Maximum number of sources supported */
diff --git a/config/openiotsdk/mbedtls/mbedtls_config_psa.h b/config/openiotsdk/mbedtls/mbedtls_config_psa.h
new file mode 100644
index 0000000..c7241ba
--- /dev/null
+++ b/config/openiotsdk/mbedtls/mbedtls_config_psa.h
@@ -0,0 +1,6 @@
+
+#define MBEDTLS_SHA1_C
+#define PSA_WANT_ALG_SHA_1
+#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */
+#undef MBEDTLS_ECP_FIXED_POINT_OPTIM
+#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */
diff --git a/docs/guides/openiotsdk_examples.md b/docs/guides/openiotsdk_examples.md
index 158691d..a0f4a68 100644
--- a/docs/guides/openiotsdk_examples.md
+++ b/docs/guides/openiotsdk_examples.md
@@ -376,6 +376,42 @@
 [Open IoT SDK build script](../../scripts/examples/openiotsdk_example.sh)
 provides the `-K,--kvsfile` option to use the persistence options listed above.
 
+### Crypto backend
+
+Open IoT SDK port supports two crypto backend implementations:
+
+-   [Mbed TLS](../guides/openiotsdk_platform_overview.md#mbed-tls) - it's the
+    default option
+-   [PSA crypto service](https://tf-m-user-guide.trustedfirmware.org/integration_guide/services/tfm_crypto_integration_guide.html)
+    from the
+    [TrustedFirmware-M (TF-M)](../guides/openiotsdk_platform_overview.md#trusted-firmware-m)
+    component
+
+The CMake variable `CONFIG_CHIP_CRYPTO` controls how cryptographic operations
+are implemented in Matter. It accepts two values:
+
+-   `mbedtls`: use Mbed TLS for crypto operations.
+-   `psa`: use
+    [PSA Cryptography API](https://armmbed.github.io/mbed-crypto/html/) for
+    crypto operations.
+
+This variable can be set in the main application `CMakeLists.txt`:
+
+```
+set(CONFIG_CHIP_CRYPTO <mbedtls | psa>)
+```
+
+The variable can also be defined with CMake CLI:
+
+```
+cmake -G <...> -DCONFIG_CHIP_CRYPTO=<mbedtls | psa> <...>
+```
+
+> 💡 **Notes**:
+>
+> The `TF-M PSA crypto` option requires enabling [TF-M](#trusted-firmware-m)
+> support.
+
 ## Building
 
 You can build examples using the dedicated VSCode task or by calling directly
@@ -388,6 +424,7 @@
 -   Select `Build Open IoT SDK example`
 -   Decide on debug mode support
 -   Decide on LwIP debug logs support
+-   Choose crypto algorithm
 -   Choose example name
 
 This will call the script with the selected parameters.
@@ -570,12 +607,12 @@
 
 ## Specific examples
 
-### Build lock-app example and run it in the network namespace
+### Build lock-app example with PSA crypto backend support and run it in the network namespace
 
 **Using CLI**
 
 ```
-${MATTER_ROOT}/scripts/examples/openiotsdk_example.sh lock-app
+${MATTER_ROOT}/scripts/examples/openiotsdk_example.sh -b psa lock-app
 
 export TEST_NETWORK_NAME=OIStest
 
@@ -595,6 +632,7 @@
 -   Select `Build Open IoT SDK example`
 -   Deny debug mode support `false`
 -   Deny LwIP debug logs support `false`
+-   Choose crypto algorithm `psa`
 -   Choose example name `lock-app`
 
 Setup network environment:
@@ -616,12 +654,12 @@
 
 The example output should be seen in the terminal window.
 
-### Build lock-app example and execute its test in the network namespace
+### Build lock-app example with mbedtls crypto backend support and execute its test in the network namespace
 
 **Using CLI**
 
 ```
-${MATTER_ROOT}/scripts/examples/openiotsdk_example.sh lock-app
+${MATTER_ROOT}/scripts/examples/openiotsdk_example.sh -b mbedtls lock-app
 
 export TEST_NETWORK_NAME=OIStest
 
@@ -641,6 +679,7 @@
 -   Select `Build Open IoT SDK example`
 -   Deny debug mode support `false`
 -   Deny LwIP debug logs support `false`
+-   Choose crypto algorithm `mbedtls`
 -   Choose example name `lock-app`
 
 Setup network environment:
@@ -660,7 +699,7 @@
 -   Enter network interface `OIStesttap`
 -   Choose example name `lock-app`
 
-### Build lock-app example in debug mode and debug it in the network namespace using the VSCode task
+### Build lock-app example with mbedtls crypto backend support in debug mode and debug it in the network namespace using the VSCode task
 
 Build example:
 
@@ -669,6 +708,7 @@
 -   Select `Build Open IoT SDK example`
 -   Confirm debug mode support `true`
 -   Deny LwIP debug logs support `false`
+-   Choose crypto algorithm `mbedtls`
 -   Choose example name `lock-app`
 
 Setup network environment:
@@ -759,7 +799,7 @@
     id: build_new_example
     timeout-minutes: 10
     run: |
-        scripts/examples/openiotsdk_example.sh new-example
+        scripts/examples/openiotsdk_example.sh -b ${{ matrix.cryptoBackend }} new-example
         .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \
         openiotsdk release new-example \
         examples/new-example/openiotsdk/build/chip-openiotsdk-new-example-example.elf \
diff --git a/examples/platform/openiotsdk/app/openiotsdk_platform.cpp b/examples/platform/openiotsdk/app/openiotsdk_platform.cpp
index 28b6da9..dff6a15 100644
--- a/examples/platform/openiotsdk/app/openiotsdk_platform.cpp
+++ b/examples/platform/openiotsdk/app/openiotsdk_platform.cpp
@@ -27,6 +27,10 @@
 #include "iotsdk/ip_network_api.h"
 #include "mbedtls/platform.h"
 
+#ifdef CONFIG_CHIP_CRYPTO_PSA
+#include "psa/crypto.h"
+#endif
+
 #include <DeviceInfoProviderImpl.h>
 #include <lib/support/CHIPMem.h>
 #include <lib/support/logging/CHIPLogging.h>
@@ -179,6 +183,15 @@
         return EXIT_FAILURE;
     }
 
+#ifdef CONFIG_CHIP_CRYPTO_PSA
+    ret = psa_crypto_init();
+    if (ret)
+    {
+        ChipLogError(NotSpecified, "PSA crypto initialization failed: %d", ret);
+        return EXIT_FAILURE;
+    }
+#endif
+
 #ifdef TFM_SUPPORT
     ret = get_psa_images_details();
     if (ret != 0)
diff --git a/scripts/build/BUILD.gn b/scripts/build/BUILD.gn
index 11ea4e9..0e716ae 100644
--- a/scripts/build/BUILD.gn
+++ b/scripts/build/BUILD.gn
@@ -31,8 +31,8 @@
     "testdata/dry_run_linux-arm64-ota-requestor-nodeps-ipv6only.txt",
     "testdata/dry_run_linux-x64-all-clusters-coverage.txt",
     "testdata/dry_run_nrf-nrf52840dk-pump.txt",
-    "testdata/dry_run_openiotsdk-lock.txt",
-    "testdata/dry_run_openiotsdk-shell.txt",
+    "testdata/dry_run_openiotsdk-lock-mbedtls.txt",
+    "testdata/dry_run_openiotsdk-shell-mbedtls.txt",
   ]
 
   sources = [
diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py
index 279191e..43eed69 100755
--- a/scripts/build/build/targets.py
+++ b/scripts/build/build/targets.py
@@ -28,7 +28,7 @@
 from builders.mbed import MbedApp, MbedBoard, MbedBuilder, MbedProfile
 from builders.mw320 import MW320App, MW320Builder
 from builders.nrf import NrfApp, NrfBoard, NrfConnectBuilder
-from builders.openiotsdk import OpenIotSdkApp, OpenIotSdkBuilder
+from builders.openiotsdk import OpenIotSdkApp, OpenIotSdkBuilder, OpenIotSdkCryptoBackend
 from builders.qpg import QpgApp, QpgBoard, QpgBuilder
 from builders.telink import TelinkApp, TelinkBoard, TelinkBuilder
 from builders.ti import TIApp, TIBoard, TIBuilder
@@ -679,6 +679,10 @@
         TargetPart('lock', app=OpenIotSdkApp.LOCK),
     ])
 
+    # Modifiers
+    target.AppendModifier('mbedtls', crypto=OpenIotSdkCryptoBackend.MBEDTLS).ExceptIfRe('-(psa)')
+    target.AppendModifier('psa', crypto=OpenIotSdkCryptoBackend.PSA).ExceptIfRe('-(mbedtls)')
+
     return target
 
 
diff --git a/scripts/build/builders/openiotsdk.py b/scripts/build/builders/openiotsdk.py
index 7f3cd68..89aad6a 100644
--- a/scripts/build/builders/openiotsdk.py
+++ b/scripts/build/builders/openiotsdk.py
@@ -42,13 +42,29 @@
             raise Exception('Unknown app type: %r' % self)
 
 
+class OpenIotSdkCryptoBackend(Enum):
+    PSA = auto()
+    MBEDTLS = auto()
+
+    @property
+    def CryptoBackendName(self):
+        if self == OpenIotSdkCryptoBackend.PSA:
+            return 'psa'
+        elif self == OpenIotSdkCryptoBackend.MBEDTLS:
+            return 'mbedtls'
+        else:
+            raise Exception('Unknown crypto backend type: %r' % self)
+
+
 class OpenIotSdkBuilder(Builder):
     def __init__(self,
                  root,
                  runner,
-                 app: OpenIotSdkApp = OpenIotSdkApp.SHELL):
+                 app: OpenIotSdkApp = OpenIotSdkApp.SHELL,
+                 crypto: OpenIotSdkCryptoBackend = OpenIotSdkCryptoBackend.MBEDTLS):
         super(OpenIotSdkBuilder, self).__init__(root, runner)
         self.app = app
+        self.crypto = crypto
         self.toolchain_path = os.path.join(
             'toolchains', 'toolchain-arm-none-eabi-gcc.cmake')
         self.system_processor = 'cortex-m55'
@@ -65,6 +81,8 @@
                            '-DCMAKE_SYSTEM_PROCESSOR={}'.format(
                                self.system_processor),
                            '-DCMAKE_BUILD_TYPE=Release',
+                           '-DCONFIG_CHIP_CRYPTO={}'.format(
+                               self.crypto.CryptoBackendName),
                            ], title='Generating ' + self.identifier)
 
     def _build(self):
diff --git a/scripts/build/test.py b/scripts/build/test.py
index 70fca73..c89a4d9 100644
--- a/scripts/build/test.py
+++ b/scripts/build/test.py
@@ -109,8 +109,8 @@
             'android-arm64-chip-tool',
             'nrf-nrf52840dk-pump',
             'efr32-brd4161a-light-rpc-no-version',
-            'openiotsdk-lock',
-            'openiotsdk-shell'
+            'openiotsdk-lock-mbedtls',
+            'openiotsdk-shell-mbedtls'
         ]
 
         for target in TARGETS:
diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt
index 1b8c95d..5ef536a 100644
--- a/scripts/build/testdata/all_targets_linux_x64.txt
+++ b/scripts/build/testdata/all_targets_linux_x64.txt
@@ -22,4 +22,4 @@
 qpg-qpg6105-{lock,light,shell,persistent-storage}
 tizen-arm-{all-clusters,all-clusters-minimal,chip-tool,light,tests}[-no-ble][-no-thread][-no-wifi][-asan][-ubsan]
 telink-tlsr9518adk80d-{all-clusters,all-clusters-minimal,bridge,contact-sensor,light,light-switch,lock,ota-requestor,pump,pump-controller,temperature-measurement,thermostat,window-covering}[-shell][-rpc][-factory-data]
-openiotsdk-{shell,lock}
+openiotsdk-{shell,lock}[-mbedtls][-psa]
diff --git a/scripts/build/testdata/dry_run_openiotsdk-lock-mbedtls.txt b/scripts/build/testdata/dry_run_openiotsdk-lock-mbedtls.txt
new file mode 100644
index 0000000..77816cf
--- /dev/null
+++ b/scripts/build/testdata/dry_run_openiotsdk-lock-mbedtls.txt
@@ -0,0 +1,8 @@
+# Commands will be run in CHIP project root.
+cd "{root}"
+
+# Generating openiotsdk-lock-mbedtls
+cmake -GNinja -S {root}/examples/lock-app/openiotsdk -B {out}/openiotsdk-lock-mbedtls --toolchain=toolchains/toolchain-arm-none-eabi-gcc.cmake -DCMAKE_SYSTEM_PROCESSOR=cortex-m55 -DCMAKE_BUILD_TYPE=Release -DCONFIG_CHIP_CRYPTO=mbedtls
+
+# Building openiotsdk-lock-mbedtls
+cmake --build {out}/openiotsdk-lock-mbedtls
diff --git a/scripts/build/testdata/dry_run_openiotsdk-lock.txt b/scripts/build/testdata/dry_run_openiotsdk-lock.txt
deleted file mode 100644
index a0c36ee..0000000
--- a/scripts/build/testdata/dry_run_openiotsdk-lock.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Commands will be run in CHIP project root.
-cd "{root}"
-
-# Generating openiotsdk-lock
-cmake -GNinja -S {root}/examples/lock-app/openiotsdk -B {out}/openiotsdk-lock --toolchain=toolchains/toolchain-arm-none-eabi-gcc.cmake -DCMAKE_SYSTEM_PROCESSOR=cortex-m55 -DCMAKE_BUILD_TYPE=Release
-
-# Building openiotsdk-lock
-cmake --build {out}/openiotsdk-lock
diff --git a/scripts/build/testdata/dry_run_openiotsdk-shell-mbedtls.txt b/scripts/build/testdata/dry_run_openiotsdk-shell-mbedtls.txt
new file mode 100644
index 0000000..70438c5
--- /dev/null
+++ b/scripts/build/testdata/dry_run_openiotsdk-shell-mbedtls.txt
@@ -0,0 +1,8 @@
+# Commands will be run in CHIP project root.
+cd "{root}"
+
+# Generating openiotsdk-shell-mbedtls
+cmake -GNinja -S {root}/examples/shell/openiotsdk -B {out}/openiotsdk-shell-mbedtls --toolchain=toolchains/toolchain-arm-none-eabi-gcc.cmake -DCMAKE_SYSTEM_PROCESSOR=cortex-m55 -DCMAKE_BUILD_TYPE=Release -DCONFIG_CHIP_CRYPTO=mbedtls
+
+# Building openiotsdk-shell-mbedtls
+cmake --build {out}/openiotsdk-shell-mbedtls
diff --git a/scripts/build/testdata/dry_run_openiotsdk-shell.txt b/scripts/build/testdata/dry_run_openiotsdk-shell.txt
deleted file mode 100644
index 6c7c63b..0000000
--- a/scripts/build/testdata/dry_run_openiotsdk-shell.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Commands will be run in CHIP project root.
-cd "{root}"
-
-# Generating openiotsdk-shell
-cmake -GNinja -S {root}/examples/shell/openiotsdk -B {out}/openiotsdk-shell --toolchain=toolchains/toolchain-arm-none-eabi-gcc.cmake -DCMAKE_SYSTEM_PROCESSOR=cortex-m55 -DCMAKE_BUILD_TYPE=Release
-
-# Building openiotsdk-shell
-cmake --build {out}/openiotsdk-shell
diff --git a/scripts/examples/openiotsdk_example.sh b/scripts/examples/openiotsdk_example.sh
index 496fc04..f80b537 100755
--- a/scripts/examples/openiotsdk_example.sh
+++ b/scripts/examples/openiotsdk_example.sh
@@ -44,6 +44,7 @@
 KVS_STORAGE_TYPE="tdb"
 KVS_STORAGE_FILE=""
 NO_ACTIVATE=""
+CRYPTO_BACKEND="mbedtls"
 
 declare -A tdb_storage_param=([instance]=sram [memspace]=0 [address]=0x0 [size]=0x100000)
 declare -A ps_storage_param=([instance]=qspi_sram [memspace]=0 [address]=0x660000 [size]=0x12000)
@@ -67,6 +68,7 @@
     -d,--debug      <debug_enable>      Build in debug mode <true | false - default>
     -l,--lwipdebug  <lwip_debug_enable> Build with LwIP debug logs support <true | false - default>
     -k,--kvsstore   <kvs_storage_type>  Select KVS storage type <ps | tdb - default>
+    -b,--backend    <crypto_backend)    Select crypto backend <psa | mbedtls - default>
     -p,--path       <build_path>        Build path <build_path - default is example_dir/build>
     -K,--kvsfile    <kvs_storage_file>  Path to KVS storage file which will be used to ensure persistence <kvs_storage_file - default is empty which means disable persistence>
     -n,--network    <network_name>      FVP network interface name <network_name - default is "user" which means user network mode>
@@ -135,6 +137,8 @@
         BUILD_OPTIONS+=(-DCONFIG_CHIP_OPEN_IOT_SDK_USE_PSA_PS=YES)
     fi
 
+    BUILD_OPTIONS+=(-DCONFIG_CHIP_CRYPTO="$CRYPTO_BACKEND")
+
     cmake -G Ninja -S "$EXAMPLE_PATH" -B "$BUILD_PATH" --toolchain="$TOOLCHAIN_PATH" "${BUILD_OPTIONS[@]}"
     cmake --build "$BUILD_PATH"
 }
@@ -269,8 +273,8 @@
     fi
 }
 
-SHORT=C:,p:,d:,l:,n:,k:,K:,c,s,h
-LONG=command:,path:,debug:,lwipdebug:,network:,kvsstore:,kvsfile:,clean,scratch,help,no-activate
+SHORT=C:,p:,d:,l:,b:,n:,k:,K:,c,s,h
+LONG=command:,path:,debug:,lwipdebug:,backend:,network:,kvsstore:,kvsfile:,clean,scratch,help,no-activate
 OPTS=$(getopt -n build --options "$SHORT" --longoptions "$LONG" -- "$@")
 
 eval set -- "$OPTS"
@@ -309,6 +313,10 @@
             KVS_STORAGE_FILE=$2
             shift 2
             ;;
+        -b | --backend)
+            CRYPTO_BACKEND=$2
+            shift 2
+            ;;
         -p | --path)
             BUILD_PATH=$CHIP_ROOT/$2
             shift 2
@@ -385,6 +393,15 @@
         ;;
 esac
 
+case "$CRYPTO_BACKEND" in
+    psa | mbedtls) ;;
+    *)
+        echo "Wrong crypto type definition"
+        show_usage
+        exit 2
+        ;;
+esac
+
 TOOLCHAIN_PATH="toolchains/toolchain-$TOOLCHAIN.cmake"
 
 if [ -z "$BUILD_PATH" ]; then