-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lib: uicc_lwm2m: Add UICC LwM2M library
Add functionality to read LwM2M bootstrap data from UICC. Signed-off-by: Stig Bjørlykke <stig.bjorlykke@nordicsemi.no>
- Loading branch information
1 parent
9c7c28c
commit 6db1f9e
Showing
24 changed files
with
1,198 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
.. _lib_uicc_lwm2m: | ||
|
||
UICC LwM2M | ||
########## | ||
|
||
.. contents:: | ||
:local: | ||
:depth: 2 | ||
|
||
The UICC LwM2M library provides functionality to read LwM2M bootstrap configuration from SIM. | ||
|
||
Dependencies | ||
************ | ||
|
||
The UICC LwM2M library requires the `nrf_modem` library to use AT commands. | ||
|
||
Configuration | ||
************* | ||
|
||
To enable the UICC LwM2M library, configure the :kconfig:option:`CONFIG_UICC_LWM2M` Kconfig option. | ||
|
||
API documentation | ||
***************** | ||
|
||
| Header file: :file:`include/modem/uicc_lwm2m.h` | ||
| Source file: :file:`lib/uicc_lwm2m/uicc_lwm2m.c` | ||
.. doxygengroup:: uicc_lwm2m | ||
:project: nrf | ||
:members: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
*/ | ||
|
||
#ifndef UICC_LWM2M_H_ | ||
#define UICC_LWM2M_H_ | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @file uicc_lwm2m.h | ||
* | ||
* @defgroup uicc_lwm2m UICC LwM2M | ||
* | ||
* @{ | ||
* | ||
* @brief Public APIs of the UICC LwM2M library. | ||
*/ | ||
|
||
/** UICC record max size is 256 bytes. The buffer size needed for the AT response is | ||
* (256 * 2) + 4 bytes for SW + 1 byte for NUL. Using 516 bytes is adequate to read | ||
* a full UICC record. | ||
*/ | ||
#define UICC_RECORD_BUFFER_MAX ((256 * 2) + 4 + 1) | ||
|
||
/** | ||
* @brief Read UICC LwM2M bootstrap record. | ||
* | ||
* @param[inout] buffer Buffer to store UICC LwM2M bootstrap record. This buffer is also | ||
* used internally by the function reading the AT response, so it must | ||
* be twice the size of expected LwM2M content + 4 bytes for UICC SW. | ||
* @param[in] buffer_size Total size of buffer. | ||
* | ||
* @return Length of UICC LwM2M bootstrap record, -errno on error. | ||
*/ | ||
int uicc_lwm2m_bootstrap_read(uint8_t *buffer, int buffer_size); | ||
|
||
/** @} */ | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* UICC_LWM2M_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
|
||
zephyr_library() | ||
|
||
zephyr_include_directories( | ||
${ZEPHYR_NRFXLIB_MODULE_DIR}/nrf_modem/include/ | ||
) | ||
|
||
zephyr_library_sources( | ||
asn1_decode.c | ||
pkcs15_decode.c | ||
uicc_lwm2m.c | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
|
||
config UICC_LWM2M | ||
bool "UICC LwM2M bootstrap support" | ||
depends on NRF_MODEM_LIB | ||
help | ||
"Enable UICC LwM2M bootstrap library" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
*/ | ||
|
||
#include <zephyr/sys/util.h> | ||
|
||
#include "asn1_decode.h" | ||
|
||
bool asn1_dec_head(asn1_ctx_t *ctx, uint8_t *tag, size_t *len) | ||
{ | ||
uint32_t hlen = 2; /* Minimum two bytes for header */ | ||
|
||
if (ctx->error || ((ctx->offset + hlen) > ctx->length)) { | ||
/* Error detected or out of data (happens at end of sequence) */ | ||
return false; | ||
} | ||
|
||
*tag = ctx->asnbuf[ctx->offset++]; | ||
*len = ctx->asnbuf[ctx->offset++]; | ||
|
||
if ((*tag & 0x1F) == 0x1F) { | ||
/* Extended tag number is unsupported */ | ||
ctx->error = true; | ||
return false; | ||
} | ||
|
||
if (*len & 0x80) { | ||
int n = *len & 0x7F; | ||
|
||
hlen += n; | ||
if (n > 3 || (ctx->offset + hlen) > ctx->length) { | ||
/* Unsupported header length or out of data (header is past buffer) */ | ||
ctx->error = true; | ||
return false; | ||
} | ||
|
||
*len = 0; | ||
for (int i = 0; i < n; i++) { | ||
*len = (*len << 8) + ctx->asnbuf[ctx->offset++]; | ||
} | ||
} | ||
|
||
if ((ctx->offset + *len) > ctx->length) { | ||
/* Out of data (value is past buffer) */ | ||
ctx->error = true; | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
void asn1_dec_octet_string(asn1_ctx_t *ctx, size_t len, uint8_t *value, size_t max_len) | ||
{ | ||
if (bin2hex(&ctx->asnbuf[ctx->offset], len, value, max_len) == 0) { | ||
/* OCTET STRING too long for buffer */ | ||
ctx->error = true; | ||
return; | ||
} | ||
|
||
ctx->offset += len; | ||
} | ||
|
||
void asn1_dec_sequence(asn1_ctx_t *ctx, size_t len, void *data, asn1_sequence_func_t sequence_func) | ||
{ | ||
/* Create a subset from the buffer */ | ||
asn1_ctx_t seq_ctx = { | ||
.asnbuf = &ctx->asnbuf[ctx->offset], | ||
.length = len | ||
}; | ||
|
||
sequence_func(&seq_ctx, data); | ||
ctx->offset += len; | ||
|
||
/* Copy error from subset */ | ||
ctx->error = seq_ctx.error; | ||
} | ||
|
||
void asn1_dec_skip(asn1_ctx_t *ctx, size_t len) | ||
{ | ||
ctx->offset += len; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
*/ | ||
|
||
/* A minimalistic ASN.1 BER/DER decoder (X.690). | ||
* | ||
* Supported types: | ||
* OCTET STRING | ||
* SEQUENCE / SEQUENCE OF | ||
*/ | ||
|
||
#ifndef ASN1_DECODE_H_ | ||
#define ASN1_DECODE_H_ | ||
|
||
#include <stdlib.h> | ||
#include <stdint.h> | ||
#include <stdbool.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** Commonly used ASN.1 tags. */ | ||
#define UP4 0x04 | ||
#define UP6 0x06 | ||
#define UC16 0x30 | ||
#define AP15 0x4F | ||
#define AP16 0x50 | ||
#define CC1 0xA1 | ||
#define CC7 0xA7 | ||
|
||
/** ASN.1 context values */ | ||
typedef struct { | ||
const uint8_t *asnbuf; /**< ASN.1 BER/DER encoded buffer */ | ||
size_t length; /**< Length of the data buffer */ | ||
uint32_t offset; /**< Current offset into asnbuf */ | ||
bool error; /**< Error detected in ASN.1 syntax */ | ||
} asn1_ctx_t; | ||
|
||
/** Function called to handle elements in a SEQUENCE */ | ||
typedef void (*asn1_sequence_func_t)(asn1_ctx_t *ctx, void *data); | ||
|
||
/** | ||
* @brief Decode ASN.1 header. | ||
* | ||
* @param[in] ctx ASN.1 context values. | ||
* @param[out] tag ASN.1 TAG. | ||
* @param[out] len Length of ASN.1 value. | ||
* | ||
* @return true when valid ASN.1 and a value exists | ||
*/ | ||
bool asn1_dec_head(asn1_ctx_t *ctx, uint8_t *tag, size_t *len); | ||
|
||
/** | ||
* @brief Decode ASN.1 OCTET STRING. | ||
* | ||
* @param[in] ctx ASN.1 context values. | ||
* @param[in] len Length of octet string to decode. | ||
* @param[out] value Decoded octet string. | ||
* @param[in] max_len Maximum length of octet string to decode. | ||
*/ | ||
void asn1_dec_octet_string(asn1_ctx_t *ctx, size_t len, uint8_t *value, size_t max_len); | ||
|
||
/** | ||
* @brief Decode ASN.1 SEQUENCE. | ||
* | ||
* @param[in] ctx ASN.1 context values. | ||
* @param[in] len Length of sequence to decode. | ||
* @param[inout] data Pointer to application specific values. | ||
* @param[in] sequence_func Function to be called to handle sequence elements. | ||
*/ | ||
void asn1_dec_sequence(asn1_ctx_t *ctx, size_t len, void *data, asn1_sequence_func_t sequence_func); | ||
|
||
/** | ||
* @brief Skip a subset of ASN.1 content. | ||
* This is used to skip parts of the content which is not of interest. | ||
* | ||
* @param[in] ctx ASN.1 context values. | ||
* @param[in] len Length of data to skip. | ||
*/ | ||
void asn1_dec_skip(asn1_ctx_t *ctx, size_t len); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* ASN1_DECODE_H_ */ |
Oops, something went wrong.