Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions samples/subsys/mgmt/mcumgr/smp_svr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,22 @@ project(smp_svr)

target_sources(app PRIVATE src/main.c)
target_sources_ifdef(CONFIG_MCUMGR_TRANSPORT_BT app PRIVATE src/bluetooth.c)

if(CONFIG_MCUMGR_TRANSPORT_UDP_DTLS)
# Use dummy certificate files
set(cert_dir certificates)
set(cert_files echo-apps-cert.der;echo-apps-key.der)
set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated)

message(WARNING "Using dummy certificate files, these are provided for demonstration only")

foreach(inc_file ${cert_files})
generate_inc_file_for_target(
app
${cert_dir}/${inc_file}
${gen_dir}/${inc_file}.inc
)
endforeach()

target_sources(app PRIVATE src/udp_dtls.c)
endif()
Binary file not shown.
Binary file not shown.
10 changes: 10 additions & 0 deletions samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ tests:
- frdm_k64f
integration_platforms:
- frdm_k64f
sample.mcumgr.smp_svr.udp_dtls:
extra_args:
- EXTRA_CONF_FILE="udp_dtls.conf"
- CONFIG_IMG_MANAGER=n
- SB_CONFIG_BOOTLOADER_NONE=y
platform_allow:
- native_sim
integration_platforms:
- native_sim
build_only: true
sample.mcumgr.smp_svr.udp.802154.subg:
extra_args: EXTRA_CONF_FILE="udp.conf;802154-subg.conf"
platform_allow: beagleconnect_freedom
Expand Down
1 change: 1 addition & 0 deletions samples/subsys/mgmt/mcumgr/smp_svr/src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
*/

void start_smp_bluetooth_adverts(void);
int setup_udp_dtls(void);
17 changes: 17 additions & 0 deletions samples/subsys/mgmt/mcumgr/smp_svr/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#ifdef CONFIG_MCUMGR_GRP_STAT
#include <zephyr/mgmt/mcumgr/grp/stat_mgmt/stat_mgmt.h>
#endif
#ifdef CONFIG_MCUMGR_TRANSPORT_UDP_DTLS
#include <zephyr/mgmt/mcumgr/transport/smp_udp.h>
#endif

#define LOG_LEVEL LOG_LEVEL_DBG
#include <zephyr/logging/log.h>
Expand Down Expand Up @@ -67,6 +70,20 @@ int main(void)
}
#endif

#ifdef CONFIG_MCUMGR_TRANSPORT_UDP_DTLS
rc = setup_udp_dtls();

if (rc == 0) {
rc = smp_udp_open();

if (rc != 0) {
LOG_ERR("UDP transport open failed: %d", rc);
}
} else {
LOG_ERR("TLS init failed, cannot start UDP transport");
}
#endif

#ifdef CONFIG_MCUMGR_TRANSPORT_BT
start_smp_bluetooth_adverts();
#endif
Expand Down
43 changes: 43 additions & 0 deletions samples/subsys/mgmt/mcumgr/smp_svr/src/udp_dtls.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/kernel.h>
#include <zephyr/net/tls_credentials.h>
#include <zephyr/logging/log.h>

LOG_MODULE_DECLARE(smp_sample);

static const unsigned char server_certificate[] = {
#include "echo-apps-cert.der.inc"
};

/* This is the private key in pkcs#8 format. */
static const unsigned char private_key[] = {
#include "echo-apps-key.der.inc"
};

int setup_udp_dtls(void)
{
int rc;

rc = tls_credential_add(CONFIG_MCUMGR_TRANSPORT_UDP_DTLS_TLS_TAG,
TLS_CREDENTIAL_PUBLIC_CERTIFICATE, server_certificate,
sizeof(server_certificate));

if (rc < 0) {
LOG_ERR("Failed to register public certificate: %d", rc);
return rc;
}

rc = tls_credential_add(CONFIG_MCUMGR_TRANSPORT_UDP_DTLS_TLS_TAG,
TLS_CREDENTIAL_PRIVATE_KEY, private_key, sizeof(private_key));

if (rc < 0) {
LOG_ERR("Failed to register private key: %d", rc);
}

return rc;
}
38 changes: 38 additions & 0 deletions samples/subsys/mgmt/mcumgr/smp_svr/udp_dtls.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Enable the UDP DTLS MCUmgr transport.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this file be called overlay-udp-dtls.conf to follow the nomenclature in the sample (not sure if there's a strict rule about that though)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overlay refers to dts overlay files, not Kconfig fragments, but also the wrong overlay-* prefix was removed recently from those files: https://github.com/zephyrproject-rtos/zephyr/tree/6abb7ff76c8609eb1f5dbedb0972855eca26778b/samples/subsys/mgmt/mcumgr/smp_svr

CONFIG_MCUMGR_TRANSPORT_UDP=y
CONFIG_MCUMGR_TRANSPORT_UDP_DTLS=y
CONFIG_MCUMGR_TRANSPORT_UDP_IPV4=y
CONFIG_MCUMGR_TRANSPORT_UDP_IPV6=y

# Network settings
CONFIG_NETWORKING=y
CONFIG_NET_UDP=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
CONFIG_NET_SOCKETS_ENABLE_DTLS=y
CONFIG_NET_SOCKETS_DTLS_TIMEOUT=30000
CONFIG_NET_SOCKETS_DTLS_MAX_FRAGMENT_LENGTH=2048
CONFIG_NET_SOCKETS_DTLS_SENDMSG_BUF_SIZE=0
CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=4
CONFIG_NET_SOCKETS_TLS_MAX_CREDENTIALS=4
CONFIG_NET_SOCKETS_TLS_MAX_CIPHERSUITES=4
CONFIG_NET_SOCKETS_TLS_MAX_CLIENT_SESSION_COUNT=1
CONFIG_NET_CONNECTION_MANAGER=y
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.1.1"
CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1"

# mbedtls settings
CONFIG_MBEDTLS_TLS_VERSION_1_2=y
CONFIG_MBEDTLS_DTLS=y
CONFIG_MBEDTLS_RSA_C=y
CONFIG_MBEDTLS_PKCS1_V15=y
CONFIG_MBEDTLS_PKCS1_V21=y
CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED=y
CONFIG_MBEDTLS_MD=y
CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=2048
CONFIG_MBEDTLS_ENABLE_HEAP=y
CONFIG_MBEDTLS_HEAP_SIZE=60000
22 changes: 22 additions & 0 deletions subsys/mgmt/mcumgr/transport/Kconfig.udp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,31 @@ config MCUMGR_TRANSPORT_UDP_MTU
MCUMGR_TRANSPORT_UDP_MTU <= MCUMGR_TRANSPORT_NETBUF_SIZE + SMP msg overhead - address size
where address size is determined by IPv4/IPv6 selection.

config MCUMGR_TRANSPORT_UDP_DTLS
bool "DTLS"
select MBEDTLS
select MBEDTLS_ENABLE_HEAP
select NET_SOCKETS_SOCKOPT_TLS
select NET_SOCKETS_ENABLE_DTLS
select TLS_CREDENTIALS
help
Enable DTLS for UDP transport, this means normal non-authenticated connections will not
be supported and the transport will not be started automatically at boot-up, the
application will need to add the certificates to the system and set them up before
opening the transport using the `smp_udp_open` function.

config MCUMGR_TRANSPORT_UDP_DTLS_TLS_TAG
int "TLS credential tag"
default 1
depends on MCUMGR_TRANSPORT_UDP_DTLS
help
The TLS tag which the application must add the certificates to before starting the UDP
transport.

config MCUMGR_TRANSPORT_UDP_AUTOMATIC_INIT
bool "UDP SMP autostart"
default y
depends on !MCUMGR_TRANSPORT_UDP_DTLS
help
Enable starting the UDP SMP transport at boot time without needing
any code in the application to do this, otherwise will need the user
Expand Down
59 changes: 58 additions & 1 deletion subsys/mgmt/mcumgr/transport/src/smp_udp.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2020, Prevas A/S
* Copyright (c) 2022-2023 Nordic Semiconductor ASA
* Copyright (c) 2022-2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -25,6 +25,10 @@
#include <zephyr/net/conn_mgr_monitor.h>
#include <errno.h>

#if defined(CONFIG_MCUMGR_TRANSPORT_UDP_DTLS)
#include <zephyr/net/tls_credentials.h>
#endif

#include <mgmt/mcumgr/transport/smp_internal.h>

#define LOG_LEVEL CONFIG_MCUMGR_LOG_LEVEL
Expand Down Expand Up @@ -167,6 +171,10 @@ static int create_socket(enum proto_type proto, int *sock)
struct sockaddr *addr = (struct sockaddr *)&addr_storage;
socklen_t addr_len = 0;

#if defined(CONFIG_MCUMGR_TRANSPORT_UDP_DTLS)
int socket_role = TLS_DTLS_ROLE_SERVER;
#endif

if (IS_ENABLED(CONFIG_MCUMGR_TRANSPORT_UDP_IPV4) &&
proto == PROTOCOL_IPV4) {
struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
Expand All @@ -187,7 +195,11 @@ static int create_socket(enum proto_type proto, int *sock)
addr6->sin6_addr = in6addr_any;
}

#if defined(CONFIG_MCUMGR_TRANSPORT_UDP_DTLS)
tmp_sock = zsock_socket(addr->sa_family, SOCK_DGRAM, IPPROTO_DTLS_1_2);
#else
tmp_sock = zsock_socket(addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
#endif
err = errno;

if (tmp_sock < 0) {
Expand All @@ -197,6 +209,29 @@ static int create_socket(enum proto_type proto, int *sock)
return -err;
}

#if defined(CONFIG_MCUMGR_TRANSPORT_UDP_DTLS)
sec_tag_t sec_tag_list[] = {
CONFIG_MCUMGR_TRANSPORT_UDP_DTLS_TLS_TAG,
};

err = zsock_setsockopt(tmp_sock, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_list,
sizeof(sec_tag_list));

if (err < 0) {
LOG_ERR("Failed to set UDP secure option: %d", errno);
return err;
}

/* Set role to DTLS server */
err = zsock_setsockopt(tmp_sock, SOL_TLS, TLS_DTLS_ROLE, &socket_role,
sizeof(socket_role));

if (err < 0) {
LOG_ERR("Failed to set DTLS role secure option: %d", errno);
return err;
}
#endif

if (zsock_bind(tmp_sock, addr, addr_len) < 0) {
err = errno;
LOG_ERR("Could not bind to receive socket (%s), err: %i",
Expand Down Expand Up @@ -305,6 +340,28 @@ int smp_udp_open(void)
{
bool started = false;

#if defined(CONFIG_MCUMGR_TRANSPORT_UDP_DTLS)
int rc;
size_t len = 0;

rc = tls_credential_get(CONFIG_MCUMGR_TRANSPORT_UDP_DTLS_TLS_TAG,
TLS_CREDENTIAL_PUBLIC_CERTIFICATE, NULL, &len);

if (rc == -ENOENT) {
LOG_ERR("Missing DTLS public certificate credential");
return rc;
}

len = 0;
rc = tls_credential_get(CONFIG_MCUMGR_TRANSPORT_UDP_DTLS_TLS_TAG,
TLS_CREDENTIAL_PRIVATE_KEY, NULL, &len);

if (rc == -ENOENT) {
LOG_ERR("Missing DTLS private key credential");
return rc;
}
#endif

#ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV4
if (k_thread_join(&smp_udp_configs.ipv4.thread, K_NO_WAIT) == 0 ||
threads_created == false) {
Expand Down
Loading